Commit messages are one of the most common ways developers communicate with other developers, including our VIP team, so it’s important that your commit message clearly communicate changes with everybody else.
Who are we writing commit messages for? #
The audience of a commit message is:
0. People reading the commit timeline.
1. People debugging code.
What is a good commit message? #
Having these assumptions in mind:
1. Good commit messages should have a subject line. One sentence briefly describing what the change is, and (if it makes sense) why it was necessary.
A good subject line gives the reader the power to know the gist of the commit without bothering to read the whole commit message.
Fix stats link on m.example.com
This does not need a high-level why part, because it’s obvious – the links weren’t working.
Stats Report: clear caches on each post to save memory
Here we need a why part, because if the message was only “clear caches on each post”, the obvious follow-up question is, “Why would you clear cache for each post in a loop?!”.
Whenever the commit is a part of a clearly-defined and named project, prefixing the commit with the project name is also very helpful. It’s not mandatory, because often the project space is vague and the list of committed files reveals similar information.
2. There should be an empty line between the subject line and the rest of the commit message (if any). Whitespace is like bacon for our brains.
3. A good commit message tells why a change was made.
Reasoning why is helpful to both of our audiences. Those following the timeline, can learn a new approach and how to make their code better. Those tracing bugs gain insight for the context of the problem you were trying to solve, and it helps them decide whether the root cause is in the implementation or higher up the chain.
Explaining why is tricky, because it’s often obvious. “I’m fixing it because it’s broken”. “I’m improving this, because it can be better.”
If it’s obvious, go one level deeper. The 5 Whys technique is great. Not only for looking for root causes of problems, but for making sure you are doing what you are doing for the right reasons.
JSON API: Split class into hierarchy for easier inclusion in ExamplePlugin Including the old code required a bunch of hacks and compatibility layers. With the new hierarchy, we can get rid of almost all the hacks and drop the files into ExamplePlugin as is.
Here the commit message very conveniently explains what the downsides were of the old approach and why the new approach is better.
Remove filtering by ticket It's not very useful, while it's slow to generate. The workflow is to usually go to the ticket page and see associated comments there.
Here the commit message shares a UX decision we made, which is the primary reason of the commit.
5. Most commits fix a problem. In this case a good commit message explains what caused the problem and what its consequences were.
Everybody needs to know what caused a problem in order to avoid causing a similar problem again. Knowing the consequences can explain already noticed erroneous behaviour and can help somebody debugging a problem compare the consequences of this, already fixed problem with the one being debugged.
If possible, avoid the word fix. Almost always there is a more specific verb for your action.
If the problem is caused by a single changeset, a good commit message will mention it.
6. A good commit message explains how it achieves its goal. But only if isn’t obvious.
Most of the time it’s obvious. Only sometimes some high-level algorithm is encoded in the change and it would benefit the reader to know it.
Add a first pass client stat for bandwidth Bandwidth is extrapolated from a month sample. From there we get the average number of bytes per pageview for each blog. This data is cached in means.json. All the code for generating the data in means.json is in the static methods of the class.
Here we explain the algorithm for guessing bandwidth data. It would have been possible to extract this information from the commit, but it would’ve taken a lot of time and energy. Also, by including it in the commit message we imply that it’s important for you to know that.
7. If the subject line of a commit message contains the word and or in other way lists more than one item, the commit is probably too large. Split it.
Make your commits as small as possible. If you notice a coding style problem while fixing a bug, make a note and fix it after you fix the bug. If you are fixing a bug and you notice another bug, make a note and fix the second bug in another commit.
The same is especially true for white space changes to existing code. White spaces changes should be a separate commit.
8. A good commit message should not depend on the code to explain what it does or why it does it.
Two notes here:
This doesn’t mean we should tell what each line of code does. It means that we should convey all the non-trivial information in the code to the commit message.
This doesn’t mean we whouldn’t include any of this information in the code. Knowing why a function exists, what it does, or what algorithm does it use can often be a useful comment.
9. It’s perfectly OK to spend more time crafting your commit message than writing the code for your commit.
10. It’s perfectly OK for your commit message to be longer than your commit.
11. A good commit message gives props and references relevant tickets.
12. Common sense always overrules what a good commit message thinks it should be.
Other perspectives #
Here’s another excellent post that explains how to approach a good commit message: http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message