Version Control

How to Write Useful Commit Messages

Habits for short, descriptive commit messages: a clear summary line, a body that explains why, and consistent conventions that keep project history readable.

On this page
  1. Who the message is for
  2. A simple structure
  3. Writing the summary line
  4. Writing the body
  5. Before and after
  6. One change per commit
  7. Mistakes to avoid
  8. Fixing a message
  9. Team conventions

Who the message is for

A commit message is written once and read many times, usually by someone who was not there: a colleague reviewing a change, a new team member trying to understand why code looks the way it does, or you, six months later, with no memory of the afternoon in question.

The diff already shows what changed, line by line. The message earns its place by adding what the diff cannot: the purpose of the change, the problem it addresses, and anything surprising about the approach. A history made of such messages becomes a searchable record of decisions. A history made of “update” and “stuff” is close to useless.

A simple structure

A widely used convention has two parts:

  1. A summary line: short, specific, and standing on its own.
  2. An optional body, separated from the summary by a blank line, explaining the reasoning.

Example:

Reject negative sample counts in averaging routine

The averaging function divided by the sample count without checking
it, so an empty or invalid input produced a confusing error far from
the cause. Validate the count at the start and report a clear message.

The summary says what the commit does. The body says why it was needed. Short changes may need only the summary.

Writing the summary line

  • Keep it brief. Around 50 characters is a common guideline, and many tools truncate long lines in logs. It is a guideline rather than a rule; clarity matters more than a character count.
  • Be specific. “Fix bug” tells the reader nothing. “Fix off-by-one error in buffer length check” tells them where to look.
  • Use a consistent mood. Many teams write in the imperative, as if completing the sentence “If applied, this commit will…”: “Add”, “Fix”, “Remove”. Pick one style and keep to it.
  • Skip the trailing full stop. It saves a character and is a common habit, though not essential.
  • Name the area if it helps. Some teams put a short prefix, such as a module name, at the start so a log can be scanned quickly.

Writing the body

Add a body when the reason for a change is not obvious. Good topics are:

  • What problem prompted the change, in a sentence or two.
  • Why this approach was chosen over an obvious alternative.
  • Side effects, limits or known gaps.
  • A reference to a ticket or issue number, if your team tracks them.

Keep lines to a reasonable width, around 72 characters, so they read well in a terminal. Write plain sentences, as you would in technical writing generally: say one thing at a time and avoid private shorthand that only you understand.

Avoid repeating the diff in words. “Changed the variable from x to y in three places” adds nothing, while “Rename x to y to match the units used in the specification” does.

Before and after

Weak messages:

  • update
  • fixes
  • changes to code
  • final version
  • more work on calibration

Stronger versions:

  • Add timeout to sensor read loop
  • Correct unit label on pressure axis
  • Move calibration constants to a config file
  • Remove unused serial port helper

None of the stronger messages is long. The difference is that each names the thing and the action.

One change per commit

The best messages are easy to write when the commit is small and focused. If you cannot summarise a commit without using the word “and”, it may contain two changes that belong in separate commits. Git’s staging area lets you split work done in one sitting into several commits, which makes the history easier to read, easier to review, and easier to reverse if one piece turns out to be wrong.

This also helps when you later hunt for the source of a problem. If every commit does one thing and says so, the log itself narrows down the search, which is useful alongside debugging strategies and root cause analysis.

Mistakes to avoid

  • Vague summaries such as “fix” or “misc”.
  • Describing your feelings or process. “Finally got it working” tells the reader nothing about the change. Leave out frustration and jokes that will not age well.
  • Blaming people. The history is permanent and shared. Describe the change, not who caused the issue.
  • Mixing unrelated work. A commit titled “Fix typo and rewrite parser” is a sign to split.
  • Including secrets. Passwords, keys and private data do not belong in messages or in the files committed with them.
  • Over-long messages for tiny changes. A one-line typo fix does not need three paragraphs.

Fixing a message

If you notice a mistake in your most recent commit and have not shared it yet, Git can amend it:

git commit --amend

This rewrites the latest commit, so avoid it once the commit has been pushed and others may have based work on it. The reasons for that caution are explained in the guide to undoing mistakes safely.

Team conventions

Small teams gain a lot from a short written convention: the summary style, whether to use prefixes, how to reference tickets, and when a body is expected. A few lines in a contributing note or readme are enough. Some teams also use a template that appears in the editor when you commit, which prompts for the key information.

Review is a good time to enforce the habit gently. A reviewer asking “can you say why in the message?” is doing the future team a favour, and good review feedback is easier to accept when it is framed around the reader rather than the author.

The aim is modest: each message should let a stranger understand, in under half a minute, what changed and why. Do that consistently and your project’s history becomes a useful tool rather than noise.

The complete guide to version control

Version Control Explained for Engineers
Read the guide

Keep exploring

Guides from other topics

All topics →