规范 git commit message 的工具

1,178 阅读5分钟

写在前面

背景:看到别人项目里清晰的commit message,再看看自己项目里的。每次都发誓我的commit message也要像别人那样清晰。结果后来做项目的时候,合格的type 有哪些来着?我也不知道这次提交算啥,那就随便写写吧... 这种时候,如果有工具提示、约束,我们就离清晰的 commit message 越来越近啦。

目前使用最广泛的写法是 Angular 规范AngularVue 都是采用这种规范书写commit message

commitlint

commitlint 主要作用是验证 commit message 是否合格。也可以使用命令行交互的方式生成符合规范的 commit message(用起来有点不顺手)。

官方文档

安装配置

# 初始化 git 仓库(如果需要)
git init
# 初始化 package.json(如果需要)
npm init -y
# 初始化 .gitignore (如果需要)
echo 'node_modules' > .gitignore
# 安装 commitlint 开发依赖
npm install --save-dev @commitlint/config-conventional @commitlint/cli # windows, mac,git bash 都可用
npm install --save-dev @commitlint/{cli,config-conventional} # mac, git bash可用
# 添加配置文件
echo "module.exports = {extends: ['@commitlint/config-conventional']};" > commitlint.config.js

# 安装 husky 开发依赖
npm install --save-dev husky
// package.json
"husky": {
  "hooks": {
    "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
  }
}

commit 测试

git add .
git commit -m 'xx' # 不符合规范,commit 失败,bash 错误信息如下
husky > commit-msg (node v12.17.0)
⧗   input: xx
✖   subject may not be empty [subject-empty]
✖   type may not be empty [type-empty]

✖   found 2 problems, 0 warnings
ⓘ   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

git commit -m 'xx: add index.html' # 不符合规范,commit 失败,bash 错误信息如下
husky > commit-msg (node v12.17.0)
⧗   input: xx: add index.html
✖   type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]

✖   found 1 problems, 0 warnings
ⓘ   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

husky > commit-msg hook failed (add --no-verify to bypass)

git commit -m "chore: lint on commitmsg" # 符合规范 type: subject ,commit 成功。注意type分号后有空格。
husky > pre-commit (node v10.1.0)
No staged files match any of provided globs.
husky > commit-msg (node v10.1.0)

使用命令行交互

# 添加开发依赖
npm install --save-dev @commitlint/prompt-cli
// 修改 package.json
{
  "scripts": {
    "commit": "commit"
  }
}
# 测试
git add .
npm run commit # 出现下面的命令行交互
> zzz@1.0.0 commit D:\gitee\zzz
> commit
Please enter a type: [required] [tab-completion] [header]
<type> holds information about the goal of a change.
<type>(<scope>): <subject>
<body>
<footer>
100 characters left
98 characters left
❯ type: xx 

# 输入错误的type,会给出提示。
# type输入正确后,要求输入scope (optional可选), subject (required), body/footer (optional)
# 可选项需要输入 :skip 忽略该选项。直接enter,会给出提示 enter :skip to omit scope。
# 输入完所有的,会生成一条 commit 记录
husky > commit-msg (node v12.17.0)
[master f0ccbff] feat: success
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a.txt

# 然后他就卡在这里,你敢信?不知道为啥。最后我ctrl c退出,继续后面的操作。
# 😭 好难用的命令行交互

commitlintprompt是真的不好用。

commitizen

以命令行的方式,帮助我们写出合格的 commit message 的工具。

npm readme

全局安装测试

# 全局安装
npm install -g commitizen

# 测试
touch b.txt
git add .
cz  # git cz, git-cz 都可以。然后出现以下交互式命令行。用起来四个字,流畅舒服。
cz-cli@4.2.2, cz-conventional-changelog@3.3.0

? Select the type of change that you're committing: (Use arrow keys)
? Select the type of change that you're committing: feat:     A new feature
? What is the scope of this change (e.g. component or file name): (press enter t
? What is the scope of this change (e.g. component or file name): (press enter t
? Write a short, imperative tense description of the change (max 94 chars):
? Write a short, imperative tense description of the change (max 94 chars):
 (9) add b.txt
? Provide a longer description of the change: (press enter to skip)
? Provide a longer description of the change: (press enter to skip)

? Are there any breaking changes? (y/N)
? Are there any breaking changes? No
? Does this change affect any open issues? (y/N)
? Does this change affect any open issues? No
husky > commit-msg (node v12.17.0)
[master f355771] feat: add b.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b.txt

本地安装配置

# 本地安装
npm install --save-dev commitizen
# 安装 cz-conventional-changelog,自动在package.json 添加配置 
./node_modules/.bin/commitizen init cz-conventional-changelog --save-dev 
# 可手动完成上述两步操作
npm i -D cz-conventional-changelog
"config": {
  "commitizen": {
    "path": "./node_modules/cz-conventional-changelog"
  }
}
// package.json 添加命令到script后,可使用 npm run commit。git commit 仍是普通的信息。
"scripts": {
  "commit": "cz"
}

vscode commit 拓展

以下两个拓展都是通过图形界面交互的方式,帮助我们写出合格的 commit message

git-commit-plugin

特点:不同 type 对应不同图标,(●'◡'●)

使用方法:

  1. 可以按拓展说明中,F1 打开 command,输入show git commit template 。然后选择type...
  2. 打开vscode 侧边栏 SOURCE CONTROL (与文件管理、搜索等同级)。当hoverSOURCE CONTROL时,有一个钢笔形的图标点击即进入到选择 type...

Commit Message Editor

使用方法:(打开过程与git-commit-plugin 使用方法 2 类似)

  1. 打开vscode 侧边栏 SOURCE CONTROL (与文件管理、搜索等同级)。当hoverSOURCE CONTROL时,有一个铅笔形的图标点击即进入到选择 type...
  2. edit as text or edit as form

比较

  1. commitlint 适合团队协作,规范所有人的commit记录。
  2. commitizen 命令行交互,操作连贯性更好,但 git commit 可提交不规范信息。
  3. vscode commit 扩展:
    • git-commit-plugin支持type图标,清晰好看。不过需要在vscode工具栏操作,有点麻烦。
    • Commit Message Editor 不太喜欢用 😭。

以上仅个人看法,欢迎大家交流批评。好奇,大型开源项目,用的什么方式规范commit message呢?

大型开源项目都用的啥?

vue

使用 commitizen 命令行交互式生成commit message。同时自定义脚本(正则匹配)验证通过git commit书写的commit message

{
  "name": "vue",
  "version": "2.6.12",
  "sideEffects": false,
  "scripts": {
    "lint": "eslint src scripts test",
    "commit": "git-cz"
  },
  "gitHooks": {
    "pre-commit": "lint-staged",
    "commit-msg": "node scripts/verify-commit-msg.js"
  },
  "lint-staged": {
    "*.js": [
      "eslint --fix",
      "git add"
    ]
  },
  "devDependencies": {  
    "yorkie": "^2.0.0"
  },
  "config": {
    "commitizen": {
      "path": "./node_modules/cz-conventional-changelog"
    }
  }
}

相关文章:

  1. Git 的学与记:工程化配置 commit 规范 from 掘金
  2. Commit message 和 Change log 编写指南 from 阮一峰