写在前面
对一个developer来说,有时候变量命名,提交代码时的提交信息会让人很头疼,本文主要聊聊怎么优雅的书写commit message。
你见过最奇葩的代码提交信息是什么?
曾在上家公司的一个项目中,见过我至今以来见过最奇葩的代码提交信息,让我至今难忘。那个项目的前三个commit记录的提交信息分别是:
First Blood
Double kill
Triple kill
简直让人啼笑皆非,不知道那位仁兄是不是在一边写代码一边开黑。你是否也见过什么样的奇葩的commit message呢?!
这样的提交信息,不仅无法告知其他人之前提交了什么内容,而且会让觉得很不认真很不专业。
那规范的commitmessage能给我们带来哪些好处呢?
规范commit message的好处
-
可读性好,根据commit信息就能明确知道本次提交的修改内容及影响范围
-
可以根据不同的提交类型,过滤掉不想关注的提交,提高效率
-
可以自动化生成changeLog,甚至可以自动更新语义话的版本
-
可以降低codereview的沟通成本
-
一份清晰规范的commit messge,可以让你表现的更专业
那么什么样的commit message才算是好的呢?我们来看看在业界被很多人认同的两种提交风格。
Angular规范
Angular 的commit信息由标题,正文和页脚三个部分组成,每个部分中间通过空行分隔。标题部分包括类型,范围和主题三个部分。
<type>(<scope>): <subject><BLANK LINE>
<body>
<BLANK LINE><footer>
type 提交类型
提交的类型必须是下面的一个:
feat:增加一个新功能
fix:修复bug
docs:只修改了文档
style:做了不影响代码含义的修改,空格、格式化、缺少分号等等
refactor:进行代码重构,既不是修复bug,也不是新功能的修改
perf:改进性能的代码
test:增加测试或更新已有的测试
chore:构建或辅助工具或依赖库的更新
scope 范围
说明当前提交的代码影响的范围,如果当前更改影响的不止一个范围时,可以使用*
subject 描述
包含对变更的简洁描述: 使用祈使句,现在时态:"change"而不是"changed"或"changes",第一个字母不要大写, 末尾没有点(.)
body 正文
使用祈使句,body应该包括为什么修改,具体修改了哪些了东西。
footer 页脚注释
用来放置 Breaking Changes 或 Closed Issues
Conventional Commits 规范
基于Angular的提交规范衍生出的规范,很大程度上以其为Augular的规范为依据 提交格式与Augular基本一致
<type>[optional scope]: <description>
[optional body]
[optional footer]
type 提交类型
类型是必须提供的,且必须是名词,其后接一个可选的作用域字段,以及一个必要的冒号(英文半角)和空格;
- 提交新功能或新特性时,必须使用feat类型;
- 修复了 bug 时,必须使用fix类型;
- 可以使用 feat 和 fix 之外的类型;
scope 范围
作用域必须是一个描述某部分代码的名词,并使用圆括号
description 描述
描述是必须项,字段必须紧接在类型/作用域的空格之后。描述指的是对代码变更的简短总结
body 正文
正文可可选的,如果书写必须起始于描述字段结束的一个空行后
footer
正文结束的一个空行之后,可以编写一行或多行脚注
BREAKING CHANGE
不兼容更新必须标示在正文区域最开始,或脚注区域中某一行的开始,必须包含大写的文本BREAKING CHANGE,后面紧跟冒号和空格。
在 BREAKING CHANGE: 之后必须提供描述,以描述对 API 的变更。例如:BREAKING CHANGE: environment variables now take precedence over config files.
可以在类型/作用域前缀之后,: 之前,附加 ! 字符,以进一步提醒注意不兼容变更。当有 ! 前缀时,正文或脚注内必须包含 BREAKING CHANGE: description
Conventional Commits规范是和SemVer规范(语义化版本)的约定是吻合的。
SemVer 是一套语义化版本控制的约定,定义的格式为 ** X.Y.Z(主版本号.次版本号.修订号)** :
X.主版本号:进行不向下兼容的修改时,递增主版本号
Y.次版本号: 做了向下兼容的新增功能或修改
Z.修订号:做了向下兼容的问题修复
Conventional Commits规范是和SemVer规范相吻合的目的是什么呢?! 我们可以根据commit的类型去自动化的生成语义化的版本。
我们比较熟知 electron 项目就采用了Conventional Commits规范,其他采用了这套规范的开源项目还有:
- yargs:广受欢迎的命令行参数解析器。
- istanbuljs:一套为 JavaScript 测试生成测试覆盖率的开源工具和类库。
- uPortal-home 和 uPortal-application-framework:用于增强 Apereo uPortal 的可选用户界面。
- massive.js:一个用于 Node 和 PostgreSQL 的数据访问类库。
- scroll-utility:一个居中元素和平滑动画的滚屏工具包实例。
- Blaze UI:无框架开源 UI 套件。
- Monica:一个开源的人际关系管理系统。
相关工具
有了规范是好事,但不想记那么多的type怎么办?又怎么保证团队每个成员真的按照规范去执行呢?这些都可以通过工具来解决。
Commitizen
一款帮助我们按照规则去提交提交代码的懒人工具,它是一个通用的工具,提供了多种commit Message风格可以选择,比如我们上面提到的Conventional规范,就可以通过按照 cz-conventional-changelog 来实现。
除了提供了一些可选的风格,还支持根据已有的规范去更改创建一套属于自己团队的风格配置。
安装:
npm install commitizen -g
选择风格:
commitizen init cz-conventional-changelog --save-dev --save-exact
or
commitizen init cz-conventional-changelog --yarn --dev --exact
提交代码时,使用git cz 代替 git commit,每一步都会有提示,保证按照规范提交。
commitlint
commit message 的 linter,用来对 message 进行检查,防止提交了不符合规范的提交信息。
可以结合 git hooks 在提交commit时进行自动检查,不符合规范的commit不允许提交。
同样的,commitlint也支持配置安装不同风格的配置,同时,你也能够发布并使用自己的配置。
安装:
npm install --save-dev @commitlint/{config-conventional,cli}
配置风格
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
结合git hooks使用
先安装husky
npm install --save-dev husky
package.json中增加配置
{
"husky":{
"hooks": {"commit-msg": "commitlint -E HUSKY_GIT_PARAMS" }
}
}
这样在输入不符合风格的commit Message会无法通过,并会给出具体的提示。
standard-version
standard-version需要使用Conventional Commits规范,能够帮助自动生成符合SemVer规范的版本和 CHANGELOG。
安装:
npm i --save-dev standard-version
package.json中增加配置:
{"scripts": {"release": "standard-version" }}
第一次发布版本,执行命令,同时生成changeLog
npm run release -- --first-release
之后版本变更,直接执行
npm run release
常见问题
一次提交多种类型怎么操作
尽可能拆分的task,每完成一部分就进行一次提交,避免一次提交过多的代码。这样能够避免一次commit修改过多文件,导致后续的维护,回退等的困难。
如果真的有这样的提交,可以选择最重要改动的type,在body部分详细写明具体的改动。
提交了不规范的信息怎么处理
如果使用了Commitizen或commitlint,基本上可以保证提交符合规范的Message,但是也可能出现选错了类型的问题,比如是新增的功能,但是一手抖,选成了fix并完成了commit,这时可以使用 git rebase -i 来编辑提交历史。
参考
Angular规范:github.com/angular/ang…
Conventional Commits 规范: www.conventionalcommits.org/en/v1.0.0-b…
SemVer规范: semver.org/
欢迎关注我的公众号「前端小苑」,我会定期在上面更新原创文章。