Git pre-receive hooks for deployment
I host this blog on a git repo that lives on the same box as the webserver. When I push to it, I want to ensure that deploys happen. Previously, it involved SSHing and doing a bit of a dance. Today, I setup a deploy-on-push script through git's pre-receive hooks. It was surprisingly difficult to find a good example of this pattern, so I wanted to publish my result.
When the pre-receive hook is invoked, it's given a line on stdin for each ref that was pushed. If the branch is master, then invoke the make publish
command in the repo.
GIT_QUARANTINE_PATH
is something I couldn't find tons of information about. It prevents you from modifying any of the refs during pre-receive. In general, this sounds like an awesome idea. In practice, it means that you can't check out the source files, so we have to unset it.
The GIT_WORK_TREE
setup allows you to put the files somewhere as you work on them, but keep the repo where it is. This was important because when I tried to git clone
, the cloned copy didn't have a reference to the most recent files.
#!/bin/bash -ex zero_commit='0000000000000000000000000000000000000000' while read -r oldrev newrev refname; do # Branch or tag got deleted, ignore the push [ "$newrev" = "$zero_commit" ] && continue # Calculate range for new branch/updated branch [ "$oldrev" = "$zero_commit" ] && range="$newrev" || range="$oldrev..$newrev" if [ "$refname" == "refs/heads/master" ]; then echo "Deploying..." unset GIT_QUARANTINE_PATH CO_DIR=`mktemp -d` GIT_WORK_TREE=$CO_DIR git checkout -f $newrev GIT_WORK_TREE=$CO_DIR git reset --hard GIT_WORK_TREE=$CO_DIR git clean -fdx cd $CO_DIR && make publish fi done