Git 是现在比较流行的版本控制工具,在开发的过程中,Git 每次提交代码,都需要写Commit message (即提交说明)。如果没有对 Commit message 进行规范,会造成很多的麻烦,比如:
- 每个人的 Commit message风格不同,格式凌乱,查看就换个不方便
- 有一些commit  没有写 message,事后就很难知道对应修改的作用。
 所以说规范的 Commit message 是很有必要的。也是有很多的好处的,比如:
- 可以统一团队的Git commit日志风格
- 方便日后查阅, Reviewing Code等
- 可以帮助我们写好 Changelog
- 能提升项目的整体质量
我们要配置git提交规范的话, 肯定需要知道它的规范是什么?先来看Git Commit 规范 是什么?
Git Commit 规范
目前规范使用较多的是 Angular 团队得规范 我们也叫这种规范做: Git 约定式提交规范。
这种规范提供了一中轻量级的的提交历史编写规则,它的内容十分的简单:
它包含了三个部分:Header,Body,Footer
| 1 | // 注意冒号 : 后有空格 | 
其中,Header 是必需的,Body 和 Footer 可以省略。
注意: 不管是哪一个部分,任何一行都不得操作72个字符(或者100个字符)。 当然, 这只是避免自动换行影响美观而已。
Header
Header 部分 只有一行,包括三个字段:**type(必填),scope(可选),subject(必填)**
type
type 字段用于说明 commit 的类别,它允许使用下面的标识
- feat:新功能(- feature)
- fix: 修改- bug
- docs:文档(- documentation)
- style:格式(不影响代码运行的变动)
- refactor:重构(即不是新增功能,也不是修改- bug的代码变动)
- test:增加测试
- chore:构建过程或者辅助工具的变动
scope
scope 用于说明  commit 的影响范围,比如: 数据层,控制层,视图层等等。因具体项目而定。
subject
subject 用于说明 commit 目的的简短描述,最好不要操作50 个字符。我们在写ubject的时候需要注意:
- 以动词开头,使用第一人称现在时,比如:change,而不是changed或者changes
- 第一个字母小写
- 结尾不加句号
Body
Body 部分是对本次 commit 的详细描述,可以分成多行。写Body 部分的时候也需要注意:
- 使用第一人称现在时候, 比如使用 change而不是changed或changes
- 应该说明代码变动的动机,以及与以前行为的对比
Footer
Footer 部分只用于这两种情况:
不兼容变动
如果当前的代码与上一版本不兼容,则Footer 部分以 BREAKING CHANGE 开头, 后面是对变动的描述,以及变动的理由和迁移的办法。
| 1 | BREAKING CHANGE: isolate scope bindings definition has changed. | 
关闭Issue
如果当前的commit 是针对某个 issue。那么在footer部分关闭这个iissue。可以一次性关系多个issue
| 1 | closes #123, #245, #992 | 
Revert
 有一种特殊情况, 如果当前的commit 是用于撤销 以前的``commit 的,则必须以Revert 开头。 后面紧跟着被撤销的Commit的Header`。
Body部分的格式是固定的,必须写成This reverts commit <hash>.,其中的hash是被撤销commit的 SHA 标识符。
如果当前 commit 与被撤销的commit,在同一个发布(release)里面,那么它们都不会出现在 Change log 里面。如果两者在不同的发布,那么当前 commit,会出现在 Change log 的Reverts小标题下面。
举个例子
我们新建一个文件夹:
| 1 | mkdir gitCommit | 
然后进入到这个文件夹:
| 1 | cd gitCommit | 
执行:
| 1 | git init | 
新建一个文件:
| 1 | touch index.js | 
执行:
| 1 | git add | 
这时候我们开始写提交的commit message,命令行输入
| 1 | git commit | 
这时候会跳出编辑器让我们编写 message, 我们则可以写成:
| 1 | feat:(*): 添加index.js文件 | 
这commit message的 Header 为 feat:(*): 添加index.js文件),表示:我们加了一个新功能(type = feat),它的影响范围是*(scope = *), 它的简短描述(subject)是:添加index.js文件
这commit message 的 Body 为:  在根目录添加了indexjs文件。表示这次的commit 的简单描述是:  在根目录添加了indexjs文件
如果我们要撤销上面的 commit 。 我们这可以 使用 git revert <commitId>
我们可以下先使用 git log, 找出要 revert 的 commitId 0(f6c37576c793b2e2f4e66a87f96c2e825e073d35)
然后执行:git revert f6c37576c793b2e2f4e66a87f96c2e825e073d35。
| 1 | Revert "feat:(*): 添加index.js文件" | 
这是的提交规范是这样的,已经默认帮我们写好了。当然我们也是可以修改的。
配置 git 提交规范
当然,在我们的日常开发当中, 需要记住上面的规范, 有点繁琐。我们的目标还是要通过工具生成和约束。 那么我们现在就来配置吧!
Commitizen
那么有什么 工具可以 做到生成规范并且约束呢? Commitizen就是一个很不错的, 很合格的工具,
Commitizen/cz-cli: 是一个格式化 commit message 的工具,可以约束提交者按照制定的规范一步一步的填写 commit message。
安装
| 1 | npm install commitizen --save | 
然后在项目的根目录里, 执行以下的命令,使其支持Angular 的 commit message 格式。
| 1 | commitizen init cz-conventional-changelog --save --save-exact | 
配置
我们打开 packge.json。 可以看到配置为:
| 1 | "config": { | 
之后,只要是用到 git commit 命令,一律改为使用 git cz, 然后就会出现选项, 用来生成符合格式的 commit message
| 1 | git cz | 
cz-customizable
上面是直接使用 cz-conventional-changelog 作为 Adapter。但是如果需要自定义 Adapter, 比如:默认提交的types 非常多;或者有些使用我们可能只需要其中的某些type。或者自定义一些type,那么就可以通过 cz-customizable 来自定义了。
安装
| 1 | npm i cz-customizable --save | 
将之前符合Angular规范的**cz-conventional-changelog适配器路径改成cz-customizable**适配器路径:  **”path“: “./node_modules/cz-conventional-changelog“ **改成  “path“: “./node_modules/cz-customizable“
| 1 | "config": { | 
配置
在跟目录下新建.cz-config.js。 内容的示例文件如:cz-config-EXAMPLE.js
| 1 | ; | 
我们可以对这个配置进行汉化处理:
| 1 | module.exports = { | 
到此, 我们使用 cz-customizable  就自定义配置完了。
最后我们使用 git cz命令进行提交说明:
 
上图我们就可以看出此时的提交说明已经汉化, 我们继续写提交说明:
 
最后我们提交到远端看到效果如下:
 
Commitizen校验
我们前面已经约束了一套代码规范提交说明了, 但是还是有人不按照规范提交代码说明怎么呢?, 那么就需要 commitlint来校验 commit 了。
安装commitlint
| 1 | npm install --save-dev @commitlint/cli | 
安装@commitlint/config-conventional
安装符合Abgular风格校验规则:
| 1 | npm install --save-dev @commitlint/config-conventional | 
然后在项目中新建 commitlint.config.js文件,并且设置校验规则:
| 1 | module.exports = { | 
安装安装huksy(git钩子工具)
| 1 | npm install husky --save-dev | 
然后在packge.json 中配置 git commit提交时的钩子:
| 1 | "husky": { | 
需要注意,使用该校验规则不能对.cz-config.js进行不符合Angular规范的定制处理,例如之前的汉化,此时需要将.cz-config.js的文件按照官方示例文件cz-config-EXAMPLE.js进行符合Angular风格的改动。
最后我们来试一试:
提交不符合规范的错误提示:
 
提交符合规范的提示:
 
需要注意:如果使用了 cz-customizable配器做了破坏Angular风格的提交说明配置,那么不能使用**@commitlint/config-conventional**规则进行提交说明校验,可以使用commitlint-config-cz对定制化提交说明进行校验。
安装:
| 1 | npm install commitlint-config-cz --save-dev | 
然后加入commitlint校验规则配置:
| 1 | module.exports = { | 
这里推荐使用**@commitlint/config-conventional**校验规则,如果想使用
cz-customizable适配器,那么定制化的配置不要破坏Angular规范即可。
git commit 触发 git cz
在提交的时候,我们都习惯了 git commit ,虽然换成 git cz 不难,但是如果让开发者在 git commit 时无感知的触发 git cz 肯定是更好的, 而且也能避免不熟悉项目的人直接 git commit 提交一些不符合规范的信息。
我们可以在husky.config.js中设置:
| 1 | "hooks": { | 
参考文档:
