Git Commit 规范参考

创业维艰
• 阅读 2263

引子

在 github 上逛逛就可以发现,其提交的 commit 都有一定格式,工作中也有相应的规定,时间长了就能体会到其中的好处。这种约束是一种良好的实践。抽出一些时间,更详细的了解相关的资料,然后做了一些实践和总结。

规范 Commit 的好处

  1. 提供更明确的历史信息,方便判断提交目的和浏览
  2. 可以过滤某些不必要的提交,方便快速查找信息
  3. 自动化生成 Changelog
  4. 向同事、公众与其他利益关系人传达变化的性质
  5. 基于提交的类型,自动决定语义化的版本变更

以上的好处,个人认为要有一个大的前提,就是每一个提交,尽量保证其目的单一性,比如说几个 bug 看似类似,就一次性修改提交。这样做,让 commit 的信息变的复杂化,阅读不方便,也容易让人想到一些不必要的关联性。

Commit 的格式

找了几个 start 较多的库,看看提交的格式。

  1. react-commit

Git Commit 规范参考

  1. vuejs-commit

Git Commit 规范参考

  1. angular-commit

Git Commit 规范参考

网上推荐的写法是第 2 和 3 种,也就是 Angular 规范,并有配套的工具。有一个文档对 commit 的格式要求有个描述叫约定式提交。下面就根据 Angular 规范和对应文档,看看详细的说明。

每个 commit message 包含一个 headerbodyfooterheader 有一个特殊的格式包含有 typescopesubject

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

header、body、footer 之间都要空一行,header 是必填项,scope 是选填项。commit message 的每一行的文字不能超过 100 个字符。这样子在 github 和 git 工具上更便于阅读。

Type

type 用于说明 commit 的类别,必须为以下类型的一种:

  • feat: 新的功能
  • fix: 修复 bug
  • docs: 只是文档的更改
  • style: 不影响代码含义的更改 (例如空格、格式化、少了分号)
  • refactor: 既不是修复 bug 也不是添加新功能的代码更改
  • perf: 提高性能的代码更改
  • test: 添加或修正测试
  • chore: 对构建或者辅助工具的更改,例如生成文档

Scope

scope 用于说明 commit 影响的范围,当影响的范围有多个时候,可以使用 *

Subject

subject 用于对 commit 变化的简洁描述:

  • 使用祈使句,一般以动词原形开始,例如使用 change 而不是 changed 或者 changes
  • 第一个字母小写
  • 结尾不加句号(.)

Body

body 用于对 commit 详细描述。使用祈使句,一般以动词原形开始,例如使用 change 而不是 changed 或者 changes。

body 应该包含这次变化的动机以及与之前行为的对比。

Footer

footer 目前用于两种情况。

1 不兼容的变动

所有不兼容的变动都必须在 footer 区域进行说明,以 BREAKING CHANGE: 开头,后面的是对变动的描述,变动的理由和迁移注释。

BREAKING CHANGE: isolate scope bindings definition has changed and
    the inject option for the directive controller injection was removed.

    To migrate the code follow the example below:

    Before:

    scope: {
      myAttr: 'attribute',
      myBind: 'bind',
      myExpression: 'expression',
      myEval: 'evaluate',
      myAccessor: 'accessor'
    }

    After:

    scope: {
      myAttr: '@',
      myBind: '@',
      myExpression: '&',
      // myEval - usually not useful, but in cases where the expression is assignable, you can use '='
      myAccessor: '=' // in directive's template change myAccessor() to myAccessor
    }

 The removed `inject` wasn't generaly useful for directives so there should be no code using it.

2 关闭 issue

如果 commit 是针对某个 issue,可以在 footer 关闭这个 issue。

## 关闭单个
Closes #234
## 关闭多个
Closes #123, #245, #992

Revert

如果 commit 用于撤销之前的 commit,这个 commit 就应该以 revert: 开头,后面是撤销这个 commit 的 header。在 body 里面应该写 This reverts commit <hash>.,其中的 hash 是被撤销 commit 的 SHA 标识符。

revert: feat(pencil): add 'graphiteWidth' option

This reverts commit 667ecc1654a317a13331b17617d973392f415f02.

示例

feat($browser): onUrlChange event (popstate/hashchange/polling)

Added new event to $browser:
- forward popstate event if available
- forward hashchange event if popstate not available
- do polling when neither popstate nor hashchange available

Breaks $browser.onHashChange, which was removed (use onUrlChange instead)
fix($compile): couple of unit tests for IE9

Older IEs serialize html uppercased, but IE9 does not
Would be better to expect case insensitive, unfortunately jasmine does
not allow to user regexps for throw expectations.

Closes #351
style($location): add couple of missing semi colons
docs(guide): updated fixed docs from Google Docs

