约定式提交

「约定大于配置」 的思想在软件工程领域得到了广泛的应用,例如 Spring、Angular 等大型项目。其目的只有一个:减少软件开发人员做决定的数量,提升开发效率。这种思想同样被应用到 Git 提交当中,即 「约定式提交」

什么是约定式提交?

约定式提交规范是一种基于提交消息的轻量级约定。所谓轻量级约定,说白了,就是有一套用于创建提交消息的简单规则,这套规则源自于Angular 提交规范,规定了提交消息的整体结构:

1
2
3
4
5
<type>(<scope>): <short summary>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

翻译成中文就是:

1
2
3
4
5
<提交类型>(<作用域>): <简要描述>
// 空一行
<正文>
// 空一行
<脚注>

header 部分

  1. 第一行是 header 部分,必须使用类型字段前缀,它由一个名词组成,只能是下面几种之一:

    • feat: 新功能
    • fix: 修复bug
    • docs:只改动了文档
    • style:修改代码格式(例如去掉空格、改变缩进、增删分号,不影响代码逻辑)
    • refactor:重构代码(理论上不影响现有功能)
    • perf:提升性能的改动
    • test:增加修改测试用例
    • chore:改变构建流程、或者增加依赖库、工具等
    • revert:回滚到上一个版本
    • ci:持续集成
    • build:构建版本
  2. 其后接一个可选的作用域字段,作用域必须是一个描述某部分代码的名词,并用圆括号包围,例如: fix(parser)。每个项目的作用域都不一样,在基于 lerna 的 monorepo 仓库中,通常用 package 名称作为 scope,例如:

    1
    2
    3
    4
    5
    6
    $ tree packages

    packages
    ├── api
    ├── app
    └── web

    那么作用域只能是 apiappweb

  3. 然后紧接着一个冒号(英文半角)和空格。

  4. 最后是简短描述,建议不要超过 50 个字符。

总结如下:

1
2
3
4
5
6
7
<type>(<scope>): <short summary>
│ │ │
│ │ └─⫸ 描述:指的是对代码变更的简短总结
│ │
│ └─⫸ 作用域: animations|bazel|benchpress|common|compiler|...

└─⫸ 提交类型:build|ci|docs|feat|fix|perf|refactor|test...

body 部分

Body 部分是对本次 commit 的详细描述,可以分成多行,提交者自由发挥。

footer 部分一般用于记录不兼容的改动,以 BREAKING CHANGE 开头,后面是对变动的描述、以及变动理由和迁移方法。最后还可以添加关闭的 issue。

1
2
3
4
5
6
BREAKING CHANGE: <breaking change summary>
// 空一行
<breaking change description + migration instructions>
// 空一行
// 空一行
Fixes #<issue number>

为什么要用约定式提交?

有了约定式提交,不仅降低了开发者的心智负担、增强团队凝聚力,还可以编写基于约定的自动化工具,优点如下:

  • 自动化生成 CHANGELOG。
  • 基于提交的类型,自动决定语义化的版本变更。
  • 向同事、公众与其他利益关系者传达变化的性质。
  • 触发构建和部署流程。
  • 让人们探索一个更加结构化的提交历史,以便降低对你的项目做出贡献的难度。

如何在项目中落地?

拒绝乱写提交消息

在项目提交过程中,为了防止乱写提交消息,可使用 commitlint 配合 husky 来实现如下的效果:

git-husky-demo

可以看到,当提交消息不符合「约定」的时候,直接拒绝此次提交。首先安装依赖包:

1
$ yarn add husky @commitlint/config-conventional @commitlint/cli --dev

然后添加 commitlint.config.js 文件:

1
2
3
module.exports = {
extends: ['@commitlint/config-conventional'],
}

最后在 package.json 中添加如下配置即可:

1
2
3
4
5
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}

交互式创建提交消息

@commitlint/prompt-cli 包还提供了一个命令行交互式创建提交消息的方式,效果如下:

commitlint-prompt-cli

这个工具严格按照提交消息撰写的流程引导开发者就行填写,而且可以看到,每一步都有详细的提示,安装方法:

1
$ yarn add @commitlint/prompt-cli --dev

然后在 package.json 中添加 scripts:

1
2
3
"scripts": {
"commit": "commit"
},

下次提交不要直接用 git commit -am 'xxx',而是用 npm run commit,会自动开启上面的命令行交互流程。

自动生成 changelog

有了规范化的提交消息,还可以用 conventional-changelog-cli 来自动生成 changelog,例如提交信息为:

可自动读取所有提交消息,并生成 changelog:

首先安装依赖:

1
$ yarn add conventional-changelog-cli --dev

然后在 pacakge.json 中添加 scripts:

1
2
3
"scripts": {
"changelogs": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
},

最后运行:

1
$ npm run changelogs

示例项目地址:git clone git@github.com:keliq/git-husky-demo.git