Git分支命名规范校验必须通过pre-commit钩子实现,使用git symbolic-ref --short HEAD获取当前分支名,并读取.git-branch-pattern配置文件中的正则规则(如^(feature|bugfix|hotfix|release|docs|chore)/[a-z0-9]([a-z0-9-]*[a-z0-9])?$)进行匹配,失败时输出明确提示并返回非零退出码中断操作。

Git分支名是否符合规范,靠肉眼检查太容易漏
人工核对分支命名既慢又不可靠,尤其当团队成员多、分支生命周期短时,feature/login-modal 写成 feature/login_modal 或 feat/login-modal 都可能逃过审查。真正有效的校验必须在本地 git checkout 和远程 git push 两个关键节点自动触发,且规则要可配置、不依赖外部服务。
用 pre-commit + 正则做实时分支名拦截
最轻量也最可靠的方案是 hook 进 pre-commit,在本地创建或切换分支前就校验名称。注意:不是所有 Git hook 都适合——pre-push 太晚(分支已存在),commit-msg 校验的是提交信息,不是分支名。
-
pre-commithook 脚本需读取当前分支名:git symbolic-ref --short HEAD 2>/dev/null,失败时说明不在任何分支(比如在 detached HEAD),应跳过校验 - 正则建议用:
^(feature|bugfix|hotfix|release|docs|chore)/[a-z0-9]([a-z0-9\-]*[a-z0-9])?$,强制小写字母、数字、连字符,禁止下划线和首尾连字符 - 别硬编码规则——把正则写进项目根目录的
.git-branch-pattern文件里,脚本优先读它;没这个文件就 fallback 到默认规则 - 校验失败时输出明确提示,例如:
Branch name "feat/auth" violates pattern: use "feature/auth",并返回非零退出码中断操作
CI 中复用同一套规则防漏网
本地 hook 可被绕过(比如 --no-verify),CI 必须二次校验。GitHub Actions / GitLab CI 里不需要重写逻辑,直接调用本地脚本即可。
- 在 CI job 中执行:
bash .githooks/pre-commit(假设脚本放在该路径),而非重新实现一遍正则匹配 - 确保 CI 环境能获取到分支名:
$GITHUB_HEAD_REF(GitHub)或$CI_COMMIT_REF_NAME(GitLab),但注意这些变量在 PR 场景下可能指向源分支而非目标分支,需结合git rev-parse --abbrev-ref HEAD辅助判断 - CI 中不要静默失败——校验不通过必须
exit 1,且日志里打印出实际分支名和预期格式,方便排查
常见坑:Windows 换行符、Git 版本差异、符号链接
脚本在 macOS/Linux 上跑得好,放到 Windows 上常挂掉,根本原因不是语法问题,而是换行符和路径分隔符。
- 脚本文件必须用 LF 换行(
dos2unix .githooks/pre-commit可修复),否则 Windows 的 Git Bash 会报/bin/bash^M: bad interpreter -
git symbolic-ref在 Git v2.22+ 才稳定支持--short,旧版本需回退到git branch --show-current(v2.22+ 引入),两者行为略有不同:前者在 detached HEAD 下报错,后者返回空字符串 - 如果项目用
git submodule或符号链接管理 hooks,确保.githooks/pre-commit是真实文件,而不是指向其他仓库的 symlink——某些 CI 环境会丢弃 symlink
规则本身越简单越好,复杂正则反而难维护。真正卡住质量的,从来不是“能不能写出来”,而是“有没有被所有人一致执行”。


