Couple of typos fixed:
- indentation
- batchLogbatchLog -> batchLog
- start periodic checking
- missing brace

Commit 相关的工具

填写提示工具 commitizen

这个工具是用来给 commit 一个引导的作用,根据提示一步一步的完善 commit。

在 Windows 环境下安装,个人遇到的问题有:

1、安装 commitizen 后,进行初始化,找不到命令

Git Commit 规范参考

尝试成功的解决方法是用 yarn 执行指令:

yarn commitizen init cz-conventional-changelog --save-dev --save-exact

2、按照说明里面直接执行 npx git-cz无效,安装了 npx 也无效

发现在 node_modules\bin\ 目录下,并没有 npx 相关可执行文件,需要安装 npx。

安装后还是无效,需要用 yarn 来执行指令

yarn npx git-cz

Git Commit 规范参考

可以发现执行指令后,显示了对应的可执行文件的路径。

如果配置了 scripts,那么提交的时候需要执行对应的指令,才会触发这个工具的作用。

还有操作的问题,在自己的戴尔笔记本用上下键切换无效,也尝试过各种组合键,也是无效,外接的键盘有效。

格式校验工具 commitlint

validate-commit-msg 已不被推荐使用。安装对应要使用的提交规范,

#it also works for Windows
yarn add @commitlint/{config-conventional,cli} --dev

# Configure commitlint to use angular config
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js

示例用的是 config-conventional 规范,这个安装后,还需要使用 commitmsg hook,推荐使用 husky。安装husky

yarn add husky --dev

然后配置 package.json

{
  "scripts": {
    "commitmsg": "commitlint -E GIT_PARAMS"
  }
}

提交时候就会触发校验,效果如下图。

Git Commit 规范参考

2018.12.09:
在最新的版本中,由于 GIT_PARAMS 参数的问题,进行了更新,配置变化如下:

{
  "scripts": {
-   "precommit": "npm test",
-   "commitmsg": "commitlint -E GIT_PARAMS"
  },
+ "husky": {
+   "hooks": {
+     "pre-commit": "npm test",
+     "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
+   }
+ }
}

或者在项目文件夹下执行下面的命令,会自动进行更正。

./node_modules/.bin/husky-upgrade

生成 Changelog 工具 Conventional Changelog

使用的工具是 Conventional Changelog,推荐使用 standard-version。commit 符合 Conventional Commits Specification 中描述的格式,就可以用程序自动生成 Changelog。

先进行安装。

yarn add standard-version --dev

然后配置package.json配置执行的脚本。

{
  "scripts": {
    "release": "standard-version"
  }
}

执行该脚本命令,产生的结果:生成文件 CHANGELOG、自动修改库的版本号、产生一个 commit,用工具查看如下图所示。

Git Commit 规范参考

每一次执行,不会覆盖之前的 CHANGELOG,只会在 CHANGELOG 的顶部添加新的内容。

感受

网上有很多类似的介绍,自己动手去实践,得到的比看到的多的多。

参考资料

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Karen110 Karen110
4年前
​一篇文章总结一下Python库中关于时间的常见操作
前言本次来总结一下关于Python时间的相关操作,有一个有趣的问题。如果你的业务用不到时间相关的操作,你的业务基本上会一直用不到。但是如果你的业务一旦用到了时间操作,你就会发现,淦,到处都是时间操作。。。所以思来想去,还是总结一下吧,本次会采用类型注解方式。time包importtime时间戳从1970年1月1日00:00:00标准时区诞生到现在
Stella981 Stella981
3年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Stella981 Stella981
3年前
Git 实战教程
1.Git配置使用Git的第一件事就是设置你的名字和email,这些就是你在提交commit时的签名,每次提交记录里都会包含这些信息。使用gitconfig命令进行配置:​$gitconfigglobaluser.name"ilimhumar"$gitconfigglobal
Wesley13 Wesley13
3年前
Java日期时间API系列23
  有时候,往往需要统计某个时间区间的销量等问题,这就需要准确的起始时间,获取准确开始时间00:00:00,获取准确结束时间23:59:59。下面增加了一一些方法,获取当天起始时间,昨天起始时间,当前月第一天开始时间,当前月最后一天结束时间,上个月第一天开始时间,上个月最后一天结束时间,某个指定月的起始结束时间等等。其中月份最后一天往往因为月份不同和
Stella981 Stella981
3年前
DevOps世界中的软件开发
!(https://oscimg.oschina.net/oscnet/f40e68cbfe8148deb00f040b4e917a0a.jpg)在整个软件开发过程中,开发人员通常需要花费大量时间来修复错误和漏洞,以便一切按计划进行交付。但是,通过DevOps实践,可以更轻松地管理和保护这些问题。这是由于以下事实:使用DevOps实践的软