#!/usr/bin/env bash
# Git pre-push hook: 拒绝 tag 号与其提交的 VERSION 文件不一致的推送。
#
# 根治反复出现的发版事故（0.3.0 / 0.4.7 / 0.4.12）：pre-commit 会在合并
# 提交上自动 bump patch，导致"打 release 分支时定的 tag"与"合并进 main 后
# 的实际 VERSION"错开一位。人工检查单挡不住读数疏忽，这里做机器强制。
#
# 校验规则：对每个被推送的 refs/tags/vX.Y.Z，检查该 tag 指向的提交里
# VERSION 文件内容 == X.Y.Z。不符则拒绝整个 push。

fail=0

while read -r local_ref local_oid remote_ref remote_oid; do
  remote_ref="${remote_ref:-}"
  local_oid="${local_oid:-}"

  case "$remote_ref" in
    refs/tags/v*) ;;
    *) continue ;;
  esac

  # 删除 tag（local_oid 全零）不校验
  case "$local_oid" in
    *[!0]*) ;;
    *) continue ;;
  esac

  tag="${remote_ref#refs/tags/}"
  want="${tag#v}"

  # tag 指向的提交（annotated tag 需 ^{commit}）
  commit=$(git rev-parse "${local_oid}^{commit}" 2>/dev/null)
  [ -z "$commit" ] && commit="$local_oid"
  got=$(git show "${commit}:VERSION" 2>/dev/null | tr -d '[:space:]')
  got="${got:-}"

  if [ -z "$got" ]; then
    printf 'pre-push: [X] tag %s 指向的提交没有 VERSION 文件\n' "$tag" >&2
    fail=1
  elif [ "$got" != "$want" ]; then
    printf 'pre-push: [X] tag/VERSION mismatch: tag=%s  VERSION-file="%s"  expected="%s"\n' \
      "$tag" "$got" "$want" >&2
    printf '          (pre-commit 常在合并提交上 bump 版本导致此错)\n' >&2
    printf '          fix: git tag -d %s && git tag -a v%s <same-commit> -m ...  再重推\n' \
      "$tag" "$got" >&2
    fail=1
  else
    printf 'pre-push: [OK] tag %s == VERSION %s\n' "$tag" "$got" >&2
  fi
done

if [ "$fail" -ne 0 ]; then
  echo "pre-push: 推送被拒绝（tag 与 VERSION 不一致）。" >&2
  exit 1
fi

exit 0
