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.
1. Write a clear subject
Section titled “1. Write a clear subject”Use a short, specific subject, commonly in the imperative form:
update ← vagueValidate email addresses during registration ← specificThe 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.
2. Use the body for the reason
Section titled “2. Use the body for the reason”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 emailscould 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.
3. Keep commits atomic
Section titled “3. Keep commits atomic”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 registrationfeat: add passwordless sign-infix: 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.
5. Common mistakes and safety
Section titled “5. Common mistakes and safety”updateorchangessays 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:orfeat: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.
6. Summary
Section titled “6. Summary”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.
7. Knowledge check
Section titled “7. Knowledge check”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.