These are the rules I follow when writing Git commit messages. I’ve found these serve me well and are compatible with most projects I work on (if a project has a specific set of rules for writing Git commit messages, those would override any rules I’ve outlined here).
1. Write your commit messages in an editor (never use -m)
2. First line is the subject
- Use the imperative mood (imagine the words "This will")
- Capitalize the first letter
- Limit the subject line to 50 characters
- Do not end the subject line with a period
3. Skip a line after the subject
4. The rest of the commit is the body
- Add line breaks so each line is a maximum of 72 characters
- Explain the thinking behind the commit
- Do not use Markdown
- The last line should reference the issue or ticket
Example
Add early return to isValid() method for clarity
When the conditional is false, we return the value immediately. Because no
further calculation is necessary in this situation, we can return the value
immediately. This doesn't change the behavior of the method but makes it
easier for a human to understand.
See #11
1. Write your commit messages in an editor
A single line is almost never sufficient for a commit message, so it is almost always better to write your commit message in an editor. The default editor, Vim, is not very user friendly but Git allows you to set the editor of your choice for writing commit messages (see how to Set Your Git Commit Message Editor).
2. First line is the subject
In the same way you summarize an email with a subject line, the first line of your commit should summarize your commit.
Use the imperative mood
The easiest way for me to write a commit message in the imperative mood is to imagine the words “This will” and then whatever comes next becomes my commit message subject line.
This will add an early return to the isValid() method for clarity
becomes
Add early return to isValid() method for clarity
(you’ll notice I’ve capitalized the first letter and dropped some words to meet the length requirement).
Capitalize the first letter
In the same way you capitalize the first letter of a sentence (or the first letter of an email subject line), capitalize the first letter of your commit message subject line.
Limit the subject line to 50 characters
This is a soft limit rule. While I certainly target 50 characters or less, if I go a character or two over I don’t see it as a problem (as long as the message still works if truncated to 50 characters).
Many editors will flag this limit by default. In Visual Studio Code, the line will turn red if you go over 50 characters.
If you are creating a commit in GitHub through their website and you go over 50 characters, it will display the message.
ProTip! Great commit summaries contain fewer than 50 characters. Place extra information in the extended description.
Do not end the subject line with a period
In the same way you don’t end an email subject line with a period, your Git commit subject line does not need a period either (plus with a 50 character limit you’ll want to save every character you can).
3. Skip a line after the subject
This visually separates the subject line from the body.
4. The rest of the commit is the body
Add line breaks so each line is a maximum of 72 characters
Some editors can be configured to do this automatically. Currently it appears that Visual Studio Code does NOT support adding line breaks (see VSCode Issue: 2718 Git: Automatically insert line breaks in git commit messages).
Explain the thinking behind the commit
When someone (often future you) is trying to understand why a change was made, this explanation of the thinking behind it is invaluable.
Do not use Markdown
A commit message is meant to be viewed as text, not rendered as HTML so markdown is not appropriate.
However, it is common to include a bulleted list starting each line with a dash (-
).
If your list items go longer than 72 characters, use a hanging indent
- Updates endpoint
- Lorem ipsum dolor sit amet lorem ipsum dolor sit amet lorem ipsum dolor sit amet lorem
ipsum dolor sit amet lorem
The last line should reference the issue or ticket
Often a commit is being created in response to some kind of issue or ticket (e.g. an issue in GitHub, Bitbucket, or Jira).
On some platforms, this reference will create a relationship between the commit and the issue (e.g. in GitHub you can write See #8088
and a relationship will be created between GitHub Issue #8088 and your commit).
See GitHub’s Linking a pull request to an issue using a keyword.
Git Commit Rules I Don’t Subscribe To
Required Commit Message Prefixes
Some projects (e.g. Angular) prefix their commits with a type value (e.g. fix
, feat
, chore
). This is part of the Conventional Commits specification.
In my experience, I’ve not found these prefixes to bring significant value and since I have only 50 characters to work with in the commit message subject, I already find myself pressed for space. Perhaps I’ll work on a project in the future that changes my mind about this.
Gitmoji is an interesting variation on this idea where an emoji is used as a prefix but still not something I like on my projects.
Automated Commit Linting
I’ve worked on projects that use something like husky commit linting, to enforce rules when writing commit messages.
In my experience, these rules do not improve the quality of the commit messages. Additionally, it can create a very frustrating user experience when you carefully craft your commit message but then your commit message fails due to some rule and you lose the message you’ve crafted (see how to recover a failed Git commit message if you’re working on a project with commit linting).
Automated Changelog Generation from Git History
While I’m a fan of keeping a changelog and a fan of good commit messages, I don’t think a well written commit message necessarily makes a good changelog entry. I don’t see the value in a changelog when it is essentially a copy of the output of git log --oneline
.
My co-worker Tanner Record did a cool thing where he turned these rules into a template that pre-populates the commit with reminders.
See his Git Rules Commit Template.