loading...
Cover image for Husky and Commitlint for Clean Git Log

Husky and Commitlint for Clean Git Log

talohana profile image Tal Ohana ・3 min read

You can 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 ⚠️

Posted on Feb 14 by:

talohana profile

Tal Ohana

@talohana

When you have to push, push. Don't stash. Fullstack Software Developer / Israel

Discussion

markdown guide
 

I think your link to 'Husky' is wrong. I guess you're speaking about this: github.com/typicode/husky :)