Twinned from https://github.com/cfsh/ninefold/issues/676 by tools/beads/import_github.py's reconcile pass.
notes/merging.md § PR-stack rules covers the harder cases and skips the plainest one.
It has: never merge on mergeable=UNKNOWN; retarget all open children to main before the parent merges; never force-push mid-cherry-pick; after a squash-merge rebuild children by cherry-picking their own commits onto fresh main (not rebase --onto); a closed PR force-pushed while closed cannot be reopened.
What it does not say: when the parent branch itself moves — a rebase onto main, a review fix, a new base — the child rebases onto the PARENT BRANCH, never onto whatever the parent moved onto.
```bash for b in feat/reaper feat/reap-office; do git switch -q $b && git rebase fix/perimeter-mentions ./presubmit.py --all && git push --force-with-lease origin $b done ```
feat/reap-office was stacked on feat/reaper. Rebasing both onto the shared base put the child's own copies of the parent's nine commits into its history, so it stopped descending from the parent:
``` $ git merge-base --is-ancestor feat/reaper feat/reap-office; echo $? 1 $ git log --oneline feat/reaper..feat/reap-office | wc -l 14 # 5 of its own + 9 duplicates of the parent's ```
GitHub reported the child PR CONFLICTING and its diff grew to include the whole parent. Nothing was lost and the fix is one command (git rebase <parent>, which drops the patch-identical duplicates), but the symptom — *my converged child PR is suddenly conflicting and twice the size* — reads as a merge problem rather than as the loop that caused it.
⚠️ The loop reads as symmetric and the stack is not. That is the whole lesson, and it is exactly the kind of thing this file exists to hold.
Under § PR-stack rules:
> - When the parent branch moves, rebase the child onto the PARENT, not onto what the parent moved onto. A for loop over both branches with one base is the tidy-looking way to break a stack: the child ends up with duplicate copies of the parent's commits, stops descending from it, and GitHub calls the PR CONFLICTING with a diff twice the size. git merge-base --is-ancestor <parent> <child> is the one-line check.
Found while working #640/#641 (session:reaper). Filed rather than added to a converged head — unclaimed.
None.
No comments.