如何配置 Git 钩子在提交前检查分支命名规范?

文章导读
最稳妥的方式是在本地仓库的 `.git/hooks` 目录下配置钩子脚本。虽然标题提及提交前检查,但实际工程中pre-push 更适合校验分支名,因为提交后分支名仍可能变动,而推送是协作的关键节点。若需本地强约束,也可使用 pre-commit。
📋 目录
  1. 核心脚本代码
  2. 配置步骤
  3. 验证方法
  4. 局限性与常见坑
  5. 参考文档
A A

最稳妥的方式是在本地仓库的 `.git/hooks` 目录下配置钩子脚本。虽然标题提及提交前检查,但实际工程中pre-push 更适合校验分支名,因为提交后分支名仍可能变动,而推送是协作的关键节点。若需本地强约束,也可使用 pre-commit。

先说结论:通过 Git 钩子脚本在提交或推送前拦截违规分支名,是低成本且有效的强制规范手段,但需注意本地钩子无法自动同步。

  • 适合:团队协同开发、对分支管理有严格要求的项目
  • 先准备:确认分支命名规则(如小写、短横线分隔),准备好校验脚本
  • 验收:尝试用违规分支名提交,确认是否被拦截并提示错误
  • 注意:本地钩子可被 `--no-verify` 绕过,关键校验建议配合 CI/CD

核心脚本代码

以下脚本修复了常见的语法错误,并增加了 detached HEAD 状态的保护,可直接保存为 `.git/hooks/pre-commit` 或 `.git/hooks/pre-push`:

#!/bin/bash
# 获取当前分支名
branch_name=$(git symbolic-ref `--short` HEAD)

# 处理 detached HEAD 状态(此时 symbolic-ref 会失败)
if [ $? -ne 0 ]; then
  exit 0
fi

# 定义正则:仅允许小写字母、数字、短横线,且不能以短横线开头或结尾
regex="^[a-z0-9]+(-[a-z0-9]+)*$"

if [[ ! "$branch_name" =~ $regex ]]; then
  echo "ERROR: Invalid branch name '$branch_name'!"
  echo "Branch name should consist of lowercase letters, numbers, and dashes."
  exit 1
fi
exit 0

配置步骤

1. 定位钩子目录

进入项目根目录,找到 Git 钩子文件夹:

cd .git/hooks/

2. 创建钩子文件

复制示例文件并重命名。若选择 pre-push(推荐用于分支名校验):

cp pre-push.sample pre-push

若选择 pre-commit(提交前校验):

cp pre-commit.sample pre-commit

3. 写入校验脚本

编辑文件,将“核心脚本代码”中的内容粘贴进去。确保第一行 #!/bin/bash 存在。

4. 赋予执行权限

脚本必须具备执行权限才能被 Git 调用。Linux/Mac 用户:

chmod +x pre-push

Windows 用户若使用 Git Bash 终端,同样执行上述命令;若使用 PowerShell 或 CMD,需确保 Git 配置正确或直接在 Git Bash 中操作。

验证方法

1. 故意创建违规分支

如何配置 Git 钩子在提交前检查分支命名规范?

创建一个包含大写字母或特殊字符的分支:

git checkout -b Feature_Login

2. 尝试提交或推送

执行 git commitgit push。如果配置成功,终端应输出 ERROR: Invalid branch name 的错误提示,且操作被终止。

3. 检查退出码

操作失败后,可通过 echo $? 查看退出码,非 0 即表示钩子拦截成功。

局限性与常见坑

1. 可被绕过风险

本地钩子并非绝对强制。用户可通过 git commit `--no-verify`git push `--no-verify` 跳过钩子检查。对于关键规范,建议在 CI/CD 流水线中再次校验。

2. 钩子不同步

原生钩子仅存在于本地,新克隆仓库的同事不会自动拥有该校验。需通过文档通知手动配置,或使用 Husky 等工具将钩子配置纳入版本管理。

3. 正则过于严格

若正则规则限制过死(如禁止下划线),可能阻碍特定场景。建议团队先确认命名规范,再编写对应的正则表达式。

4. 权限问题

脚本若无执行权限,Git 会忽略该钩子而不报错。Windows 用户有时会遇到权限丢失问题,需重新 chmod。

参考文档