Skip to content

Commit 67b4edf

Browse files
lilyshen0722rehearsal
authored andcommitted
docs(runbooks): what a squash merge lands — two surfaces, one composition, measured on nine merges (TASK-223)
A squash merge composes one message from two surfaces: the squash-message subject box (seeded with the PR title) and the branch's commit messages. The PR body is not an input. Measured on the nine PRs this pod landed between 09:08:43Z and 09:19:20Z on 2026-09-30, by recomputing the expected message from the PR title and the branch commits and comparing it to main character for character. - 1 commit: subject = `<subject box> (#N)`; body = that commit's message minus its first line. - 2+ commits: same subject; body = per commit, `* <full subject>`, blank line, then the commit body. Subject matched the default (PR title + ` (#N)`) in 8 of 9; body matched the composition in 9 of 9, an 8-commit PR included. #2031 is the exception that shows the box is editable: its title ended `(TASK-204 late delta)` and the landed subject is the commit's own subject with ` (#N)` appended. The body is the surface that bites, and amending the tip does not amend earlier commits — measured on #2049, whose merge message today carries commit 1's retracted `split('@media (prefers-reduced-motion')[1]` framing at line 13 and its retraction at line 58. Also recorded because the doc quotes them: `gh pr view --json commits` truncates headlines (17 of these 22 commits, every one to 69 characters plus an ellipsis, the longest intact being 72), and `git log -1 --format=%B <merge>` is the only reader that shows what main says. Scope: this is the message, not the tree. Fidelity of what landed to what was reviewed stays rule 32's patch-id comparison; the tree/origin check is rule 49.
1 parent c58d8b5 commit 67b4edf

1 file changed

Lines changed: 100 additions & 0 deletions

File tree

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# What a squash merge lands
2+
3+
A squash merge writes **one** commit to main, and its message is composed from
4+
two surfaces: the **squash-message subject** (a text box in the merge dialog,
5+
seeded with the PR title) and the **branch's commit messages**. The PR *body* is
6+
not an input to it. Both halves below were measured against the nine PRs this pod
7+
landed between 09:08:43Z and 09:19:20Z on 2026-09-30, by recomputing the expected
8+
message from the PR title and the branch commits and comparing it to what main
9+
carries, character for character.
10+
11+
## The composition
12+
13+
| PR shape | landed subject | landed body |
14+
|---|---|---|
15+
| **1 commit** | `<subject box>` + ` (#N)` | that commit's message **minus its first line** |
16+
| **2+ commits** | `<subject box>` + ` (#N)` | per commit, in order: `* <full commit subject>`, a blank line, then that commit's message body |
17+
18+
The subject box is seeded with the **PR title**, so the default is
19+
`<PR title> (#N)` — true in 8 of the 9. The body matched this composition
20+
**exactly in 9 of 9**, single-commit and 8-commit PRs included.
21+
22+
| PR | commits | landed subject | landed body |
23+
|---|---|---|---|
24+
| #2015 | 1 | title + `(#2015)` | the commit body |
25+
| #2017 | 3 | title + `(#2017)` | 3 bullets + bodies |
26+
| #2024 | 2 | title + `(#2024)` | 2 bullets + bodies |
27+
| #2031 | 1 | **the COMMIT subject** + `(#2031)` | the commit body |
28+
| #2043 | 8 | title + `(#2043)` | 8 bullets + bodies |
29+
| #2045 | 3 | title + `(#2045)` | 3 bullets + bodies |
30+
| #2046 | 1 | title + `(#2046)` | the commit body |
31+
| #2048 | 1 | title + `(#2048)` | the commit body |
32+
| #2049 | 2 | title + `(#2049)` | 2 bullets + bodies |
33+
34+
## #2031 is the one that shows the box is editable
35+
36+
Its PR title was `… the concurrency discriminator is the run, not the SHA
37+
(TASK-204 late delta)`. The landed subject is `… the concurrency
38+
discriminator is the run, not the SHA (#2031)` — the commit's own subject, with
39+
GitHub's ` (#N)` still appended. So the presser can overwrite the subject box,
40+
and ` (#N)` is added to whatever sits in it. One in nine — and the practical
41+
reading runs the other way from the usual one: **do not assume the PR title is
42+
what landed.** Read the merge commit.
43+
44+
## Why the body is the surface that bites
45+
46+
A claim that must not land is fixed on **both** surfaces — the PR title (the
47+
subject) **and every commit message that carries it** (the body). Nothing else
48+
reaches either: a PR *body* edit is not an input to the composition at all, and a
49+
PR comment reaches neither.
50+
51+
**Amending the tip does not amend earlier commits.** Measured on #2049, whose
52+
branch carried two commits with the tip amended to retract an over-claim: main's
53+
merge message today carries both texts, side by side —
54+
55+
```
56+
line 13: `split('@media (prefers-reduced-motion')[1]` is 865 lines / 33,883 characters
57+
line 58: right; calling it "fiction about the code" was the wrong reason, and is retracted.
58+
```
59+
60+
— the retracted framing in commit 1's body and its retraction in commit 2's, in
61+
one message. `git log -1 --format=%B <merge>` is the only reader that shows
62+
this. The PR page shows the current branch state, which is what the author last
63+
saw; main shows what landed.
64+
65+
## Checking what landed — and what will land
66+
67+
```bash
68+
PR=2049
69+
M=$(git log --format=%H --grep="(#$PR)\$" -1 origin/main) # the merge commit
70+
git log -1 --format=%s "$M" # the landed subject
71+
git log -1 --format=%B "$M" # the landed body — the surface main reads
72+
gh pr view "$PR" --json title -q .title # the seeded subject
73+
gh api repos/Team-Commonly/commonly/commits/<oid> -q .commit.message # lossless branch message
74+
```
75+
76+
Two instrument notes, both measured. `gh pr view <N> --json commits -q
77+
'.commits[] | .messageHeadline'` is **lossy**: across the nine PRs' 22 commits,
78+
17 headlines ended in `…` and every one of those measured exactly 70 characters
79+
(69 plus the ellipsis), while the longest intact one is 72 — so the cut lands
80+
somewhere between, and the projection counts commits faithfully while quoting
81+
them wrongly. Read the commit object above for the text itself; the branch
82+
commits survive the branch deletion inside the PR record. The second note is the
83+
one that matters here: this is the same class as the PR page, a summary that is
84+
right about the shape and wrong about the words. And the composition is a fact about the
85+
**message** only: whether what landed is what was reviewed is a separate
86+
measurement — the patch-id comparison in rule 32 of
87+
`docs/development/review-checklist.md`, and the tree/origin check in rule 49.
88+
89+
## Habits this buys
90+
91+
- **Before a press:** the PR title is one of two surfaces; the commit list is the
92+
other. Read both. A commit-message fix moves the head and so costs a re-stamp
93+
(rule 44); a title edit does not.
94+
- **After a merge:** `git log -1 --format=%B <merge>` answers "what does main
95+
say"; the PR page answers "what did the branch say last".
96+
- **A landed-and-wrong message cannot be unlanded.** A follow-up commit puts a
97+
correction next to it, which is a different artifact from a fix — the remedy
98+
that works is the one taken before the press.
99+
- **Never cite a PR title as a landing claim.** #2031 is the counterexample that
100+
cost nothing; the same mechanism with a wrong title is the one that does.

0 commit comments

Comments
 (0)