天天看點

如何規範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