I write better Git commit messages than you do

Victor Hamzat
6 min readMar 4, 2023

--

a graph of git commit messages against time(XKCD)

When I learned to code, I always believed that commit messages were the center stage for me to discuss all I did in my code. I usually include even the minute details; it sometimes goes like this: “I added a hover effect and padding to the buttons and centered them on the screen.” Some other times I would be in a rush and give the shortest git commits, for example, “Fixed button.” This might look harmless until you check your code months later and wonder what you meant by the commit. So the question is: what makes a good commit message?

Writing a Git Commit message

Let’s start: how do you make a Git commit? You can write a Git commit message with the following code:

git commit -m "a descriptive message"

that’s not all You can also add a body or description.

git commit -m "a title" -m "a body"

Writing multi-line commit messages might be difficult with the second -m flag. It would be better to edit your commit messages in an editor; that is what git commit command is for. It opens a COMMIT_EDITMSG window in your editor (by default, it uses VIM; you check here to change to VS Code) where you can edit your commit messages.

Now, let’s get back to the initial question: what makes a good commit message?

Rules for writing good commit messages

Tone

You should use an imperative tone, just like you’re giving a command or instruction, so instead of “added login API routes” you’ll have “add login API routes”. To test if you’re using the right tone, you can try completing this sentence with your Git commit subject: “If applied, this commit will insert the subject here”.

Character Limit:

Your title or subject should be capped at 50 characters, so make it as concise as possible. You could have noticed this if you use vs code for your git commits.

With this constraint, every space is important, so make sure you don’t have unnecessary punctuation, especially periods at the end of your commit messages.

Give detailed explanations when necessary in the commit body

Some code changes need to be explained to properly guide the team members on why such decisions were made and how they were implemented. That being said, not all code changes need a body; a well-crafted title would be enough. For example, a typo fix in the doc doesn’t need a description; you could just use git diff to check the code difference and see what typo was fixed.

Note: When you write the body of a commit message, you must mind its right margin and wrap text manually. The recommendation is to do this at 72 characters so that Git has plenty of room to indent text while still keeping everything under 80 characters overall. source

Use the pound (#) sign to refer to Git issues and discussions

Your git commit is frequently intended to fix a certain issue or be related to a discussion on GitHub or GitLab. You could reference them in your commit message by using the pound sign(#) followed by the issue number.

The Issue number

If done correctly, your commit would reference the issue.

a git commit referencing a GitHub Issue

That feels like a lot of rules to keep in mind; one might forget them. What if we could have a set of guidelines and linting for our Git commit messages? Well, there it is. Welcome to the world of “conventional commitment.”

What is Conventional commit?

The Conventional Commits specification is a lightweight convention on top of commit messages. It provides an easy set of rules for creating an explicit commit history. Conventional commit helps you give valuable information about code changes at a glance through its standards for commit messages.

It gives your commit messages this structure:

<type>[optional scope]: <description>

[optional body]

[optional footer]

It uses type to communicate the intent of the code change. Here are some commit types.

  • feat: use when a new feature is introduced in the code.
  • fix: use when a bug is fixed.
  • chore: use when a code change does not relate to a fix or feature and doesn’t modify the core code or test files (e.g., dependencies bump).
  • Refactor: used when restructuring existing code.
  • CI: use for continuous integration-related code changes.
  • Revert: use when reverting to a previous commit.
  • test: use when adding new tests or updating previous tests.

Other commit types are build, docs, style, perf, etc. You can view the full specification here.

Integrate conventional commit in your development environment.

When working with teams, it is critical to have consistency across code, which is why large organizations have coding style guides. That also applies to commit messages; you can have a linter for your Git commits. 2 well-known tools do just that in the JS world: Commitlint and Commitizen. I’ll be discussing Commitlint in this blog.

Setting up Commitlint

First, we need to install the Commitlint CLI

npm install --save-dev @commitlint/cli @commitlint/config-conventional #npm
yarn add -D @commitlint/cli @commitlint/config-conventional #yarn
pnpm add -D @commitlint/cli @commitlint/config-conventional #pnpm

Then we install Husky to create git hooks for our commit messages.

npx husky-init && npm install       # npm
npx husky-init && yarn # Yarn 1
yarn dlx husky-init --yarn2 && yarn # Yarn 2+
pnpm dlx husky-init && pnpm install # pnpm

The command will set up Husky, modify the package.json file, and create a .husky folder where pre-commit and commit-msg files are present. By default, the pre-commit file will run npm test when you commit. You can comment it out or delete it to stop this behavior.

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# npm test <--- remove or comment the test

We can then add a commit-msg git hook to support Commitlint by running this command.

npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'

Let’s test if it works by running this command.

git add .
git commit -m "let's see if this works"
Failed to Commit

It shows an error with a detailed explanation and prevents the git commit. Let’s change the commit message and check that it works.

git commit -m "fix: remove typo in landing page header"

now it works

Successful commit

Conclusion

Git commits are stories that describe the origin of a repository and where it is headed. A good Git commit should follow a sequence, just like in stories. Of course, there could be plot twists, but it should still follow a pattern. Having a set of rules to guide your writing is certainly a step in the right direction. Thank you for reading. See you next time.

--

--