Git Hooks with Husky v9
posted in dev-setup on • by Wouter Van Schandevijl •typicode/husky : Git hooks made easy 🐶 woof!
Hooks
git hooks
Run a program before certain points in gits execution.
pre-commit
andpre-push
hooks are probably the most interesting.
They are defined in .git/hooks
.
You can find some example files in that directory. Remove their .sample
suffix
to test them out.
The githooks are saved locally and not pushed to the remote. This is obviously a problem
when working in a team but the .git/hooks
folder can be changed globally or for the current repository
with the core.hooksPath
setting.
This is obviously never going to happen but you could skip githooks with:
git commit --no-verify
git push --no-verify
# Or if you want to really quickly skip it ;)
git commit -n
Husky
Or, use Husky to easily make the git hooks part of the repository itself and share it with the entire team.
npm install husky --save-dev
npx husky init
This will add a prepare
npm script in your package.json
. The prepare script runs after
an npm install
to ensure things are setup for everyone.
"scripts": {
"prepare": "husky"
},
And it creates a .husky/pre-commit
which you can try out by doing a git commit
!
Avoid having to git reset HEAD~
all the time by ending your script with exit 1
while
testing/setting it up.
Finally it sets the core.hooksPath
to .husky/_
. Husky creates files in that
directory to link all githooks with the h
shell script which will execute a
.husky/SOME_GITHOOK
if it exists.
Husky also adds a gitignore to the _
folder to keep the generated files out
of your git repository.
git config core.hooksPath
# --> .husky/_
Script h
In this order:
- If
HUSKY=2
it executesset -x
to print commands with arguments - If the
.husky/XXX
file does not exist (with XXX for examplepre-commit
), the script exits - If
~/.config/husky/init.sh
(or$XDG_CONFIG_HOME/husky/init.sh
) exists, it executes it- This is the place to setup
PATH
, or set an environment variable likeNVM_DIR
- This is the place to setup
- If
HUSKY=0
the script exits - It adds
node_modules/.bin
to thePATH
- It executes
.husky/XXX
(stops on first error)
CI/CD
You may not be installing the devDependencies
during a production build.
To avoid the prepare
npm script from failing:
"scripts": {
"prepare": "husky || true"
},
Project Not in Git Root Directory
Prepush script that works around the frontend project package.json
not being in the
root of the git repository.
Set the package.json
script manually and then do an npm install
.
"scripts": {
"prepare": "cd .. && husky frontend/.husky"
},
The script with some path juggling:
#!/bin/sh
# Path Juggling
originalPath=`pwd`
if [ "`git rev-parse --show-cdup`" != "" ]; then cd `git rev-parse --show-cdup`; fi
cd ./frontend-project-folder/
# Linting
npm run lint
if [ $? -ne 0 ]; then
cd $originalPath
exit -1
fi
# Testing
npm test
if [ $? -ne 0 ]; then
cd $originalPath
exit -1
fi
# Build
npm run build
hasBuildErrors=$?
cd $originalPath
exit $hasBuildErrors
Alternatives
toplenboren/simple-git-hooks : A simple git hooks manager for small projects
evilmartians/lefthook : Fast and powerful Git hooks manager for any type of projects
pre-commit/pre-commit : A framework for managing and maintaining multi-language pre-commit hooks