Multi-project Git Hooks

Multi-project Git Hooks

Given a logical project setup, it is possible to manage Git hooks across multiple projects and contexts, without resorting to per-project setups and external tools.

I keep work code in something like ~/dev/work, so in my ~/.gitconfig I use the includeIF directive to load an additional .gitconfig file specific to work projects.

In ~/.gitconfig add:

[includeIF "gitdir:~/dev/work/"]
    path = ~/dev/work/.gitconfig

In ~/dev/work/.gitconfig add:

[core]
    hooksPath = ~/dev/work/.hooks

Create the directory ~/dev/work/.hooks and add some hooks. They can be as simple or as fancy as you require.

~/dev/work/.hooks/pre-commit:

#!/bin/bash

if [[ -f "$PWD/package.json" ]]; then
  npm run --if-present lint
fi

if [[ -f "$PWD/go.mod" ]]; then
  go fmt
fi

~/dev/work/.hooks/pre-push

#!/bin/sh

if [[ -f "$PWD/package.json" ]]; then
  npm run --if-present test
fi

if [[ -f "$PWD/go.mod" ]]; then
  go test
fi

Of course, this can also be done per-project, in the project/.git/config file, or globally, in the ~/.gitconfig file.

Sometimes, when I the git-hooks run when they shouldn't, the escape hatch is to use --no-verify with git-commit and git-push.

I use the includeIF directive for more things than git hooks, e.g. to manage my identities; load in different GPG signing keys, setup different commit e-mail addreses, all based on the context I work in.

Just a quick tip that helps me out every day.

Files touched in this guide:

  • ~/.gitconfig
  • ~/dev/work/.gitconfig
  • ~/dev/work/.hooks
  • ~/dev/work/.hooks/pre-commit
  • ~/dev/work/.hooks/pre-push

/v.