天天看点

如何规范git commit提交

相信很多人使用SVN、Git等版本控制工具时候都会觉得每次提交都要写一个注释有什么用啊?好麻烦,所以我每次都是随便写个数字就提交了,但是慢慢的我就发现了,如果项目长期维护或者修改很久之前的项目,没有一个清晰明了的注释是多么的DT,我就经历过找回自己之前被修改的代码,然后看到自己写的git commit 瞬间崩溃了,真是自己选的路跪着也要走完呀!于是我就想规范一下自己,所以在网上搜罗了一些相关文章,总结了一下。

展示一下曾经我错误的style:

如何规范git commit提交

一、规范git分支

请移步相关文章:git项目分支管理

二、做好提交前的Code Review

何时做Code Review ?

 在向 master 、 develop 、 bugfix 提交Merge Request 的时候做Code review,在存在以下问题时会拒绝合并并且给出修改意见:

  • 代码不符合约定的规范
  • 代码有更好的实现方式
  • 边界条件错误

Git hook可以做一些什么?

  • 前端eslint 、stylelint 代码规范检测
  • git commit 规范检测

在Cube 项目,写好关键字和简短描述,请勿提交无实际内容的commit msg 

简化为

<type>(<scope>): <subject>      

下面就介绍一下如何用Git hook进行操作。

相关代码检测请移步对应文章:

eslint使用指南

stylelint使用指南

下面是怎样进行git commit 规范检测

Commit Message 格式

要想规范git commit 提交,我们先要了解一下Commit Message格式,目前规范使用较多的是 Angular 团队的规范, 继而衍生了 Conventional Commits specification. 很多工具也是基于此规范, 它的 message 格式如下:

每次提交,Commit message 都包括三个部分:Header,Body 和 Footer。

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

其中,Header 是必需的,Body 和 Footer 可以省略。

不管是哪一个部分,任何一行都不得超过100个字符。这是为了避免自动换行影响美观。

  • 标题行(第一行/header): 必填, 描述主要修改类型和内容
  • 主题内容(body): 描述为什么修改, 做了什么样的修改, 以及开发的思路等等
  • 页脚注释(footer): 放 Breaking Changes 或 Closed Issues
  • scope: commit 影响的范围, 比如: route, component, utils, build...
  • subject: commit 的概述, 建议符合 50/72 formatting
  • body: commit 具体修改内容, 可以分为多行, 建议符合 50/72 formatting
  • footer: 一些备注, 通常是 BREAKING CHANGE 或修复的 bug 的链接.

注:该工具要输入时都可以用\n 来换行操作, 回车直接结束描述!!如果想结束重来可以使用ctrl + c

Header

Header部分只有一行,包括三个字段:

type

(必需)、

scope

(可选)和

subject

(必需)。

type(必填):

type

用于说明 commit 的类别。

  • feat:新增功能
  • fix:bug 修复
  • docs:文档更新
  • style:不影响程序逻辑的代码修改(修改空白字符,格式缩进,补全缺失的分号等,没有改变代码逻辑)
  • refactor:重构代码(既没有新增功能,也没有修复 bug)
  • perf:性能, 体验优化
  • test:新增测试用例或是更新现有测试
  • build:主要目的是修改项目构建系统(例如 glup,webpack,rollup 的配置等)的提交
  • ci:主要目的是修改项目继续集成流程(例如 Travis,Jenkins,GitLab CI,Circle等)的提交
  • chore:不属于以上类型的其他类,比如构建流程, 依赖管理
  • revert:回滚某个更早之前的提交

如果

type

feat

fix

,则该 commit 将肯定出现在 Change log 之中。其他情况(

docs

chore

style

refactor

test

)由你决定,要不要放入 Change log,建议是不要。

如何规范git commit提交

 scope(可选):

scope

用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。

如何规范git commit提交

subject(必填):

subject

