相信很多人使用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進行操作。
相關代碼檢測請移步對應文章:
下面是怎樣進行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
- 第一個字母小寫
- 結尾不加句號(
.
)
Body(可省)
Body 部分是對本次 commit 的詳細描述,可以分成多行。
有兩個注意點。
(1)使用第一人稱現在時,比如使用change
而不是changed
或changes
。
(2)應該說明代碼變動的動機,以及與以前行為的對比。
Footer(可省)
Footer 部分只用於兩種情況。
1)不兼容變動
如果當前代碼與上一個版本不兼容,則 Footer 部分以BREAKING CHANGE
開頭,后面是對變動的描述、以及變動理由和遷移方法。
2)關閉 Issue
如果當前 commit 針對某個issue,那么可以在 Footer 部分關閉這個 issue 。
Closes #234
也可以一次關閉多個 issue 。
Closes #123, #245, #992
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格式是否符合規范
#安裝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
參考: