Skip to content

Good Commit Messages

A commit message helps someone understand a change later without opening every file first. Git accepts a vague message such as update, but that message does not explain the change. A useful message makes local history easier to inspect and helps reviewers understand the intent.

Use a short, specific subject, commonly in the imperative form:

update ← vague
Validate email addresses during registration ← specific

The imperative describes the effect of applying the commit: “Validate…”, “Fix…”, or “Add…”. Prefer the behavior or purpose over a list of edited files. The subject does not have to explain every implementation detail.

When the reason is not obvious, add a body below a blank line:

Validate email addresses during registration
Previously, invalid addresses could create accounts whose activation emails
could not be delivered.

The subject states the change; the body gives context and explains why it matters. A list such as “update validation; add test” only repeats what a diff already shows. Implementation detail can be useful when it explains a non-obvious decision, but is not required in every message. A simple change may need only a subject.

An atomic commit has one coherent purpose, not necessarily one file. Email validation code and its tests can belong in one commit. An unrelated button color change belongs in a separate commit. This makes history easier to review and allows a change to be handled independently later.

Before committing, inspect the selected content with git status and git diff --staged. A good message cannot make unrelated selected changes coherent.

4. Optional conventions and ticket references

Section titled “4. Optional conventions and ticket references”

Some teams use Conventional Commits, for example:

fix: prevent invalid email registration
feat: add passwordless sign-in

fix: labels a correction to existing behavior; feat: labels a new capability. This format can support changelogs and automation when a team uses it consistently. Git does not require it, and a prefix does not rescue a vague subject such as fix: update.

When a ticket provides useful context, include its identifier alongside a readable subject:

fix: prevent invalid email registration (AUTH-42)

Do not use AUTH-42 alone as the entire message. The identifier may help find the discussion, but the commit should still make sense on its own.

  • update or changes says too little about the purpose.
  • A body that only enumerates edited files omits the reason for the change.
  • One commit for unrelated backend and UI changes makes later review harder.
  • A fix: or feat: prefix is a convention, not Git validation of quality.
  • A ticket number alone does not describe a change.

Do not rewrite existing history just to practice better messages. Use a disposable repository for experiments, and review message and staged content before creating a new commit.

A useful subject says what the commit achieves. Add a body when the reason needs explanation. Keep each commit focused on one purpose; code and tests for that purpose can stay together. Prefixes and ticket references are aids, not substitutes for a clear message.

Should email validation and its tests be split merely because they edit different files?

No. They serve the same purpose and can form one atomic commit.

What should a body explain when the subject already states the change?

The reason or context behind the change, especially when it is not obvious from the subject or diff.