@@ -90,18 +90,66 @@ func runView(cfg *config.Config, opts *viewOptions) error {
9090}
9191
9292func viewShort (cfg * config.Config , s * stack.Stack , currentBranch string ) error {
93+ var repoOwner , repoName string
94+ if repo , err := cfg .Repo (); err == nil {
95+ repoOwner = repo .Owner
96+ repoName = repo .Name
97+ }
98+
9399 for i := len (s .Branches ) - 1 ; i >= 0 ; i -- {
94100 b := s .Branches [i ]
101+ merged := b .PullRequest != nil && b .PullRequest .Merged
102+ indicator := branchStatusIndicator (cfg , s , b )
103+ prSuffix := shortPRSuffix (cfg , b , repoOwner , repoName )
95104 if b .Branch == currentBranch {
96- cfg .Outf ("● %s %s\n " , cfg .ColorBold (b .Branch ), cfg .ColorCyan ("(current)" ))
105+ cfg .Outf ("» %s%s%s %s\n " , cfg .ColorBold (b .Branch ), indicator , prSuffix , cfg .ColorCyan ("(current)" ))
106+ } else if merged {
107+ cfg .Outf ("│ %s%s%s\n " , cfg .ColorGray (b .Branch ), indicator , prSuffix )
97108 } else {
98- cfg .Outf ("○ %s\n " , b .Branch )
109+ cfg .Outf ("├ %s%s%s \n " , b .Branch , indicator , prSuffix )
99110 }
100111 }
101112 cfg .Outf ("└ %s\n " , s .Trunk .Branch )
102113 return nil
103114}
104115
116+ // branchStatusIndicator returns a colored status icon for a branch:
117+ // - ✓ (purple) if the PR has been merged
118+ // - ⚠ (yellow) if the branch needs rebasing (non-linear history)
119+ // - ○ (green) if there is an open PR
120+ func branchStatusIndicator (cfg * config.Config , s * stack.Stack , b stack.BranchRef ) string {
121+ if b .PullRequest != nil && b .PullRequest .Merged {
122+ return " " + cfg .ColorMagenta ("✓" )
123+ }
124+
125+ baseBranch := s .BaseBranch (b .Branch )
126+ if needsRebase , err := git .IsAncestor (baseBranch , b .Branch ); err == nil && ! needsRebase {
127+ return " " + cfg .ColorWarning ("⚠" )
128+ }
129+
130+ if b .PullRequest != nil && b .PullRequest .Number != 0 {
131+ return " " + cfg .ColorSuccess ("○" )
132+ }
133+
134+ return ""
135+ }
136+
137+ func shortPRSuffix (cfg * config.Config , b stack.BranchRef , owner , repo string ) string {
138+ if b .PullRequest == nil || b .PullRequest .Number == 0 {
139+ return ""
140+ }
141+ prNum := fmt .Sprintf ("#%d" , b .PullRequest .Number )
142+ if owner != "" && repo != "" {
143+ url := fmt .Sprintf ("https://github.com/%s/%s/pull/%d" , owner , repo , b .PullRequest .Number )
144+ prNum = fmt .Sprintf ("\033 ]8;;%s\033 \\ %s\033 ]8;;\033 \\ " , url , prNum )
145+ }
146+ colorFn := cfg .ColorSuccess // green for open
147+ if b .PullRequest .Merged {
148+ colorFn = cfg .ColorMagenta // purple for merged
149+ }
150+ return fmt .Sprintf (" %s" , colorFn (prNum ))
151+ }
152+
105153func viewFull (cfg * config.Config , s * stack.Stack , currentBranch string ) error {
106154 client , clientErr := cfg .GitHubClient ()
107155
@@ -123,6 +171,8 @@ func viewFull(cfg *config.Config, s *stack.Stack, currentBranch string) error {
123171 bullet = "●"
124172 }
125173
174+ indicator := branchStatusIndicator (cfg , s , b )
175+
126176 prInfo := ""
127177 if clientErr == nil && repoErr == nil {
128178 pr , err := client .FindPRForBranch (b .Branch )
@@ -136,7 +186,7 @@ func viewFull(cfg *config.Config, s *stack.Stack, currentBranch string) error {
136186 branchName = cfg .ColorCyan (b .Branch + " (current)" )
137187 }
138188
139- fmt .Fprintf (& buf , "%s %s%s \n " , bullet , branchName , prInfo )
189+ fmt .Fprintf (& buf , "%s %s %s%s \n " , bullet , branchName , indicator , prInfo )
140190
141191 commits , err := git .Log (b .Branch , 1 )
142192 if err == nil && len (commits ) > 0 {
0 commit comments