是 commit 目的的简短描述,

  • 以动词开头,使用第一人称现在时,比如

    change

    ,而不是

    changed

    changes

  • 第一个字母小写
  • 结尾不加句号(

    .

如何规范git commit提交

Body(可省)

Body 部分是对本次 commit 的详细描述,可以分成多行。

有两个注意点。

(1)使用第一人称现在时,比如使用

change

而不是

changed

changes

(2)应该说明代码变动的动机,以及与以前行为的对比。

如何规范git commit提交

Footer(可省)

Footer 部分只用于两种情况。

1)不兼容变动

如果当前代码与上一个版本不兼容,则 Footer 部分以

BREAKING CHANGE

开头,后面是对变动的描述、以及变动理由和迁移方法。

如何规范git commit提交

2)关闭 Issue

如果当前 commit 针对某个issue,那么可以在 Footer 部分关闭这个 issue 。

Closes #234      

也可以一次关闭多个 issue 。

Closes #123, #245, #992      

如何规范git commit提交

Revert

还有一种特殊情况,如果当前 commit 用于撤销以前的 commit,则必须以 revert: 开头,后面跟着被撤销 Commit 的 Header。

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

This reverts commit 667ecc1654a317a13331b17617d973392f415f02.      

Body部分的格式是固定的,必须写成 This reverts commit &lt;hash>. ,其中的 hash 是被撤销 commit 的 SHA 标识符。

如果当前 commit 与被撤销的 commit,在同一个发布(release)里面,那么它们都不会出现在 Change log 里面。如果两者在不同的发布,那么当前 commit,会出现在 Change log 的 Reverts 小标题下面。

用Commitizen替代你的 git commit (使用工具生成符合规范的commit message)

上面我们已经了解了Commit Message的格式是什么样的了,如果让我们自己手动敲出那些格式也不是不可能,但是我相信那不是程序员的作风,大多数人会疯掉吧,,那么就需要通过commitizen/cz-cli 工具,我们需要借助它提供的  git cz  命令替代我们之前的  git commit  命令, 帮助我们生成符合规范的 commit message .

 安装命令如下。

npm install --save-dev commitizen      

初始化项目以使用cz-conventional-changelog适配器

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

因为commitizen工具是基于Node.js的,对于没有package.json文件的项目上面命令会不成功,所以先创建一个空的package.json文件,再执行上面命令即可,有package.json文件的项目可以忽略本条命令。

npm init --yes      

 至此就算完整的安装完了,之后在需要 git commit  的地方更换成 git cz  指令,这是就会出现选项,用来生成符合格式的Commit message.

 使用commitlint工具检验commit格式是否符合规范

 虽然上面安装了commitizen工具,可以使用工具帮助我们生成符合规范的commit message,但是原有的 git commit  命令还是可以正常使用的,我们使用commitlint工具进行commit格式是否符合规范,防止有人继续使用  git commit  操作提交出不规范的信息。

#安装commitlint cli和传统配置
npm install --save-dev @commitlint/{config-conventional,cli}
#对于Windows:
npm install --save-dev @commitlint/config-conventional @commitlint/cli

#配置commitlint使用传统的config配置文件,在项目根目录生成就可以了 
echo "module.exports = {extends: [\'@commitlint/config-conventional\']}" > commitlint.config.js
      

在刚刚生成的配置文件commitlint.config.js制定提交message规范

/**
 * feat:新增功能
 * fix:bug 修复
 * docs:文档更新
 * style:不影响程序逻辑的代码修改(修改空白字符,格式缩进,补全缺失的分号等,没有改变代码逻辑)
 * refactor:重构代码(既没有新增功能,也没有修复 bug)
 * perf:性能, 体验优化
 * test:新增测试用例或是更新现有测试
 * build:主要目的是修改项目构建系统(例如 glup,webpack,rollup 的配置等)的提交
 * ci:主要目的是修改项目继续集成流程(例如 Travis,Jenkins,GitLab CI,Circle等)的提交
 * chore:不属于以上类型的其他类型,比如构建流程, 依赖管理
 * revert:回滚某个更早之前的提交
*/



