Free lesson · Git Mastery
Commit Message Conventions
Commit Message Conventions
A note from Swati Bajpai, Engineering Manager at Google Search Infrastructure.
Why Commit Messages Matter
A commit's message is what tells future readers - including your future self - what the commit does and why. It's the human-readable interface to the change, layered over the technical diff that Git stores. A commit's diff shows what changed; the commit's message shows why.
Most engineers underweight commit messages. The reasoning seems sound: "the code shows what I did." But the code only shows the result, not the reasoning. Six months later, when someone (often the original author) needs to understand why a change was made, the diff alone isn't enough. The commit message is what completes the picture.
I manage a fourteen-person team at Google Search Infrastructure. We've cared about commit hygiene for years because we use commit history actively - for retrospectives, incident response, changelog generation, debugging. The conventions we've evolved aren't arbitrary; they're shaped by what we've found valuable when reading commits weeks, months, or years after they were written.
Module 18 covers commit hygiene in depth. This topic frames why conventions matter and the high-level patterns. Subsequent topics cover specific aspects: subject lines (18.2), commit bodies (18.3), atomic commits (18.4), conventional commits (18.5), signing (18.6), trailers (18.7), and team-scale practices (18.8).
The Two Audiences
A commit message serves two distinct audiences:
The reviewer. Someone looking at the commit during code review. They need to understand the change well enough to evaluate it. The message should provide context the diff doesn't show.
The archaeologist. Someone looking at the commit months or years later, trying to understand history. They need the rationale, the alternatives considered, the constraints that shaped the choice.
The same commit message serves both audiences, but with different emphases. Good commit messages anticipate both needs.
The reviewer cares about the current state - what's being changed, why now, what the tradeoffs are. The archaeologist cares about the historical context - what problem was being solved, what was tried before, what came after. The best commit messages give both audiences what they need.
The Standard Structure
The widely-adopted structure has three parts:
Subject: brief summary (1 line, <= 72 chars)
<blank line>
Body: paragraphs explaining the change (1 or more)
<blank line>
Trailers: structured metadata (optional, at the end)
A specific example:
Add fuzzy matching to search query parser
The previous parser required exact token matches, which caused
search failures for common typos. The new parser uses Levenshtein
distance with a configurable threshold to match terms with small
deviations.
Performance impact is minimal: <2ms added to query parsing on
typical inputs. Memory usage unchanged.
This addresses the long-standing user complaints in #4521 and
related tickets. The threshold is initially set conservatively
at distance=1 and can be tuned based on observed accuracy.
Issue: SEARCH-1287
Reviewed-by: alice@example.com
The structure separates concerns. Subject gives the gist. Body explains the why and the what. Trailers carry structured metadata. Each part is optional except the subject - but each part adds value when used appropriately.
Why Conventions Help
A team without commit message conventions accumulates inconsistent history. Some commits have detailed explanations; some are terse. Some reference tickets; some don't. Some follow imperative mood; some use past tense. The accumulated mess makes the history harder to search and harder to learn from.
Conventions don't make commits "fancy." They make commits consistent, which makes the history navigable. When every commit follows the same structure, you can scan many commits quickly, search effectively, and rely on certain information being present.
Specific benefits of conventions:
Searchability. git log --grep="fix" works when commits consistently start with type prefixes. Otherwise the same search misses commits that say "fixed" or "fixes" or other variations.
Changelog generation. Tools like conventional-changelog parse structured messages to generate release notes automatically. Without conventions, the generation requires manual effort.
Ticket cross-referencing. When commits reference tickets in a consistent format, ticket systems can show all related commits. Without conventions, the connections are partial.
Incident response. During a production issue, scanning recent commits looking for the cause is faster when the messages are structured.
Onboarding. New team members learn from history. Consistent commit messages make learning easier.
The benefits compound across years of development. The cost of conventions (a few seconds per commit to think about format) is small. The cost of inconsistent history (slow searches, manual changelog, lost context) grows with the project's age.
The Imperative Mood
A widely-adopted convention: commit subjects use the imperative mood - "Add" not "Added" or "Adds"; "Fix" not "Fixed" or "Fixes".
The rationale: a commit completes a sentence like "This commit will...". The imperative reads naturally:
- "This commit will add fuzzy matching." ✓
- "This commit will added fuzzy matching." ✗
The imperative is also shorter and more direct. The convention applies to the subject only; bodies can use whatever tense reads best.
This is one of those small conventions that adds clarity at almost no cost. Teams that adopt it consistently find their history reads more naturally.
Length Conventions
The widely-followed length rules:
Subject: 50-72 characters. Short enough to display in narrow terminal columns; long enough to be informative. The "50" target is from Tim Pope's classic guide; "72" is the hard maximum.
Body lines: 72 characters wrapped. Same reason; ensures readability in any terminal. Modern terminals are wider but the convention is durable.
The length conventions matter for terminal display. Git tools like log and show often render in 80-column or narrower views. Subjects that exceed 72 chars get truncated; body lines that exceed 72 chars wrap awkwardly. The conventions ensure readability across many display contexts.
These length rules can be enforced via commit-msg hooks (Topic 17.4). The enforcement keeps them consistent without requiring everyone to remember.
A Pattern at Google Search Infrastructure
The team's commit message conventions, from our team handbook:
SUBJECT (required):
Format: type(scope): brief description
Type: feat, fix, docs, refactor, test, chore, perf, build
Scope: a lowercase identifier (optional)
Description: imperative mood, < 72 chars total
BODY (recommended for non-trivial changes):
- Explain what and why, not how
- Wrap at 72 characters
- Multiple paragraphs allowed
- Reference related decisions, issues, alternatives considered
TRAILERS (required for non-trivial changes):
Issue: TICKET-123
Reviewed-by: name@example.com (set automatically by tooling)
Co-authored-by: name@example.com (when applicable)
The conventions are documented in our team handbook. New engineers learn them during their first week. They become muscle memory within a few weeks of writing commits. The standard structure means I can scan commits quickly during reviews and find the right commit when investigating issues later.
A Specific Story From My Stripe Days
Around 2018 at Stripe, I was Principal Engineer on a team that had recently adopted conventional commit messages. Before the adoption, commit history was inconsistent - some commits had detailed explanations, some were one-word messages.
About a year into using the conventions, we had a production incident. A specific behavior had regressed; the team needed to find when it started. Without conventions, this would have meant scanning many commits manually. With them, the search was structured:
git log --grep="^fix" --since="3 months ago" | grep -i "balance"
The query searches recent fix-typed commits for the keyword balance. Without the type prefix convention, the same search would need to scan all commits, including non-fixes, and rely on inconsistent terminology. The structured format made the search precise.
The query found the relevant commits in seconds. The fix had been committed two months earlier with a clear message explaining what it did and why; the regression was caused by an unrelated commit that had inadvertently undone part of the fix.
The recovery: revert the offending commit, restore the original fix's behavior. About fifteen minutes from incident detection to fix in production.
The lesson: conventions pay off most at unpredictable moments. The discipline of writing structured commits during normal work creates a searchable history. When that searchability is needed - usually during an incident - it's already there.
Without the conventions, the same incident might have taken hours to root-cause.
What "Good" Means Varies by Context
The conventions in this topic are widely useful but not universal. Different contexts have different needs:
Open source projects often follow conventional commits (Topic 18.5) strictly because changelogs depend on the format.
Internal corporate projects often have organization-specific conventions, especially around ticket references.
Personal projects can be looser; the discipline isn't necessary if you're the only person reading history.
Highly regulated environments may require additional fields (signers, change-control numbers) beyond what general conventions cover.
The pattern: adopt what fits your context, document the conventions clearly, enforce them via hooks where it matters.
Common Failure Patterns
The patterns I see in commits that don't follow conventions:
Empty or near-empty subjects. "Update file" tells future readers nothing.
Mismatched tense. "Fixed the bug" - sometimes mixing past and imperative within the same project.
Truncated subjects. Subjects that run over 80 chars and get cut off in tool views.
No body for complex changes. A 500-line diff with a 5-word subject loses essential context.
Missing ticket references. Future readers can't connect commits to work-tracking system.
Auto-generated content. Messages like "Merge pull request #123" - the platform's default, which conveys nothing about what was actually changed.
Each of these reduces the value of the history. None are individual disasters; cumulatively, they make commit history substantially less useful.
What Comes Next
Topic 18.2 covers subject lines in depth. Topic 18.3 covers commit bodies. Topic 18.4 covers atomic commits - the size and scope of a single commit. Topic 18.5 covers conventional commits - a specific structured convention. Topic 18.6 covers commit signing. Topic 18.7 covers trailers and metadata. Topic 18.8 covers practices at team scale.
What Goes Wrong
Warning: Common commit-message mistakes:
No team conventions. Inconsistent history; hard to search later.
Subjects too long. Truncated in tool views; lose information.
Bodies too short for complex changes. Lose essential context.
Past tense in subjects. "Added" instead of "Add"; harder to scan consistently.
Missing ticket references. Commits can't be traced to work-tracking system.
Auto-generated subjects like "Merge pull request #X". No information about the actual change.
Try It
Exercise: Apply commit conventions:
- Look at your last 20 commits. Are they consistent in format?
- Identify one commit where the message could be improved. What's missing?
- Write a commit message that follows the standard structure (subject + body + trailers).
- Discuss conventions with your team. What's the current convention? Should it change?
- Look at a project you admire (Linux kernel, Vue.js, etc.). Read their recent commits. Note the patterns.
- For one week, write commits as if they'll be read by a stranger in two years.