提交日志是一个非常重要的信息,良好的格式的提交日志可以如下诸多作用:

  • 提供更多的历史信息,方便快速浏览,快速定位到提交的性质,是bug修复还是新功能等

  • 可以过滤掉某些commit,以便于快速查找信息

  • 可以直接从commit生成change log,省去大家记录版本变动的工作,但是要求大家规范提交注释

  • 可读性好,清晰,不必深入看代码即可了解当前commit的作用。

  • 为 Code Review 做准备

  • 方便跟踪工程历史

  • 提高项目的整体质量,提高个人工程素质

#日志格式

比如,前端和框架就使用如下格式的 Commit message

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

其中,header 是必需的,body 和 footer 可以省略。 不管是哪一个部分,任何一行都不得超过72个字符(或100个字符)。这是为了避免自动换行影响美观。

Header

Header部分只有一行,包括三个字段:type(必需)、scope(可选)和subject(必需)。

type

用于说明 commit 的类别,只允许使用下面10个标识。

  • feat:新功能(feature)
  • fix:修补bug
  • docs:文档(documentation),例如添加注释
  • style: 格式,例如格式化代码
  • refactor:重构(即不是新增功能,也不是修改bug的代码变动)
  • test:增加测试
  • build:变更项目依赖或调整项目结构
  • perf: 性能优化
  • ci: 更改持续集成配置文件等
  • chore:构建过程或辅助工具的变动

如果type为feat和fix,则该 commit 将肯定出现在 Change log 之中。其他情况(docs、chore、style、refactor、test)由你决定。

scope

scope用于说明 commit 影响的范围,一般情况为数据层、控制层、视图层等等,框架内部可以用此字段标示出影响的组件及模块、bugfix的可以补充条线作为后期统计的点,视项目不同而不同。

如果你的修改影响了不止一个scope,你可以使用*代替。

#Git Hook

上面然有了明确的日志格式,但是只局限了文档约定。如果随便输入了点日志就点提交,或者是不小心误敲错了类型,那么都将破坏上诉约定。

如何在提交时就读对日志进行检查,避免人为的出现日志错误呢?

毫无疑问,使用 git hook 即可,与提交相关客户端钩子有:

pre-commit 钩子在键入提交信息前运行。 它用于检查即将提交的快照,例如,检查是否有所遗漏,确保测试运行,以及核查代码。 如果该钩子以非零值退出,Git 将放弃此次提交,不过你可以用 git commit --no-verify 来绕过这个环节。 你可以利用该钩子,来检查代码风格是否一致(运行类似 lint 的程序)、尾随空白字符是否存在(自带的钩子就是这么做的),或新方法的文档是否适当。

prepare-commit-msg 钩子在启动提交信息编辑器之前,默认信息被创建之后运行。 它允许你编辑提交者所看到的默认信息。 该钩子接收一些选项:存有当前提交信息的文件的路径、提交类型和修补提交的提交的 SHA-1 校验。 它对一般的提交来说并没有什么用;然而对那些会自动产生默认信息的提交,如提交信息模板、合并提交、压缩提交和修订提交等非常实用。 你可以结合提交模板来使用它,动态地插入信息。

commit-msg 钩子接收一个参数,此参数即上文提到的,存有当前提交信息的临时文件的路径。 如果该钩子脚本以非零值退出,Git 将放弃提交,因此,可以用来在提交通过前验证项目状态或提交信息。 在本章的最后一节,我们将展示如何使用该钩子来核对提交信息是否遵循指定的模板。

post-commit 钩子在整个提交过程完成后运行。 它不接收任何参数,但你可以很容易地通过运行 git log -1 HEAD 来获得最后一次的提交信息。 该钩子一般用于通知之类的事情。

其他还有一些钩子,暂时与此文无关,不做介绍,可参阅 git hook

因此以检查日志来说,则使用 commit-msg 即可。

Git Hook 其实在每个仓库中都已经为我们写好了示例,在项目目录下的 .git/hooks 目录下即可找到一堆名为 xxx.sample 的文件,下图是一个 commit-msg.sample 的示例,要启用钩子,则只用将此文件的 .sample 后缀去掉即可。

commit-msg.sample
commit-msg.sample

但是,这个钩子文件的内容有点陌生,里面看起来是 bash 的脚本代码,写起来似乎没有那么容易。

#使用前端技术栈来快速启用钩子

写点 bash 有点难,用 bash 来验证上面规范的日志那就更难。 但是借助 npm 的强大生态,我们可以使用 commitlinthusky 来实现此需求,基本零代码即可实现。

husky 是一个以简化 Git Hook 使用的库, 使用它可以非常方便的安装钩子, 假设我们需要再代码提交前通过测试,则只需要如下两行代码即可:

npx husky add .husky/pre-commit "npm test"
git add .husky/pre-commit

commitlint 是一个专门用来检查提交日志是否符合规范的库,进行检查也需要一行代码即可:

npx --no -- commitlint --edit $1

借助这两个工具,实现日志检查只需要如下的步骤:

假设当前目录已经是git仓库,且具备 package.json 文件(没有则可以直接 npm init -y 生成一个)。

# 安装 husky
npm install husky --save-dev

# 安装 commitlint 
npm install --save-dev @commitlint/config-conventional @commitlint/cli

# 启用 husky
npx husky install

# 新增日志检查钩子
npx husky add .husky/commit-msg \"npx --no -- commitlint --edit '$1'\"

至此大功告成,此时如果提交日志不符合规范,git提交将无法创建。

如果修改要验证的git日志的格式,只用在项目根目录下新建一个 commitlint.config.js 文件即可,如允许 scope 为空:

module.exports = {
    extends: ['@commitlint/config-conventional'],
    rules: {
        'scope-enum': [0, 'never']
    }
};

具体完整的配置可参考 文档 https://github.com/conventional-changelog/commitlint/blob/master/docs/reference-rules.md

同时,以上的步骤并不需要每个人都照着命令去敲一次,只需要仓库的维护者操作一次,并在 package.json 中的 scrips 下加入 "postinstall": "npx husky install" 即可。 这样其他人在拉取或者更新仓库后只用重新执行下 npm install 即可。

原理: 安装的依赖和配置都已经保存到仓库了,其他人更新后也会有这些依赖和配置, “postinstall” 的作用是在 npm install 之后自动执行 npx husky install 这样就激活了 husky ,所以只用一个人操作一次即可。

#By The Way

最后不只是检查提交提交日志,如果要在提交前检查是否通过了eslint,则可以如下配置:

npx husky add .husky/pre-commit \"npx eslint ./\"

以上的意思是,新增一个 pre-commit 的钩子,执行内容为 npx eslint ./