#!/usr/bin/env bash # Conventional Commits 提交信息校验闸门(本机 hook) # 安装:cp templates/commit-msg ~/.githooks/commit-msg && chmod +x ~/.githooks/commit-msg # git config --global core.hooksPath ~/.githooks # 绕过:git commit --no-verify(不建议);CI 侧 .gitea/scripts/ci_gate.py 会再拦一次,绕不过。 # 规则必须与 .gitea/scripts/ci_gate.py 完全一致 —— 两处不一致 = 本地绿、CI 红(或反之)。 set -uo pipefail msg_file="${1:-}" [ -n "$msg_file" ] || { echo "commit-msg: 缺少提交信息文件参数" >&2; exit 1; } [ -f "$msg_file" ] || exit 0 # 取第一条非注释行作为标题 subject_line="" while IFS= read -r line; do case "$line" in ''|'#'*) continue ;; esac subject_line="$line"; break done < "$msg_file" [ -n "$subject_line" ] || exit 0 # 放行自动生成的提交 case "$subject_line" in Merge\ *|Revert\ \"*|fixup!\ *|squash!\ *|amend!\ *) exit 0 ;; esac TYPES="feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert" RE='^('"$TYPES"')(\([a-zA-Z0-9._/-]+\))?!?: .{3,}$' fail() { cat >&2 <(<范围>): <简短描述> 类型 : feat 新功能 | fix 修缺陷 | docs 文档 | style 格式(不改逻辑) refactor 重构 | perf 性能 | test 测试 | build 构建/依赖 ci CI 配置 | chore 杂务 | revert 回滚 范围 : 可选,小写,如 (card) (weknora) (deploy) 正确示例 feat(asset): 新增按歌曲生成应援序列 fix(parser): 修复表格解析越界导致的 500 ci: 接入 Gitea Actions 自动编译 要点 · 类型小写,冒号后必须有一个空格,描述 ≥3 个字符 · 标题 ≤72 字符,结尾不要加句号 · 说明「为什么」写正文(空一行后),一行一件事 · 破坏性变更:类型后加 !,并在正文写 BREAKING CHANGE: 说明 · ⚠️ 正文不要直接在 -m 里写反引号 / \$()(会被 shell 先执行): git commit -F - <<'EOF' 临时绕过(不推荐,CI 仍会拦截): git commit --no-verify EOF exit 1 } [ ${#subject_line} -le 72 ] || fail "标题 ${#subject_line} 字符 > 72" case "$subject_line" in *. | *。) fail "标题结尾不要加句号" ;; esac printf '%s' "$subject_line" | grep -Eq "$RE" || fail "不符合 <类型>(<范围>): <描述>"