Commit messages are one of the most important parts of using version control. Badly written messages make it much harder to see at a glance what's changed in the project.
Keep your commits as small and atomic as possible. The best way to consider this is to think about reverting your commit. That is, if something is wrong in a commit, what are the logically separate parts that could be undone?
It may be tempting to commit everything you have at once, but you should break it down. It's common to work on multiple things at once (fixing bugs as you notice them, e.g.), but these should be split up. git's patch mode is perfect for this:
The GitHub apps can also do the same:
Commit messages should strive to follow [Tim Pope's guidelines][tpope], which are fairly universally adopted amongst git users. This format looks like:
Capitalized, short (50 chars or less) summary
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body. The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.
Write your commit message in the imperative: "Fix bug" and not "Fixed bug"
or "Fixes bug." This convention matches up with commit messages generated
by commands like git merge and git revert.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, preceded by a
single space, with blank lines in between, but conventions vary here
- Use a hanging indent
The default tools included with git (the vim gitcommit
syntax highlighting,
e.g.) will highlight this correctly for you.
The most important point is the subject/body distinction. The first line is a summary of the commit, but should be reasonably succinct. Overflowing the 50 character limit should be avoided, but it's not a huge problem. If you have anything else you need to say, it should be in the body of the commit message.
-
Always write in the imperative:
Prefer "Fix bug", not "Fixed bug". Similarly,
-
Try to always start with a verb:
"Send", "Allow", "Check", "Fix" and "Merge" are all good examples of this. This follows from using the imperative.
-
Avoid using "and"/"also" wherever possible:
Using "and" in a commit message indicates that you're really changing two things at once. This should be split into two separate commits. Use patch mode (
git add -p
) if needed. -
Don't add trailing full-stop to summary:
Email subjects don't end with full-stops, so neither should commit message summaries. However, the body should.
-
Give enough information to be useful:
Summaries like "Update" mean nothing. "Update image" is better, but "Update homepage image" is even better. "Change homepage image resolution" is the best of the lot.
The inverse is true too; don't stuff too much information in there. "Change homepage image resolution from 800x600 to 1080x900" is too long, and is a bit of an information overload. If someone needs to know what exactly was changed, they can look at the change itself.
Here's some recent commits from various HM projects, showing the bad and the good:
-
Provide better error reporting for failed backups
- Awesome! -
doc block
- No verb, and vague. Suggest:Add doc block
-
add synopsis
- Good, but missing intention. Suggest:Add synopsis for WP CLI
-
New home icon
- No verb. Suggest:Add new home icon
-
Update
- Bad; tells us nothing about what you're changing. Suggest:Update homepage image
-
Don't instantiate class if it doesn't exist.
- Almost perfect, but should not have trailing full-stop
Some longer commits too:
-
Hide tabs until the modal is fully open Avoids the visual height glitch when opening the excludes modal where the initial height includes all tabs contents and then quickly animates back to the correct height.
Almost perfect, but text should be wrapped to 72 characters.
-
Fixed wrong css path The file is located in css/vendor/jquery-ui/ not css/.
Perfect! (Could drop the trailing full-stop though.)
-
Fixing redactor for test html email Previous version of this did not check for the use of InnerHTML, which unfortunately caused all of redactor instances to break. This extra check is only used on the test html email instance; which sets its data on init, triggering an innerHTML.
Perfect! Describes the technical reasons for the change, as well as summarising it succinctly.
I shall follow this!