Husky and Commitlint for Clean Git Log
Tags: javascript, git, node, npm
Published: 2020-05-29 10:55:03


---
canonical_url: https://talohana.com/blog/clean-git-log
---
You can find the source code of the article in [this github repo](https://github.com/talohana/husky-commitlint-blogpost)

# Introduction 🚀

In our programming life most of us came across git logs which looked like this
```git
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](https://github.com/typicode/husky) and [commitlint](https://github.com/conventional-changelog/commitlint) to avoid this problem, and the sooner the better!

---

# Husky 🐺
Git provides us with something called [Git Hooks](https://git-scm.com/book/en/v2/Customizing-Git-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
```json
{
  .
  .
  "husky": {
    "hooks": {   
      "pre-commit": "echo git hooks are awesome!"
    }
  }
}
```
And then when commiting you should see our hook running
```git
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](https://en.wikipedia.org/wiki/Lint_(software)) 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](https://github.com/conventional-changelog/commitlint#shared-configuration), for this blogpost i'm going to use [angular's convention](https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#-commit-message-guidelines) 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`
```javascript
// 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

```bash
> 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
```json
{
  .
  .
  "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
```bash
> 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 ⚠️