一种结构清晰,主次分明的Commit Message规范,能够使团队中的commit内容清晰明了,指明提交目的,同时也方便日后回溯问题。但手动执行提交规范又会非常繁琐,项目中用到了commitzen来规范提交的commit格式,这里简单介绍下接入的过程。
1. commit message 的格式
某个阳光明媚的日子,收到了一个线上bug,火速排查想找到原因,看看是哪一次的代码变动造成了这个问题,打开git commit记录,翻了几页发现commit记录大家写的“千奇百怪”,想从commit记录上找到有“价值”的描述犹如“大海捞针”,所以在修复完问题,着手看了看commit message的格式以及相关规范。
一条良好commit message应该至少包含三个部分: Header、Body、Footer。
<type>(<scope>): <subject>
// 空一行
<body>
// 空一行
<footer>
其中Header 是必需的,Body 和 Footer 可以省略。 为了避免自动换行影响美观,任何一行建议都不超过72个字符(或100个字符)。
1.1 Header
Header部分只有一行,包括三个字段:type(必需)、scope(可选)和 subject(必需)
- type:用于说明 commit 的类别
feat:新功能(feature)
fix:修补bug
docs:文档(documentation)
style: 格式(不影响代码运行的变动)
refactor:重构(即不是新增功能,也不是修改bug的代码变动)
test:增加测试
chore:构建过程或辅助工具的变动
-
scope: 用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同
-
subject: commit 目的的简短描述,一般以动词开头
1.2 Body
body是对本次 commit 的详细描述,可以分成多行
1.3 Footer
Footer辅助信息,一般用于两种情况
- 不兼容变动 如果当前代码与上一个版本不兼容,则 Footer 部分以BREAKING CHANGE开头,后面是对变动的描述、以及变动理由和迁移方法
- 关闭 Issue 如果当前 commit 针对某个issue,那么可以在 Footer 部分关闭这个 issue (可依次关闭过个issueCloses #123, #245, #992)
1.4 提交方式
提交Commit message方式,常用的如下。
$ git commit -m "test commit"
但这种方式要想符合上面提到的提交规范,操作起来还是非常繁琐的。这里就不得不提到Commitizen这个插件了。
2、Commitizen介绍及相关插件配置
[Commitizen]是一个撰写符合上面提到的Commit Message标准的一款工具,可以帮助开发者提交符合规范的Commit Message。
2.1 安装commitizen
-
安装
commitizen和 首选适配器cz-conventional-changelognpm install commitizen cz-conventional-changelog -
在package.json中配置如下:
... "config": { "commitizen": { "path": "./node_modules/cz-conventional-changelog" } }
2.2 安装cz-customizable,配置cz-config文件
-
安装
cz-customizable作为commitizen插件npm install -g cz-customizable -
修改package.json中配置:
... "config": { "commitizen": { "path": "node_modules/cz-customizable" } } -
在根目录中创建
.cz-config.js文件,并在文件中进行如下配置:module.exports = { types: [ { value: 'feat', name: 'feat: 新增一个功能', }, { value: 'fix', name: 'fix: 修复一个Bug', }, { value: 'docs', name: 'docs: 文档变更', }, { value: 'style', name: 'style: 代码格式(不影响功能,例如空格、分号等格式修正)', }, { value: 'refactor', name: 'refactor: 代码重构,注意和特性、修复区分开', }, { value: 'perf', name: 'perf: 提升性能', }, { value: 'test', name: 'test: 添加一个测试', }, { value: 'chore', name: 'chore: 变更构建流程或辅助工具', }, ], appendIssueFromBranchName: true, allowTicketNumber: false, isTicketNumberRequired: true, footerPrefix: 'JTFW-', messages: { type: '请选择提交类型:', subject: '请输入提交信息:', body: '请输入提交详细内容. 用 "|" 换行:\n', footer: '请输入家服iwork编号:', confirmCommit: '确定要执行上面的提交吗?', }, allowCustomScopes: true, // skipQuestions: ['scope', 'breaking'], // 想跳过的问题列表 subjectLimit: 100, // subject主题限制长度 };也可根据需要将想要配置,按照配置规则写入,详见: github.com/leoforfree/…
2.3 安装commitlint-config-cz,配置commitlint.config.js文件
-
安装 依赖包
npm install commitlint commitlint-config-cz --save-dev -
在根目录中创建
.commitlint.config.js文件,并在文件中进行如下配置:module.exports = { extends: ['@commitlint/config-conventional'], rules: { 'type-enum': [2, 'always', [ 'feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'chore', 'revert', 'WIP', ]], 'type-case': [0], 'type-empty': [2, 'never'], // type不能为空 'subject-case': [2, 'always', 'sentence-case'], 'subject-empty': [2, 'never'], // subject不能为空 'subject-full-stop': [0, 'never', '.'], 'header-max-length': [0, 'always', 72], }, };
2.4 git钩子配置
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'
npx husky add .husky/prepare-commit-msg 'exec < /dev/tty && node_modules/.bin/cz --hook || true'
2.5 使用时的具体效果如下:
当使用 git commit 提交时, 触发 prepare-commit-msg 钩子

按照提示输入,若不符合lint规则,则会退出,无法正常提交,如下图示例:


修改提交信息后,提交成功

查看git log,提交内容如下所示:

3. 如何无感接入
上述插件组合接入时,步骤会略微繁杂,为了降低使用者的接入成本,我们考虑将其放入@lbgfe/git-hooks包中。涉及commitizen及相关包的配置融合成一个命令,同时也需要避免重复写入。这里简单总结了无感接入的实现过程。
3.1 引导用户安装包
提示用户安装如下包:commitizen、commitlint-config-cz、@commitlint/config-conventional、cz-customizable,如未全部安装,则退出并提示用户安装命令
3.2 写入配置文件
cz命令汉化+自定义步骤的配置文件为.cz-config.js,对commit信息进行lint规则检测的配置文件为commitlint.config.js。
- 将二者对应的配置信息常量化(转为对象),加上前缀
module.exports =,以此作为文件内容来创建新文件,路径为接入用户的根目录。 - 如果该文件已经存在,则需要将二者的配置信息做并集处理,遇到重复属性则以新写入为准。
3.3 执行git钩子的写入
需要写入两个git钩子commit-msg和prepare-commit-msg。
- 检测用户是否已安装
husky包且版本大于5.0 - 执行git钩子的写入命令
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'
npx husky add .husky/prepare-commit-msg 'exec < /dev/tty && node_modules/.bin/cz --hook || true'
4. 快速体验commitizen带来的便捷
上文提到的@lbgfe/git-hooks包,只要升级到0.0.20及以上版本,即可一键接入commitizen包及其相关配置,无需多余操作。
# 安装hooks包
npm install @lbgfe/git-hooks
# 初始化,完成接入
npx lbg-hooks init
书写良好且规范的commit信息,可以让开发者更好地区分自己每次提交的细节,不同的开发者也可以通过commit记录来了解当时开发的场景。同时,commit和需求ID的绑定,在追溯问题时,也可以快速定位代码更改的背景。
作者介绍
王明忠:天生的乐观派,而且永不止步
蔡晓琳:认真coding,远离bug