codel
← Back to the index

WRT-11 · SEC. 05 Content & Writing

Release Notes From Git Log, Not From Memory

Turn the commits since your last release into human release notes, every line tied to a real commit.

FORMAT
workflow
DIFFICULTY
beginner
TIME
15 min
TOOLS
claude-code · cursor · codex-cli · gemini-cli
MODELS
any
COPIES
0 so far

When to use this

It's release day and nobody remembers what actually shipped. Writing notes from memory misses half the changes and overstates the other half. The real record is already in git.

The pattern

Pastes as plain text
Step 1: Find the shipped range.
"Find the last deployed release point in this repo: check deployment metadata
or release records first, then tags, release branches, or a CHANGELOG heading.
Do not assume a tag or commit was shipped. If you cannot verify a deployed
range, label the output DRAFT UNRELEASED NOTES and ask me for the range rather
than defaulting to the last 30 days. List every commit in the verified range
with hash and subject line, and tell me what range you chose."

Step 2: Draft grouped by user impact.
"Group those commits into release notes with these sections: New,
Improved, Fixed, Breaking. Rules: describe what the user can now do
differently, not what the code does ('CSV export on the reports page',
not 'refactored exporter class'). Merge multiple commits that ship one
feature into one entry. Put pure chores (dependency bumps, CI,
refactors with no behavior change) in a final Internal section I can
delete. Cite the commit hash after every entry."

Step 3: Verify against the diffs, not the messages.
"For each entry, open the cited commit's actual diff and confirm the
entry doesn't promise more than the code delivers. Commit messages
exaggerate. Flag any entry where the diff shows less than the message
claims, and downgrade the wording to match the diff."

Step 4: Read the Breaking section yourself, twice. That's the one
users screenshot when it's wrong.

Real example output

Range: v1.8.0..HEAD, 47 commits.

**New**
- Export any report as CSV from the reports page (a3f91c2, 8bd0e11)
- Dark mode follows your OS setting automatically (5c2a9f0)

**Fixed**
- Webhook retries no longer fire twice when a delivery times out (e77d431)

**Breaking**
- `GET /v1/reports` now paginates at 100 rows; clients reading the raw array must follow `next_cursor` (91cc7a8)

Step 3 flagged one entry: commit f20b115 says "add SSO support" but the diff only adds the config schema, no login flow. Moved from New to Internal.

Why it works

Git history records code changes, not necessarily what reached users. Verifying the deployed range first prevents draft work from being announced as shipped, while the diff check in step 3 catches the classic failure: release notes written from commit messages inherit every exaggeration in them. Hash citations make each claim auditable in one click.

Related patterns

Entry WRT-11 · by codel · 2026-07-09 · CC-BY-4.0