Commit message, why does it matter?

Appaloosa Store
Appaloosa Store Engineering
6 min readMay 22, 2019

Let’s start with a little story

This is a story about Alice and Bob, in a common situation, at work. You might recognize yourself or someone you know, it’s just a coincidence, or not.

Let’s start with Alice: I have a problem on this model. It was not changed for years… Why now? What happens?

git blame

the commit message is exactly: fix model. This is the only summary of what changed +563 -120lines.

OK. That was a HUGE fix.

Oh, the breaking line was changed here, 3 years ago… it looked ok before this commit. But, why was it modified? These changes were reviewed, these changes had to be done for a specific reason, even if it sounds really strange. Now you can imagine this modification like something as strange as:

   - valid?
+ !valid?

The good news is that the author of the commit is here, it’s Bob! Let’s ask him, he has to know, he wrote that.

“Hi, I’ve a little question for you…”

“Yeah of course”, right now, Bob is smiling, and doesn’t know what is coming next.

“Ok, so I came into this commit, and I’ve an issue with this line you changed, do you know why?”

Of course, he didn’t know. It was 3 years ago. And this is normal, Alice also doesn’t remember what she ate 3 weeks ago, do you? what about 3 years ago?

Nothing can help Alice and Bob to know why this tiny line was changed along with almost 600 others.

Obviously, if the author of the commit was a former colleague who left the company, the result would be the same. Nobody could tell Alice why this change happened.

We have a powerful tool, use it correctly

I think we can simplify this by telling that a project is mainly: people, time and lines of code. New people come in, other leave, time flies and lines of code can change at each new commit. But we all have, or almost all, a powerful tool: our commit messages.

The commit history is the thing that needs to reflect our thoughts when we make changes somewhere, because it’s also the thing that is not changing with time, once you write something it stays with time. Of course, we all know that it can change, but please don’t abuse on rewriting the history!

Tell us WHY you’ve done your changes

All changes we made have reasons, we didn’t change things just for changing it. And this why, is, I think, the most important part. The how is already shown by the difference between the old and the new code, the why isn’t. Focusing on explaining it can help you, and your colleagues in the future to understand the changes. It allows everyone to be confident when something has to change.

Let’s take our fantastic fix modelexample. Don’t you feel more confident if it was more like (spoiler: this looks like a known convention, we will talk about it later in this article):

fix(model): change rule of validationchange the way of validating this model. We don’t want it to be valid anymore because we had a lot of end users that doesn’t understand itCloses #23

The issue #23 will have a lot more information that can help us to know if we really want to change it. Then you can be able to stop trying to guess why a change was made. We all know that, a change can be a bug, but maybe when it was made, it was a feature, who knows? :)

This can be a difficult exercise, to do that you have to take a step back on what you do and take time to write it. Take time, really. It’s not wasting time, it’s more like saving time on the future.

Of course, it’s a lot more difficult to do when you changed a lot of things in the same commit…

Little changes on commit, for write, easy review, easy revert

First of all, this will help you to write timeless understandable commits. It’s easier to summarize few changes than many, at least, I think.

Also, if every commit you make corresponds to an intention, it can be easier to review for your colleagues. It can also be a way to learn as you can see how your colleague get there.

Another reason to split commits is to facilitate reverts. If each of your commit is an intention, then you can revert each of them separately without wondering if your app will worked, and you exactly know what were the changes.

Conventions ensure homogeneity

Applying all of the above points is already a victory over changes understanding. Having a convention for this over all developers working on a same project has also some benefits.

As everyone is going to write commits with the same formatting, it’s easier for tools to generate things for us, like changelogs.

Let’s have a look on the AngularJS’s commit message convention

This convention is also known as conventional-changelog.

I decide to focus on this one for this article because I work with it for years now, and we decide to take this one and adapt it to our needs at Appaloosa.

With that convention we ensure that each commit is formatted the same way:

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

type is a word in a predefined list which tells what’s the purpose of the commit. For example, our overcommit configuration is checking that the type is matching one of those keys: feat, fix, docs, style, refactor, perf, test, build, revert. The main benefit from this, is that I didn’t need to tell you what each one is doing, because they’re understandable by themself. Then, looking to your history, you knows what’s the purpose of each commit, without having to go to the code.

scope is an optional part, it’s the way to know what piece of the app is affected by these changes. On the Angular commit rules the scope needs to also corresponds to a predefined word in a list, corresponding to a npm package. In our case, we don’t have such a list and each developer can put what he wants for the scope, for example `mobile_v1_xxx` targets the v1 of our mobile API.

subject is a sentence describing the changes. It has to be concise and understandable. There is a popular quote from Chris Beams that can be used to write it:

If applied, this commit will …

Then, your subject line should complete this sentance.

You can find more about it here https://chris.beams.io/posts/git-commit/ it’s another way of writing good commits!

body here is the why. The body can be as long as you want, the main goal is to produce a text that is explaining the motivations of doing this commit and the changes made from the previous behavior. This is, I think, what is often missing in commits, that’s the right place to explain the why. We don’t have to write a body for each commit, only when we think it’s necessary. I personally try to write a body each time I think that my commit can be ambiguous. I think one day someone, even myself, will be happy to get those answers!

footer is used for breaking changes and things related to process. You can have an integration with an external tool that is going to automatically change the status of a ticket according to the tag you put here.

You can find here the full specification of this convention: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit

Please take care of your git history, for you in the future, and for all the people that are going to work on it.

I’ve some open questions about git history:

  • Do you prefer git rebase or git merge while merging into your master branch?
  • What do you think about writing commits in the mother language of all developers instead of english by default, mainly to facilitate the comprehension?

Thank you for reading! 🙏

You should subscribe to our blog to be notified whenever a new article is available! 👋

This article was written by Mélanie Araujo Martins of Appaloosa’s dev team.

--

--