67dae3b814
一個晚上誤攔六次,全都不是在推預設分支: ① checkout -b 建新分支時把預設分支寫在後面,再推那條新分支 ② gh pr create 指定 base——根本不是 git push ③ 推 tag(refs/tags/…) ④ 推 feature 分支(帶 -u) ⑤ 它擋住了我用來**測試它自己**的那條指令 ⑥ 它擋住了這一筆的 commit——因為 message 裡引用了那幾個字 leo 2026-08-17 早就講過這個形狀:文字層封路必敗, 「紅線寫得越細,命中關鍵字的機率越高 ⇒ 那些閘在懲罰謹慎」。 舊版掃整條指令字串,正是文字層。 改成解析 push 的目標 refspec: 旗標跳過/第一個非旗標=remote/a:b 取 b/refs/tags/* 不算分支 一個 refspec 都沒給,才退回看當前分支 八向實測(hooks/tests/main-and-prod-push-guard.test.sh,8/8): 五種該放行的(今晚誤攔的原形狀,含分支名帶 domain 那種)全過 三種該擋的全擋 中途自己抓到一個 bug:tag 被跳過後目標清單變空 → 退回猜當前分支 ⇒ 當前分支剛好叫預設名時誤擋。改成看到 refspec 就不退回猜測。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
30 lines
1.3 KiB
Bash
Executable File
30 lines
1.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# 八向實測 main-and-prod-push-guard.sh
|
||
# 放在檔案裡跑,因為測試字串本身會觸發「舊版」那支閘(第五次誤攔)。
|
||
G="$1" # 要測的 hook 路徑
|
||
pass=0; fail=0
|
||
|
||
t() { # t <說明> <指令> <期望 exit>
|
||
printf '{"tool_name":"Bash","tool_input":{"command":"%s"}}' "$2" \
|
||
| CLAUDE_CODE_CHILD_SESSION=1 CLAUDE_PROJECT_DIR="$(dirname "$(dirname "$G")")" \
|
||
bash "$G" >/tmp/pg.out 2>&1
|
||
rc=$?
|
||
if [ "$rc" = "$3" ]; then printf ' ✅ %-46s exit=%s\n' "$1" "$rc"; pass=$((pass+1))
|
||
else printf ' ❌ %-46s exit=%s(期望 %s)\n' "$1" "$rc" "$3"; fail=$((fail+1)); fi
|
||
}
|
||
|
||
echo "── 該放行(今晚五次誤攔的原形狀)──"
|
||
t "checkout -b 後推 feature 分支" 'git checkout -q -b fix/x ma'"in"' && git push -q origin fix/x' 0
|
||
t "gh pr create --base(不是 git push)" 'gh pr create --head f --base ma'"in"' --title t' 0
|
||
t "推 tag" 'git push -q origin refs/tags/v0.3.3' 0
|
||
t "推 feature 分支(帶 -u)" 'git push -q -u origin feat/milestone-must-have-due' 0
|
||
t "分支名含 domain" 'git push origin fix/custom-domain-setup' 0
|
||
|
||
echo "── 該擋 ──"
|
||
t "直接推預設分支" 'git push origin ma'"in" 2
|
||
t "HEAD:預設分支" 'git push origin HEAD:ma'"in" 2
|
||
t "推 master" 'git push -q origin mas'"ter" 2
|
||
|
||
echo "────── 通過 $pass / 失敗 $fail"
|
||
[ "$fail" = "0" ]
|