Lately, I have been paying closer attention to the changelogs I get from products and services when updates are needed. Here are some examples:
- Fixed some bugs.
- Made some accessibility improvements.
- We've made improvements and fixed bugs for a smoother ride.
When I think about some of the first commit messages I made as a junior developer I have to hang my head in dismay:
- Pointed and clicked around a bit and now things seem to work.
- Did what programmer X told me to do and now the banner is blue.
This can be frustrating! I asked our community of contributors the following questions:
- What makes a good Git commit message?
- What makes a bad one?
- What rules do you think a project should have around what a commit message contains?
Here are their answers:
Great writing is key
As with anything you write, you should think about who is going to read it. Then adapt the amount and depth of information accordingly.
Improving your natural language and writing skills is essential for a healthy career in software development. It's not just code that counts.
Be descriptive and don't assume
I spend a lot of my time collaborating in the OpenStack community, and its code reviewers have some fairly exacting standards compared to what I see from other projects "in the wild."
I'll often spend far longer composing a solid commit message than I do writing the actual code implementation or fix. Sometimes commit messages can end up many times longer than the diffs they're explaining.
To summarize some of the contributor guidance:
- Describe why a change is being made, not just what is changing
- The first commit line is the most important (like the subject line of an email)
- Don't assume reviewers understand the original problem you're fixing
- Don't assume the reviewer has access to external web services or the site (summarize defect reports and other relevant discussions)
- Don't assume the code is self-evident and self-documenting (though there is no need to repeat points you also make in your code comments)
- Don't include information only relevant to earlier revisions of the change (we expect contributors to squash revisions together and edit their commit messages accordingly).
There's a brief section on the topic in the OpenStack Contributors Guide: https://docs.openstack.org/contributors/common/git.html#commit-messages
Your future self will thank you
I cannot agree more with Jeremy. +1000
Jeremy said, "describe why a change is being made, not just what's changing."
Imagine you're someone else, in a faraway future, trying to work out this commit.
Put yourself in other people's shoes, as the old saying goes.
Use the bug ID
I recommend adding the bug ID at the start of the commit message so that it's easier to track the commits at a later stage using the
$ git commit -m "BZ#19xxxxx
To come up with thoughtful commits, consider the following:
- Why have I made these changes?
- What effect have my changes made?
- Why was the change needed?
- What are the changes in reference to?
Tell the whole story
I like to imagine there is a hidden prefix to every commit message that reads "By applying this."
A good commit message includes exactly what will happen and why. It is insufficient to merely have the work ticket reference because that decentralizes the information; Git is decentralized. As a software developer, I want to know why the proposed changes are being considered. What specific problem is being addressed? What alternate solutions were considered (and discarded)? What unexpected things were discovered during the creation of the changeset that influenced the current content?
There's no prize for shortest commit message. Your future self and future colleagues will appreciate you going into depth to explain the problem and why this changeset is the answer. Harness those cooking blogs where there's a five-paragraph life story. Here, however, make the problem the subject of the life story.
But don't be overly verbose
A good git commit message contains information about what was done, and nothing else. For instance, if you needed to update the .gitignore, just say "updated .gitignore." Folks can dive into the commit itself for more details. It doesn't need to be verbose.
A bad commit message is something like, "oh crap" or "try this". Granted, I've been guilty of this, but it doesn't help anyone if they need to look at commits at a glance.
Rules are very subjective. They can differ from lead to lead and team to team. But at the very least, give some contextual information about the commit. Especially if it's a large one. No one has time to skim through 1000+ files with a heavy change history.
Use present tense
I like project manager-styled commit messages written in present and not future terms (for example, "add" instead of "added"). However, it's usually only possible if commits are frequent. There's only so much "how did I do it" you can remember when you're faced with a deadline. Yet, well-written commits not only help collaborators, but are also helpful to the committer in recollecting history.
Don't rely on links
One thing I like to remind colleagues of is that you're not just explaining to the people who are going to decide whether to approve your commit. You're also explaining to future developers and users who have found this commit in a bisect or blame operation and are trying to understand its relevance.
If the only context supplied is a link to some external system, and that far in the future the system it links to is no longer in use or has otherwise become inaccessible to that individual, your commit message has been rendered useless and may just as well be blank.
All too often, I go digging in the Git history of some open source project, and find commit messages which are nothing more than a bug ID or a link to some company's internal and private defect tracker.
Don't be that project!
Clear and concise changelogs
As a release communications manager, I often read the entire release board. I also met with developers to discuss any areas that weren't clear yet. Then I tested the release early. After that, I would write a release post by sourcing the changelogs and corresponding revised or new content.
The changelogs are personal reminders for developers, but also have corresponding issues and tickets for them. You should capitalize product names appropriately, use a spell checker, be consistent with punctuation, and sentence structure. The lead developer should proofread these as well. Your customers, that are developers, are reading these. What information should they know before running the update to better serve their customers?
As a frequent release manager, I like messages that name the component a commit touches, and a brief description of what was changed. Also having a reference back to where the request for this work came from helps to tie fixes together long after we forgot about your clever branch name.
- "fix fatal error" is not ideal.
- "ISS-304: Fix fatal error in Login Access Control function for users
with the Partner role" is better.
- "ISS-304: Login Access Control: fix fatal error in getPartnerId()" is
I can look at the entire relationship between a Git commit, branch, merge commit, and inspect the individual lines and files that were changed. But I don't have that kind of time in the middle of a release. I want to be able to relate back to the source of this work in the project management tool, have some idea of which components are being changed, and in what way.
Make it a habit
My favorite commit that I'm guilty of is, "commit before I switch branches" because I have to work on something else more urgent. Sometimes, I need to commit my current work to a totally different project. My manager's strategy is to have us work as we normally do. But then when we rebase, he wants us to squash commits where it makes sense and write better messages. I can't say we always do this, but his method does make sense.
I have a lot of "this is broken don't know why" type messages too (haha) where I try things but want to commit that attempt before I try something else in case method A was closer to fixing the issue than method B. Writing code is a hot mess. And I've been writing it for over 10 years.
What commit message advice or tips do you live by? Let us know in the comments.