@@ -480,7 +480,21 @@ export class SSHRuntime implements Runtime {
480480 throw new Error ( `Failed to clone repository: ${ cloneStderr || cloneStdout } ` ) ;
481481 }
482482
483- // Step 4: Update origin remote if we have an origin URL
483+ // Step 4: Create local tracking branches for all remote branches
484+ // This ensures that branch names like "custom-trunk" can be used directly
485+ // in git checkout commands, rather than needing "origin/custom-trunk"
486+ initLogger . logStep ( `Creating local tracking branches...` ) ;
487+ const createTrackingBranchesStream = await this . exec (
488+ `cd ${ cloneDestPath } && for branch in $(git for-each-ref --format='%(refname:short)' refs/remotes/origin/ | grep -v 'origin/HEAD'); do localname=\${branch#origin/}; git show-ref --verify --quiet refs/heads/$localname || git branch $localname $branch; done` ,
489+ {
490+ cwd : "~" ,
491+ timeout : 30 ,
492+ }
493+ ) ;
494+ await createTrackingBranchesStream . exitCode ;
495+ // Don't fail if this fails - some branches may already exist
496+
497+ // Step 5: Update origin remote if we have an origin URL
484498 if ( originUrl ) {
485499 initLogger . logStep ( `Setting origin remote to ${ originUrl } ...` ) ;
486500 const setOriginStream = await this . exec (
@@ -689,10 +703,24 @@ export class SSHRuntime implements Runtime {
689703
690704 // 2. Checkout branch remotely
691705 // If branch exists locally, check it out; otherwise create it from the specified trunk branch
692- // Note: After git clone from bundle, branches exist as origin/* refs, so we need to check both
693- // local branch and origin/branch when creating the new branch
706+ // Note: We've already created local branches for all remote refs in syncProjectToRemote
694707 initLogger . logStep ( `Checking out branch: ${ branchName } ` ) ;
695- const checkoutCmd = `(git checkout ${ shescape . quote ( branchName ) } 2>/dev/null || git checkout -b ${ shescape . quote ( branchName ) } origin/${ shescape . quote ( trunkBranch ) } 2>/dev/null || git checkout -b ${ shescape . quote ( branchName ) } ${ shescape . quote ( trunkBranch ) } )` ;
708+
709+ // DEBUG: Log git state after clone
710+ initLogger . logStep ( `[DEBUG] Inspecting git state after clone...` ) ;
711+ const debugStream = await this . exec (
712+ `echo "=== Current branch ===" && git branch && echo "=== All branches ===" && git branch -a && echo "=== HEAD ===" && git rev-parse HEAD && echo "=== Files ===" && ls -la` ,
713+ { cwd : workspacePath , timeout : 30 }
714+ ) ;
715+ const [ debugOut ] = await Promise . all ( [
716+ streamToString ( debugStream . stdout ) ,
717+ debugStream . exitCode ,
718+ ] ) ;
719+ initLogger . logStdout ( debugOut ) ;
720+
721+ // Try to checkout existing branch, or create new branch from trunk
722+ // Since we've created local branches for all remote refs, we can use branch names directly
723+ const checkoutCmd = `git checkout ${ shescape . quote ( branchName ) } 2>/dev/null || git checkout -b ${ shescape . quote ( branchName ) } ${ shescape . quote ( trunkBranch ) } ` ;
696724
697725 const checkoutStream = await this . exec ( checkoutCmd , {
698726 cwd : workspacePath , // Use the full workspace path for git operations
@@ -716,6 +744,18 @@ export class SSHRuntime implements Runtime {
716744 }
717745 initLogger . logStep ( "Branch checked out successfully" ) ;
718746
747+ // DEBUG: Log git state after checkout
748+ initLogger . logStep ( `[DEBUG] Inspecting git state after checkout...` ) ;
749+ const debugStream2 = await this . exec (
750+ `echo "=== Current branch ===" && git branch && echo "=== HEAD ===" && git rev-parse HEAD && echo "=== Files ===" && ls -la && echo "=== Last commits ===" && git log --oneline -5` ,
751+ { cwd : workspacePath , timeout : 30 }
752+ ) ;
753+ const [ debugOut2 ] = await Promise . all ( [
754+ streamToString ( debugStream2 . stdout ) ,
755+ debugStream2 . exitCode ,
756+ ] ) ;
757+ initLogger . logStdout ( debugOut2 ) ;
758+
719759 // 3. Run .cmux/init hook if it exists
720760 // Note: runInitHook calls logComplete() internally if hook exists
721761 const hookExists = await checkInitHookExists ( projectPath ) ;
0 commit comments