changelog · Sep 11, 2026
How We Write the Changelog
The changelog is written by a person, from commit messages, on the day before release. A look at the five rules we follow and the one-line git command that gives us the raw material.
Our changelog is written by a person. That sounds like a strange thing to say, until you've read a changelog that was generated from commit titles and noticed that every line is true and none of them is useful.
The process is not complicated. It has a few moving parts, and each one exists because we got something wrong once.
The raw material
Every commit message in our repository starts with one of four words: add, change, fix or refactor, followed by a colon. The first three describe something a user could notice. The fourth doesn't, and that's the point of having it.
On the day before a release, whoever is writing the notes runs one command to see what's in scope. Between the last release's tag and this one, it lists the user-facing commits in the order they landed.
git log --no-merges --reverse --pretty='%s' 2.6.0..2.7.0 | grep -E '^(add|change|fix):'Run against a small test repository with five commits, it printed four lines: the quick switcher, the undo fix, the narrower sidebar and the dark mode flash. The refactor commit never appeared. On a real release the list has between twenty and sixty lines, and it is a starting point, not a draft.
Five rules for turning it into prose
Write for the person, not the codebase. "Fix null check in merge reducer" becomes "Undo after a merge could step back past the merge point." Nobody who uses Quillfold knows what a reducer is, and nobody should have to.
Say what was wrong before saying what's fixed. A fix is only meaningful if you recognise the problem. If the reader thinks "yes, that happened to me", they trust the rest.
One change, one sentence, and no adjectives. We don't write "significantly improved" or "much faster". If something is faster, we give the number and the situation, or we say nothing.
Group by what it feels like, not by where it lives. The sections are "What's new", "What changed" and "What we fixed". There is no section called "Internals".
Name what is still broken. Every release has a "Known issues" paragraph, even if it's two lines, and it is never empty.
Why a human, and why late
Ravi once suggested we automate the whole thing, and for a month we tried. The output was accurate and nobody read it. Commit messages are written for the people who'll maintain the code next week. A changelog is written for someone deciding whether to update today.
Those are different readers with different questions, and a script can't switch between them. So the commits do the bookkeeping and a person does the translating.
We write it the day before, not the day of, for a plain reason. Writing the notes is the last real review of the release. More than once, the sentence we couldn't write honestly turned out to describe a change we shouldn't ship yet. If you can't explain it in one plain line to a stranger, you may not understand it well enough to release it.
What we still get wrong
We are bad at the order. Our notes put the biggest change first, and that isn't always the one most people care about. A tiny fix for a bug everyone hit can matter more than a feature half the users will never open. We have tried a "most requested" label and found that it just moves the argument somewhere else.
For now, the first section stays the biggest change, and the fixes list is numbered so you can scan it quickly. It is not a perfect system. It has one useful property: every line in it was written by someone who read the diff.
No comments yet
Comments are open. Have a thought or a question? Share it below.