DEV Community

loading...
Cover image for A guide on commit messages

A guide on commit messages

yvonnickfrin profile image 🦁 Yvonnick FRIN Originally published at yvonnickfrin.dev ・8 min read

The comic is from Daniel Stori. It is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License


The time you had an archive file on your disk called "version 1" should be far away. I bet you use some tool for version control like GitHub, Gitlab, Bitbucket, ... So you must write commits everytime you want to add your code to a project. Have you ever wondered if your commits messages are good? Maybe you don't like writing them and wonder why you have to do it every time you want to push code. After all, isn't the change sufficient enough?

In this article, we will talk about writing good commit messages, and not good commits, even if these two subjects are closely linked (here is a good article from Tobias GΓΌnther that summarize well best practices about version control).

Why commit messages are important?

So, is the change sufficient? Obviously, the answer is no. But why?

Commit messages have a lot of uses. This is the first way to communicate with your fellow developers on a project. The change defines how you achieve something but the commit message explains why you are doing it. It must give enough context to avoid a developper to wonder why some code is written like that. With proper explanations you won't spend precious time asking yourself why a developer pushed this code. In some cases like open source projects, busy maintainers won't even read your code if you don't give them a minimum of information like a nicely written commit message.

Commit messages are not only for your coworkers but also for your future self as Peter Hutterer said in this great article On commit messages.

Any software project is a collaborative project. It has at least two developers, the original developer and the original developer a few weeks or months later when the train of thought has long left the station.

Peter Hutterer - On commit messages

A project is designed to be maintained in the long term. Sometimes years after a piece of code was written, you may ask yourself why it has been written like that. It happened to me this week with a function I coded only 6 months ago. With a well written commit message, it is easier to get back in the state of mind at the time you wrote this change.

Taking care of your commit messages can also simplify your daily life. Some tools becomes more interesting with a meaningful commit history like a few git commands log, rebase, cherry-pick, ... When you come back from holidays a simple git log --pretty will give you a lot of information about what your coworkers did while you were away. Writing good commit messages forces you to split your change, making it easier to review with git log -p.

Speaking of review, did you ever struggle rebasing your code on some change a developer made? It becomes easier to know why a change was made if the commit message carries real meaning. It makes rebase result much more predictible. Another example is git blame command which, by the way, isn't there to make fun of your colleagues, but to give you context on a specific line of code. It can be pretty useful when you want to refactor a piece of code.

Last but not least, a well structured commit history allows changelog generation between two versions of your project to inform your users what changed.

This is a huge amount of reasons to start taking time to write good commit messages.

How to write a good commit message

Now that you are convinced commit messages are important, let's talk about how to write good ones. I picked commit messages from a project I work on called immutadot. As you can see, these commit messages are not consistent, which makes them hard to read.

fix #72 unnecessary object copies
Fixing unshift documentation examples
seq.chain path parameter fix #18
Remove built files
Add tests
Add Circle CI base config
Rename es -> src
Add lang package with toggle, fix exports
Core package
Enter fullscreen mode Exit fullscreen mode

In these commit messages, we can see a few mistakes in term of style, content and metadata. Chris Beams accurately describes these three points in his article How to Write a Git Commit Message.

Style. Markup syntax, wrap margins, grammar, capitalization, punctuation. Spell these things out, remove the guesswork, and make it all as simple as possible. The end result will be a remarkably consistent log that’s not only a pleasure to read but that actually does get read on a regular basis.

Content. What kind of information should the body of the commit message (if any) contain? What should it not contain?

Metadata. How should issue tracking IDs, pull request numbers, etc. be referenced?

Chris Beams - How to Write a Git Commit Message

We can see there are capitalized messages, metadata for only two commits... Eventually, some messages content are so light we can't figure out what the commit does. In the same article, Chris goes through 7 rules to write a good commit message :

  1. Separate subject from body with a blank line
  2. Limit the subject line to 50 characters
  3. Capitalize the subject line
  4. Do not end the subject line with a period
  5. Use the imperative mood in the subject line
  6. Wrap the body at 72 characters
  7. Use the body to explain what and why vs. how

