#!/bin/sh # # Copyright © 2018 Nick Bowler # # Simple git post-receive hook to deploy a nanoc site # # License WTFPL2: Do What The Fuck You Want To Public License, version 2. # This is free software: you are free to do what the fuck you want to. # There is NO WARRANTY, to the extent permitted by law. GIT=/usr/bin/git worktreedir=/var/cache/git-worktrees master_update= while read old new ref x; do case $ref in refs/heads/master) master_update=$new ;; esac done worktree_remove() { # welp, git doesn't appear to have a way to ONLY remove worktree tracking # files, it removes the work tree itself which we don't want to do. So do # this manually. for f in worktrees/*/gitdir; do exec 3<"$f" || continue read l <&3 || continue if test x"$l" = x"$1/.git"; then rm -f "$f" $GIT worktree prune -v break fi done exec 3<&- } cd_to_worktree_ () { tmpfile=`mktemp` exec 3>"$tmpfile" 4<"$tmpfile" rm -f "$tmpfile" branch=${1##*/} repodir=`pwd` reponame=${repodir##*/} worktree=/no/where # Remove any stale worktrees... $GIT worktree prune -v # First just try to add a new worktree tmp_worktree=`mktemp -d "${worktreedir%/}/$reponame-$branch-XXXXXXXX"` $GIT worktree add "$tmp_worktree" "$branch" 2>/dev/null || rmdir "$tmp_worktree" $GIT worktree list --porcelain >&3 exec 3<&- while read a b x <&4; do case $a in worktree) worktree=${b:-/no/where} ;; branch) if test x"$b" = x"refs/heads/$branch"; then if cd "$worktree"; then test x"`pwd -P`" != x"$worktree" || { exec 4<&-; return 0; } cd - fi # Clean up worktree_remove "$worktree" fi ;; esac done # Failed? exec 4<&- return 1 } # Usage: cd_to_worktree branch # # Change the current working directory to the worktree for the specified # branch, creating it if necessary. cd_to_worktree () { # Try twice: stale entries might be removed by first pass and 2nd will work if cd_to_worktree_ "$@" || cd_to_worktree_ "$@"; then printf 'using worktree %s\n' "`pwd -P`" unset GIT_DIR fi } deploy_branch () { printf 'Deploying %s\n' "$1" ( cd_to_worktree $1 { flock -w 60 9 || exit git reset --hard || exit git clean -qfd -e gitlock || exit nanoc || exit nanoc deploy master || exit } 9>gitlock ) } ret=true if test ${master_update:+y}; then deploy_branch master || ret=false fi $ret