Using git hooks locally

Git comes with the concept of "hooks" which are scripts that get executed when and event occurs. A common use case for git hooks is to run a test suite before a commit (pre-commit) is made. If the script that is executed exits with a non-zero value (error) then the commit is prevented.

In my most recent use case I set up a hook to deploy this blog when I push to master. To do this I added a pre-push hook.

Writing git hooks

Git will look inside a repository's .git/hooks/ directory for available hooks by default. So if it finds a file matching the name of a hook, in this case pre-push it will attempt to execute it. If the file is not executable the hook will not run. So the first thing that needs done is to create a hook file and make it executable.

touch .git/hooks/pre-push
chmod +x .git/hooks/pre-push

Now that the file is created and made executable we can write the content of the git hook. In my case I want it to build my blog then use rsync to upload it to my cloud server.

This seems super risky. Pushing files directly to the server to update them... Relax, everyone used to do it back in the day with a thing called PHP

This blog is a simple Python script, it was previously JS but the dependencies kept breaking, that converts markdown to html. It uses a virtual env which adds an extra step to the hook script. In order to activate the virtual env and run build the script needs to know which directory it is being called from. This is the reason for the SCRIPT_DIR var in the shell script below.

#!/bin/bash
set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

source "$SCRIPT_DIR/../venv/bin/activate"
python "$SCRIPT_DIR/../generate_blog.py"

rsync -avz --delete "$SCRIPT_DIR/../build/" root@00.0.000.000:/var/www/briandouglas.ie/

Due to the above script being in the .git/hooks folder and being an executable file named pre-push it will get called before each push. If the script fails, the push will not complete.

Remember to run chmod +x $file to make it an executable. Otherwise git will ignore them.

Hooks and version control

Now you may have noticed that because the file is inside .git/hooks that it won't be included in your version control. You will surely want to add it to version control so that your team mates can avail of your awesome hooks.

To include the hooks in your version control you will need to specify a custom hooks path. This can be done with the following command, which tells git to look in the .githooks folder for any hooks.

git config core.hooksPath .githooks

After running that config update you will now be able to add your hooks to version control.

Until next time,

- Brian