A commit message is a letter to the future. Six months from now, a colleague — or you — will run git log trying to understand why a specific change was made. The quality of your commit messages determines how much time that investigation takes.
For non-native English speakers, commit messages present a specific challenge: they need to be concise (ideally under 72 characters in the subject line), semantically precise, and written in a specific grammatical style that does not match everyday speech.
This guide covers the advanced patterns: the Conventional Commits specification, the semantic vocabulary of changes, linking issues, and the English writing discipline that separates a good git history from an exceptional one.
The Grammar Rule That Surprises Everyone
The universal convention in English commit messages is to write the imperative mood — a verb form that sounds like a command:
- Correct:
Fix the race condition in the session handler - Incorrect:
Fixed the race condition(past tense) - Incorrect:
Fixing the race condition(gerund) - Incorrect:
This fixes the race condition(declarative)
Why the imperative? Because git revert generates messages like Revert "Add feature X". The subject line of a commit should complete the sentence: “If applied, this commit will…”
- “If applied, this commit will Fix the race condition in the session handler.”
- “If applied, this commit will Add support for OAuth 2.0 device flow.”
This is the grammatical contract of the commit message format.
The Conventional Commits Specification
Conventional Commits is a widely adopted specification that adds structured semantic meaning to commit messages. It is the foundation for automated changelogs, semantic versioning, and CI/CD pipelines that parse commit history.
Basic Format
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
The Types and Their Meanings
Each type carries a precise semantic meaning:
| Type | Meaning | CHANGELOG section |
|---|---|---|
feat |
A new feature visible to users | Features |
fix |
A bug fix | Bug Fixes |
docs |
Documentation changes only | — |
style |
Formatting, whitespace — no logic change | — |
refactor |
Code restructuring — no feature or fix | — |
perf |
Performance improvement | Performance |
test |
Adding or updating tests | — |
build |
Build system or dependency changes | — |
ci |
CI configuration changes | — |
chore |
Maintenance tasks | — |
revert |
Reverting a previous commit | — |
The Breaking Change Marker
A ! after the type (or BREAKING CHANGE: in the footer) signals that this commit introduces an incompatible API change — it bumps the major version in semantic versioning:
feat!: Remove deprecated v1 authentication endpoints
BREAKING CHANGE: The /api/v1/auth/* endpoints have been removed.
Consumers must migrate to /api/v2/auth/* before upgrading.
See migration guide: https://docs.example.com/migration/v1-to-v2
Writing the Subject Line
The subject line is the most-read part of a commit message. Rules:
- 50-72 characters maximum (72 is the hard limit most tools enforce)
- Lowercase after the type prefix (except proper nouns)
- No period at the end
- Be specific — “Fix bug” is useless; “Fix null pointer in cart item removal” is useful
Specificity Examples
| Vague | Specific |
|---|---|
fix: Fix bug |
fix: Prevent null pointer when cart is empty at checkout |
feat: Add feature |
feat(auth): Add TOTP-based two-factor authentication |
refactor: Refactor code |
refactor(parser): Extract token validation into standalone module |
chore: Update deps |
chore: Upgrade PostgreSQL driver from 14.2 to 15.0 |
docs: Update readme |
docs: Add environment variable reference to deployment guide |
Using Scope
The optional scope in parentheses identifies the subsystem or module affected:
feat(api): Add pagination to /users endpoint
fix(auth): Correct token expiry calculation for UTC offsets
perf(search): Cache Elasticsearch query results for 60 seconds
Scopes are team conventions — agree on a consistent list (e.g., api, auth, ui, db, ci) and stick to it.
Writing the Commit Body
The body is optional for simple changes but essential for:
- Non-obvious decisions
- Bug fixes where the root cause is not self-evident
- Breaking changes
- Anything that will confuse the next reader
Body Writing Rules
- Separate from the subject with a blank line
- Wrap at 72 characters per line (most editors can do this automatically)
- Explain why, not what — the diff shows what changed; the body explains the reasoning
- Use full sentences with capital letters and punctuation
- Write in present tense for descriptions, but past tense for context is acceptable
Body Examples
Good body — explains the reasoning:
fix(cache): Use write-through strategy for session data
Previously, sessions were cached with a write-back strategy, which
created a window where a server restart could lose session data
before it was persisted. This was acceptable in development but
caused intermittent logouts in production during rolling deploys.
Write-through adds a small latency cost (~2ms per write) but
eliminates the data loss risk entirely.
Good body — explains a constraint:
feat(export): Limit CSV export to 100,000 rows
The previous implementation had no row limit, which allowed users
to trigger exports that consumed all available memory on the export
worker. We've added a hard limit of 100,000 rows with a clear
error message directing users to the API for larger datasets.
This is a temporary measure while we implement streaming exports
in the next sprint. See JIRA-4821.
Linking Issues and References
Issue References in the Footer
The footer section is used for metadata — issue links, co-authors, and breaking change notes:
Closes #342
Fixes JIRA-1234
Refs #298, #301
Reviewed-by: Alice Chen <alice@example.com>
Co-authored-by: Bob Smith <bob@example.com>
Keyword conventions:
Closes #XorFixes #X— automatically closes the issue when the PR merges (GitHub/GitLab)Refs #XorRelated to #X— links without closingPart of #X— signals this is one commit in a larger feature
Multi-Repository References
When a commit addresses an issue in a different repository:
Fixes org/other-repo#45
Linking to Documentation and Decisions
See ADR-027 for the rationale behind this approach.
Migration guide: https://docs.example.com/migrate/v3
Spec: https://www.rfc-editor.org/rfc/rfc7519 (JWT)
The Revert Commit
When reverting, Git generates:
Revert "feat(auth): Add TOTP-based two-factor authentication"
Add a body explaining why you reverted:
Revert "feat(auth): Add TOTP-based two-factor authentication"
Reverting due to a critical regression in the SMS fallback path.
When TOTP is enabled and the user has no recovery codes, the login
flow enters an unrecoverable state. Reverting to unblock release;
the fix will be tracked in AUTH-892.
Commit Message Anti-Patterns to Avoid
These are common patterns — some from non-native speakers, some universal:
| Anti-pattern | Problem | Better |
|---|---|---|
WIP |
No information | feat(auth): Implement TOTP setup flow (in progress) |
fix: fixed |
Duplicate and vague | fix(api): Return 404 instead of 500 for missing resources |
changes |
Noise | Describe the actual change |
as per review comments |
No substance | List what specifically changed |
update |
Almost meaningless | Specify what was updated and why |
minor fix |
Relative and vague | Describe the specific fix |
temp |
Never meant to be permanent | Address and commit properly |
Practical English Tips
Use the active voice. Commit messages should be active, direct, and precise:
- Active:
Remove deprecated authentication endpoints - Passive:
Deprecated authentication endpoints are removed
Prefer concrete verbs. Instead of “update” or “change”, use the verb that precisely describes the change:
Add,Remove,Replace,Extract,Rename,Move,Fix,Correct,Prevent,Allow,Disable,Enable,Upgrade,Downgrade,Revert
One change per commit. This is as much an English principle as a git principle. If your commit message needs “and” to describe what changed, consider splitting it into two commits.
Key Takeaways
- Use the imperative mood: “Fix the bug”, not “Fixed” or “Fixes”.
- Conventional Commits adds structured semantic meaning:
feat,fix,refactor,chore, and others signal impact level and CHANGELOG category. - The
!suffix andBREAKING CHANGE:footer signal major version bumps. - Subject lines should be 50-72 characters, specific, and use concrete verbs.
- Body explains the why, not the what — the diff shows what changed.
- Footers contain issue references (
Closes #X), co-authors, and breaking change notes. - Avoid anti-patterns:
WIP,fix: fixed,update,changes— they corrupt your git history.
A well-maintained git history is a living document. Write it for the engineer who will need it at 11 PM during an incident — that engineer might be you.
Keep practising
Turn this article into muscle memory
Five-minute exercises with instant feedback — built from the same kind of real IT language.
What to read next
Frequently asked questions
What will I learn from "Writing Effective Commit Messages: Advanced English and Conventional Commits"?
This is a Advanced-level Writing article covering git, commit-messages, conventional-commits, documentation and writing. Go beyond basic commit messages — learn Conventional Commits format, semantic meaning, linking issues, and the English writing patterns that make git history truly useful.
Is this article free to read?
Yes. Every article on CoderSlingo, including this one, is free to read with no account, sign-up, or paywall.
How is reading this article different from doing an exercise?
Articles like this one explain concepts and vocabulary in context through prose, while exercises are interactive drills — fill-in-the-blank, matching, and multiple-choice — that test and reinforce specific terms. Reading builds understanding; exercises build recall.
Can I practice the vocabulary used in this article?
Yes — this article's topic lines up with our git exercises. Use the "Practice this vocabulary" link below to jump straight into a matching drill.
How long does "Writing Effective Commit Messages: Advanced English and Conventional Commits" take to read?
About 8 min. Most CoderSlingo articles, including this one, are written to be read in one sitting, without needing a dictionary open in another tab.
Do I need to create an account to read or save this article?
No account is required to read any article. If you complete exercises elsewhere on the site, your progress is saved locally in your browser — no login needed.
What if I don't understand a technical term used in this article?
Check the site Glossary for plain-English definitions of common IT terms, or browse the #git tag page for other Writing articles that use the same vocabulary in different contexts.
Can I share or link to "Writing Effective Commit Messages: Advanced English and Conventional Commits"?
Yes — use the Twitter/X or LinkedIn share buttons at the end of the article, or copy the page URL directly. Attribution back to CoderSlingo is appreciated but the content is free to reference.
When was this Writing article published?
This article was published in 2026. New Writing articles are added regularly — visit the #git tag page to see the full, continuously updated list.
Where can I find more articles like this one?
See "Git Commit Messages: Best Practices and English Tips", "Writing Effective Commit Messages in English", "How to Write Effective Git Commit Messages" in the Related Articles section below, or browse all Writing articles from the main Blog index.