DEV Community

Cover image for How to Write Useful Commit Messages (My Commit Message Template)
Jacob Herrington (he/him)
Jacob Herrington (he/him)

Posted on • Updated on

Git Commit Message Template How to Write Useful Commit Messages (My Commit Message Template)

We've all lived the XKCD about git commit messages at some point.

XKCD - As a project drags on, my git commit messages get less and less informative

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
Enter fullscreen mode Exit fullscreen mode

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.

Why should you care?

😤 I don't care, skip to the template! 🚀

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.

First, the subject line

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

Next, the first body "paragraph"

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 recently changed my mind on how I format commit messages:

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Now the second body "paragraph"

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.
Enter fullscreen mode Exit fullscreen mode

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!
Enter fullscreen mode Exit fullscreen mode

The other sections: Additional notes and co-authors

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.

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.

These changes should resolve issue #1337.

This commit removed the left-pad dependency, so please stop using it!

Co-authored-by: nspinazz89 <nick@example.com>
Enter fullscreen mode Exit fullscreen mode

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:

  1. What was done at a glance
  2. Why the change was necessary
  3. The details about what was done
  4. 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.

The final 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!

Include any additional notes, relevant links, or co-authors.
Enter fullscreen mode Exit fullscreen mode

There's more...

I'm writing a lot of articles these days, I run a podcast, and I've started sending out a newsletter digest about all of the awesome stories I'm hearing.

You can also follow me on Twitter, where I make silly memes and talk about being a developer.

Top comments (46)

Collapse
 
ryansmith profile image
Ryan Smith • Edited

Nice guide, great points here.

I think commit-messages should be a lot like commenting code. Instead of re-stating the obvious in the commit message, having some meaning definitely gives more value. My general rule of thumb is to write a complete statement, not a question, sentence fragment, or a word. It should have a subject and a predicate in it. That is not to test people's English skills, but to ensure that it provides meaning.

I noticed some repositories have a policy on prefixing with "feat", "fix", "docs", etc. but I'm wondering if anyone finds those useful? To me, those seem like unnecessary clutter and are a crutch for not writing useful commit messages. Is "(feat) Add users" better than "Implement functionality to add users"? I suppose the argument could be they are easier to scan in a listing, but if it is an invitation to be brief then wouldn't that mean having to look deeper into it to really figure out what it is?

Collapse
 
mohamedelidrissi_98 profile image
Mohamed ELIDRISSI

"I noticed some repositories have a policy on prefixing with "feat", "fix", "docs", etc. but I'm wondering if anyone finds those useful?"

There's an npm package named commitizen that does just the same, it enforces to select the type of modifications that were made and it appends it to the beginning of the commit's subject, I personally find it useful but not strictly necessary

Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

As a maintainer, I see the benefit of having some of those prefixes, but I think you can lean on GitHub or GitLab labels for that kind of support.

Good thoughts!

Collapse
 
svsven profile image
Sven van Steenis

There are cases where prefixes like that can be useful - writing "fix" followed by an issue number can automatically resolve said issue on Github, and there are similar integrations with for example JIRA. Granted, it doesn't have to be a prefix, or even be in the subject line for that matter - but still.

Outside of automated stuff like that I suppose it comes down to personal preferences. In my case I have found prefixes like that to be useful sometimes when skimming through a log on projects with multiple people.

Collapse
 
ryansmith profile image
Ryan Smith

I like having a Jira (or whatever platform) issue number in it. Even if there is no automation set up to read that, usually the Jira issue title/description/comments give more history of it that might not be captured in the commit message.

Collapse
 
codemouse92 profile image
Jason C. McDonald

One team I heard of uses a standardized set of emojis in this same way.

Collapse
 
emptyother profile image
emptyother

How would that work? Replace ✔ for "fixed", 🆕 for "feat", 📄 for "docs" in the commit messages or something?

Thread Thread
 
codemouse92 profile image
Jason C. McDonald • Edited
Collapse
 
sonicoder profile image
Gábor Soós

Those pefixes can be used for automatic versioning of a library with a tool like semantic-release

Collapse
 
andrewbrown profile image
Andrew Brown 🇨🇦

Tagging your commits with the associated ticket I think is the most essential part of a git commit.
I do understand that the author is focusing on just the content. So it's just me saying in addition to.

Depending on your size of the commit you may want to consider how verbose a git commit message should be.

I suppose if you squashing multiple commits to merge into a branch you could then be more verbose. I guess this going to depend on your workflow.

No opposition here, just some thoughts.

Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

Absolutely. I'd say 50% of my commit messages are subject line only, you don't always need a commit message with this much context.

I also think tagging a related issue is critical, but of course, that is assuming your issues are kept up to date! 😉

I don't tend to squash commits when I have a choice. I tend to err on the side of too many commits. Atomic commits have always served me well and I would be afraid to lose some of the benefits by squashing too frequently. 🤷‍♀️

Collapse
 
andrewbrown profile image
Andrew Brown 🇨🇦

I used to work for a startup where one of the co-founders insisted you always have a hyphen between the commit message and the id eg.

