Writing Effective Commit Messages in English
A beginner's guide to writing clear, professional Git commit messages in English — with real examples, common mistakes, and the Conventional Commits standard.
A commit message is a small piece of writing with a big impact. It tells your teammates — and your future self — what changed, and why. A good commit message saves hours of archaeology later. A bad one leaves the team guessing. Learning to write clear, professional commit messages in English is one of the most practical writing skills a developer can build.
Why Commit Messages Matter
When you run git log, you see a history of decisions. Each commit message is a record of intent. When a bug appears six months from now, the team will search that history. They will read commit messages to understand why a change was made, not just what changed (the diff already shows that).
A well-written commit message answers three questions:
- What changed?
- Why did it change?
- Is there anything important to know about how it changed?
Key Vocabulary
- Subject line — the first line of a commit message, typically 50 characters or fewer
- Body — the optional longer explanation below the subject line
- Imperative mood — a grammatical style using command form: “Fix bug” not “Fixed bug” or “Fixing bug”
- Scope — the part of the codebase affected by the change
- Breaking change — a change that is incompatible with the previous version
- Conventional Commits — a widely used standard for structuring commit messages
- Changelog — a log of changes, often generated from commit messages automatically
The Golden Rule: Use the Imperative Mood
The most important grammar rule for commit messages is to use the imperative mood in the subject line. This means writing as if you are giving a command.
Think of it this way: your subject line should complete the sentence “If applied, this commit will…”
| Correct (imperative) | Incorrect |
|---|---|
| Fix login redirect bug | Fixed login redirect bug |
| Add user avatar upload | Adding user avatar upload |
| Remove deprecated API endpoint | Removes deprecated API endpoint |
| Update dependencies to latest | Updated dependencies to latest |
This convention is used by Git itself. When Git auto-generates a merge commit, it writes “Merge branch ‘feature/login’ into main” — imperative mood.
The Conventional Commits Standard
Many professional teams use the Conventional Commits specification. It adds a structured prefix to the subject line that makes messages easier to read and enables tools to auto-generate changelogs.
The format is:
type(scope): short description
Common Types
- feat — a new feature:
feat(auth): add OAuth2 login support - fix — a bug fix:
fix(cart): correct total calculation with discount codes - docs — documentation changes:
docs(readme): update local setup instructions - refactor — code restructuring without behaviour change:
refactor(api): simplify error handling middleware - test — adding or updating tests:
test(payments): add unit tests for retry logic - chore — maintenance tasks:
chore(deps): upgrade react to 18.3.0 - perf — performance improvements:
perf(images): lazy-load product thumbnails - ci — CI/CD changes:
ci: add deploy step for staging environment
Real Examples
feat(notifications): add email digest for weekly activity summary
Users can now opt in to a weekly email summary of their account activity.
This addresses the feature request from issue #412.
Breaking change: The NotificationService constructor now requires a mailer
instance to be passed explicitly.
fix(search): prevent crash when query contains special characters
Certain characters such as & and ? were not being URL-encoded before
being sent to the search API, causing a 400 error. Added encoding in
the SearchService buildQuery method.
Closes #891
Writing a Good Commit Body
The subject line tells what happened. The body explains why. Not every commit needs a body — simple changes like fix(typo): correct spelling in welcome email are self-explanatory. But any commit that involves a non-obvious decision deserves an explanation.
Good Body Practices
Keep lines under 72 characters. Many tools display commit messages in narrow terminals. Wrapping at 72 characters ensures readability.
Explain the motivation, not the mechanics. The diff already shows what changed. The body should explain why this approach was chosen.
Reference issues and pull requests. Use phrases like “Closes #123”, “See also #456”, or “Related to #789” to link context.
Example of a Well-Structured Commit
refactor(database): replace raw SQL queries with ORM calls
Raw SQL in the UserRepository was becoming difficult to maintain and
test. Switching to the ORM layer allows us to:
- Use the built-in query builder with type safety
- Mock the data layer more easily in unit tests
- Benefit from automatic SQL injection protection
Performance tests show no regression. Query execution time is within
5ms of the original for all tested endpoints.
See also: ADR-012 (architecture decision record on ORM adoption)
Common Mistakes to Avoid
Vague messages like “fix stuff”, “wip”, or “update” are useless. They tell the reader nothing.
Past tense subject lines like “Fixed the bug” break the imperative convention and look inconsistent in git log output.
Mixing unrelated changes in one commit makes it impossible to revert selectively. Each commit should do one thing.
Explaining the obvious: “Changed line 42 from X to Y” is not useful. The diff shows that. Write why.
Quick Checklist Before You Commit
Before writing your commit message, ask yourself:
- Does the subject line complete “If applied, this commit will…”?
- Is it 50 characters or fewer?
- Does it use imperative mood?
- If the change is complex, is there a body explaining the reasoning?
- Are relevant issue numbers referenced?
Writing good commit messages is a habit, not a talent. With practice, it becomes second nature — and your future teammates (including future you) will thank you for it.
Navigating Nuance: Commit Messages for Non-Native Speakers
Writing effective commit messages is crucial not just for code review but also for demonstrating professionalism and clarity within a development team. For developers whose first language isn’t English, this can feel particularly challenging – it’s not just about conveying the technical change; it’s about doing so in a way that’s readily understood by colleagues who may have different expectations of phrasing and detail. Let’s be honest, “fixed bug” doesn’t always cut it. A good commit message acts as a mini-narrative, explaining why something was changed, not just what was changed.
One common hurdle is the tendency to translate directly from one’s native language. While intention is important, literal translations often result in awkward or unclear wording. For example, if your native language uses a phrase like “resolved issue” that’s perfectly acceptable within that context, it might sound overly formal and slightly stilted when used in an English-speaking professional environment. Similarly, focusing solely on the technical specifics – “modified line 42 of file X” – can obscure the reason for the modification. Think about how you would explain this change to a teammate who wasn’t intimately familiar with the codebase.
Consider a scenario: You receive a code review comment stating, “This needs more context.” It’s frustrating, but it’s often a gentle nudge towards writing a better commit message. The reviewer isn’t criticizing your coding; they’re asking you to articulate why that particular change was necessary. A good response wouldn’t simply say “Fixed code.” Instead, try something like: “Added a commit message explaining the rationale behind refactoring the user authentication flow to improve security and reduce potential vulnerabilities as highlighted in the recent audit report.” See how much more informative that is? It provides context, references external information, and demonstrates an understanding of the broader implications.
Finally, remember that embracing slightly longer, more descriptive messages – especially when starting out – is perfectly acceptable. Aim for clarity over brevity. Don’t be afraid to use phrases like “As part of…” or “To address…” These small additions significantly improve comprehension. Furthermore, if you’re unsure about the best phrasing, don’t hesitate to ask a senior developer for feedback. A quick conversation can often prevent misunderstandings and build confidence in your ability to communicate effectively.