相信很多人使用SVN、Git等版本控制工具時候都會覺得每次送出都要寫一個注釋有什麼用啊?好麻煩,是以我每次都是随便寫個數字就送出了,但是慢慢的我就發現了,如果項目長期維護或者修改很久之前的項目,沒有一個清晰明了的注釋是多麼的DT,我就經曆過找回自己之前被修改的代碼,然後看到自己寫的git commit 瞬間崩潰了,真是自己選的路跪着也要走完呀!于是我就想規範一下自己,是以在網上搜羅了一些相關文章,總結了一下。
展示一下曾經我錯誤的style:

一、規範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,建議是不要。
scope(可選):
scope
用于說明 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
開頭,後面是對變動的描述、以及變動理由和遷移方法。
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 <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