@@ -12,6 +12,7 @@ import {
1212 getCurrentBranch ,
1313 checkout ,
1414 pullBranch ,
15+ fetchAndUpdateBranch ,
1516 rebaseBranch ,
1617 mergeBranch ,
1718 deleteBranch ,
@@ -41,12 +42,11 @@ async function runSync(options: { all?: boolean }): Promise<void> {
4142
4243 // ── Step 1: Always pull default branch ───────────────────────────────────────
4344 const startBranch = await getCurrentBranch ( ) ;
44- if ( startBranch !== defaultBranch ) {
45- await checkout ( defaultBranch ) ;
46- }
47- await withSpinner ( `Pulling ${ defaultBranch } ...` , ( ) => pullBranch ( defaultBranch ) ) ;
48- if ( startBranch !== defaultBranch ) {
49- await checkout ( startBranch ) ;
45+ if ( startBranch === defaultBranch ) {
46+ await withSpinner ( `Pulling ${ defaultBranch } ...` , ( ) => pullBranch ( defaultBranch ) ) ;
47+ } else {
48+ // Update local default branch ref via fetch without checking it out
49+ await withSpinner ( `Pulling ${ defaultBranch } ...` , ( ) => fetchAndUpdateBranch ( defaultBranch ) ) ;
5050 }
5151 console . log ( theme . success ( ` ${ symbols . success } Pulled latest ${ defaultBranch } ` ) ) ;
5252
@@ -148,6 +148,18 @@ async function runSync(options: { all?: boolean }): Promise<void> {
148148 const diverged = await hasDiverged ( branch . branchName , defaultBranch ) ;
149149 if ( ! diverged ) continue ;
150150
151+ const isCurrentBranch = branch . branchName === currentBranch ;
152+
153+ // For non-current branches without a worktree we can't rebase/merge without checkout
154+ if ( ! isCurrentBranch && ! branch . worktreePath ) {
155+ console . log (
156+ theme . muted (
157+ ` ${ symbols . arrow } ${ branch . branchName } is behind ${ defaultBranch } — switch to it to update` ,
158+ ) ,
159+ ) ;
160+ continue ;
161+ }
162+
151163 const action = await select < 'rebase' | 'merge' | 'skip' > ( {
152164 message : `${ defaultBranch } has new commits not in ${ branch . branchName } . What do you want to do?` ,
153165 options : [
@@ -159,18 +171,17 @@ async function runSync(options: { all?: boolean }): Promise<void> {
159171
160172 if ( action === 'skip' ) continue ;
161173
162- if ( currentBranch !== branch . branchName ) {
163- await checkout ( branch . branchName ) ;
164- }
174+ // Run in the worktree directory for non-current branches; current branch uses process cwd
175+ const cwd = isCurrentBranch ? undefined : ( branch . worktreePath ?? undefined ) ;
165176
166177 try {
167178 if ( action === 'rebase' ) {
168- await rebaseBranch ( defaultBranch ) ;
179+ await rebaseBranch ( defaultBranch , cwd ) ;
169180 console . log (
170181 theme . success ( ` ${ symbols . success } Rebased ${ branch . branchName } onto ${ defaultBranch } ` ) ,
171182 ) ;
172183 } else {
173- await mergeBranch ( defaultBranch ) ;
184+ await mergeBranch ( defaultBranch , true , cwd ) ;
174185 console . log (
175186 theme . success ( ` ${ symbols . success } Merged ${ defaultBranch } into ${ branch . branchName } ` ) ,
176187 ) ;
@@ -181,10 +192,6 @@ async function runSync(options: { all?: boolean }): Promise<void> {
181192 theme . warning ( ` ${ symbols . warning } ${ action } failed for ${ branch . branchName } : ${ msg } ` ) ,
182193 ) ;
183194 }
184-
185- if ( currentBranch !== branch . branchName ) {
186- await checkout ( currentBranch ) ;
187- }
188195 }
189196
190197 await configManager . saveBranches ( projectId , branchesFile ) ;
0 commit comments