diff --git a/CHANGELOG.md b/CHANGELOG.md index 7add6858..4ffba985 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,30 @@ true until the next version shipped. ### Fixed +- The union-merge page did not say why rebasing works where merging does not + (#1116 follow-up). + + `CONTEXT.md` told a contributor to rebase rather than click *Update branch*, and + gave the commands, but not the reason. The reason is the part that makes the advice + transferable: **git reads `.gitattributes` from the tree it is merging INTO**, so a + branch opened before the driver landed cannot use it. + + Measured on #1107, whose head predates #1108: + + merge main INTO the branch conflicts: CHANGELOG.md + rebase the branch ONTO main conflicts: + + `grep -c 'CHANGELOG.md.*merge=union'` gives 0 on that head and 1 on main. Merging + brings main's commits into a tree whose attributes have no driver; rebasing replays + the branch onto main, where the driver is already in force. So for any branch older + than the driver, *Update branch* cannot work even in principle. + + THE ARM FOR THIS WAS RED ON THE UNMUTATED TREE FIRST. Its grep spanned the prose's + line break -- "the tree it is / merging **into**" -- so a line-based pattern found + 0 on a correct document. The mutation then reddened it as well, which looks like a + working removal proof and is two failures agreeing. Re-anchored on a phrase that + fits one line; the control is green and the mutation still reddens. + - A `CONFLICTING` badge on a changelog entry is GitHub, not git (#1116). #996 gave `CHANGELOG.md` a union merge driver, and it does what it was argued to diff --git a/CONTEXT.md b/CONTEXT.md index 205fe1a9..d9390ec7 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -500,6 +500,22 @@ Measured, on four branches rebased onto the driver after it landed: zero CHANGEL conflicts, one `## [Unreleased]`, every entry present, `docs_style.sh` green. The same merges showed `CONFLICTING` on GitHub throughout. +### And why rebasing works where merging does not + +The advice above is not a preference. Git reads `.gitattributes` from the tree it is +merging **into**, so a branch that predates the driver cannot use it: + + merge main INTO the branch conflicts: CHANGELOG.md + rebase the branch ONTO main conflicts: + +Measured on #1107, whose head predates #1108 (`grep -c 'CHANGELOG.md.*merge=union'` +gives 0 on that head and 1 on main). Merging brings main's commits into a tree whose +attributes have no driver; rebasing replays the branch onto main, where the driver is +already in force. + +So for any branch opened before the driver landed, *Update branch* cannot work even +in principle — and that is most branches that have been open more than a day. + ### What the driver does not excuse A **release cut** edits `## [Unreleased]` into `## [1.0-alphaN] - date`, which is the diff --git a/test/docs_style.sh b/test/docs_style.sh index 0908172a..9df6abdf 100755 --- a/test/docs_style.sh +++ b/test/docs_style.sh @@ -590,6 +590,13 @@ check "and names the command rather than only the problem" \ "$(grep -c 'git rebase origin/main' "$SRCDIR/CONTEXT.md")" "1" check "and warns against the button that reintroduces the conflict" \ "$(grep -ci 'do not click' "$SRCDIR/CONTEXT.md")" "1" +# ANCHORED ON ONE LINE. The first spelling of this arm spanned the prose's line +# break -- "the tree it is / merging into" -- so a line-based grep found 0 on the +# unmutated tree and the arm was red for the sentence it was asserting. The mutation +# then reddened it too, which looked like a working proof and was two failures +# agreeing. Same class as a drift-guard that does not join line continuations. +check "and says WHY rebasing works where merging does not" \ + "$(grep -c 'merging \*\*into\*\*' "$SRCDIR/CONTEXT.md")" "1" echo "checks run: $checks"