#!/bin/sh # Copy a Git hook into the user's .git/hooks/ directory. # If a different hook of that name is already present, back it up first. # # Usage: # install-hook # Example: # install-hook ${PENCIL_HOME}/utils/git/hooks/prepare-commit-msg # Require exactly one argument that does not start with a '-' if [ "$#" != '1' -o "$(echo "$1" | cut -c1)" = '-' ]; then echo "install-hook: Copy a Git hook into the user's .git/hooks/ directory." echo 'Usage:' echo ' install-hook ' exit 1 fi hash_content() { # Print a hash of a file's content filename="$1" md5sum "${filename}" | cut -d ' ' -f 1 } back_up() { # Make a backup copy of a given file file="$1" backup="${file}.bak" echo "Backing up ${file} -> ${backup}" cp "${file}" "${backup}" } find_git_root() { # Find the directory containing our .git directory. # Resolves 'git worktree' indirection. # Prints nothing if the cwd is not under Git git_root="$(git rev-parse --show-toplevel 2>/dev/null)" if [ ! "${git_root}" ]; then return fi dot_git="${git_root}/.git" if [ -d $dot_git ]; then echo $git_root else # 'git worktree': .git points to the true root dir cat $dot_git \ | grep -E '^gitdir:' \ | sed -r -e 's/^gitdir:\s*//;' -e 's|/\.git/worktrees/.*||;' fi } hook="$1" if [ ! -e "${hook}" ]; then echo "Hook ${hook} does not exist"; exit 1; fi if [ ! -r "${hook}" ]; then echo "Hook ${hook} is not readable"; exit 1; fi hook_name="$(basename "${hook}")" git_root="$(find_git_root)" if [ ! "${git_root}" ]; then echo "Not a Git repository -- not attempting to install hook" exit 0 fi destination="${git_root}/.git/hooks/${hook_name}" # Check if a hook is already present if [ -e "${destination}" ]; then if [ "$(hash_content ${hook})" = "$(hash_content $destination)" ]; then echo "Git hook .git/hooks/${hook_name} already in place" exit 0 else # A different hook exists: back it up back_up "${destination}" "${hook}" fi fi # Install the new hook echo "Installing Git hook ${destination}" cp "${hook}" "${destination}"