你见过最奇葩的代码提交信息是什么?别再为写commit message头疼了!

4,945 阅读7分钟

写在前面

对一个developer来说,有时候变量命名,提交代码时的提交信息会让人很头疼,本文主要聊聊怎么优雅的书写commit message。

你见过最奇葩的代码提交信息是什么?

曾在上家公司的一个项目中,见过我至今以来见过最奇葩的代码提交信息,让我至今难忘。那个项目的前三个commit记录的提交信息分别是:

First Blood

Double kill

Triple kill

简直让人啼笑皆非,不知道那位仁兄是不是在一边写代码一边开黑。你是否也见过什么样的奇葩的commit message呢?!

这样的提交信息,不仅无法告知其他人之前提交了什么内容,而且会让觉得很不认真很不专业。

那规范的commitmessage能给我们带来哪些好处呢?

规范commit message的好处

  1. 可读性好,根据commit信息就能明确知道本次提交的修改内容及影响范围

  2. 可以根据不同的提交类型,过滤掉不想关注的提交,提高效率

  3. 可以自动化生成changeLog,甚至可以自动更新语义话的版本

  4. 可以降低codereview的沟通成本

  5. 一份清晰规范的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-homeuPortal-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/

欢迎关注我的公众号「前端小苑」,我会定期在上面更新原创文章。