Skip to content

Commit d345ca1

Browse files
authored
Merge pull request #178 from netresearch/retro/stacked-pr-retarget-dismisses-approval
docs(pull-request-workflow): a stacked PR loses its approvals when its base merges
2 parents 9af71aa + 9df7d0f commit d345ca1

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

skills/git-workflow/references/pull-request-workflow.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,31 @@ gh pr merge 123 --squash --delete-branch
907907
gh pr close 123
908908
```
909909

910+
### A stacked PR loses its approvals the moment its base merges
911+
912+
Stacking — PR B opened against PR A's branch so B can build on text or code that exists only there — is the right shape when B has no anchor without A. GitHub retargets B to `main` automatically when A merges, which is the point of the pattern. What it also does is **dismiss every review on B**, because the base changed:
913+
914+
```
915+
reviews : github-actions=DISMISSED decision=REVIEW_REQUIRED
916+
```
917+
918+
Nothing about B changed. Its head SHA is the same, its checks are still green, no file moved. But `REVIEW_REQUIRED` is a host gate, not advice, so B cannot merge until an approval lands on that head again — and an automated approver only reruns on a new head. The recovery is to give it one, with the plain (merging) form of the command in [Updating a PR branch without a local clone](#updating-a-pr-branch-without-a-local-clone--gh-pr-update-branch---rebase):
919+
920+
```bash
921+
gh pr update-branch $PR --repo $OWNER/$REPO
922+
```
923+
924+
That merges the now-advanced base into B, which re-triggers CI **and** the approval workflow. Budget the full check matrix again, not a re-check.
925+
926+
Note the difference in *why* you reach for it. That section's caution is that `--rebase` force-updates and *can* reset approvals; here the approvals are **already** gone before you touch anything, dismissed by the retarget itself, and the update is what restores them.
927+
928+
Two things follow when you plan a stack:
929+
930+
- **Expect the second CI run.** The stack saves you a conflict, not a pipeline. If B's diff would conflict only trivially with A, opening B against `main` and resolving once may be cheaper than a retarget plus a full rerun.
931+
- **Merging the base advances `main`, so the child may now conflict.** The retarget makes B's *diff* correct, not its *tree*: anything both PRs touched — a shared `CHANGELOG.md` "Unreleased" section is the usual one — conflicts on the update-branch. Resolve it there; do not merge the base into the child while the child is queued.
932+
933+
Observed 2026-08-13 on netresearch/t3x-nr-llm#759, stacked on #758 for a documentation anchor that existed only on that branch.
934+
910935
### Handling Stale PRs
911936

912937
```yaml

0 commit comments

Comments
 (0)