Protect your git branches with Husky

tl:dr

To add a pre-commit git hook with Husky:

  • Install Husky with npm install husky --save-dev
  • Set the pre-commit command in your package.json:
"scripts": {
    "precommit": "npm test"
},

What are git hooks?

Git hooks are scripts launched when carrying out some git actions. The most common one is the pre-commit hook that runs when performing git commit, before the commit is actually created.

The scripts are located in the .git/hooks folder. Check out the .sample file examples in your local git repository.
Git Hooks

Why do I need to install the Husky package then?

The problem with git hooks is that they are in the .git directory, which means that they are not committed hence not shared between developers.

Husky takes care of this: when a developer runs npm install, it will automatically create the scripts in .git/hooks:
Husky Git Hooks

Theses scripts will parse your package.json and run the associated command. For example, the pre-commit script will run the npm run precommit command

"scripts": {
    "precommit": "npm test"
},

To add husky to your project, simply run npm install husky --save-dev.

For more complex commands, I recommend to use a separate bash script : "precommit": "bash ./scripts/check-lint.sh".

Enhancing your git flow

Git hooks are a convenient way to automate tasks during your git flow and protect you from pushing unwanted code by mistake.

  • Check for linting errors

If you have tools to check the code quality or formatting, you can run it on a pre-commit hook:

"scripts": {
    "precommit": "prettier-check \"**/*.js\" && eslint . --quiet"
},

I advise to run those tests on your CI tool as well, but checking it on a precommit hook can make you save a lot of time as you won’t have to wait for your CI to set up your whole project and fail only because you forgot a semicolon.

  • Protect important branches

In some rare situations, you have to push code directly on a branch that is deployed. One way to protect it from developers in a hurry who forget to run the tests locally is to launch them on a pre-push hook:

"scripts": {
    "prepush": "./scripts/pre-push-check.sh"
},
#!/bin/bash
set -e

branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
if [ "$branch" == "master" ]
then
    npm test
fi

If your tests fail, the code won’t be pushed.


You liked this article? You'd probably be a good match for our ever-growing tech team at Theodo.

Join Us