Appearance
date: 2026-06-07 tags: [git, pull-requests, rebase, stacked-prs, github] status: active graduated_to:
A stacked PR reads dirty after its base merges — but git rebase auto-resolves it, no hand-merge
Symptom — after a base PR in a stack merges into the sprint branch, GitHub flags the PRs above it mergeable_state: dirty (looks like a merge conflict needing manual resolution). Seen this session: merging #297 flipped #314/#315/#316 all to dirty at once.
Root cause — dirty reflects a conflict against the merge base, but the conflicting commits are the now-already-merged ancestors, not the PR's own work. A plain git rebase <new-base> recognises them as applied cherry-picks (skipped previously applied commit …) and drops them — there is nothing to resolve by hand. Bonus: the PR diff shrinks to its genuine net-new changes (#314 went 15 files/2032+ → 2 files/86+).
Fix — for each stacked PR: git fetch, git rebase origin/<sprint-branch>, git push --force-with-lease. All three rebased cleanly (bee281b, 26ead1b, 6262d39) and flipped dirty → mergeable. Do not open a conflict editor or recreate the branch — if the rebase doesn't skip cleanly (real textual conflict), then stop and resolve; the auto-skip is the common case after a stack-mate merges.
Guard — build-from-qa-plan's rebase action encodes the procedure (rebase a dirty stacked PR onto its base rather than hand-resolving). This entry records why it works, so a future reader doesn't mistake dirty for a real conflict and redo the stack.