Git hooks are great, especially in larger companies – they allow you to do everything from pre-commit syntax checking to post-push IRC reporting and more. The way Git implements its hooks (as scripts with specific names), however, has a drawback: it’s nontrivial to have a given hook event call multiple different scripts.
For small-time operations, this often isn’t much of a problem – everything can just get put into the same hook script. As my employer’s usage of Git has expanded along with its engineering team, however, we find ourselves wanting to be able to do more mix-and-matching of various hook functionality across different repositories. The ideal situation would be to have one script per functional item, and simply tell Git which ones to call for a given repository + event combination.
I created githook-proxy.sh for this purpose. It’s not all that complex (less than 20 lines of bash when you omit the comments), but it provides very handy functionality. Here’s how it works:
First, symlink the proxy script into the repository’s hooks directory, named like the hook event you want to proxy…
cd /path/to/repo/.git/hooks ln -s /path/to/githook-proxy.sh pre-commit
Second, in the same directory symlink in each of the actual hook scripts you want to run, named like the hook event plus a suffix:
ln -s ~/check-syntax.sh pre-commit-01-check-syntax ln -s ~/fix-style.sh pre-commit-02-fix-style
And you’re done! The proxy script will automatically find the suffixed hooks and run them in sorted order (hence the usage of -01-… and -02-…) when that hook event occurs. You can repeat the process for each other hook event you want to multiplex. For hooks where the exit code matters, the proxy still runs all the matching scripts, but aggregates the exit codes – if one or more scripts exited nonzero, the proxy will also exit nonzero.