git commit 提交信息规范入门

语言: CN / TW / HK

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指的是每次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 the git 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-verifyoption. 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存在大写字母,所以被截止了不能提交。