使用 git 提交代码时,不同人对代码修改内容的描述不同,有些人可能描述的很详细,有些人却短短几个字只写个大概,团队其他成员看到这样的内容不能很快的确定代码做了哪些修改,所以为了团队中更好的协作和从 git log 中定位问题,定义一个 git 提交规范很有必要
较为常用的是 Conventional Commits Specification (约定式提交 规范),约定式提交规范规定,提交内容需包含以下信息:
[optional scope/可选的代码作用范围]:
[optional body/可选的正文]
[optional footer/可选的脚注]
其中 type 和 description 为必需项。description 中用一句话描述修改的内容,type 可选择的值包括:
feat: 新增功能、新增特性,production changes
fix: 修复 bug,production changes
style: 不影响代码运行的修改(如空格、格式化、换行缩进、行尾分号等),development changes
refactor: 代码重构,既没有修复 bug 也没有新增功能的修改(删除冗余代码、简化代码、变量重命名等),development changes
perf: 只为了优化性能进行的代码修改,production changes
build: 影响项目构建(涉及脚本、配置、工具)或依赖项的修改,之前被称为 chore,也可以不设置这一项而用 chore 代替,development changes
ci: 持续集成和部署系统相关文件的修改,development changes
docs: 文档变更(包括给用户看的文档,和给内部开发人员看的文档),development changes
test: 测试用例的增加或修改,development changes
revert: 代码回滚,恢复上次提交内容,production changes
chore: 其他没有分类的更改,development changes
------
production changes:生产变更,影响最终的生产代码
development changes:开发变更,不影响最终的生产代码
正文部分详细说明做了什么修改,为什么修改等,脚注部分放 Breaking Changes 或 Closed Issues
每次提交代码都书写以上那么详细的信息又会有些繁琐,可以使用 commitizen 这个工具提高效率,它提供了一个 git cz 来代替原有的 git commit 命令,在用它提交代码时可以填写规范中必需的字段
全局安装 commitizen:
npm install -g [email protected]
项目中安装并配置 cz-customizable:
npm i --save-dev [email protected]
// package.json
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
}
}
项目根目录创建配置文件 .cz-config.js 来自定义提示内容:
module.exports = {
// 可选类型
types: [
{
value: 'feat',
name: 'feat: 新功能'
},
{
value: 'fix',
name: 'fix: 修复bug'
},
{
value: 'style',
name: 'style: 代码格式(不影响代码运行的修改)'
},
{
value: 'refactor',
name: 'refactor: 代码重构(既不是增加feature,也不是修复bug)'
},
{
value: 'perf',
name: 'perf: 性能优化'
},
{
value: 'build',
name: 'build: 影响项目构建或依赖项的修改'
},
{
value: 'ci',
name: 'ci: 持续集成和部署系统相关文件的修改'
},
{
value: 'docs',
name: 'docs: 文档变更'
},
{
value: 'test',
name: 'test: 增加或修改测试用例'
},
{
value: 'revert',
name: 'revert: 回退代码'
},
{
value: 'chore',
name: 'chore: 其他没有分类的更改'
}
],
// 消息步骤
messages: {
type: '请选择提交类型:',
customScope: '请输入修改范围(可选):',
subject: '请简要描述提交(必填):',
body: '请输入详细描述(可选):',
footer: '请输入要关闭的issue(可选):',
confirmCommit: '确认使用以上信息提交?(y/n/e/h)'
},
// 跳过问题
skipQuestions: ['body', 'footer'],
// subject文字长度默认是72
subjectLimit: 72
}
提交代码时,使用 git cz 代替 git commit,就可以看到提示内容
但是如果在提交代码时忘记使用了 git cz 命令,就不会使用到上边的工具和规范,可以通过 git hooks 来解决
git hooks 指的是 git 在执行某事件前后可以进行的一些额外操作,如果希望提交代码时阻止不符合提交规范的提交内容,就可以使用 git hooks 钩子函数
git hooks 钩子函数:
Git Hook | 调用时机 | 说明 |
---|---|---|
pre-applypatch | git am 执行前 | |
applypatch-msg | git am 执行前 | |
post-applypatch | git am 执行后 | 不影响 git am 的结果 |
pre-commit | git commit 执行前。 它不接受任何参数,并且在获取提交日志消息并进行提交之前被调用。 脚本 git commit 以非零状态退出会导致命令在创建提交之前中止。 |
可以用 git commit --no-verify 绕过 |
commit-msg | git commit 执行前。 可用于将消息规范化为某种项目标准格式。 还可用于在检查消息文件后拒绝提交。 |
可以用 git commit --no-verify 绕过 |
post-commit | git commit 执行后 | 不影响 git commit 的结果 |
pre-merge-commit | git merge 执行前 | 可以用 git merge --no-verify 绕过 |
prepare-commit-msg | git commit 执行后,编辑器打开之前 | |
pre-rebase | git rebase 执行前 | |
post-checkout | git checkout 或 git switch 执行后 | 如果不使用 --no-checkout 参数,则在 git clone 之后也会执行。 |
post-merge | git commit 执行后 | 在执行 git pull 时也会被调用 |
pre-push | git push 执行前 |
|
pre-receive | git-receive-pack 执行前 | |
update | ||
post-receive | git-receive-pack 执行后 | 不影响 git-receive-pack 的结果 |
post-update | 当 git-receive-pack 对 git push 作出反应并更新仓库中的引用时 | |
push-to-checkout | 当 git-receive-pack 对 git push 做出反应并更新仓库中的引用时,以及当推送试图更新当前被签出的分支且 receive.denyCurrentBranch 配置被设置为 updateInstead 时 | |
pre-auto-gc | git gc --auto 执行前 | |
post-rewrite | 执行 git commit --amend 或 git rebase 时 | |
sendemail-validate | git send-email 执行前 | |
fsmonitor-watchman | 配置 core.fsmonitor 被设置为 .git/hooks/fsmonitor-watchman 或 .git/hooks/fsmonitor-watchmanv2 时 | |
p4-pre-submit | git-p4 submit 执行前 | 可以用 git-p4 submit --no-verify 绕过 |
p4-prepare-changelist | git-p4 submit 执行后,编辑器启动前 | 可以用 git-p4 submit --no-verify 绕过 |
p4-changelist | git-p4 submit 执行并编辑完 changelist message 后 | 可以用 git-p4 submit --no-verify 绕过 |
p4-post-changelist | git-p4 submit 执行后 | |
post-index-change | 索引被写入到 read-cache.c do_write_locked_index 后 |
pre-commit:会在提交前被调用,并且可以按需指定是否要拒绝本次提交
commit-msg:可以用来规范化标准格式,并且可以按需指定是否要拒绝本次提交
使用 husky + commitlint 可以检查提交描述是否符合规范要求
commitlint:用于检查提交信息
husky:是 git hooks 工具
安装 commitlint:
npm install --save-dev @commitlint/[email protected] @commitlint/[email protected]
创建配置文件 commitlint.config.js:
module.exports = {
// 继承的规则
extends: ['@commitlint/config-conventional'],
// 定义规则类型
rules: {
// type 类型定义,表示 git 提交的 type 必须在以下类型范围内
'type-enum': [
2,
'always',
[
'feat',
'fix',
'style',
'refactor',
'perf',
'build',
'ci',
'docs',
'test',
'revert',
'chore'
]
],
// subject 大小写不做校验
'subject-case': [0]
}
}
安装 husky:
npm install [email protected] --save-dev
生成 .husky 文件夹:
npx husky install
在 package.json 中添加 prepare 命令:
// npm set-script prepare "husky install"
"scripts": {
"prepare": "husky install"
},
执行 prepare 命令:
npm run prepare
在 husky 中添加 commitlint 的 hook,并指定在 commit-msg 的 hooks 下执行 npx --no-install commitlint --edit “$1”
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
生成的 .husky/commit-msg 文件:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit $1
设置到这个步骤,不符合规范的 commit 将提交失败
在 pre-commit hooks 函数中,可以使用 husky 配合 eslint 对代码进行检测及格式化
在 husky 中添加 commitlint 的 hook,并指定在 pre-commit 的 hooks 下执行 npx eslint --ext .js,.vue src 来进行代码检测:
npx husky add .husky/pre-commit "npx eslint --ext .js,.vue src"
生成的 .husky/pre-commit 文件:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx eslint --ext .js,.vue src
这时在 git 提交代码时若不符合 eslint 规则,git commit 将会执行失败无法提交代码
使用 lint-staged 可以实现在代码提交时,只检查本次修改代码的文件而不是所有文件,并在出现错误时自动修复。使用 vue cli 创建的项目已经安装了 lint-staged
在 package.json 中配置:
"lint-staged": {
"src/**/*.{js,vue}": [
"eslint --fix",
"git add"
]
},
如上配置,每次它只会在本地 commit 之前,校验提交的内容是否符合本地配置的 eslint 规则,校验会出现两种结果:
修改 .husky/pre-commit 文件为:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
这时提交代码时不符合规范的文件会被自动修复