Scenario
A stack whose trunk is itself a feature branch with its own PR to main (a common "stack on top of an in-review PR" setup):
main
└── feat/base → PR #1 (base: main) ← stack trunk, created with --base feat/base
└── feat/layer-2 → PR #2 (base: feat/base)
└── feat/layer-3 → PR #3 (base: feat/layer-2)
PR #1 is then squash-merged into main on GitHub and feat/base is deleted. GitHub automatically retargets PR #2's base to main.
Observed
The stack's local metadata keeps trunk: { branch: "feat/base", head: <old sha> } forever:
gh stack view --json still reports the deleted branch as trunk.
sync cannot fast-forward the trunk (its remote ref no longer exists), and nothing offers to migrate the stack onto main.
- Because the trunk commits were squashed, the layers also need a
rebase --onto to shed the now-duplicated trunk commits — the merged-PR recovery that works so nicely for stack members doesn't cover the trunk.
Expected
When the trunk's remote branch is gone and a merged PR from that branch into X exists, sync (or a dedicated command) should offer to migrate the stack trunk to X and cascade-rebase, mirroring the existing squash-merge recovery for in-stack branches. Even just a gh stack init --retrunk <branch> escape hatch would help — today init --adopt refuses branches that already have PRs, so there is no supported path.
Workaround that worked
git branch -f feat/base origin/main (keep the local trunk name, point it at main)
gh stack rebase (cascades cleanly; git skips the squashed patches)
- Hand-edit the
gh-stack JSON state file in .git/ to set trunk: { branch: "main", head: <origin/main sha> }
After step 3, sync works normally again. Editing an internal state file obviously isn't a supported interface, hence this issue.
Version: gh-stack v0.0.8, gh 2.x, repo uses squash-merge as the default merge method.
Scenario
A stack whose trunk is itself a feature branch with its own PR to
main(a common "stack on top of an in-review PR" setup):PR #1 is then squash-merged into
mainon GitHub andfeat/baseis deleted. GitHub automatically retargets PR #2's base tomain.Observed
The stack's local metadata keeps
trunk: { branch: "feat/base", head: <old sha> }forever:gh stack view --jsonstill reports the deleted branch as trunk.synccannot fast-forward the trunk (its remote ref no longer exists), and nothing offers to migrate the stack ontomain.rebase --ontoto shed the now-duplicated trunk commits — the merged-PR recovery that works so nicely for stack members doesn't cover the trunk.Expected
When the trunk's remote branch is gone and a merged PR from that branch into
Xexists,sync(or a dedicated command) should offer to migrate the stack trunk toXand cascade-rebase, mirroring the existing squash-merge recovery for in-stack branches. Even just agh stack init --retrunk <branch>escape hatch would help — todayinit --adoptrefuses branches that already have PRs, so there is no supported path.Workaround that worked
git branch -f feat/base origin/main(keep the local trunk name, point it at main)gh stack rebase(cascades cleanly; git skips the squashed patches)gh-stackJSON state file in.git/to settrunk: { branch: "main", head: <origin/main sha> }After step 3,
syncworks normally again. Editing an internal state file obviously isn't a supported interface, hence this issue.Version: gh-stack v0.0.8, gh 2.x, repo uses squash-merge as the default merge method.