How (and Why) To Write an Awesome Commit Message (or PR)

Sam Vilain
Parsable Blog
Published in
6 min readMar 2, 2016

Writing a good commit message is a great way to capture the logic that’s going into your work as you work. Sometimes this might seem like unnecessary work, because the person who is reviewing your code already knows the reasons why you’re doing what you’re doing. Perhaps you’re the only one working on the code base. So you just write something very short instead of a good commit message. Who cares? Think about all of these people:

  • Someone on your team you didn’t expect to review your work has some free cycles, but looks at it, doesn’t understand what is going on or why and doesn’t review your work. You just missed the chance to get additional hands on deck!
  • Someone on another team is trying to read and understand what you’re doing to gain a new skill. You could have passively coached them and grown your team!
  • Someone later, perhaps a new hire, is looking back at the code to try and understand why something is the way it is. They have to figure it out without the benefit of all of the real-life meetings you had about it. Without having read all the requirements documents and tech specs. They might make some wrong assumptions, and break something important you worked on because they didn’t understand the code, changing the tests you wrote, too. Perhaps they’re not as clever as you and can’t see what you see as obvious. You might not still be working here by then, but perhaps you’ve exercised your shares — therefore you still have an interest that the time and energy you’ve put in to solving the problem becomes part of the institutional knowledge of the company, and doesn’t leave with you. Don’t let those late stage hires ruin your chances of reaping the rewards of your hard work!
  • You in the long-term future are debugging your code and you hit a code branch you wrote and forgot why it was there. You missed the chance to remind yourself instantly with a quick git blame of all of the things that were going through your head when you wrote that code. You would be surprised at how quickly you can forget.
  • You in the near-term future are working on something not so straightforward, and so you are simply trying to formulate a working theory of what you are trying to do. So, you can write down your own reasoning and then later, through techniques like rebasing or patch stack systems like stacked git, either disprove your earlier theory or support it. This way, you can make your own changes smaller and easier for your team to review. (clearly, for this point to apply, you need to apply this to every change, and not just do it on the PR, as well as be very good with a tool like stacked git).
  • The upstream maintainer of the code you just patches might have no idea of the unique problems you’re experiencing. They didn’t have those problems, and so they might reject your change, forcing your fork into exile from the main branch, a maintenance burden that might impact the stock payout, too!

The key thing to note is that it isn’t just for others — it’s for yourself. Think of how much faster you can move, with the cognitive burden of remembering everything removed! Don’t think of the short moments you have following the below steps as an impediment. Use them as an opportunity to truly master the Zen of programming. Taking a brief moment to focus on your breathing and clear your mind of any irrelevant distractions of the ego are recommended, but not required.

The Questions Every Commit Message (or PR Cover) Should Answer—or — a Checklist For Every Commit Message

  1. What problem or scenario is this change solving? — stand back. Describe the problem the the change addresses, or the sequence of events that lead to the problem. It might seem obvious now, but trust me — this is the most frequent source of “wha…?” moments when maintaining code. State the obvious — don’t let you or others lose sight of the why. At the very minimum, including a reference to your JIRA or whatever can help people resume context, but just putting a ticket ID in is bare compliance, and not Zen mastery.
  2. What was wrong with the old code? — it can often help to explain how the code prior to your change didn’t work. Where did it go wrong? Did you already figure out a failed assumption of another commit? Mention the commit ID and what the other commit got wrong!
  3. What is your approach to solve the problem, tactically? I don’t mean to describe what your change does. I can read that from the actual diff. That’s not interesting. If you have a higher level description of your change, such as the name of an algorithm, or an entertaining analogy, write it in! Another super useful thing to know is that if there is another approach to solve the problem which you considered, but decided not to do or figured out couldn’t work, say why that approach was inappropriate.
  4. A subject: can you summarize it in plain English in 10 words or less? a lot of git tooling is geared towards the practices of the core git and linux community, and they have a limit of 55 or 60 characters or something like that. Try to look back at your commit message, and then explain it to somebody non-technical in a few words. Your experience with git, and especially things like rebasing and cherry picking, will be improved by this practice. Use the imperative mood (“Make X do Y”) and not progressive (“Making X do Y”) or past tense (“Made X do Y”). (Update: an easier way to express this is to make the statement complete the sentence, “Once merged, this commit will…”) I would recommend not including things like function names, classes, and to limit use of acronyms and jargon in the subject. Try to spell out any abbreviations in full in the commit message body if you put them in the subject. The biggest exception to this is one word before a colon; if the codebase is modular, and your change affects just one module or component, then feel free to include that at the start of the subject line with a colon.

If, after doing this, the change message seems boring, obvious or droll, don’t worry about it and just commit it. Sometimes the changes themselves are like that. With the detail written down, you are now free to forget its inanity. Banish it from your mind and think about more exciting things!

Skipping Questions

As you get better at running through this list, you will find that in particular steps 2 and 3 don’t apply to many changes: for example, when adding new functionality, you can typically imply that the problem with the old code was that it didn’t exist by using a verb like “Add” or “Implement” in the subject. Not all changes are significant enough to need a tactical summary. Sometimes the problem can even be described in the subject. But be careful here: err on the side of quickly writing information you think is not required, because it doesn’t take long, whereas the head scratching which can occur without that “obvious” information can take hours or even longer.

Use the Right Tool

Use a tool like GitX or git gui to make commits — both of these will help you keep your commit messages well formed, and help you pick out related changes into a patch series from that working tree you got working by making dozens of iterative changes. Explain each part of it. You’ll be surprised at the bugs you shake out before they make it out to the wild! Make sure you know how to use the ‘-p’ flag to git add, the dynamic duo of the ‘ — fixup’ flag to ‘git commit’ and the ‘— autosquash’ flag to ‘git rebase -i’ — and don’t be afraid to force push to your PR branch.

--

--

Sam Vilain
Parsable Blog

British Kiwi expat. Open Source Software Engineer