@@ -457,6 +457,76 @@ func watchAndMerge(previewWorktreePath, baseBranch string, branchEnabled map[str
457457 }
458458 }
459459
460+ // Refresh branch info from current worktrees
461+ // Returns: new branches added, branches removed
462+ refreshBranchInfo := func () (added []string , removed []string ) {
463+ gitRoot , _ := getGitRoot ()
464+ worktrees , err := getWorktrees ()
465+ if err != nil {
466+ return nil , nil
467+ }
468+
469+ // Track current branch names
470+ currentBranches := make (map [string ]bool )
471+
472+ for _ , wt := range worktrees {
473+ // Skip main worktree, default branch, preview branch, detached
474+ if wt .Path == gitRoot || wt .Branch == baseBranch ||
475+ wt .Branch == "main" || wt .Branch == "master" ||
476+ wt .Branch == previewBranchName || wt .Detached || wt .Branch == "" {
477+ continue
478+ }
479+
480+ currentBranches [wt .Branch ] = true
481+
482+ // Add new branch if not in branchInfo
483+ if _ , exists := branchInfo [wt .Branch ]; ! exists {
484+ commitsAhead , _ := getCommitCountBetween (baseBranch , wt .Branch )
485+ hasWIP := false
486+ if hasChanges , err := hasUncommittedChanges (wt .Path ); err == nil {
487+ hasWIP = hasChanges
488+ }
489+
490+ branchInfo [wt .Branch ] = & BranchInfo {
491+ Branch : wt .Branch ,
492+ CommitsAhead : commitsAhead ,
493+ WorktreePath : wt .Path ,
494+ HasWIP : hasWIP ,
495+ }
496+ added = append (added , wt .Branch )
497+
498+ // Initialize state maps for new branch
499+ branchEnabled [wt .Branch ] = false // Off by default
500+ stagedEnabled [wt .Branch ] = previewStaged
501+ unstagedEnabled [wt .Branch ] = previewUnstaged
502+ lastHeads [wt .Branch ], _ = getBranchHead (wt .Branch )
503+ lastWIPHash [wt .Branch ] = getWIPHash (wt .Path )
504+ } else {
505+ // Update worktree path (might have changed)
506+ branchInfo [wt .Branch ].WorktreePath = wt .Path
507+ }
508+ }
509+
510+ // Find removed branches
511+ for branch := range branchInfo {
512+ if ! currentBranches [branch ] {
513+ removed = append (removed , branch )
514+ }
515+ }
516+
517+ // Remove deleted branches from all maps
518+ for _ , branch := range removed {
519+ delete (branchInfo , branch )
520+ delete (branchEnabled , branch )
521+ delete (stagedEnabled , branch )
522+ delete (unstagedEnabled , branch )
523+ delete (lastHeads , branch )
524+ delete (lastWIPHash , branch )
525+ }
526+
527+ return added , removed
528+ }
529+
460530 pollInterval := 5 * time .Second
461531
462532 // Setup signal handling for graceful exit
@@ -888,6 +958,15 @@ func watchAndMerge(previewWorktreePath, baseBranch string, branchEnabled map[str
888958 return nil
889959
890960 case 'b' , 'B' :
961+ // Refresh branch list before showing modal
962+ added , removed := refreshBranchInfo ()
963+ if len (added ) > 0 {
964+ addLog ("New branches available: %s" , strings .Join (added , ", " ))
965+ }
966+ if len (removed ) > 0 {
967+ addLog ("Branches removed: %s" , strings .Join (removed , ", " ))
968+ }
969+
891970 // Show branch toggle modal
892971 drawScreen ()
893972 drawModal ("Toggle Branches" , buildBranchModalLines ())
@@ -1060,6 +1139,17 @@ func watchAndMerge(previewWorktreePath, baseBranch string, branchEnabled map[str
10601139 }
10611140
10621141 case <- ticker .C :
1142+ // Refresh branch list to detect new/removed worktrees
1143+ added , removed := refreshBranchInfo ()
1144+ if len (added ) > 0 {
1145+ addLog ("New branches available: %s" , strings .Join (added , ", " ))
1146+ drawScreen ()
1147+ }
1148+ if len (removed ) > 0 {
1149+ addLog ("Branches removed: %s" , strings .Join (removed , ", " ))
1150+ drawScreen ()
1151+ }
1152+
10631153 // Get currently enabled branches
10641154 branches := getEnabledBranches ()
10651155 if len (branches ) == 0 {
0 commit comments