1.前言
在git commit中提交信息中,如果能找按照规范写好,能提高可读性以及项目维护效率。本文针对message的规范和提交检测工具进行介绍。
2.参考的规范:Angular Team Commit Specification
详细的提交信息可以让人知道本次提交对原项目进行哪方面的修改。是修复bug、添加组件或模块、修改代码风格还是重构。从message中也可以知道针对哪部分的文档或模块进行修改。
但这个message到底要怎么去写比较好?这里可以参考Angular团队的git-commit-guidelines。以下为该团队对message做出的规范格式:
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
每一次提交信息都包含着header、body和footer。头部包括type,scope和subject。
如果本次提交时是对上一次的提交进行回滚,则header需要以revert:
开头,在body里需要写明:This reverts commit <hash>.hash指的是每次commit提交后git生成的SHA值。每次提交的SHA值可以通过git log查看到:
1.header
在header中,type和subject是必填项,scope是选填项。下面对头部这三个部分进行详细介绍:
(1)type
必填项,用于说明本次提交做出哪种类型的修改,必须是以下任意一值:
- feat: A new feature(新功能)
- fix: A bug fix(bug的修复)
- docs: Documentation only changes(修改项目中的文档)
- style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)(不影响代码逻辑下的样式修改,通常是风格修改,例如空格、格式、分号方面的修改等)
- refactor: A code change that neither fixes a bug nor adds a feature(重构,不包括修复bug和添加新功能)
- perf: A code change that improves performance(性能优化)
- test: Adding missing or correcting existing tests(添加或者修改测试代码)
- chore: Changes to the build process or auxiliary tools and libraries such as documentation generation(对构建过程或辅助工具和库(如文档生成)的更改)
(2)scope
选填项,用于说明本次提交中改动的位置。国内通常以项目名/模块名
为格式。一次提交中如果有多处修改,官方说可以用*
去缺省。但个人倾向于每次提交都是针对单处修改,这样子阅读提交信息会更详细。
(3)subject
必填项,用于简要地描述本次提交中所做出的修改。而且需要满足格式:
- 如果用英文描述,则英文单词只能是一般现在时或者祈使语气
- 首字母不能大写
- 不能以
.
作为结尾
2.body
选填项,相对于上述的subject,body用于更加详细的描述本次提交中所做出的修改。其中需要包括本次修改的动机以及对比于修改之前的改进之处。
3.footer
选填项,主要包括以下两点:
- break changes:任何关于与上个版本不兼容的更改(breaking change)的信息,例如版本升级、数据字段更改、接口参数变化等。如果存在breaking change,则需要以
BREAKING CHANGE:
开头后接空格或者两行新行后,写清楚更改的内容。 - affect issues:指明本次修改是否针对某次issues。
3.提交信息预格式化工具
(1)commitizen
官方推荐的用于编写合格的提交信息的工具,用于替代git commit
指令。详细配置可看:commitizen。我本人没有用到这个工具,是因为vscode提交已经习惯了用按钮去提交,如果项目中用到commitizen,则之后提交需要用git cz
替代git commit
指令进行提交。会改变整个操作流程,在团队里推广不了。
(2)Commit Message Editor
这里我选择了一款VSCode中的生成格式化提交信息的工具Commit Message Editor,操作可看下图:
(1)普通操作时
(2)使用Angular格式提交信息时
4.提交信息检查工具
1.安装
npm install -D @commitlint/config-conventional @commitlint/cli husky
husky:一个git hooks工具。
commitlint:一个用于检测提交信息格式(commit message format)的工具
2.配置
(1).huskyrc
首先配置husky方面,在根目录新建一个名为.huskyrc
(也可以是.huskyrc.json
)的文件,写入以下内容:
//.huskyrc
{
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
上述代码目的是为了在git执行commit和merge之前,先执行commitlint -E HUSKY_GIT_PARAMS。从而使commitlint检测提交信息。
拓展:git hooks有很多个周期函数,更多可点击查看githooks。有人会问为什么不用"pre-commit"
和"pre-commit-msg"
。
我们可以在刚刚附注的githooks网址里查看"pre-commit"
的解释:
This hook is invoked by git-commit[1], and can be bypassed with the--no-verify
option. It takes no parameters, and is invoked before obtaining the proposed commit log message and making a commit. Exiting with a non-zero status from this script causes thegit commit
command to abort before creating a commit.
看打粗部分的解释,"pre-commit"
是在获取已提交的commit log message之前触发的。因此不能检测提交信息。
再看以下"pre-commit-msg"
的解释:
This hook is invoked by git-commit[1] right after preparing the default log message, and before the editor is started.
对比以下"commit-msg"
的解释:
This hook is invoked by
git-commit[1] and
git-merge[1], and can be bypassed with the
--no-verify
option. It takes a single parameter, the name of the file that holds the proposed commit log message. Exiting with a non-zero status causes the command to abort.
可以知道,"pre-commit"
和"pre-commit-msg"
都是在因git commit触发的,而"commit-msg"是因git commit和git merge触发的,在多人合作项目中避免不了git merge指令,因此我们选择"commit-msg"
周期函数。
(2)commitlint.config.js
其后配置commitlint的参数,写入以下内容:
//commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional']
}
上面代码意思为指定提交信息的检测规则为'@commitlint/config-conventional'。
检测规则有很多类,最常用的是上面采用的Conventional Commits specification。此规则是根据上文所说的Angular Team Commit Specification衍生出来的。commitlint更多规则可看:Shared configuration。
拓展:上面网址的规则中有两个比较类似的规则:
自己对比看了一下,'@commitlint/config-angular'
是几乎满足了本文第二点中介绍的header、body、footer中所有的规则。然后添加了header中的type和scope必须为小写的规则。
而'@commitlint/config-conventional'
是继承'@commitlint/config-angular'
的全部规则上还有一些小的约束,例如:
- header最大长度为100个字符
- body和footer每行的最大长度为100个字符,注意这里是每行,即可以换行。
添加了以上两个配置后,每次git commit前就会根据规则检查,如果不符合规则,则会中断,例如:
我提交的信息为:ci(.huskyrC): test,因为scope存在大写字母,所以被截止了不能提交。