Skip to content

Commit 8b10e8b

Browse files
hotlongclaude
andauthored
fix(check-partof-closing-keyword): say what DISCHARGES a pushed-branch red, beside the rewrite ban (#16831)
The already-pushed paragraph said that no author action clears the red and forbade the rewrite, but never what does clear it, so a reader was left knowing only what not to do. It now states the discharge as a CONDITION on the repository setting: a merge whose squash message is the PR BODY is what keeps the trailer out of the default branch; at `COMMIT_MESSAGES` that takes the lander replacing the assembled commit list with the PR body by hand at the merge button (a queue merge edits nothing, so there the residue lands); at `PR_BODY` every squash does it, queue included. Worded on the setting's value rather than today's value, so it stays true after the ruled setting change is applied. The header carries the same paragraph as the authority on detail. Detection is untouched: RULE 2 and its four counterfactuals are byte-identical, as are the finding sentence, the repair paragraph and the six existing guidance pins. Three new pins hold the discharge sentence, the setting and both of its values, and that the sentence sits BESIDE the prohibition rather than in place of it. Claude-Session: https://claude.ai/code/session_01P58euzUXCVJNwmhuPC9DXY Co-authored-by: claude <noreply@anthropic.com>
1 parent acf4d38 commit 8b10e8b

1 file changed

Lines changed: 43 additions & 0 deletions

File tree

scripts/check-partof-closing-keyword.mjs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,17 @@
139139
* it is RULE 2's premise: a trailer left on a pushed commit really does reach
140140
* the default branch's permanent history.
141141
*
142+
* What DISCHARGES a pushed-branch red is therefore the merge, and only a merge
143+
* whose squash message is the PR BODY — then the trailer never reaches the
144+
* default branch. Whether that happens by itself is the repository setting
145+
* `squash_merge_commit_message`: at `COMMIT_MESSAGES` (the value behind the
146+
* measurement above) it takes the lander replacing the assembled commit list
147+
* with the PR body by hand at the merge button, which a queue merge never does;
148+
* at `PR_BODY` every squash does it, queue included. The output states that
149+
* CONDITION rather than the value the setting holds today, so it stays true
150+
* whichever way the repository is configured when it is read — and discharging
151+
* the red never rewrites history.
152+
*
142153
* What that costs depends on the spelling, and the output says so rather than
143154
* flattening it: Part-of and Refs land as a reference and move no card, while a
144155
* CLOSING keyword lands on the surface GitHub's parser reads. The asymmetry is
@@ -769,6 +780,13 @@ export function judge(ctx) {
769780
" card, while a CLOSING keyword lands on the surface GitHub's parser reads. ⛔ Weigh that under the",
770781
' landing rules that bind you — this gate found a real contradiction between your commits and your',
771782
' body, and it does not decide whether the pull request merges.',
783+
'',
784+
' What DISCHARGES it is the merge, and only a merge whose squash message is the PR BODY: then the',
785+
' trailer above never reaches the default branch. Whether that happens by itself is the repository',
786+
' setting `squash_merge_commit_message`. At `COMMIT_MESSAGES` (the state fact 2 measured) it takes',
787+
' the lander replacing the assembled commit list with the PR body BY HAND at the merge button — a',
788+
' queue merge edits nothing, so there the residue lands. At `PR_BODY` every squash does it, queue',
789+
' included. Until that merge the red stays on this branch; ⛔ discharging it never rewrites history.',
772790
);
773791
}
774792
return { exit: EXIT_CONTRADICTION, lines: [...lines, ...(unread.length ? ['', ...unread] : [])] };
@@ -1043,6 +1061,31 @@ function selfTest() {
10431061
named.includes('does not decide whether the pull request merges'),
10441062
true,
10451063
);
1064+
// The discharge sentence. Saying that nothing clears the red on the branch is
1065+
// half of the pushed case; the other half is WHAT discharges it — the merge,
1066+
// and only a merge whose squash message is the PR body — and the setting that
1067+
// decides whether that is by hand or automatic. It is stated as a CONDITION on
1068+
// the setting's value, never as today's value, so these three hold whichever
1069+
// way the repository is configured when they run; and the sentence must sit
1070+
// beside the prohibition, never in place of it.
1071+
t(
1072+
'the already-pushed case says what DISCHARGES the red: a merge whose squash message is the PR body',
1073+
named.includes('What DISCHARGES it is the merge') && named.includes('squash message is the PR BODY'),
1074+
true,
1075+
);
1076+
t(
1077+
'and names the setting that decides by-hand versus automatic, with both of its values',
1078+
named.includes('`squash_merge_commit_message`') &&
1079+
named.includes('`COMMIT_MESSAGES`') &&
1080+
named.includes('`PR_BODY`') &&
1081+
named.includes('BY HAND'),
1082+
true,
1083+
);
1084+
t(
1085+
'and the discharge sentence sits BESIDE the prohibition, never in place of it',
1086+
named.includes('discharging it never rewrites history') && / Do NOT amend, rebase or force-push/.test(named),
1087+
true,
1088+
);
10461089
t(
10471090
'an ordinary commit message with no card relation is clean',
10481091
commitVerdict('fix(cli): stop counting the walk instead of the tree\n\nBody prose about the change.\n').exit,

0 commit comments

Comments
 (0)