Do you keep a tidy Git commit history?

Ali Haydar
4 min readSep 23, 2021

Commits form one of the core concepts in git. They are snapshots of your branch at a certain point, recording your code changes. When you create a new commit, you usually add a message that describes your code changes. The commit messages are the logs of your changes.

In multiple instances, I have encountered unclear commit messages. This was frustrating, not just because of my slight obsession with quality and tidiness but also because I needed to urgently understand what was going on in this change to fix a production bug. Has this change caused the bug? Should I revert the change?

I just needed to review the project changes on other occasions, and I would appreciate clear, concise commit messages. Some of the messages I didn’t enjoy much included:

  • Update
  • Problem
  • fixing Issue
  • Adding code
  • bug fixes

Going through this type of commit message doesn’t help with anything. It might be better to allow empty commit messages instead (don’t do that).

As you can see, writing clean and tidy commit messages has lots of benefits, from enabling troubleshooting issues, reading the history, and potentially generating changelogs (I worked in teams that use the commit history to create release notes).

How can we maintain a tidy git commit history?

In this post, we will explore conventional commits and commitizen, which would help create better commit messages that communicate the intention of the code changes to anyone reading them.

I’d like to note that even with these kinds of tools and conventions, it is still possible to write unclear messages (e.g. feat: add some code to the repo). However, these tools help in the formatting and constitute a gentle reminder that commits messages are important.

Setup conventional commits

According to the documentation, the conventional commit specification is a lightweight convention on top of the commit message that provides an easy set of rules for creating an explicit commit history, making it easier to write automated tools on top of it.

The convention suggests writing the commit message in the following format:

<type>[optional scope]: <description>[optional body][optional footer(s)]

The type could be anything of your choice, depending on your project. For example, the type could be fix, feat, docs, test, ci.

In addition to the messages that show the intention of the commit, conventional commits relate directly to releases and [sematic versionning](https://semver.org/). The “fix” type commits should be translated to PATCH releases, “feat” type commits should be translated to MINOR releases, commits with BREAKING CHANGE in the commits, regardless of type, should be translated to MAJOR releases.

Let’s try these out on an actual project.

  • Create a GitHub repository and clone it to your local
  • Create a single js file that we will use to make changes. Create a main.js file and enter: console.log(‘first line’)

We will install [Commitizen](https://github.com/commitizen/cz-cli), a node.js tool, to create commit messages following the conventional commits specs.

  • Run npm i commitizen -g
  • Initialize your project to use cz-conventional-changelog adapter: commitizen init cz-conventional-changelog ——save-dev ——save-exact. Notice a config section got added to your package.json file.
  • Now, let’s stage our changes and create our first commit: git add, then git cz (notice we are not using git commit here, git cz will handle the commit under the hood). We will get prompted as follows:

* The second question asks about the scope of the change (depending on your project, the scope could be a file or module). Skip by pressing enter

* The third step would ask to enter a short description. For example: create a blog post about conventional commits

* The next question asked to enter a longer description optionally. Press enter to skip

* Afterwards, there is a question if that’s a breaking change. Enter N

* If you use a system like Jira and have an issue ID you’d want, the following questions supports this

After you press enter, the new commit will be created. Type git log to check how this commit message looks like:

feat: create a blog post about conventional commits

Add another change to your main.js file, then try to commit it in the traditional manner: git commit -m ‘some updates. Notice the error: error: pathspec ‘some updates' did not match any file(s) known to git.

Without using commitizen, try to enter a commit according to the convention: git commit -m ‘feat: add a new line to test conventional commits. The commit works well in this case, but as you’ve already noticed, commitizen makes it easier for us to enter the right message with the necessary details.

In our example, we used the cz-conventional-changelog library default rules. However, these can be updated according to your team’s needs.

Would this process enforce writing clean commit messages? Of course not, but it’s a first step towards writing a tidy commit history.

I hope this was helpful. Let me know your thoughts.

--

--

Ali Haydar

Software engineer (JS | REACT | Node | AWS | Test Automation)