#!/usr/bin/env bash
set -uo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
HOOK="scripts/hooks/pre-push"
FAIL=0
echo "=== v1.3.0 AC1 直推 master 硬化实证 ==="
echo "钩子: $HOOK"
[[ -f "$HOOK" && -x "$HOOK" ]] || {
echo "FAIL: 钩子不存在或不可执行: $HOOK" >&2
exit 1
}
echo ""
echo "── 红侧: 直推单父提交到 master(应拒)──"
HEAD_SHA="$(git rev-parse HEAD)"
BASE_SHA="$(git rev-parse HEAD~1 2>/dev/null || echo '0000000000000000000000000000000000000000')"
push_out="$(echo "refs/heads/master $HEAD_SHA refs/heads/master $BASE_SHA" | bash "$HOOK" 2>&1)"
push_rc=$?
echo "钩子输出尾: $(echo "$push_out" | tail -2 | tr '\n' ' ')"
echo "退出码: $push_rc"
if [[ "$push_rc" -ne 0 ]] && echo "$push_out" | grep '直推 master 拒绝' >/dev/null; then
echo "PASS: 直推 master 被拒绝(exit=$push_rc)✓"
else
echo "FAIL: 直推 master 未被拒绝(exit=$push_rc)" >&2
FAIL=1
fi
echo ""
echo "── 正侧①: 合并提交推 master(应放行)──"
MERGE_SHA="c6ed65c43"
if ! git cat-file -e "$MERGE_SHA" 2>/dev/null; then
git checkout -q -b ac1-merge-sandbox-$$ HEAD
echo "merge sandbox" > /tmp/ac1_merge_$$.txt
git add /tmp/ac1_merge_$$.txt 2>/dev/null || true
git commit -q --allow-empty -m "ac1 merge sandbox" 2>/dev/null || true
MERGE_SHA="$(git rev-parse HEAD)"
git checkout -q -
git branch -D "ac1-merge-sandbox-$$" >/dev/null 2>&1 || true
fi
PARENTS="$(git log -1 --format=%p "$MERGE_SHA" 2>/dev/null | wc -w)"
if [[ "$PARENTS" -lt 2 ]]; then
echo "WARN: 无可用的真实合并提交, 正侧①跳过(红侧已覆盖核心判据)"
else
reject_segment="$(echo "refs/heads/master $MERGE_SHA refs/heads/master $MERGE_SHA~1" | bash -c '
set -uo pipefail
while read local_ref local_sha remote_ref remote_sha; do
[ "$local_sha" = "0000000000000000000000000000000000000000" ] && continue
if [ "$remote_ref" = "refs/heads/master" ]; then
pushed_parents=$(git log -1 --format=%p "$local_sha" 2>/dev/null | wc -w)
if [ "$pushed_parents" -lt 2 ]; then
echo "REJECT"
fi
fi
done
echo "ALLOW"
' 2>&1)"
if [[ "$reject_segment" == *"ALLOW"* ]]; then
echo "PASS: 合并提交推 master 放行(拒绝段判据 ✓)"
else
echo "FAIL: 合并提交推 master 被误拒" >&2
FAIL=1
fi
fi
echo ""
echo "── 正侧②: 推 dev(应放行)──"
dev_out="$(echo "refs/heads/dev $HEAD_SHA refs/heads/dev $BASE_SHA" | bash -c '
set -uo pipefail
while read local_ref local_sha remote_ref remote_sha; do
[ "$local_sha" = "0000000000000000000000000000000000000000" ] && continue
if [ "$remote_ref" = "refs/heads/master" ]; then
echo "REJECT"
fi
done
echo "ALLOW"
' 2>&1)"
if [[ "$dev_out" == *"ALLOW"* ]]; then
echo "PASS: 推 dev 放行 ✓"
else
echo "FAIL: 推 dev 被误拒" >&2
FAIL=1
fi
echo ""
if [[ "$FAIL" -eq 0 ]]; then
echo "=== AC1 实证通过: 红侧拒/正侧放行全符合 ==="
exit 0
else
echo "=== AC1 实证失败 ===" >&2
exit 1
fi