|
139 | 139 | * it is RULE 2's premise: a trailer left on a pushed commit really does reach |
140 | 140 | * the default branch's permanent history. |
141 | 141 | * |
| 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 | + * |
142 | 153 | * What that costs depends on the spelling, and the output says so rather than |
143 | 154 | * flattening it: Part-of and Refs land as a reference and move no card, while a |
144 | 155 | * CLOSING keyword lands on the surface GitHub's parser reads. The asymmetry is |
@@ -769,6 +780,13 @@ export function judge(ctx) { |
769 | 780 | " card, while a CLOSING keyword lands on the surface GitHub's parser reads. ⛔ Weigh that under the", |
770 | 781 | ' landing rules that bind you — this gate found a real contradiction between your commits and your', |
771 | 782 | ' 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.', |
772 | 790 | ); |
773 | 791 | } |
774 | 792 | return { exit: EXIT_CONTRADICTION, lines: [...lines, ...(unread.length ? ['', ...unread] : [])] }; |
@@ -1043,6 +1061,31 @@ function selfTest() { |
1043 | 1061 | named.includes('does not decide whether the pull request merges'), |
1044 | 1062 | true, |
1045 | 1063 | ); |
| 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 | + ); |
1046 | 1089 | t( |
1047 | 1090 | 'an ordinary commit message with no card relation is clean', |
1048 | 1091 | commitVerdict('fix(cli): stop counting the walk instead of the tree\n\nBody prose about the change.\n').exit, |
|
0 commit comments