Clean Git Log with Husky and Commitlint
Find the source code of the article in this github repo
Introduction
In our programming life most of us came across git logs which looked like this
4a3e5ba fix
c8a54df style change
0677dc5 fix
84ebabf fix
dbf7300 fix bug
6942670 pr changes
32d06bc pr changes
It's impossible to understand from these commits what is going on in our repository and makes it harder to navigate between commits.
There is a simple solution you can apply in 5 minutes using husky and commitlint to avoid this problem, and the sooner the better!
Husky
Git provides us with something called Git Hooks, simply lets us hook into specific git workflow (commiting, pushing, etc) and run commands.
Although you can write your git hooks from scratch, there is an easier solution using husky.
Heading to your project, add husky by running npm i -D husky
.
Now we can test husky by adding some hook to our package.json
file
{
"husky": {
"hooks": {
"pre-commit": "echo git hooks are awesome!"
}
}
}
And then when commiting you should see our hook running
husky > pre-commit (node v10.17.0)
git hooks are awesome!
[master ec5599a] first commit with husky
1 file changed, 3 insertions(+)
Commitlint
Commitlint, as it's name suggests, helps us to lint our git commits.
First, add commitlint cli to our project by running npm i -D @commitlint/cli
Now you can choose from various conventions listed here, for this blogpost i'm going to use angular's convention which follows the commit template of
type(scope?): subject #scope is optional
Adding it by running npm i -D @commitlint/config-conventional
Lastly, we need to create commitlint config file named commitlint.config.js
// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
};
Now we can test commitlint, for example if we run commitlint with text that does not follow the conventional commit pattern we will get an error
> echo fix | npx commitlint
⧗ input: fix
✖ subject may not be empty [subject-empty]
✖ type may not be empty [type-empty]
✖ found 2 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
Putting it all together
What we actually want is that for against every git commit
we run, commitlint will lint our commit message, and abort if any errors comes along.
For this we only need to add the following husky hook
{
.
.
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
}
Now if we try to commit with non-conventional message we should get commitlint's errors and the commit will be aborted
> echo hello >> temp_file
> git commit -am "fix"
husky > commit-msg (node v10.17.0)
⧗ input: fix
✖ subject may not be empty [subject-empty]
✖ type may not be empty [type-empty]
✖ found 2 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
husky > commit-msg hook failed (add --no-verify to bypass)
As mentioned in the last line of the output, you can suppress errors by appending --no-verify
to our git commands, use with caution.