Testing pre-commit with git
It’s great to run tests on your code before you commit it. It’s even better to make that happen automatically!
git lets you run a script before a commit succeeds by creating what is known as a “pre-commit” hook; it’s simply an executable located at .git/hooks/pre-commit
.
However, there are a few gotchas: by default, git will just run it against your current (possibly dirty) checkout. To make sure you’re actually testing the code you’re about to commit, we can stash your other changes while the tests run.
This brings up another issue: that popping a git stash that includes an index will often result in conflicts; we can solve this by using git reset --hard
before we pop from the stash.
One last thing: we want to recover to the original directory state no matter what happens (e.g. maybe our test suite itself fails); so we use a bash trap
to ensure that our stash popping happens no-matter the exit path.
With that all said, here is what I use as a pre-commit hook for my lua projects:
#!/bin/bash
set -eufo pipefail
if [ -n "$(git status -z)" ]; then
git stash -q --keep-index --include-untracked
trap "git reset -q --hard && git stash pop -q --index" EXIT
fi
echo "## Running luacheck"
luacheck .
echo
echo "## Running tests with busted"
busted
echo