Git Commit Messages: Best Practices and English Tips

How to write clear, consistent, professional git commit messages in English — with the Conventional Commits format, real examples, and the most common mistakes to avoid.

Your commit history is a log of decisions written in English. Every developer on your team — now and in the future — will read it. A clear commit history is documentation. A messy one is noise.

Writing good commit messages is a writing skill, not just a Git skill. Here is everything you need to do it well.


Why Commit Messages Matter

A bad commit history looks like this:

fix
wip
asdf
changes
fixed the thing
updated
more work on login
final fix (for real this time)

A good commit history tells a story:

feat(auth): add JWT refresh token rotation
fix(api): return 422 instead of 500 on invalid email format  
docs(readme): document environment variable setup for local dev
refactor(cart): extract price calculation into a pure function
chore(deps): upgrade React from 18.2 to 18.3

The difference is not skill level — it is habit and practice.


The Conventional Commits Format

Conventional Commits is the most widely used standard for commit message formatting in professional teams. The pattern is:

<type>(<scope>): <short description>

[optional body]

[optional footer: closes #123, breaking change note, etc.]

The most common types

TypeWhen to use it
featA new feature
fixA bug fix
docsDocumentation changes only
styleFormatting, whitespace — not CSS styling
refactorCode restructured without changing behaviour
testAdding or fixing tests
choreMaintenance: dependency updates, CI config, build scripts
perfPerformance improvement
revertReverting a previous commit

The scope (optional but useful)

The scope is the part of the codebase affected: auth, api, ui, db, cart, payments, ci, readme

fix(auth): handle expired tokens gracefully
refactor(db): replace raw queries with ORM methods


Writing the Subject Line

The subject line is the single most important part of the commit message. It appears in git log, pull request lists, and code review tools.

Rules for the subject line

  1. Use the imperative mood — write as if giving a command
    add user authentication
    added user authentication
    adding user authentication

  2. Keep it under 72 characters — longer titles get truncated in many tools

  3. Start with the type, then a colon, then the description
    feat(payments): add Stripe webhook handler

  4. Describe what the commit does, not how
    fix(api): prevent duplicate email registration
    fix(api): added if-statement check for existing email

  5. Don’t end with a period
    fix: correct typo in error message.
    fix: correct typo in error message


The Imperative Mood: Why It Matters

The imperative mood means writing a verb as if giving an instruction. Think of it as: “If applied, this commit will ___.”

  • “If applied, this commit will add JWT authentication”
  • “If applied, this commit will fix the null pointer on login”
  • “If applied, this commit will remove deprecated API endpoints”

Imperative vs. other verb forms

❌ Wrong✅ Correct (imperative)
added password validationadd password validation
fixing memory leak in cachefix memory leak in cache
updated dependenciesupdate dependencies
new feature: dark modefeat(ui): add dark mode toggle
changes to improve performanceperf(db): add index on user email column

Common English Verbs for Commit Messages

You do not need a large vocabulary. These verbs cover most situations:

VerbUse for
addNew feature, file, endpoint, test, dependency
fixBug fix
updateModifying something that already exists
remove / deleteRemoving code, files, endpoints
refactorRestructuring code without changing behavior
renameRenaming files, functions, variables
improveMaking something better (vague — try to be more specific)
extractMoving code into a separate file or function
mergeMerging branches (usually auto-generated)
revertUndoing a previous change
bumpVersion number increase (common for chore/deps commits)
migrateMoving data or code to a new format/location

Writing the Commit Body (For Complex Changes)

For simple changes, the subject line is enough. For complex refactors, architectural changes, or non-obvious fixes, add a body.

The body answers: Why was this change made? Not what — the diff shows what. The body explains the reasoning.

fix(auth): prevent session fixation on login

Previously, the session ID was not regenerated after successful 
authentication, making the app vulnerable to session fixation attacks.

This change calls `req.session.regenerate()` immediately after 
the user credentials are validated, before writing any data to the 
session.

Closes #487
Related to #423 (auth hardening sprint)

Useful phrases for commit bodies

“Previously, this code…” — explains what was happening before
”This change…” — explains what you changed and why
”This fixes…” / “This resolves…” — links to the problem
”Note: this is a breaking change — callers must update…” — flags impact
”Closes #123” / “Fixes #456” — links to a GitHub issue (auto-closes it on merge)


Rewriting Bad Commit Messages: Practice

Try to improve these before reading the corrections:

Bad: fix stuff in auth
Better: fix(auth): redirect to /login after session timeout


Bad: wip
Better: feat(search): implement fuzzy search using fuse.js (in progress) — or, even better, use a branch and squash before merging.


Bad: updated the thing
Better: chore(ci): update Node.js version to 22 in GitHub Actions workflow


Bad: changes for sarah
Better: refactor(reports): split CSV export into a background job per Sarah's review


When the “Right” Format Doesn’t Matter

Not every commit needs Conventional Commits format. On a solo project, a small team with a different convention, or a prototype, strict formatting may be overkill. What always matters:

  1. The subject line tells you what happened without reading the diff
  2. You were not lying — the message describes what the commit actually does

The first commit — the one that starts a new project — is traditionally just:

initial commit

No type, no scope. Everyone understands it.


Good commit messages are a professional signal. When a senior developer reads your git history and sees clear, consistent, informative messages, they trust your work before they read a single line of code.