Narrative Commits: How I Structure PRs for Fast Reviews
Reviewers shouldn’t reverse-engineer your intent. Narrative commits turn a PR into a readable story.
Bad pattern: flat PRs
- What I mean by “flat”: commits don’t tell a story, just a pile of diffs with unclear intent or order
- Huge diff, 1–2 commits
- Or: 30+ commits where many are noise (lint/format/import fixes)
- Mixed refactors/logic/tests in the same commits
- Vague messages
- Hard to review, easy to miss bugs
Good pattern: narrative commits
- Each commit does one thing and advances the story
- Clear, imperative messages with intent
- Order commits so they read like a progression. For me this often looks like this
- refactor to prepare for changes
- add failing tests
- implement change in functionality
- Less guessing for reviewers means more bugs caught and better and quicker feedback
Narrative commits: an example
extract the csv parser from the handler to set up isolated changes
add support for multiple pool assignments - add failing tests
add support for multiple pool assignments - implement
handle overlapping assignments - add failing tests
handle overlapping assignments - implement
How I structure commits
- Make commits tell a story
- One purpose per commit. Usually: refactor, implement, or test.
- Keep refactors separate from behavior changes.
- Write focused messages
- Use imperative: “add support…”, “handle…”, “extract…”.
- Add a short “why” when it’s not obvious.
- Remove noise the noise of typo/lint-only commits.
- Ask reviewers to review commit-by-commit.
Make it happen: continuous interactive rebase
- Don’t wait for a big cleanup at the end. Shape the branch as you go as the story becomes clear.
- Amend a previous commit or use interactive rebase to keep a clean commit history
- Recommended: The interactive rebase tool in JetBrains IDEs
- CLI alternative:
git rebase -i
PR descriptions: right-size the context
- The stronger the commit narrative, the lighter the description can be.
- Minimal (you paired/already synced): “Paired with X. Review commit-by-commit; focus on Y.”
- Brief (most cases): why now, scope boundaries, risks, testing notes, links; include screenshots for UI/API changes.
- Detailed (bigger impact): problem, approach/tradeoffs, alternatives, migration/observability.
What if I quash on merge?
Still worth it. Review happens before merge; the narrative benefits reviewers and future you regardless of merge strategy.