Writing Better Git Commit Messages
Good commit messages make code history readable and teammates happier. Learn the conventions that turn git log from noise into a useful timeline of decisions.
Writing Better Git Commit Messages
Most developers treat commit messages as an afterthought. “fix”, “WIP”, “asdf”, “final final v2” — we’ve all seen them (and written them). But commit messages are one of the highest-value low-effort improvements you can make to how you work.
A good commit history is a conversation with your future self and your teammates.
Why Commit Messages Matter
When something breaks in production at 2 AM, you run git log to understand what changed. If the history reads:
fix
more fix
oops
working now
…you have no idea where to look. A good history looks like:
fix: prevent double-charge on payment retry
feat: add email verification on signup
refactor: extract auth middleware from route handlers
You can instantly see what each commit does, find when a behaviour changed, and understand the reasoning — without reading the diff.
The Conventional Commits Format
Conventional Commits is the most widely adopted standard. The format is:
<type>(<scope>): <short summary>
<optional longer body>
<optional footer>
Types
| Type | When to use |
|---|---|
feat | A new feature |
fix | A bug fix |
refactor | Code change that neither fixes a bug nor adds a feature |
docs | Documentation only changes |
test | Adding or fixing tests |
chore | Build process, dependency updates, tooling |
perf | Performance improvement |
ci | CI/CD configuration changes |
Examples
feat(auth): add JWT refresh token rotation
fix(payments): handle Stripe webhook timeout correctly
refactor(users): extract email validation into shared util
chore: upgrade psycopg2 to 2.9.9
docs(api): document rate limiting headers in README
The Rules for a Great Subject Line
- Keep it under 72 characters — git log truncates longer lines
- Use the imperative mood — “add feature” not “added feature” or “adds feature”. Think: “If applied, this commit will add feature.”
- Don’t end with a period
- Capitalise the first letter after the colon
- Be specific — “fix null pointer in user service” beats “fix bug”
When to Write a Body
Short one-liners are fine for simple changes. Add a body when:
- The why isn’t obvious from the code
- There’s a subtle constraint or trade-off the reviewer should know
- You’re working around a bug in a dependency
Separate the subject from the body with a blank line. Wrap body text at 72 characters.
fix(orders): skip cancelled orders in revenue calculation
Revenue reports were including cancelled orders because the status
filter was applied after aggregation. Moving the WHERE clause before
GROUP BY fixes the double-counting.
Fixes: #412
Common Mistakes
Vague summaries — “update code”, “changes”, “stuff” tell nobody anything.
Mixing concerns — One commit should do one thing. If your message needs “and” in it, consider splitting the commit.
Missing context — “fix crash” is less useful than “fix crash when user has no billing address on checkout”.
Past tense — “fixed the bug” vs “fix the bug”. Imperative is the convention.
Setting Up a Commit Message Template
You can create a template to remind yourself of the format every time you commit:
# Create the template file
cat > ~/.gitmessage << 'EOF'
# <type>(<scope>): <subject> (72 chars max)
#
# Why is this change needed?
#
# How does this change address the issue?
#
# Types: feat, fix, refactor, docs, test, chore, perf, ci
EOF
# Tell git to use it
git config --global commit.template ~/.gitmessage
Amending the Last Commit
Made a typo in your message? Fix it before pushing:
git commit --amend -m "fix(auth): handle expired session tokens correctly"
Never amend commits you’ve already pushed to a shared branch.
The Takeaway
Good commit messages take 30 extra seconds to write and save hours of debugging later. Start with Conventional Commits — pick a type, write a clear imperative subject, and add a body when the why isn’t obvious from the diff.
Your teammates (and future-you at 2 AM) will thank you.
Related Articles
How to Write Clean Functions in JavaScript
Learn how to write clean JavaScript functions that are easy to read, test, and maintain. This guide covers naming, single responsibility, pure functions, and avoiding common pitfalls.
Free Resources I'd Use to Learn Web Development Today
The best free web development resources available today — from structured curricula to documentation, YouTube channels, and practice platforms. Everything you need without paying a cent.
Git Basics: The Commands You Need on Day One
Learn the essential Git basics every developer needs to know. This guide covers git init, add, commit, push, pull, branches, and merge — with practical examples for beginners.