@zhenxuan/commit-hook
v1.3.3
Published
甄选 git commit message validation hook
Readme
commit-hook
一个 Git commit-msg 校验与提交信息构建工具。它强制提交标题格式、自动提取需求编号与当前迭代号。提供两种使用方式:
- 校验门禁(
hly-commit-msg --check <file>):仅校验格式,不交互、不写文件,给commit-msghook 用 - 交互提交(
hly-commit):收集类型 + 标题,自动提取需求编号与迭代号并确认,补全 trailer 后提交,给npm run commit用
特性
- 强制提交标题格式:
<type>: <summary> - 限制提交类型白名单:
featurebugfixconflicti18nteststyleother conflict/i18n自动带入默认标题(「解决冲突」/「多语言」),无需手动输入feature/bugfix类型必须填写rdcID,其余类型非必填- 从标题自动提取需求编号(如
ven-123456)作为rdcID/featureID - 自动匹配迭代号:根据当前日期在
bin/iterations.json迭代日历文件中匹配 - 迭代日历过期提醒(交互模式):当前日期晚于迭代日历中最后一个发版日时,提示更新日历,可继续提交或退出提交
- 交互式确认(交互模式):从标题提取的信息作为默认值,可直接回车确认或手动修改
- 自动校验
rdcID/featureID格式 - 自动清理并重写 trailer 字段,避免重复
- merge commit 自动跳过,不阻塞合并
安装
npm install -D @zhenxuan/commit-hook --legacy-peer-deps配置 husky(校验模式)
在 .husky/commit-msg 中写入:
#!/usr/bin/env sh
npx --yes -p @zhenxuan/commit-hook hly-commit-msg --check "$HUSKY_GIT_PARAMS"确保文件有执行权限:
chmod +x .husky/commit-msg注意:hook 里的 commit message 文件路径来自 husky 注入的环境变量
HUSKY_GIT_PARAMS,不要写成$1。husky v4 执行 hook 命令时不带位置参数,git 传入的参数只会出现在HUSKY_GIT_PARAMS里(写成$1会导致"未获取到 commit message 文件路径")。
这样直接执行 git commit 时只做格式校验,不弹交互。校验项:
- 标题格式
<type>: <summary>和类型白名单 - 已有的
rdcID/Module/featureIDtrailer 不重复
使用(交互模式,推荐)
项目无需本地脚本,在 package.json scripts 里加上 commit,直接 npx 调用包的 hly-commit:
{
"scripts": {
"commit": "npx --yes -p @zhenxuan/commit-hook hly-commit"
}
}hly-commit 会收集类型和标题,再调用交互模式自动提取并确认,最后执行提交:
- 选择提交类型(回车默认
feature) - 输入标题(
conflict/i18n自动带入「解决冲突」/「多语言」,跳过此步) - 从标题自动提取需求编号,按当前日期匹配迭代号
- 逐项交互确认(回车使用默认值,可手动修改)
- 将
Iteration/rdcID/Module/featureID补全到提交信息 - 执行
git commit(commit-msg hook 会以--check模式校验)
示例:
npm run commit交互过程:
请选择提交类型:
1) feature
...
输入序号或类型名(直接回车默认 feature):
请输入提交标题(可直接粘贴需求标题,例如:ven-174799-企业码免密混付):
> ven-174623 调整协议价弹窗标题
请确认提交信息(直接回车使用默认值):
迭代号 (20260814):
rdcID (ven-174623,必填):
Module (可留空):最终写入的提交信息:
feature: ven-174623 调整协议价弹窗标题
Iteration: 20260814
rdcID: ven-174623
featureID: ven-174623选择 conflict / i18n 时标题自动带入、跳过输入:
请选择提交类型:
3) conflict
输入序号或类型名(直接回车默认 feature): 3
标题(自动): 解决冲突
请确认提交信息(直接回车使用默认值):
迭代号 (20260814):
rdcID (可留空):
Module (可留空):发布意图(全量/灰度/暂缓)不再写入提交信息,pick 时由发布负责人根据冻结清单手动挑选。
提交类型
| 类型 | 用途 | rdcID |
|------|------|-------|
| feature | 新功能 | 必填 |
| bugfix | 缺陷修复 | 必填 |
| conflict | 冲突解决(标题自动带入「解决冲突」) | 非必填 |
| i18n | 多语言/国际化(标题自动带入「多语言」) | 非必填 |
| test | 测试相关 | 非必填 |
| style | 样式/格式化 | 非必填 |
| other | 其他 | 非必填 |
迭代日历维护
迭代日历在独立的 bin/iterations.json 文件中,为按发版日排序的日期数组,每个日期是一个迭代的发版日:
[
"2026-01-16",
"2026-03-13",
"2026-04-10",
"2026-05-15",
"2026-06-12",
"2026-07-17",
"2026-08-14",
"2026-09-11",
"2026-10-16",
"2026-11-13",
"2026-12-11"
]匹配规则:根据当前日期,匹配列表中第一个大于等于今天的日期作为当前迭代。迭代号为该日期去掉横线的形式(如 2026-08-14 → 20260814)。
新增迭代时,在 bin/iterations.json 数组末尾追加日期即可。
迭代日历过期提醒
当当前日期晚于迭代日历中最后一个发版日(即列表已过期、无法匹配新迭代)时,交互模式第一步就会弹出提醒,必须先确认是否继续,才能进入后续的确认流程:
[commit-msg] 当前日期(2026-12-20)已晚于迭代日历中最后一个发版日(2026-12-11),迭代日历可能已过期。
[commit-msg] 请更新 commit-hook:npm update @zhenxuan/commit-hook --legacy-peer-deps;或联系开发者。如需立即提交可选择继续。
是否继续提交?(继续/退出):- 输入
继续:继续提交,迭代号留空由用户手动填写 - 输入
退出:中止本次提交
这是提醒机制,不强制拦截;--check 校验模式不交互,只做格式校验,不会弹出该提醒。
更新迭代日历后发布
# 修改 bin/iterations.json 里的迭代日历
# 版本号 +1
npm version patch
# 发布
npm publish
# 使用方更新
npm update @zhenxuan/commit-hook --legacy-peer-deps常见问题
为什么我提交被拦截了?
- 标题缺少 type,格式应为
<type>: <summary> - type 不在白名单内(
feature/bugfix/conflict/i18n/test/style/other) feature/bugfix类型未填写rdcID- 手动填写的
rdcID/featureID格式不合法(应为字母-数字,如ven-174623)
合并提交会受影响吗?
不会,merge commit 会自动跳过;git revert 生成的提交(Revert "..." 开头)也会自动跳过。
找不到匹配的迭代号怎么办?
如果当前日期不在 ITERATIONS 常量范围内(通常是迭代日历已过期),交互模式第一步会提示更新 commit-hook(npm update @zhenxuan/commit-hook --legacy-peer-deps)或联系开发者;选择「继续」后可直接手动输入迭代号或留空。
