@@ -2544,6 +2544,52 @@ func TestRebase_Issue512StaleRecordedBase(t *testing.T) {
25442544 })
25452545}
25462546
2547+ func testIssue512RepeatedRegularMerge (t * testing.T , run func (* config.Config ) error ) {
2548+ t .Helper ()
2549+ repo := setupIssue512Repo (t )
2550+ issue250WriteFile (t , repo .writer , "trunk-only.txt" , "before merge\n " )
2551+ issue250Git (t , repo .writer , "add" , "." )
2552+ issue250Git (t , repo .writer , "commit" , "-m" , "trunk before merge" )
2553+ issue250Git (t , repo .writer , "merge" , "--no-ff" , "origin/parent" , "-m" , "merge parent" )
2554+ issue250Git (t , repo .writer , "push" , "origin" , "main" )
2555+ withIssue250Repo (t , repo .dir )
2556+ cfg := issue512Config (t , repo .mergedHead )
2557+ require .NoError (t , run (cfg ))
2558+ assertIssue512History (t , repo )
2559+
2560+ issue250Git (t , repo .dir , "branch" , "-D" , "parent" )
2561+ sf , err := stack .Load (repo .gitDir )
2562+ require .NoError (t , err )
2563+ sf .Stacks [0 ].Branches [0 ].Head = ""
2564+ require .NoError (t , stack .Save (repo .gitDir , sf ))
2565+ issue250WriteFile (t , repo .writer , "trunk-only.txt" , "after merge\n " )
2566+ issue250Git (t , repo .writer , "add" , "." )
2567+ issue250Git (t , repo .writer , "commit" , "-m" , "trunk after merge" )
2568+ issue250Git (t , repo .writer , "push" , "origin" , "main" )
2569+
2570+ require .NoError (t , run (cfg ))
2571+ assertIssue512History (t , repo )
2572+ assert .Equal (t , "after merge" , issue250Git (t , repo .dir , "show" , "child:trunk-only.txt" ))
2573+ }
2574+
2575+ func TestRebase_Issue512RepeatedRegularMerge (t * testing.T ) {
2576+ testIssue512RepeatedRegularMerge (t , func (cfg * config.Config ) error {
2577+ return runRebase (cfg , & rebaseOptions {remote : "origin" })
2578+ })
2579+ }
2580+
2581+ func TestRebase_MergedHeadPreservesUnmergedRecordedBase (t * testing.T ) {
2582+ restore := git .SetOps (& git.MockOps {
2583+ IsAncestorFn : func (a , b string ) (bool , error ) {
2584+ return ! (a == "unmerged-local" && b == "main" ), nil
2585+ },
2586+ })
2587+ defer restore ()
2588+ base , err := resolveMergedRebaseOldBase ("merged" , "unmerged-local" , "unmerged-local" , "main" , "child" )
2589+ require .NoError (t , err )
2590+ assert .Equal (t , "merged" , base , "a recorded base not in the destination must not discard unmerged work" )
2591+ }
2592+
25472593func TestRebase_Issue512SelectedRangeWithPrunedParent (t * testing.T ) {
25482594 for _ , mode := range []string {"upstack" , "downstack" , "no-trunk" } {
25492595 t .Run (mode , func (t * testing.T ) {
@@ -3458,6 +3504,44 @@ func TestRebase_LegacyContinuePersistsCatalogUnderOperationLock(t *testing.T) {
34583504 assert .ErrorIs (t , err , os .ErrNotExist )
34593505}
34603506
3507+ func TestRebase_LegacyContinueKeepsNamedTrunkForForkPoint (t * testing.T ) {
3508+ dir := t .TempDir ()
3509+ writeStackFile (t , dir , stack.Stack {
3510+ Trunk : stack.BranchRef {Branch : "main" },
3511+ Branches : []stack.BranchRef {
3512+ {Branch : "parent" , PullRequest : & stack.PullRequestRef {Number : 10 , Merged : true }},
3513+ {Branch : "child" , Base : "recorded" },
3514+ },
3515+ })
3516+ require .NoError (t , saveRebaseState (dir , & rebaseState {
3517+ OriginalBranch : "child" , ConflictBranch : "parent" , RemainingBranches : []string {"child" },
3518+ OriginalRefs : map [string ]string {"parent" : "stale" , "child" : "before" },
3519+ UseOnto : true , OntoOldBase : "stale" , TrunkRef : "main" , TrunkSHA : "pinned" ,
3520+ }))
3521+ mock := newRebaseMock (dir , "child" )
3522+ mock .IsAncestorFn = func (a , b string ) (bool , error ) { return a != "stale" , nil }
3523+ mock .MergeBaseForkPointFn = func (ref , branch string ) (string , error ) {
3524+ assert .Equal (t , "main" , ref )
3525+ if ref != "main" {
3526+ return "" , fmt .Errorf ("No such ref: %s" , ref )
3527+ }
3528+ return "" , nil
3529+ }
3530+ rebased := false
3531+ mock .RebaseOntoFn = func (target , oldBase , branch string , _ git.RebaseOpts ) error {
3532+ rebased = true
3533+ assert .Equal (t , "pinned" , target )
3534+ assert .Equal (t , "recorded" , oldBase )
3535+ assert .Equal (t , "child" , branch )
3536+ return nil
3537+ }
3538+ restore := git .SetOps (mock )
3539+ defer restore ()
3540+ require .NoError (t , runRebase (issue250TestConfig (t ), & rebaseOptions {cont : true }))
3541+ assert .True (t , rebased )
3542+ assert .NoFileExists (t , filepath .Join (dir , rebaseStateFile ))
3543+ }
3544+
34613545func TestRebase_LegacyPhaseGuards (t * testing.T ) {
34623546 for _ , tc := range []struct {
34633547 phase string
0 commit comments