We've all lived the XKCD about git commit messages at some point.
I am no exception. This is what the commit messages for my blog look like:
fixxxx stuff post post post post posts mmm posts front maddy Add chris oliver add syntax article add git patch article fix video video arty art art Fix links oops
Because my blog's git history is only ever seen by me, that's okay. I've accepted that I'll never be able to take full-advantage of git in my blog, and I'm totally fine with that.
Unfortunately, some people treat real projects with multiple contributors a lot like I treat my blog. I've found that this practice is the result of ignorance rather than laziness. So I'm going to share some tips on how you should use commit messages in real projects.
Git is a powerful tool, even if you only use it for keeping a history of code changes and don't take advantage of its most powerful features.
However, you'll find that the deeper you dig, the more powerful git becomes. You'll also find that many of the most useful features of git work under the assumption that commit messages are helpful.
Think about the last time you used
git blame. Would it have been helpful if you found a commit message that read,
fixed a bad bug? Probably not, you were probably trying to find more context about code you were working on; you needed an explanation of what and why.
Git commit messages must include the what and why behind each change so that the brave git spelunkers of tomorrow can step into the headspace of a commit's author. If a commit message doesn't include that information, why write one at all? Commit messages are only useful if they are useful to someone trying to understand a change at some point in the future.
In order to create a template for a good commit message, I'll break commit messages down into several sections.
In a commit message, the first line (sometimes called a subject line) should be isolated from the body. Ideally, this line summarizes the changes made in a commit.
When I write subject lines, I try to finish the sentence, "This commit will..."
For example, I might write a subject line that reads something like,
Remove unused, commented code. That would finish my sentence nicely: "This commit will remove unused, commented code."
When it comes to formatting your subject line, there are one or two rules to remember.
First, the first character in your subject line should be capitalized; this is just a common convention. In my experience, it also makes it easier to read long lists of one-line commits.
Second, your commit message shouldn't be longer than fifty characters. That is because tools like GitHub truncate the line at fifty characters. Therefore, to allow others to effectively scan and grok your subject line, you should try to summarize the entire change in fifty characters.
The first line of my commit message template looks like this:
Summarize the change in less than 50 characters
In some commits, the subject line is enough to convey the entire idea. For example, if your commit will
Add a comma to the README, you probably don't have to explain yourself.
However, in most commits, your changes might benefit from some additional context. We don't want future developers to be missing context while trying to understand the reasoning behind a change.
This is where the message body comes into play. I divide the body into "paragraphs," which are just loosely defined strings of text separated by white space. They can be bullet points, sentences, or something else; it's just important that they are easy to read and understand from a cold start.
In the past, I usually used the first paragraph of a commit message body to explain what I had done. These days, I've moved away from what and started documenting why.
Ben Orenstein@r00kMost commit messages are next to useless because they focus on WHAT was done instead of WHY.
This is exactly the wrong thing to focus on.
You can always reconstruct what changes a commit contains, but it's near impossible to unearth the reason it was done.
(thread)17:33 PM - 20 Sep 2019
So, in this case, we want to lead with why we are making the change.
Here is an example:
Refactor the coupon UI Because: - The old UI code is fairly slow - There were a few unused dependencies - The old UI has aged poorly
The great thing about these "paragraphs" is that there is only one formatting rule: Wrap at 72 characters. This is more of a legacy tradition than anything substantial. However, the primary reason is that this allows git some space to indent (assuming a max character limit of 80). I recommend following this rule even though it's not always strictly necessary.
Here is the commit message template so far:
Summarize the change in less than 50 characters Because: - Explain the reasons you made this change - Make a new bullet for each reason - Each line should be under 72 characters
Now that we've summarized the change and shared our reasons for making the change, it might be prudent to explain exactly what we did in a longer form.
I use the second "paragraph" to give a more detailed explanation of what I did in the change, for example:
Refactor the coupon UI Because: - The old UI code is fairly slow - There were a few unused dependencies - The old UI has aged poorly I thought it was necessary to remove some of the old coupon UI code. Unfortunately, it has aged pretty poorly, and I think this refactor makes the code much easier to support in the long-run. Primarily, this commit improves the performance of the coupon component. It also removes some unused dependencies.
This section of the commit body should explain what was done with a little bit more depth than the 50 character summary. The formatting is up to you (as long as you're wrapping at 72 characters).
Here is the updated template:
Summarize the change in less than 50 characters Because: - Explain the reasons you made this change - Make a new bullet for each reason - Each line should be under 72 characters Explain exactly what was done in this commit with more depth than the 50 character subject line. Remember to wrap at 72 characters!
At this point, we're writing effective and coherent commit messages. However, sometimes a commit message needs a few extra notes. That can be done in the last section.
Refactor the coupon UI Because: - The old UI code is fairly slow - There were a few unused dependencies - The old UI has aged poorly I thought it was necessary to remove some of the old coupon UI code. Unfortunately, it has aged pretty poorly, and I think this refactor makes the code much easier to support in the long-run. Primarily, this commit improves the performance of the coupon component. It also removes some unused dependencies. These changes should resolve issue #1337. This commit removed the left-pad dependency, so please stop using it! Co-authored-by: nspinazz89 <email@example.com>
In this example I was able to:
- reference a related issue
- add a line to warn that I removed a dependency
- include a reference to a person that worked on the commit with me
At this point, anyone who looks at this commit message is going to know:
- What was done at a glance
- Why the change was necessary
- The details about what was done
- Any useful details concerning the change
This makes our commit message infinitely more useful to our future selves and any other developers who need to understand our code.
Even if you disagree with my methodology for writing commit messages, it's hard to deny that we must write commit messages that allow other developers to step into our headspace when they are reading our code.
I think most people agree that a hallmark of "good" code is maintainability, you can augment the maintainability of your code by writing commit messages that help others understand and even change your code in the future.
Summarize the change in less than 50 characters Because: - Explain the reasons you made this change - Make a new bullet for each reason - Each line should be under 72 characters Explain exactly what was done in this commit with more depth than the 50 character subject line. Remember to wrap at 72 characters! Include any additional notes, relevant links, or co-authors.
You can also follow me on Twitter, where I make silly memes and talk about being a developer.