#!/bin/sh
#
# A hook script that blocks committer and author names that are
# root (or a configured blacklisted name).
# XXX: should allow only applying this to certain branches.
#
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# Config
# ------
# hooks.noroot.branches
#   List of branches for which commits by root should be disallowed.
# hooks.noroot.match
#   XXX: figure out format
#

set -e

# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"

# --- Safety check
if [ -z "$GIT_DIR" ]; then
	echo "Don't run this script from the command line." >&2
	echo " (if you want, you could supply GIT_DIR then run" >&2
	echo "  $0 <ref> <oldrev> <newrev>)" >&2
	exit 1
fi

if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
	exit 1
fi

# --- Config
branches=$(git config --get hooks.noroot.branches || echo "")
# XXX: hooks.noroot.match

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
	newrev_type=delete
else
	newrev_type=$(git cat-file -t $newrev)
fi

case "$refname","$newrev_type" in
	refs/heads/*,commit)
		git log --pretty="format:%h \"%an\" \"%cn\"%n" "$oldrev".."$newrev" | \
		while read hash an cn; do
			if [ "$an" = "\"root\"" -o "$cn" = "\"root\"" ]; then
				echo "*** Committing as root not allowed in this repository," >&2
				echo "*** Please fix your GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL,"
				echo "*** GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL."
				echo "*** Offending commit was $hash."
				exit 1
			fi
		done
		;;
	refs/remotes/*,commit)
		# tracking branch
		;;
	refs/tags/*,*)
		# we could track tags, but we've decided they're not
		# interesting
		;;
	*,delete)
		# not interesting
		;;
	*)
		# Anything else (is there anything else?)
		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
		exit 1
		;;
esac

# --- Finished
exit 0
