#!/usr/bin/env bash
# Blocks pushing any commit that adds or changes a game-derived or local-only file (.githooks/game-derived; see
# pre-commit). Adapted from DW5's hooks (issue 017).
hooks=$(cd "$(dirname "$0")" && pwd)
status=0
while read -r local_ref local_sha remote_ref remote_sha; do
    case "$local_sha" in *[!0]*) ;; *) continue ;; esac  # branch deletion
    case "$remote_sha" in
        *[!0]*) if git cat-file -e "$remote_sha^{commit}" 2>/dev/null; then
                    range=$(git rev-list "$remote_sha..$local_sha")
                else  # the remote has commits we have not fetched
                    range=$(git rev-list "$local_sha" --not --remotes)
                fi ;;
        *) range=$(git rev-list "$local_sha" --not --remotes) ;;  # a new branch
    esac
    for commit in $range; do
        # -m: a merge commit's changes against each parent, so nothing hides in a merge.
        bad=$(git -c core.quotepath=off diff-tree --no-commit-id --name-only -r --root -m --diff-filter=ACMR "$commit" \
              | sort -u | "$hooks/blocked-paths") || { echo "Push blocked: cannot read the blocked-path list." >&2; exit 1; }
        if [ -n "$bad" ]; then
            echo "Push blocked: commit $commit contains game-derived or local-only files:" >&2
            echo "$bad" >&2
            status=1
        fi
    done
done
exit $status