#243 - This is my commit message

Pull requests would be halted for this superficial format. A simple hook could have enforced that formating to satisfy the co-founder but they also refused to accept an automated solution.

Insanity!

Thread Thread
 
jacobherrington profile image
Jacob Herrington (he/him)

There is enforcing reasonable processes and rituals, and then there is being picky. ;)

Collapse
 
dinkydani21 profile image
Danielle

Great article! What are your thoughts on the Conventional Commits method?

My commits all have a type and a scope plus some info if necessary:

feat(landing): added pricing page

New page for pricing in addition to the section on the homepage
... etc
... etc
Collapse
 
defman profile image
Sergey Kislyakov

Should be "add" though, iirc. So I can read your commit like "this commit will add pricing page".
But nevertheless, I'm using this method too and it's great. It looks nice and understandable in the commit log and I can even generate the changelog file without worrying about manual editing of changes.

Collapse
 
benstigsen profile image
Benjamin Stigsen

I usually don't specify the WHY, unless something was rewritten. I usually do:

Additions, changes/fixes and removals

Additions:
 - Added class <Bar>
     - Added new function <foo()> for handling input
 - ... 

Fixes:
- ...

Changes:
- Updated README.md
    - Added todo list
- ... 

Removed:
- ... 
Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

I can see how this would be useful, but I think Ben's point about why people look at commit messages is super important.

I don't use git blame to find out what was done nearly as often as why.

Collapse
 
raulingg profile image
Raul Robinson Quispe Mendez

I like this kinda commits. I'd add a scope and type like the Angular commit message

Something like

fix(User container): blabla...

Furthermore with this kinda commits you can generate a sweet changelog effortlessly.

Collapse
 
nbull92 profile image
NBull92

I really like the template idea. I find quiet often that commit messages are not useful, or they were set the time. But as time went in, they became hard to understand or contain zero context. For which I am also very guilty of writing

Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

I'm not always the best at following my own advice here, but having a template goes a long way towards remembering to follow a convention.

Collapse
 
pavelloz profile image
Paweł Kowalski

I love how people in 2019 still repeat the 72 characters limit mantra like they were developing kernel under Linus supervision using terminal from 1984.

Collapse
 
emptyother profile image
emptyother

He said 50 this time.. Our terminals are shrinking. 😱

72 is good for the subject line as a guideline. It shouldn't be enforced in any way. I prefer git clients that just give me a warning when I cross it.

How about the commit body? I've seen some people do manual word wrapping/line breaks there, and some git clients warn when I don't. Any reason to do manual word wrapping?

And markdown syntax in the commit message body, yay or nay?

Collapse
 
pavelloz profile image
Paweł Kowalski • Edited

Do whatever works and doesnt get in the way in your team.

Thats my recommendation. ;)

Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

I prefer 50 for the subject line specifically because that's when GitHub starts to truncate.

I have my line wrapping done automatically, though.

Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

Obviously, it's preference, I like it though.

Collapse
 
vbarzana profile image
Victor A. Barzana

Nice article, in my company we use the id of the jira task, for example:
"TEST-123: This is my beautiful explanatory commit".
This later shows up in Jira and we know that there is already a commit, PR for a certain task by using the Git plugin for Jira.

Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

The last company I worked at did this with Clubhouse (sort of like Jira lite).

Collapse
 
patallen profile image
Patrick Allen

Inspiration taken from chris.beams.io/posts/git-commit/ ?

Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

This is in my alias file: alias beams="echo "https://chris.beams.io/posts/git-commit/" | pbcopy"

I followed that to the letter until reading Ben's Twitter thread.

Collapse
 
alialp profile image
Ali Alp • Edited

Carrying a good message , but the template is not practical .
If even we force coders to write such a long commit messages the commit count will drop because they fear to commit, you need to get more familiar with the human nature. No matter what is the standards we do the easiest one

Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

Interesting opinion. It doesn't affect me in that way. I also don't write every commit message like this: at least half are subject line only.

Collapse
 
andrewsmith289 profile image
Andrew Smith • Edited

I dunno. I think the diffs speak for themselves. If I want to know what changed, I look at the diff. Isn't that what everybody does?

ETA: I don't really have time to write pretty commit messages knee deep in feature requests.

Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

That's sort of the point of the article. A commit message should be about why not what. What is only useful as an afterthought to support the why.

Collapse
 
ben profile image
Ben Halpern

What a great series. I feel like if you land on this post you immediately have a great library of resources to read back on if you want to start with the basic tricks and move to this.

Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

That's the goal! Series are a great feature for the way I tend to write articles.

Collapse
 
hasii2011 profile image
Humberto A Sanchez II

The link to just skip to the template is broken:
//#the-final-template

Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

Hmm! That might be a bug with DEV, I'll look into it :) Thanks for letting me know!

Collapse
 
hasii2011 profile image
Humberto A Sanchez II

Super

Collapse
 
granttransition profile image
Grant Smith

This is a great read, thanks. You may have finally persuaded me to stop writing my lunch order into commit messages 😇

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

"Aaaaaaa 🥰" perfection.