@@ -918,6 +918,79 @@ func TestTrackRejectsUntrackedParent(t *testing.T) {
918918 }
919919}
920920
921+ func TestTrackUsesMergeBaseAnchorForStaleAdoption (t * testing.T ) {
922+ repo := testutil .SetupGitRepo (t )
923+
924+ testutil .Run (t , repo , "git" , "switch" , "-c" , "feature/base" )
925+ testutil .WriteFile (t , filepath .Join (repo , "feature-base.txt" ), "feature base\n " )
926+ testutil .Run (t , repo , "git" , "add" , "feature-base.txt" )
927+ testutil .Run (t , repo , "git" , "commit" , "-m" , "add feature base" )
928+ originalFeatureBaseHead := strings .TrimSpace (testutil .Run (t , repo , "git" , "rev-parse" , "HEAD" ))
929+
930+ testutil .Run (t , repo , "git" , "switch" , "-c" , "feature/child" )
931+ testutil .WriteFile (t , filepath .Join (repo , "feature-child.txt" ), "feature child\n " )
932+ testutil .Run (t , repo , "git" , "add" , "feature-child.txt" )
933+ testutil .Run (t , repo , "git" , "commit" , "-m" , "add feature child" )
934+ originalFeatureChildHead := strings .TrimSpace (testutil .Run (t , repo , "git" , "rev-parse" , "HEAD" ))
935+
936+ testutil .Run (t , repo , "git" , "switch" , "feature/base" )
937+ testutil .WriteFile (t , filepath .Join (repo , "feature-base.txt" ), "feature base advanced\n " )
938+ testutil .Run (t , repo , "git" , "add" , "feature-base.txt" )
939+ testutil .Run (t , repo , "git" , "commit" , "-m" , "advance feature base" )
940+ advancedFeatureBaseHead := strings .TrimSpace (testutil .Run (t , repo , "git" , "rev-parse" , "HEAD" ))
941+
942+ runtime := newTestRuntime (repo )
943+ mainHead , err := runtime .Git .ResolveRef (runtime .Context , "main" )
944+ if err != nil {
945+ t .Fatalf ("resolve main head: %v" , err )
946+ }
947+ state := store.RepoState {
948+ Version : 1 ,
949+ Repo : "hack-dance/stack" ,
950+ DefaultRemote : "origin" ,
951+ Trunk : "main" ,
952+ Branches : map [string ]store.BranchRecord {},
953+ }
954+ if err := runtime .Store .WriteState (runtime .Context , state ); err != nil {
955+ t .Fatalf ("write state: %v" , err )
956+ }
957+
958+ executeCommand (t , runtime , "track" , "feature/base" , "--parent" , "main" )
959+ executeCommand (t , runtime , "track" , "feature/child" , "--parent" , "feature/base" )
960+
961+ state , err = runtime .Store .ReadState (runtime .Context )
962+ if err != nil {
963+ t .Fatalf ("read state after track: %v" , err )
964+ }
965+ if got := state .Branches ["feature/base" ].Restack .LastParentHeadOID ; got != mainHead {
966+ t .Fatalf ("expected feature/base anchor %q, got %q" , mainHead , got )
967+ }
968+ if got := state .Branches ["feature/child" ].Restack .LastParentHeadOID ; got != originalFeatureBaseHead {
969+ t .Fatalf ("expected feature/child merge-base anchor %q, got %q" , originalFeatureBaseHead , got )
970+ }
971+ if originalFeatureBaseHead == advancedFeatureBaseHead {
972+ t .Fatalf ("expected feature/base head to advance" )
973+ }
974+
975+ executeCommand (t , runtime , "restack" , "--all" , "--yes" )
976+
977+ state , err = runtime .Store .ReadState (runtime .Context )
978+ if err != nil {
979+ t .Fatalf ("read state after restack: %v" , err )
980+ }
981+ if got := state .Branches ["feature/child" ].Restack .LastParentHeadOID ; got != advancedFeatureBaseHead {
982+ t .Fatalf ("expected feature/child anchor to update to %q, got %q" , advancedFeatureBaseHead , got )
983+ }
984+ if got := strings .TrimSpace (testutil .Run (t , repo , "git" , "rev-parse" , "feature/child" )); got == originalFeatureChildHead {
985+ t .Fatalf ("expected feature/child head to change after restack" )
986+ }
987+
988+ mergeBase := strings .TrimSpace (testutil .Run (t , repo , "git" , "merge-base" , "feature/base" , "feature/child" ))
989+ if mergeBase != advancedFeatureBaseHead {
990+ t .Fatalf ("expected feature/child merge-base %q after restack, got %q" , advancedFeatureBaseHead , mergeBase )
991+ }
992+ }
993+
921994func TestVersionCommandPrintsBuildInfo (t * testing.T ) {
922995 repo := testutil .SetupGitRepo (t )
923996 runtime := newTestRuntime (repo )
0 commit comments