Automating Jekyll deployment, take two

Back last year, I posted about how I set up a non-bare git repository on NearlyFreeSpeech so I could work on the site from both my laptop and desktop. This has worked fine, but the fact that it's not the 'right' way to do it hasn't sat well with me.

The issue I was having with a bare repository came down to deleting the temporary clone that was used to build the site. Despite working fine from the command line and via SSH, attempting to remove the temporary clone used to build the site gave Directory not empty errors, all related to the .git subdirectory. Because the directory wasn't completely removed, creating the temporary repository failed when the script next ran.

After converting the repository from non-bare to bare, I started with the post-receive hook that I'd first tried (via Bart Lantz). This threw the same error, but worked thanks to the multiple rm -rf lines. Experimenting with adding a delay didn't seem to change much, but I found a very relevant Stack Overflow question that tackled what was likely the same situation. The second answer gave me the solution: rather than using git clone which creates the .git subdirectory that couldn't be removed cleanly, use git archive to export a copy of all the files. This was the key to solving the problem and after a bit of trial and error gave me the final version of my post-receive hook.

#!/bin/bash

# set up variables
REPO_PATH=/path/to/barerepo.git/
PUBLIC_WWW=/var/www
TMP_CLONE=/tmp/repo

# archive the repository to the temp directory
mkdir $TMP_CLONE
cd $REPO_PATH
git archive master | tar -xf - -C $TMP_CLONE

# build the site, putting it in the PUBLIC_WWW directory
jekyll build --source $TMP_CLONE --destination $PUBLIC_WWW

# clean up the temp repository
rm -rf $TMP_CLONE

exit

I'm still not positive what causes the original issue, but other reading I've done makes me suspect that the instance of git running on the server during the execution of the post-receive hook is locking access to parts of the .git subdirectory. This would explain why I wasn't able to replicate the issue on the command line or when running the script via SSH, as well as why multiple rm lines eventually removed the directory. Either way, using git archive is an ideal workaround and it's nice to have learned a little more about git.