#!/usr/bin/env bash
set -euo pipefail

while read local_ref local_sha remote_ref remote_sha; do
  if [ "$local_sha" = "0000000000000000000000000000000000000000" ]; then
    continue  # branch deletion, skip
  fi

  # Only check commits unique to this branch — not commits already on main
  # (including GitHub squash-merge commits which carry GitHub's own key).
  base=$(git merge-base "$local_sha" origin/main 2>/dev/null \
    || git rev-list --max-parents=0 HEAD)

  while IFS= read -r line; do
    sha="${line%% *}"
    status="${line##* }"
    if [ "$status" != "G" ]; then
      echo "error: commit ${sha} is unsigned or unverified — sign your commits before pushing"
      exit 1
    fi
  done < <(git log --format="%H %G?" "${base}..${local_sha}")

  # DCO. Separate from the signature above: signing proves who committed, the
  # trailer asserts the right to contribute. No git config adds it to every
  # commit (format.signOff only affects format-patch), so without this check a
  # missing trailer surfaces in CI — and on a first-time contributor's fork PR,
  # not until a maintainer approves the run.
  while IFS=$'\t' read -r sha author_name author_email; do
    expected="Signed-off-by: ${author_name} <${author_email}>"
    if ! git log -1 --format='%B' "${sha}" | grep -qiF "${expected}"; then
      echo "error: commit ${sha} is missing '${expected}'"
      echo "       add it with 'git commit --amend --signoff', or"
      echo "       'git rebase --signoff ${base}' for a whole branch"
      exit 1
    fi
  done < <(git log --format='%H%x09%an%x09%ae' "${base}..${local_sha}")
done