Chris Beams - How to Write a Git Commit Message

I personnally apply a subset of these rules:

  • Limit the subject line to 50 characters
  • Capitalize the subject line
  • Use the imperative mood in the subject line

Not only does the character limit force you to be concise, which is a great skill, but it fits well with a lot of tools as explained in Tim Pope article A Note About Git Commit Messages.

I tend to think the perfect is the enemy of the good. That is why I omitted talking about commit messages body. I think we have enough work to do on the summary line. But I would add one rule as counterpart:

  • Add a pull request/merge request tracking ID

Most of the time, we use tools to discuss during a code review process like GitHub, Gitlab, ... All pieces of information about the change will be at least described there. I added this rule about tracking ID so it becomes easy to find related pull/merge request. Writing a commit body is better than adding tracking IDs because if you change your repository manager solution, you will lose all this precious context information and your tracking IDs will be useless.

Here is a more recent example from a project I work on called gitmoji-changelog that follow these rules:

Make core independent from the git client (#171)
Upgrade Docker image version (#167)
Add maven preset (#172)
Add a generic preset using configuration file (#160)
Improve error messages for preset system (#161)
Publish Canary version on master push (#141)
Enter fullscreen mode Exit fullscreen mode

Having a consistent style makes it much more easier to read. You can figure out the context of the change, and metadata are directly accessible. The most important thing is to find common rules in your team to ensure having a well structured commit history. There are some conventions that can help you finding these but we will be back on this subject later.

If you have difficulties to find out what message you should write, maybe you should split your commit in smaller parts. Peter Hutterer listed in his article On commit messages a few examples where it is difficult to find out a good commit message because your commit patch may not be logical.

Bonus

If you use practices like pair or mob programming, don't forget to add your coworkers names in your commit messages:

$ git commit -m "Refactor usability tests.
>
>
Co-authored-by: name <name@example.com>
Co-authored-by: another-name <another-name@example.com>"
Enter fullscreen mode Exit fullscreen mode

Commit conventions

As written in the previous section, you should define a commit convention for your team. It exists open source commit conventions that could be a good source of inspiration. They also come with a whole ecosystem that includes tools to help you write commit messages, generate changelog, create releases, ... A lot of things that can take a large amount of time. There are well documented so you don't have to write documentation about your own commit message convention.

We will talk about two of them Conventional Commits and gitmoji.

Conventional Commits

It is a specification inspired from Angular commit message guidelines. It features a few interesting rules like:

  • Commit must be prefixed with a type (feat, fix)
  • A scope may be provided to point out a specific section of a the codebase (really interesting for monorepos)
  • Breaking changes must be included in a footer section

Here is how a commit message must be structured using this specification:

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
Enter fullscreen mode Exit fullscreen mode

Read more in their specification section.

gitmoji

I'm fond of gitmoji commit convention. It lies on categorizing commits using emojies. I'm a visual person so it fits well to me but I understand this convention is not made for everyone.

I was not totally honest in my previous commit examples from gitmoji-changelog. There is a missing part as you should have guessed now.

:recycle: Make core independent from the git client (#171)
:whale: Upgrade Docker image version (#167)
:sparkles: Add maven preset (#172)
:sparkles: Add a generic preset using configuration file (#160)
:recycle: Improve error messages for preset system (#161)
:construction_worker: Publish Canary version on master push (#141)
Enter fullscreen mode Exit fullscreen mode

These text aliases are widely used in tools like Slack, Discord, ... Most of the repository manager tools like GitHub or GitLab interprets them and display it well in their UI:

♻️ Make core independent from the git client (#171)
🐳 Upgrade Docker image version (#167)
✨ Add maven preset (#172)
✨ Add a generic preset using configuration file (#160)
♻️ Improve error messages for preset system (#161)
πŸ‘·β€β™‚οΈ Publish Canary version on master push (#141)
Enter fullscreen mode Exit fullscreen mode

I like this convention because I know at first glance what kind of change do a commit. It comes with a cli called gitmoji-cli that helps you write your commit messages and I made a changelog generator for it.

There are more of them. Keep in mind that these are guidelines, you can mix them to get something that fills your need. For example, using gitmoji convention with the scope notion of conventional commits if you work on a monorepo.


Feedback is appreciated πŸ™ Please tweet me if you have any questions @YvonnickFrin!

Discussion (39)

pic
Editor guide
Collapse
suckup_de profile image
Lars Moelleken

You can share your git commit conventions in the team via e.g.:

add this into your "~/.gitconfig"-file

[commit]
  template = ~/.gitmessage

example: github.com/voku/dotfiles/blob/mast...

Collapse
stephencweiss profile image
Stephen Charles Weiss

Just to confirm - this is a template, but does not act as a linter, correct? So, you could pair this with something like commitlint (github.com/conventional-changelog/...)

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

Waouh! Didn't know about it, thank you for sharing!

Collapse
iamschulz profile image
I am Schulz

If you work with Jira, It's also nice to prefix your commit with the ticket number, e.g.

XYZ-123: add the thing

That way you can easily navigate to the corresponding ticket and see why the change was made.

Collapse
stephencweiss profile image
Stephen Charles Weiss

I love linking like this, but it also proves problematic over time as teams move PM software and context is lost. For the most part, I'm trying to get in the habit of writing commits that include the sufficient context to explain why a change was made without relying on a ticket.

... definitely makes for longer commits though /shrug

Collapse
checkmatez profile image
Max

Maybe put ticket number in the footer of commit message? So it stays linked, but wouldn't clutter up git log since you can't tell at a glance what XYZ-123 means, when viewing git log output.

Collapse
yvonnickfrin profile image
Collapse
sneakycrow profile image
Zachary E. Sohovich

Checkout a package called commitzen. I've been using it professionally alongside Jira and it's made the commit messages very clean and meaningful.

In addition, utilizing a Changelog and proper versioning is super helpful.

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

Thank you for sharing about commitzen.

In addition, utilizing a Changelog and proper versioning is super helpful.

I could not agree more!

Collapse
vascoalramos profile image
Vasco Ramos

What a great article!

Usually, I do all my projects on my own, hence my commit habits and good practices are roughly none and this is felt when I work with other colleges in a team, like in a university project...

This article presents itself as an awesome way to start improving these collaboration skills!

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

Thank you!

Sure, side projects are a good way to practice. I try to pay attention on these details so it helps potential contributors πŸ‘Œ

It is easier to apply on professional work if it is already an habit πŸ‘

Collapse
tonivdv profile image
Toni Van de Voorde

Thanks for taking the time writing about this important topic. We also implemented a convention and at the time we were inspired by the following (old) blog post chris.beams.io/posts/git-commit/ . Combining this with some custom convention for the projects needs is very powerful!

Excerpt from the post:

A properly formed Git commit subject line should always be able to complete the following sentence:

If applied, this commit will your subject line here

For example:

  • If applied, this commit will refactor subsystem X for readability
  • If applied, this commit will update getting started documentation
  • If applied, this commit will remove deprecated methods
  • If applied, this commit will release version 1.0.0
  • If applied, this commit will merge pull request #123 from user/branch

Notice how this doesn’t work for the other non-imperative forms:

  • If applied, this commit will fixed bug with Y
  • If applied, this commit will changing behavior of X
  • If applied, this commit will more fixes for broken stuff
  • If applied, this commit will sweet new API methods

Remember: Use of the imperative is important only in the subject line. You can relax this restriction when you’re writing the body.

Collapse
epranka profile image
Edvinas Pranka

Great article, thanks! I always have problems with the commit messages. Especially in the new projects. So often it comes to:

rm -rf .git
git init
git commit -am "Initial commit"

:D

Thanks again :)

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

Glad it please you πŸ˜„

Collapse
jessekphillips profile image
Jesse Phillips

I really like the depth you decided to go. You had emphasized the value of the message and the explained how it added value to other tools.

I joined dev.to specifically to help get this point across.

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

Thank you for sharing. I definitely added your series in my reading list πŸ™Œ

Collapse
eyarz profile image
Eyar Zilberman

Great article!

The only part that I was missing and I would like to understand more on, is once you decide on your project commit message conventions, how do you verify everyone (including yourself) is following it?

BTW, funny story - I actually wrote a really similar post a few months ago:
datree.io/resources/git-commit-mes...

Collapse
vishnuharidas profile image
Vishnu Haridas

I have come across recommendations to write commit messages in present tense by some people and past tense by some other.

For example,

$git commit -m "Updated the search API to include search filters."
$git commit -m "Update the search API to include search filters."

Any preferences in the tense of the commit message?

Collapse
ginomempin profile image
Gino Mempin • Edited

In our project, we combine the conventions for branch naming and commit messages. Then we partially automate the commit message format with git hooks.

For example, our branches are commonly organized by ticket number and type. So, something like bug/#123/moduleA/crash-on-close. You can then setup a git commit hook that provides a template like this:

#123: bugfix: [Fixed ...]

[Details]

where #123 and bugfix are parsed from the branch name. You can also use git commit templates, but they are not as dynamic as git hooks.

Collapse
patarapolw profile image
Pacharapol Withayasakpunt • Edited

I wonder if it is safe, if it is ever done, to rename a commit message? -- help.github.com/en/github/committi...

One more wonder, is, how often should I commit?

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

It depends if someone or something depend on this commit identifier. Amending a commit and push force it will change the commit identifier.

In my opinion you should commit as often as possible. It will help you split your code πŸ‘Œ Keep in mind you must commit only working things. The first four points in the following article git-tower.com/blog/version-control... describe well what is a good commit πŸ‘

Collapse
jofisaes profile image
JoΓ£o Esperancinha

Really nice article! I really love the tips you gave and the convention examples you mentioned.

I think the gitmoji convention must bet a lot of fun to use, although I never used it professionally so far.

thanks for sharing! πŸ‘

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

Thank you, I use it on professional project. It really depends on your team and the common rules you commit to. In my opinion emojies are compatible with professional project since we already use it a lot in chatting tools at work πŸ˜„

Collapse
kironroy profile image
Kiron Roy

This a great article. I am also cleaning up my commit messages for this project SQL practice. I use Visual Studio's GitHub interface.

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

I think a well structured commit history helps potential contributors. Nice initiative!

Collapse
kironroy profile image
Kiron Roy

I only use GitHub to host my portfolio and maintain my C# page. Contributing to open source is my next step, so I need to write great commit comments

Collapse
ac000 profile image
Andrew Clayton

But will you remember why you made those changes in six months time?

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

If your stuff is open source I would recommend paying attention on your commit history if you want to attract some contributors πŸ˜„

Collapse
vuesomedev profile image
GΓ‘bor SoΓ³s

Conventional Gitmoji commits the missing part 🐳

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

You can't be more right!

Collapse
sudo_kaizen profile image
Orim Dominic Adah

Husky has something to offer here. It can help automate these things

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

Sure, automate this kind of checks is nice πŸ‘

Collapse
shanadinacaroti profile image
Shana Dina Caroti • Edited

Thanks for Sharing! IΛ‹m looking forward to use your guiding tips in my future projects! ☺️

Collapse
yvonnickfrin profile image
Collapse
tbetous profile image
Thomas Betous

Great article ! Well documented with great sources !

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

Thanks Thomas for your review πŸ™