當我們瀏覽一個項目的 commit 歷史時,經常發現它們可讀性很差,不知所云,不明白它們解決了什麼問題或者增加了什麼新特性。 就算可以通過 diff 工具知道那些文件變更了,如果 commit message 寫得很糟糕,語義不清,很難知道為什麼要做這些變更。
比如下面來自本人某個真實項目的糟糕例子:
上圖很多提交只是簡單地描述做了哪些變更,新建或者刪除了某些文件。而且像add width: 100%, fix flow error 這些信息,依然讓人很困惑,是修改了某個公共模塊還是某個特定模塊或頁面,會不會有意外的影響?
add width: 100%
fix flow error
message是對commit的總結、注釋,不是簡單地描述做了什麼變更(CRUD某個文件),更應該是讓閱讀歷史的人明白,你為什麼做了這些變更,這些變更影響了哪些模塊或頁面,是否修復了某些 bug,是否是break change,儘可能讓項目的其他成員理解此次commit的上下文、意圖。
message
commit
break change
好的commit message,可以提高code review的速度,方便歷史回溯,還可以幫助自動生成更新日誌。
commit message
code review
很多開源項目會在CONTRIBUTING中說明它們採用的commit message格式,大同小異,以目前javascript社區比較出名的、最先由Angular團隊推出的conventional-changelog舉例。
javascript
Angular
首先,格式是:
<type>(<scope>): <subject> <BLANK LINE> <body> <BLANK LINE> <footer>
再看一個具體的例子:
type scope subject | | | | | | | | | feat(button): add disabled prop ---- subject line ---- blank prevent to click when button is disabled ---- body, long description ---- blank Fixes #bugID ---- footer, issue/bug reference ---- blank BREAKING CHANGE: just to illustrate ---- footer, Beeaking change
在詳細講解每個值的意思之前,有幾點需要共識:
subject line
body
footer
subject
.
必須是以下值的一個。參考Angular 項目的 Contribution.md,裡面已經解釋得很清楚。
清晰地分類,提倡大家使用意圖明確、單一目標的小提交,而不是混雜的大提交。
可選,表示影響的範圍、功能、模塊
對變更的簡潔描述
更詳細的描述
Fixes #xx
Breaking change
首先,我們需要commitlint來檢查我們的commit message是否符合規範。如果不符合,它會攔截提交並給出理由。
commitlint
這點是通過git hooks來實現的
git hooks
// package.json
"husky": { "hooks": { "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", } }
還有,我們需要配置告訴commitlint項目採用的標準,其實就是配置一些規則,有點像eslint。比如
eslint
# .commitlintrc.yml
extends: - "@commitlint/config-conventional" rules: subject-case: # 中文需要忽略該選項 - 0
詳細的安裝、配置步驟在裏就不展開。
對於初次接觸的開發員而言,完全手寫符合規範的message可能有點不適應,這時候可以藉助 commitizen。
commitizen
commitizen提供可交互命令行界面,開發者通過回答問題來生成最終的commit message
同樣,我們需要告訴commitizen項目採用的標準:
"config": { "commitizen": { "path": "./node_modules/cz-conventional-changelog" } },
有了這些附帶上下文、metadata的歷史後,我們可以藉助conventional-changelog 自動生成對應的變更日誌
metadata
conventional-changelog -p angular -i CHANGELOG.md -s -r 0
-p angular表示使用Angular規範。
-p angular
生成的CHANGELOG.md大概長這樣:
CHANGELOG.md
可以看到,如果我們想要充分自定義我們自己的規範,藉助上述的工具,我們只需要
conventional-changelog
推薦閱讀: