IncludeIf: A digital space written in pencil
Git is going to have (or by now has – via 2.54.0) a new, well, sorta, new feature called git-hooks which you can define in your configuration. This article will explain the how.
The way you configure these hooks is pretty simple:
You can test a hook by running git hook run git-hook-name. All the events are
named according to what you can have in .git/hooks/, aka, all the ones found
in man 5 githooks.
For more, continue reading.
I, for example have, via my own custom gittooling
Now each project I work on use these hooks when I run git commit. I don’t
need to define them in each project or via a shared githook directory.
My Javascript projects automatically run a testsuite when I push them:
The "#" is needed to exclude additional parameters when the hook is called
from an actual pre-push attempt. When running git hook run pre-push
everything works well. When running it from the actual push, it adds the remote
and the location as seen with GIT_TRACE=1 git push origin:
The documentation is a unclear about it. STDIN, or ignoring the data might be fine too. It
depends on your level of comfort and what your hook is trying to do. Hooks
often get additional details via STDIN. For example a push hook gets the
remote and url as regular arguments. And it gets LOCAL_REF, LOCAL_SHA,
REMOTE_REF and REMOTE_SHA via STDIN.
In this case npm run test ignores STDIN, but if your script might read
these, you need to be aware that git also sends data in this way. For me the
quickest fix was to simply add "#" to the command to ignore the additional
arguments. So never do this, k?
All my javascript projects have the hook enabled, but I have some npm repo’s that do not need to have their test run, mainly because they just ship css files and CSS doesn’t really have tests other than “let’s see how it works in the browser”, you can thus tell the hook not to run in your local config:
Now your hook won’t run in that specific repo.
I personally love this new approach to hooks. It allows for setting up multiple
hooks without having to add hooks to .git/hooks, which is a good escape
hatch in itself – but it shouldn’t have been the default.
The way these hooks are being defined allows people to create hooks via framework, packages, or toolkits without having to take over complete hookdirs. I’m looking at you Husky… I’ve had this problem where our frontend folks decided husky was more important than my hooks and I had to undo a take over from husky. With this new setup husky and I could live life in harmony (in theory at least, my hate for these hook frameworks is probably too deep, but you can dream :)).