notes/merging.md: the PR-stack rules do not say what to rebase a child onto when the parent moves nf-hih ← Beads

open priority 2 task unassigned

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.

How it bit, today, in a shape that looks tidy

```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.

Suggested line

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.

Dependencies

None.

Comments

No comments.

Add a comment