I write better Git commit messages than you do
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.
If done correctly, your commit would reference the 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"
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
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.