How to Write Good Git Commit Messages (With Examples)

By Md Faizan

Published On:

Follow Us
A developer's monitor showing a git commit history list on a tidy desk with a keyboard and notebook

Six months from now, someone on your team — quite possibly you — will stare at a commit titled “fix stuff” and have no idea what it changed or why. Commit messages are the smallest documentation a project has, and the most-read. This guide gives you a format that takes seconds to follow, examples of good and bad messages, and the reasoning that makes a project’s history actually useful.

Good commit messages are one leg of a healthy documentation habit; the other two are a README developers actually read and a changelog users actually read.

The short version: a format that works

A commit message has two parts — a subject line and an optional body — separated by a blank line:

Capitalized, imperative subject of 50 characters or less

Body: explain WHAT changed and WHY, wrapped at 72 characters.
The body is where the reasoning lives: what problem existed,
what this change does about it, and anything a future reader
needs before touching this code again.

Five rules carry almost all of the value:

  1. Keep the subject to about 50 characters. It stays readable in git log --oneline, in GitHub lists and in email subjects.
  2. Write the subject in the imperative mood. “Add password reset” — not “Added”, “Adds” or “Adding”. A useful test: the subject should complete the sentence “If applied, this commit will ___.”
  3. Separate subject and body with a blank line. Git tooling depends on it — without it, your whole message becomes the subject in many views.
  4. Use the body to explain what and why, not how. The diff already shows how. The body is for intent, context, trade-offs and links to the issue being fixed.
  5. One logical change per commit. A commit that fixes a bug, renames a file and upgrades a dependency cannot be described by any single honest subject line. Split it.

Bad messages, rewritten

Instead of thisWrite this
fix bugFix totals rounding down on invoices with tax-exempt items
updatesUpdate README install steps for Node 20
final version 2Remove deprecated v1 search endpoint
asdf(this commit should not exist — squash it before merging)
changed some filesAdd rate limiting to the login endpoint

Notice the pattern: every good version names the thing affected and the change made, in words a teammate who never saw the code can understand.

The body is where the value is

Subject lines get the attention, but bodies prevent the archaeology. A good body answers three questions:

  • What was wrong or missing? “Password reset emails were arriving up to an hour late because they shared the marketing queue.”
  • What does this change do about it? “Moves reset emails to the transactional queue and adds a priority flag.”
  • What should a reader be careful about? “Requires the new queue name in production config before deploy; see the linked issue.”

That is four sentences, and it will save a future debugging session. Link the issue or pull request (“Refs #123”, or your tracker’s format) so the discussion that produced the change is one hop away.

Conventional Commits: a popular structured option

Many teams add a type prefix to the subject, following the Conventional Commits convention:

  • feat: — a new feature
  • fix: — a bug fix
  • docs: — documentation only
  • refactor: — a code change that neither fixes a bug nor adds a feature
  • test: — adding or correcting tests
  • chore: — build, tooling and maintenance

Example: feat: add CSV export to reports page. The payoff is mechanical: tools can group history by type, generate changelog drafts automatically, and even suggest version bumps — feat suggests a minor version, fix a patch, and a breaking-change marker a major one, in the spirit of Semantic Versioning. Adopt the convention if that automation helps your team; the five rules above matter more than the prefix.

Team habits that keep history clean

  • Agree the convention in the project docs, ideally where contributors already look. A short “Committing” section near your README’s contributing notes beats a wiki page nobody opens.
  • Review messages in pull requests the way you review code. A misleading message merged today is misinformation for years.
  • Fix messages before merging, not after. Amending or squashing is safe on your own unmerged branch; rewriting history that teammates have already pulled creates real pain. When in doubt, leave the history and write the next message better.
  • Keep commits small enough to describe. If you cannot summarize a commit in 50 characters, it is probably two commits wearing a trench coat.

Frequently asked questions

How long should a commit message be?
The subject: about 50 characters. The body: as long as the reasoning needs — usually a short paragraph or a few bullets, wrapped around 72 characters per line.

Should every commit have a body?
No. A one-line subject is fine for a change whose subject fully explains it (“Fix typo in install instructions”). Reach for the body whenever the why is not obvious from the diff.

What tense and mood should I use?
Imperative present: “Add”, “Fix”, “Remove”. Git itself uses it (“Merge branch…”), and it keeps subjects short and consistent.

Can I fix a bad message after pushing?
On a branch only you use, yes — amend and force-push carefully. On shared history, prefer not to rewrite; correct the record in the pull request description or a follow-up commit note instead.

Do commit messages really matter for a solo project?
Yes — your future self is the teammate. Solo histories are read during exactly the same “why did I do this?” moments, with nobody else to ask.

Bottom line

A good commit message is a 50-character imperative subject, a blank line, and a body that explains what changed and why. It takes under a minute longer than “fix stuff”, and it pays that minute back the first time anyone — including you — has to understand the project’s past. Pair the habit with a maintained changelog and your project’s history stops being a mystery and starts being documentation.

Leave a Comment