Git Hooks are scripts that run automatically every time you run a specific command (e.g.
git push) in a Git repository. They allow you to customize parts of your development flow for the better (IMHO). You can lint staged files, run tests before you push the code, or lint the commit-message (which is useful when using automated version management tools like semantic-release).
Right upfront, I'm a fan of git hooks. But, they are not without controversy. At least in the teams, I was in. Not everyone recognized the benefits of Git Hooks. I think that Git Hooks - especially together with ESLint, Prettier, and others - enforce a code standard, -quality, warn about common errors, bad practices, mistakes and point out errors earlier.
Sure, these checks can also be performed with the help of Travis CI and others. This is true, but it takes a while for these checks to run, and in that time you have to wait for the results - before you can act. So I prefer to run them locally myself and see what I'm about to push to origin. This is especially the case if you are using Travis' smaller plans. You'd need to wait until the other tasks on Travis are completed before your commit is validated. This can take time, especially in bigger teams.
I often heard that engineers do not want to wait until the hooks are completed but want to push immediately. I can only counter that, if it is really necessary there is still the possibility to bypass the Git hooks with
--no-verify. But to reject them from the beginning I think is the wrong way IMHO.
How to set up husky
Let's look at one known player in the node-world for git hooks: husky.
It is easy to install and prepare Git hooks with this command (docs).
# install husky and create a sample pre-commit hook npm install husky --save-dev && npm exec husky init
The default git hook will run
npm test when you commit. You can see the git hook in the
husky created during the setup. We want to have a hook that automatically lints our code when we push commits. So let's add a git hook manually.
Note: I assume that you have installed and set up ESLint already.
With the following command, we add a
# runs ESLint on git push (TODO: check) npx husky add .husky/pre-push 'npm run eslint . "$1"'
If you commit and push a change now, you'll see that husky executes
npm run eslint . first. When the command exits successfully it will allow the push, if not the push will be aborted.
Take a closer look a the
.husky/pre-push file. It is easy to see how you can extend the generated hooks. Simply edit it and add new commands. This is how it looks in one of my projects now:
"$(dirname "$0")/_/husky.sh" yarn lint yarn test.
This will first lint my code and then run the tests. Because this is a simple bash file you can do whatever you want to do with bash commands.
It is up to you what you want to do with git-hooks. You can lint commit messages, run tests, and more. Talk with your team and think about different use-cases. I am sure you can come up with some.
Once you add and use git hooks you probably want to take care of other use-cases as well. For instance, how can you bypass the hooks and how to disable them in CI. The husky docs are great, they did a decent job in explaining how to use husky in different use-cases. Take a look at them if you are lost.
All in all, I am a fan of git hooks, as I said at the beginning of this article. Git Hooks may slow down pushing or committing, but in the long run, you benefit from those few seconds you have to wait for the feedback of the hook.
Do you like this article? Do you want to support me? Tell your friends on Twitter about it. Thank you!
Questions and Feedback
You got any questions or want to add your thoughts? Let me know in the comments below, please.