Hazem Azzam

All posts
Writing

How to Write Professional Commit Messages

Good commit messages turn git history into documentation: they explain what changed and why, without making the next reader trawl through diffs. This post covers subject lines, optional bodies, Conventional Commits, and habits that keep messages clear for you and your team.

3 min read
gitworkflowdocumentationteambest-practices

Why commit messages matter

A commit is more than a snapshot of files. It is a decision record: what you chose to change and—when you write well—why that choice made sense. Professional messages make code review faster, help newcomers ramp up, and keep git blame, git bisect, and release notes useful. Vague messages (“fix”, “wip”, “updates”) force everyone to open diffs to learn anything at all.

Investing one minute in the message often saves hours later.

The basic shape

Most teams converge on a simple layout:

  1. Subject line — single line, present tense / imperative mood, typically 50 characters or fewer as a soft limit so tools and terminals display it cleanly.
  2. Blank line — separates the subject from the body everywhere Git expects it (logs, emails, formats).
  3. Body — optional for tiny edits; encouraged when behavior, motivation, or rollout steps are not obvious from the diff alone. Wrap body text around 72 characters so plain-text readers stay readable.

Think of the subject as completing: “If applied, this commit will…”

Examples:

  • “Add Redis-backed session store”
  • “Reject negative quantities on cart update”
  • “Align pagination controls with design tokens”

Avoid trailing punctuation on the subject if your style guide does (many teams skip the period).

Conventional Commits

Many projects prefix the subject with a type and optional scope:

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

Common types include:

TypeTypical use
featNew capability users or operators notice
fixBug fix
docsDocumentation only
styleFormatting, missing semicolons—no logic change
refactorInternal change without fixing a bug or adding a feature
perfPerformance improvement
testTests added or corrected
build / ciTooling, pipelines, packaging
choreMaintenance that does not fit elsewhere

Examples:

  • feat(auth): support refresh token rotation
  • fix(api): return 422 on invalid ISO dates
  • chore(deps): bump eslint to 9.x

Consistency matters more than the exact taxonomy: pick types your team will actually use.

Imperative mood

Write “Fix null dereference” not “Fixed” or “Fixes”. Imperative matches Git’s own generated messages (Merge branch…, Revert…) and reads like a command to the codebase. It stays short and avoids tense debates.

What belongs in the body

Use the body when:

  • Motivation is not visible in the diff (policy change, incident response, ticket context—without inventing ticket numbers you do not have).
  • You need to describe tradeoffs (“chose X over Y because…”).
  • There are migration steps, feature flags, or follow-up work.
  • You are removing code—say what replaced it or why it is safe.

For straightforward changes (“rename variable for clarity”), a subject alone is often enough.

Example body:

Replace synchronous file writes with a bounded queue so uploads
during traffic spikes do not block request threads. Max queue depth
defaults to 100; overflow returns 503 with Retry-After.

Tested: load test script in ops/load/upload-spike.js on staging.

Small commits, readable history

Professional practice usually favors many focused commits over one enormous squashed blob—each commit passes tests and represents one logical step. Reviewers can follow the narrative; git bisect finds the breaking change.

When your hosting workflow squashes on merge, rewrite the squash message so it still summarizes the whole change meaningfully—do not settle for a list of thirty subjects unless your tooling generates a good summary.

Anti-patterns to avoid

  • Noise: “final”, “really fix”, “oops”.
  • Only ticket IDs in the subject with no human-readable summary (fine to add IDs in the body or footer).
  • Mixing unrelated changes in one commit—hard to describe honestly in one subject.

Summary

Professional commit messages combine a clear imperative subject, optional body for context, and consistent types when your team adopts Conventions. They respect the next reader—often you, weeks later—and keep history a trustworthy asset.


Rate this post

All fields are optional. Just stars is fine.

No ratings yet