git cz不能直接替代git commit,因其仅规范提交信息格式,不约束分支流向、合并策略或权限控制;它解决“写得对不对”,而分支流程解决“该不该这么走”,二者必须协同。

git cz 为什么不能直接替代 git commit
因为 git cz 只负责生成符合规范的提交信息,不干预分支流向、合并策略或权限控制。它和 git commit 是平级命令,只是交互方式不同;如果你在 hotfix 分支上执行 git cz,它不会自动校验你是否该从 main 拉出、也不会阻止你把修复合进 develop 而漏掉 main。
常见错误现象:
- 开发人员在
feature/login分支用git cz提交了feat,却忘了切回develop合并,导致功能“消失” - 线上紧急修复走
hotfix/v2.1.0-login,提交信息规范漂亮,但只合入develop,没同步到main,上线时 bug 仍在
所以 Commitizen 解决的是「写得对不对」,分支流程解决的是「该不该这么走」——两者必须配合,不能互相替代。
commitizen 配置如何适配多分支场景
默认的 cz-conventional-changelog 不区分分支,但团队实际需要按分支类型约束 type 和 scope。比如:
-
hotfix/*分支应强制只允许fix和chore,禁用feat和refactor -
release/*分支应只允许chore(版本号更新)、docs(发布说明),且scope必须填release -
feature/*分支可放开feat、refactor、test,但scope建议限定为模块名(如user、cart)
实现方式不是靠 Commitizen 本身,而是结合 husky 的 pre-commit 或 commit-msg 钩子做分支判断:
#!/bin/sh
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [[ "$BRANCH" =~ ^hotfix/.* ]]; then
if ! grep -q "^(fix\|chore):" "$1"; then
echo "❌ hotfix 分支只允许 fix/chore 类型提交"
exit 1
fi
fi
这个脚本放在 .husky/commit-msg 中,就能在提交前拦截非法类型。
为什么 husky + commitlint 比单纯用 git cz 更可靠
git cz 是交互式引导,依赖人主动执行;而 husky + commitlint 是硬性拦截,只要配置生效,任何 git commit 都绕不过去。
关键差异点:
-
git cz可被跳过:有人直接敲git commit -m "update",Commitizen 完全无感 -
commit-msg钩子作用于所有提交,无论用什么命令、什么工具触发 -
@commitlint/config-conventional校验的是最终字符串格式,不关心你是不是用 cz 生成的 - 配合
HUSKY_GIT_PARAMS环境变量,能精准读取当前提交信息文件路径,避免误判
示例错误拦截:
当有人在 main 分支执行 git commit -m "feat: 新增后台管理",commitlint 会报错:error: subject may not be empty [subject-empty](因为未通过交互填写 scope),同时也会因 type 不符合生产分支策略被钩子拒绝。
release 分支上提交信息的 scope 怎么填才不踩坑
很多团队在 release/v2.1.0 分支提交时乱填 scope,比如写成 release/v2.1.0 或空着,结果导致自动生成 changelog 时分类错乱、语义化版本(SemVer)升级失败。
正确做法是统一约定 scope 为 release,且仅用于两类操作:
- 版本号变更(
chore(release): bump version to v2.1.0) - 发布说明更新(
docs(release): update CHANGELOG.md for v2.1.0)
这样做的好处:
- changelog 工具(如
conventional-changelog-cli)能准确归类为「发布项」而非「功能项」 - CI 流程可通过
scope === 'release'自动触发打包、打 tag、推送镜像等动作 - 避免把 release 分支的提交误判为功能变更,影响自动化版本号计算逻辑
注意:不要在 release 分支上提交业务代码修改——那说明流程已失控,应退回 develop 修复再重拉 release。











