背景
目前开发中,git commit message书写不规范是个很常见的问题, 所以可以引入
commitizen来辅助生成提交信息,减少书写成本,提高规范性。
配置步骤
1.安装依赖
如标题所示,需要的依赖包共有三个:husky、commitizen、cz-customizable,具体每个包的详细信息就不再介绍了,不了解且有兴趣的同学可以自行去npm上查看README文件。
# yarn
yarn add husky commitizen cz-cuztomizable -D
# npm
npm i husky commitizen cz-cuztomizable -D
#pnpm
pnpm i husky commitizen cz-cuztomizable -D
2.增加自定义cz配置
cz-customizable提供了自定义配置的能力,在需要执行cz命令的文件夹 (一般为根目录,特殊配置的monorepo项目根据实际情况来看) 下创建.cz-config.js文件,并添加自定义配置,完整配置见README
- cz-config.js
// .cz-config.js
// 个人demo,经由ChatGPT润色的中文版
module.exports = {
// 这里配置type的option值,可自行调整顺序或修改文案
types: [
{
value: 'feat',
name: 'feat(新功能): 向现有功能添加新功能或改进'
},
{
value: 'fix',
name: 'fix(修复): 修复代码库中的bug或者issues'
},
{
value: 'chore',
name: 'chore(任务): 构建/工程依赖/工具/文档更新/格式化'
},
{
value: 'docs',
name: 'docs(文档): 为代码库更新文档'
},
{
value: 'style',
name: 'style(样式): 改善代码库的格式或风格, 修改页面样式'
},
{
value: 'refactor',
name: 'refactor(重构): 对代码库的结构或组织进行重组或改进'
},
{
value: 'perf',
name: 'perf(性能): 代码库性能优化'
},
{
value: 'init',
name: 'init(初始化): 项目初始化'
},
{
value: 'test',
name: 'test(测试): 自动化测试'
},
{
value: 'revert',
name: 'revert(回退): 撤销之前某个提交'
},
{
value: 'build',
name: 'build(构建): 重构系统编译配置'
}
],
// 每一步的提示信息
messages: {
type: '请选择提交类型',
scope: '请选择文件修改范围',
subject: '请输入commit标题(必填)',
body: '请输入commit描述, 可通过&换行(选填)',
// breaking: '列出任何BREAKING CHANGES(破坏性修改)(可选)',
// footer: '请输入要关闭的issue(可选)',
confirmCommit: '确定提交此 commit 吗?'
},
// 配置scope可选项,mono项目可按子项目维度划分,非mono项目可按功能or业务模块划分
scopes: ['global', 'scope1', 'scope2'],
// commit描述的换行符
breaklineChar: '&',
skipQuestions: ['breaking', 'footer'],
// 标题首字母大写
upperCaseSubject: true,
// 标题必填
requiredSubject: true
};
此配置文件可同时被IDE的cz插件使用,如VsCode的
Visual Studio Code Commitizen Support插件,如果想让插件使用此配置,配置文件需要位于项目根目录下
3. 配置huksy,通过git hook触发cz
在package.json中增加husky相关配置
...
"husky": {
"hooks": {
...
"prepare-commit-msg": "sh ./bash/prepare-commit-msg.sh"
}
}
...
4. 增加相关脚本
- check-msg
# ./bash/check-msg.sh
#!/bin/bash
# 该文件用来判断当前是不是 git merge 状态,如果是的话,本地 .git下 会存在 MERGE_MSG 文件
# 尝试读取该文件内容,如果是 Merge branch 开头,我们认为此时就是 merge 状态
# 在该状态下,跳过 lint-staged 和 commitizen 两步,因为检查没有意义
# 补充rebase的判断,如果处于rebase状态,也跳过相关操作
set -e
# merge 信息存放位置
check_file=$(pwd)"/.git/MERGE_MSG";
#rebase目录
check_rebase_apply=$(pwd)"/.git/rebase-apply";
check_rebase_merge=$(pwd)"/.git/rebase-merge";
# 判断文件是否存在
if [ -f "$check_file" ]; then
# 读取 merge 信息
mergeMsg=`cat '.git/MERGE_MSG'`;
# 如果是以 Merge branch 开头,返回2
if [[ $mergeMsg =~ ^Merge.*branch ]]; then
exit 2;
# 其他特殊情况解决冲突,正常不会走到此if分支
elif [[ $mergeMsg = *"Conflict"* ]]; then
exit 2;
fi;
fi;
# reabase过程返回2
if [ -d "$check_rebase_apply" ] || [ -d "$check_rebase_merge" ]; then
exit 2;
fi;
# 非Merge状态也非rebase状态
exit 1;
- prepare-commit-msg
# ./bash/prepare-commit-msg.sh
#!/bin/bash
# calculate bin dir
# merge 信息, 通过merge&rebase生成的commit不再执行git-cz
sh -e $(pwd)"/bash/check-msg.sh";
if [ "$?" = "1" ]; then
# 打开 commitizen 交互界面,辅助生成 commit 信息
INFRA_DIR_NAME=$(dirname $(dirname "$0"))
cd $INFRA_DIR_NAME
# 打开新的终端运行cz,并标识是由hook触发的
exec < /dev/tty && npx cz --hook || true
fi;
4. 愉快的使用
这时候可以直接正常执行git commit指令,hook会自动触发cz, 保证每位同学都可以享受到插件带来的效果。
总结
- 优势
- 如果直接通过cz指令去触发,那么会首先打开cz交互页面,生成相关信息后再去执行pre-commit配置的lint相关检测,如果检测不通过可能会导致本次信息白写的情况,但是通过hook执行的话就可以先执行lint,通过之后再触发cz
- 坑
- 部分设备可能执行cz会报错(获取到了错误的git仓库路径),通过排除变量发现大概率是git版本问题,版本过低执行会出问题,遇到这情况可以尝试升级git版本。另外,任何地方抛错都不会阻塞本次提交,只会直接跳到最后一步,就是安装插件以及配置hook前的状态
- 不会被
--no-verify跳过 - 可以直接
ctrl + c跳过(cz执行过程中) - 如果直接使用
git commit -m 'xxxx'来提交的话,触发hook后新生成的message会把-m里面的覆盖掉 - 使用IDE里的git插件提交代码的话,因为无法获取到终端,会直接报错跳过,不影响正常提交 (VsCode可以配合
Visual Studio Code Commitizen Support插件使用,其余IDE可自行搜索cz相关插件)