module.exports = { extends: [\'@commitlint/config-conventional\'] };

module.exports = {
  extends: [\'@commitlint/config-conventional\'],
  rules: {
    \'type-enum\': [2, \'always\', [
      "feat", "fix", "docs", "style", "refactor", "test", "chore", "revert"
    ]],
    \'subject-full-stop\': [0, \'never\'],
    \'subject-case\': [0, \'never\']
  }
};      

rule配置说明 :rule由name和配置数组组成,如: name:[0, \'always\', 72] ,数组中第一位为 level ,可选 0,1,2 ,0为禁用规则,1为警告,2为错误,第二位为应用与否,可选 always|never ,第三位该rule的值。

上面我们就完成了commitlint的安装与提交规范的制定。检验commit message的最佳方式是结合git hook,所以需要配合Husky。

什么是husky?(GitHook 工具 —— husky介绍及使用)

husky继承了Git下所有的钩子,在触发钩子的时候,husky可以阻止不合法的commit,push等等。注意使用husky之前,必须先将代码放到git 仓库中,否则本地没有.git文件,就没有地方去继承钩子了。 

安装husky

npm install --save-dev husky      

在 package.json 文件通过字段直接添加git钩子。 husky.hooks 

// package.json
{
  "husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS,"  //commitlint检测
      "pre-commit": "npm run stylelintt && npm run eslintt"  //js、css检测,这两个检测需要自己配置,pre-commit会优先于commit-msg执行
    }  
  }
}      

这段配置告诉了 git hooks  ,当我们在当前项目中执行  git commit -m \'测试提交\'  时将触发  commit-msg事件钩子 并通知

husky

,从而执行  commitlint -E HUSKY_GIT_PARAMS 命令,也就是我们刚开始安装的 ./node_modules/.bin/commitlint ,它将读取 commitlint.config.js 配置规则并对我们刚刚提交的

测试提交

这串文字进行校验,若校验不通过,则在终端输出错误,commit终止。

使用 commit-msg 给出了我们想要的东西:只要创建新的提交就会执行它。传递husky的 HUSKY_GIT_PARAMS 给 commitlint 通过 -E|--env 标记它引导到相关的编辑文件。默 -e 认为 .git/COMMIT_EDITMSG 。

 测试

现在你可以自己手动提交 git commit -m "foo: this will fail" 如果不符合规则,自然就会报错,不通过了,这就是为什么要用 commitizen 代替 git commit的原因了,只要跟着commitizen 选择,把必填的都写上就不会报错,必然可以通过了。

生成 Change log

conventional-changelog 是一款可以根据项目的

commit

 和 

metadata

信息自动生成 

changelogs

 和 

release notes

的系列工具,并且在辅助 standard-version 工具的情况下,可以自动帮你完成生成

version

、打

tag

, 生成

CHANGELOG

等系列过程。 

conventional-changelog 生态主要模块

  • conventional-changelog-cli - conventional-changelog 核心命令行工具
  • standard-changelog - 针对 angular commit 格式的命令行工具
  • conventional-github-releaser - 利用 git metadata 针对 Github 的发布工具
  • conventional-commits-detector - commit message 规范引用检测
  • commitizen - 针对开发者简单的 commit 规范
  • commitlint - commit Lint 工具

安装

npm install -g conventional-changelog-cli      

基本使用

conventional-changelog -p angular -i CHANGELOG.md -s      

上面命令不会覆盖以前的 Change log,只会在

CHANGELOG.md

的头部加上自从上次发布以来的变动。

如果你想生成所有发布的 Change log,要改为运行下面的命令。

conventional-changelog -p angular -i CHANGELOG.md -s -r 0      

为了方便使用,可以将其写入

package.json

scripts

字段。

{
  "scripts": {
    "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
  }
}      

以后,直接运行下面的命令即可。

npm run changelog      

参考:

Commit message 和 Change log 编写指南

优雅的提交你的 Git Commit Message

如何写好 Git commit log?

git commit 提交规范 & 规范校验

Cube Git flow