Appearance
使用 Husky + Commitlint 规范 Git 提交信息
前言
优雅的 Git 提交信息,可以很直观表达仓库的变更,方便团队协作、问题追溯。并且直接可以根据 git log
产出 CHANGELOG
。
怎么样才能算是优雅的 Git 提交信息呢?
「Conventional Commits」团队为我们提供了约定式提交规范,一种用于给提交信息增加人机可读含义的规范。该规范很大程度上基于 Angular Commit Guidelines。
当然,光有规范肯定不行,规范是死的,人是活的,如果没有工具约束,规范就是白谈。
以下是关于使用相关工具规范 Git 提交信息的教程。
Husky 使用
关于 Git 钩子
Git 本身就有钩子(hooks)功能,能在特定的重要动作发生时触发自定义脚本。钩子都被存储在 Git 目录下的 hooks
子目录中,即项目根目录的 .git/hooks
中。
但是 Git 的钩子,配置比较繁琐,并且我们需要用到的比如 pre-commit
钩子,属于客户端钩子,并不会同步到其他协作人员的 .git
目录中。
而 Husky 的出现,可以让我们很方便地配置 Git 钩子,解决了 Git 原生钩子配置繁琐、协作人员之间不能同步的问题。
以下关于 Husky 的讲解,都是 5.0
及以后的版本。5.0
及以后的版本,初始化后,会在项目根目录下生成 .husky
目录,可以在其中添加自定义钩子配置文件。
安装
shell
npm install husky -D
设置 NPM 的 prepare
脚本
拓展知识:
prepare
脚本属于生命周期脚本,如果你配置了该脚本,那么在你每次npm install
的时候,prepare
脚本都会自动执行,当然也可以手动调用:npm run prepare
。你可以查阅官方文档,了解其他的生命周期脚本,以及会触发生命周期脚本的命令。
shell
# 写入 prepare 脚本到 package.json
npm set-script prepare "husky install"
# 手动运行一次
npm run prepare
每次运行 npm run prepare
,都会在 .husky/_
下生成 husky.sh
和 .gitignore
两个文件,如果原本有的话,会被覆盖。
在 .husky
下的自定义钩子文件,都需要引入 .husky/_/husky.sh
脚本,由于 .husky/_
下的两个文件没有被 Git 管理,有时候切换分支时,.husky/_
下的文件会丢失,导致 git commit
时报错,这时只需重新执行下 npm run prepare
。
添加钩子
添加两个钩子:pre-commit
、commit-msg
,后面需要用到。
shell
npx husky add .husky/pre-commit ""
npx husky add .husky/commit-msg ""
Commitlint 使用
上面我们安装了 Husky,并且添加了两个钩子,但此时还不能约束开发人员的 Git 提交信息。我们需要借助 Commitlint 来辅助校验提交信息。
安装
shell
npm install @commitlint/cli @commitlint/config-conventional -D
@commitlint/cli
是 Commitlint 命令行工具本体@commitlint/config-conventional
是基于「约定式提交规范」的配置文件
配置使用「约定式提交规范」
shell
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
在 Husky 的 commit-msg
钩子中使用
- 可以通过脚本写入到
.husky/commit-msg
shell
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
- 也可以直接在
.husky/commit-msg
中添加
shell
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no -- commitlint --edit "$1"
测试
shell
git add .
# 应该失败
git commit -m "测试"
# 应该成功
git commit -m "chore: 使用 Husky + Commitlint 规范 Git 提交信息"
lint-staged 使用
lint-staged 可以配合 Husky 的 pre-commit
钩子,在 Git 提交之前,对暂存的文件运行 linters 校验。
安装
官方推荐的方式是运行 npx mrm@2 lint-staged
,默认会把配置写入到 package.json
,不过我不喜欢,我选择手动安装。
shell
npm i lint-staged -D
在 Husky 的 pre-commit
钩子中使用
shell
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
配置
lint-staged 默认会对所有暂存的文件进行 lint。我们可以通过配置文件缩小文件范围,以及配置 lint 的方式。
在根目录下创建 .lintstagedrc
配置文件,我常用的配置如下:
json
{
"src/**/*.{js,jsx,md,ts,tsx,json,vue,css}": [
"prettier --write",
"eslint --fix"
]
}
更多配置可以参考官方文档。
熟悉「约定式提交规范」
上面配置了一通插件,也是时候了解下,该怎么样书写规范的 Git 提交信息了。
语法
shell
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
# 译文
<类型>[可选 范围]: <描述>
[可选 正文]
[可选 脚注]
- 类型和描述必填,其他可选。
- 类型包括(可以参考 Angular 约定):
build
:影响构建系统或外部依赖关系的更改(示例范围:gulp、Brocoli、npm)ci
:对 CI 配置文件和脚本的更改(示例范围:Travis、Circle、BrowserStack、SauceLabs)docs
:仅文档的更改feat
:新功能开发fix
:bug 修复perf
:提高性能的代码更改(性能优化)refactor
:既不修复错误也不添加功能的代码更改(代码重构)style
:不影响代码含义的更改(空白、格式、缺少分号等)test
:添加缺失的测试代码或修改现有的测试代码
- 范围在 Commitlint 的拓展下,可以支持多个,用
/
、\
或,
分割。 - 正文可以多行,每行正文都是一段描述性的句子,每行正文前后都需要有空行。
- 脚注可以多行,脚注和脚注之前不需要空行。脚注语法:
<Word-token>:<space><value>
<Word-token><space>#<value>
示例
1. 不包含正文的提交说明
docs: 更新 README.md
2. 包含范围的提交说明
feat(userManage): 开发用户管理模块
包含了 !
字符以提醒注意破坏性变更的提交说明
feat!: 产品发货时向客户发送邮件
包含了范围和破坏性变更 !
的提交說明
feat(api)!: 产品发货时向客户发送邮件
包含了描述并且脚注中有破坏性变更的提交说明
feat: 允许默认的配置对象扩展其他配置
BREAKING CHANGE: 配置文件中的 `extends` 现在用于扩展其他配置文件
包含了 ! 和 BREAKING CHANGE 脚注的提交说明
chore!: 放弃对 Node 6 的支持
BREAKING CHANGE: 使用的 JavaScript 功能将不再支持 Node 6
包含多行正文和多行脚注的提交说明
fix: 防止请求打架
为当前请求设置请求 ID 和一个唯一标志。取消掉当前请求之前的请求响应。
删除之前用于缓解请求打架问题设置的超时器,现在已经不需要了。
Reviewed-by: Wang
Refs: #demo
Commitizen 安装使用
如果你不能清楚的记得不同的类型对应的含义,又不想频繁翻阅文档,可以选择安装 Commitizen。
初始化
如果你使用的是 **npm 5.2+,**可以直接使用 npx
,不需要全局安装 Commitizen。如果你使用的是 **npm 5.2 **以下的版本,请自行查阅官方文档。
运行以下命令进行初始化:
shell
npx commitizen init cz-conventional-changelog --save-dev --save-exact
配置
上一步的初始化操作,会帮我们安装 cz-conventional-changelog
,并且在 package.json
中写入 config
配置:
json
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
但是我不喜欢把配置信息放在 package.json
中,显得杂乱,我选择把配置剥离。
在根目录下创建 .czrc
文件,在其中写入同样的配置,并把 package.json
中的 config
删除。
json
{
"path": "./node_modules/cz-conventional-changelog"
}
最后在 package.json
配置一个命令,避免每次都要敲 npx cz
这样不太熟悉的命令:
json
"scripts": {
"commit": "cz"
}
使用
shell
# 先暂存需要提交的文件
git add xxx
# or 暂存所有
git add .
# 启动 Commitizen
npm run commit
你会看到以下命令行引导:
只需要跟着引导选择、输入、回车。
以上,希望对你有帮助。