pre-commit钩子需通过git symbolic-ref --short head获取当前分支名,并结合外置配置文件(如.branchrc)校验前缀、长度及禁用模式,失败时退出码为1以拦截提交。

pre-commit钩子中如何拦截非法分支名
Git 本身不校验分支命名,必须靠 pre-commit 钩子在本地提交前拦截。关键不是“能不能做”,而是“在哪做、怎么触发最稳”:必须在创建分支后、首次提交前就生效,否则开发者可能已推送到远端。
常见错误是把校验逻辑放在 commit-msg 或 pre-push——前者只管 commit message,后者太晚,分支早已存在;后者还无法阻止本地分支创建。
- 校验入口必须是
pre-commit钩子,且需额外检查当前所在分支是否符合规范(因为钩子只对暂存区文件起作用,不天然感知分支) - 用
git symbolic-ref --short HEAD获取当前分支名,比git branch --show-current兼容性更好(支持 Git 2.13+) - 正则建议锚定开头和结尾,例如
^feature\/[a-z0-9]+(-[a-z0-9]+)*$,避免匹配到feature/login-page-extra中的login片段
支持哪些分支前缀及如何配置可扩展性
硬编码前缀(如只允许 feature/、fix/)会卡住团队演进。真正可行的是把规则外置为配置文件,让 .git-hooks/branch-rules.json 或项目根目录的 .branchrc 控制行为。
示例配置:
{ "prefixes": ["feature/", "fix/", "docs/", "chore/"], "max_length": 48, "forbidden_patterns": ["_", "UPPER"] }
- 读取配置应有 fallback:若配置不存在,默认启用基础规则(如仅
feature/和fix/) - 长度限制要包含整个分支名,不只是后缀部分;
max_length设为 48 是因 GitHub UI 在 PR 列表里会截断过长名称 -
forbidden_patterns建议用字符串而非正则,降低使用者门槛;内部转成new RegExp(pattern, 'i')即可
Windows 下 pre-commit 钩子执行失败的典型原因
脚本在 macOS/Linux 跑得好好的,一到 Windows 就报 /bin/sh: line 0: exec: node: not found 或权限拒绝——根本不是代码问题,而是 Git for Windows 的 shell 环境和路径解析差异。
- 钩子文件必须用 LF 换行(
core.autocrlf=false+ 提交前检查),否则 Windows 的 CRLF 会让 bash 解析失败 - 不要直接写
#!/usr/bin/env node,改用#!/usr/bin/env sh并在脚本内调用node ./validate-branch.js - 路径拼接别用
__dirname + '/rules.json',而要用path.resolve(__dirname, '..', '.branchrc'),否则 Windows 下__dirname可能含反斜杠导致 resolve 失效
如何让团队成员免手动安装钩子
指望每人手动复制钩子文件到 .git/hooks/ 下?基本等于没做。自动化安装必须绑定到 npm script 或 CI 初始化流程。
- 在
package.json的preparescript 中执行ln -sf ../../scripts/pre-commit .git/hooks/pre-commit(macOS/Linux)或用copy命令(Windows) - 更稳妥的做法是用
husky@8+,但注意它默认不处理分支创建事件——需配合simple-git在pre-commit钩子里主动检查分支名 - 务必加 README 提示:“首次
npm install后钩子自动启用;如已克隆仓库,请运行npm run setup-hooks”
pre-commit,所以必须额外补充 post-checkout 钩子来提醒当前分支名不合规。











