@@ -1017,3 +1017,86 @@ func TestDetermineSyncRemote(t *testing.T) {
10171017 assert .Equal (t , "origin" , result )
10181018 })
10191019}
1020+
1021+ func TestRunSyncSkipsWorktreeBranches (t * testing.T ) {
1022+ testutil .SetupTest ()
1023+ defer testutil .TeardownTest ()
1024+
1025+ t .Run ("skips branch checked out in another worktree" , func (t * testing.T ) {
1026+ mockGit := new (testutil.MockGitClient )
1027+ mockGH := new (testutil.MockGitHubClient )
1028+
1029+ // Setup: no existing sync state
1030+ mockGit .On ("GetConfig" , "stack.sync.stashed" ).Return ("" )
1031+ mockGit .On ("GetConfig" , "stack.sync.originalBranch" ).Return ("" )
1032+ mockGit .On ("GetCurrentBranch" ).Return ("feature-c" , nil )
1033+ mockGit .On ("SetConfig" , "stack.sync.originalBranch" , "feature-c" ).Return (nil )
1034+ mockGit .On ("IsWorkingTreeClean" ).Return (true , nil )
1035+ mockGit .On ("GetConfig" , "branch.feature-c.stackparent" ).Return ("feature-b" )
1036+ mockGit .On ("GetConfig" , "stack.baseBranch" ).Return ("" ).Maybe ()
1037+ mockGit .On ("GetDefaultBranch" ).Return ("main" ).Maybe ()
1038+
1039+ stackParents := map [string ]string {
1040+ "feature-a" : "main" ,
1041+ "feature-b" : "feature-a" ,
1042+ "feature-c" : "feature-b" ,
1043+ }
1044+ mockGit .On ("GetAllStackParents" ).Return (stackParents , nil ).Maybe ()
1045+
1046+ // Parallel operations
1047+ mockGit .On ("FetchRemote" , "origin" ).Return (nil )
1048+ mockGH .On ("GetPRsForBranches" , mock .Anything ).Return (make (map [string ]* github.PRInfo ))
1049+
1050+ // feature-b is in another worktree
1051+ mockGit .On ("GetWorktreeBranches" ).Return (map [string ]string {
1052+ "feature-b" : "/other/worktree" ,
1053+ }, nil )
1054+ mockGit .On ("GetCurrentWorktreePath" ).Return ("/Users/test/repo" , nil )
1055+
1056+ mockGit .On ("GetRemoteBranchesSet" ).Return (map [string ]bool {
1057+ "main" : true ,
1058+ "feature-a" : true ,
1059+ "feature-b" : true ,
1060+ "feature-c" : true ,
1061+ })
1062+
1063+ // Process feature-a (not skipped)
1064+ mockGit .On ("CheckoutBranch" , "feature-a" ).Return (nil )
1065+ mockGit .On ("GetCommitHash" , "feature-a" ).Return ("aaa111" , nil )
1066+ mockGit .On ("GetCommitHash" , "origin/feature-a" ).Return ("aaa111" , nil )
1067+ mockGit .On ("FetchBranchFromRemote" , "origin" , "main" ).Return (nil )
1068+ mockGit .On ("GetUniqueCommitsByPatch" , "origin/main" , "feature-a" ).Return ([]string {"aaa111" }, nil )
1069+ mockGit .On ("GetMergeBase" , "feature-a" , "origin/main" ).Return ("main123" , nil )
1070+ mockGit .On ("GetCommitHash" , "origin/main" ).Return ("main123" , nil )
1071+ mockGit .On ("Rebase" , "origin/main" ).Return (nil )
1072+ mockGit .On ("FetchBranch" , "feature-a" ).Return (nil )
1073+ mockGit .On ("PushWithExpectedRemote" , "feature-a" , "aaa111" ).Return (nil )
1074+
1075+ // feature-b is SKIPPED (in another worktree) - no checkout/rebase/push calls
1076+
1077+ // Process feature-c (not skipped)
1078+ mockGit .On ("CheckoutBranch" , "feature-c" ).Return (nil )
1079+ mockGit .On ("GetCommitHash" , "feature-c" ).Return ("ccc333" , nil )
1080+ mockGit .On ("GetCommitHash" , "origin/feature-c" ).Return ("ccc333" , nil )
1081+ mockGit .On ("GetUniqueCommitsByPatch" , "feature-b" , "feature-c" ).Return ([]string {"ccc333" }, nil )
1082+ mockGit .On ("GetMergeBase" , "feature-c" , "feature-b" ).Return ("bbb222" , nil )
1083+ mockGit .On ("GetCommitHash" , "feature-b" ).Return ("bbb222" , nil )
1084+ mockGit .On ("Rebase" , "feature-b" ).Return (nil )
1085+ mockGit .On ("FetchBranch" , "feature-c" ).Return (nil )
1086+ mockGit .On ("PushWithExpectedRemote" , "feature-c" , "ccc333" ).Return (nil )
1087+
1088+ // Return to original branch
1089+ mockGit .On ("CheckoutBranch" , "feature-c" ).Return (nil )
1090+ // Clean up sync state
1091+ mockGit .On ("UnsetConfig" , "stack.sync.stashed" ).Return (nil )
1092+ mockGit .On ("UnsetConfig" , "stack.sync.originalBranch" ).Return (nil )
1093+
1094+ err := runSync (mockGit , mockGH , "origin" )
1095+
1096+ assert .NoError (t , err )
1097+ // Verify feature-b was never checked out
1098+ mockGit .AssertNotCalled (t , "CheckoutBranch" , "feature-b" )
1099+ mockGit .AssertExpectations (t )
1100+ mockGH .AssertExpectations (t )
1101+ })
1102+ }
0 commit comments