#!/bin/sh
# Only main and tags may be pushed, each to the same name. Every pushed commit is checked.
# stdin: <local ref> <local sha> <remote ref> <remote sha>
top="$(git rev-parse --show-toplevel)"
zero=0000000000000000000000000000000000000000
status=0
while read -r local_ref local_sha remote_ref remote_sha; do
  # Only main -> main and tags -> the same tag.
  case "$remote_ref" in
    refs/heads/main | refs/tags/*) ;;
    *) remote_ref="(not allowed) $remote_ref" ;;
  esac
  if [ "$local_ref" != "$remote_ref" ]; then
    echo "pre-push: refusing to push $local_ref -> $remote_ref (only main and tags)" >&2
    status=1
    continue
  fi
  if [ "$local_sha" = "$zero" ]; then
    echo "pre-push: refusing to delete $remote_ref" >&2
    status=1
    continue
  fi
  if [ "$(git cat-file -t "$local_sha")" = "tag" ]; then
    msg="$(mktemp)"
    git cat-file tag "$local_sha" >"$msg"
    python3 "$top/scripts/scrub_check.py" --message "$msg" || status=1
    rm -f "$msg"
  fi
  commit="$(git rev-parse "$local_sha^{commit}")"
  if [ "$remote_sha" = "$zero" ]; then
    spec="$commit"
  else
    spec="$remote_sha..$commit"
  fi
  python3 "$top/scripts/scrub_check.py" --range "$spec" || status=1
done
exit $status
