題注:如果喜歡我們的文章別忘了點選關注阿里南京技術專刊呦~ 本文轉載自 阿里南京技術專刊-知乎,歡迎大牛小牛投遞阿里南京前端/後端開發等職位,詳見 阿里南京誠邀前端小夥伴加入~。
commit message 是開發的日常操作, 寫好 log 不僅有助於他人 review, 還可以有效的輸出 CHANGELOG, 對專案的管理實際至關重要, 但是實際工作中卻常常被大家忽略. 希望通過本文, 能夠幫助大家重視和規範 commit message 的書寫.
起因
知乎上有個問題: 如何寫好 Git commit log? 很有意思, 能看到各種提交風格: 有用 emoji 的, 有用唐詩的, 有用隨機生成的. 風格沒有對錯, 只要能夠體現出 commit 所做的修改即可.
但是最讓我印象深刻的是 @李華橋 的答案:
這種東西,當然要藉助工具了,才能夠寫得即規範,又格式化,還能夠支援後續分析。 目前比較建議的是,使用終端工具 commitizen/cz-cli + commitizen/cz-conventional-changelog + conventional-changelog/standard-version 一步解決提交資訊和版本釋出。
甚至,如果想更狠一點,在持續整合裡面加入 marionebl/commitlint 檢查 commit 資訊是否符合規範,也不是不可以。
本文就順著這個方向, 給大家介紹下如何保障專案 commit message 的規範和格式化.
Commit Message 格式
目前規範使用較多的是 Angular 團隊的規範, 繼而衍生了 Conventional Commits specification. 很多工具也是基於此規範, 它的 message 格式如下:
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
複製程式碼
我們通過 git commit 命令帶出的 vim 介面填寫的最終結果應該類似如上這個結構, 大致分為三個部分(使用空行分割):
- 標題行: 必填, 描述主要修改型別和內容
- 主題內容: 描述為什麼修改, 做了什麼樣的修改, 以及開發的思路等等
- 頁尾註釋: 放 Breaking Changes 或 Closed Issues
分別由如下部分構成:
- type: commit 的型別
- feat: 新特性
- fix: 修改問題
- refactor: 程式碼重構
- docs: 文件修改
- style: 程式碼格式修改, 注意不是 css 修改
- test: 測試用例修改
- chore: 其他修改, 比如構建流程, 依賴管理.
- scope: commit 影響的範圍, 比如: route, component, utils, build...
- subject: commit 的概述, 建議符合 50/72 formatting
- body: commit 具體修改內容, 可以分為多行, 建議符合 50/72 formatting
- footer: 一些備註, 通常是 BREAKING CHANGE 或修復的 bug 的連結.
這樣一個符合規範的 commit message, 就好像是一份郵件.
git commit 模板
如果你只是個人的專案, 或者想嘗試一下這樣的規範格式, 那麼你可以為 git 設定 commit template, 每次 git commit 的時候在 vim 中帶出, 時刻提醒自己:
修改 ~/.gitconfig, 新增:
[commit]
template = ~/.gitmessage
複製程式碼
新建 ~/.gitmessage 內容可以如下:
# head: <type>(<scope>): <subject>
# - type: feat, fix, docs, style, refactor, test, chore
# - scope: can be empty (eg. if the change is a global or difficult to assign to a single component)
# - subject: start with verb (such as 'change'), 50-character line
#
# body: 72-character wrapped. This should answer:
# * Why was this change necessary?
# * How does it address the problem?
# * Are there any side effects?
#
# footer:
# - Include a link to the ticket, if any.
# - BREAKING CHANGE
#
複製程式碼
Commitizen: 替代你的 git commit
我們的目標還是要通過工具生成和約束, 那麼現在就開始吧.
commitizen/cz-cli, 我們需要藉助它提供的 git cz 命令替代我們的 git commit 命令, 幫助我們生成符合規範的 commit message.
除此之外, 我們還需要為 commitizen 指定一個 Adapter 比如: cz-conventional-changelog (一個符合 Angular團隊規範的 preset). 使得 commitizen 按照我們指定的規範幫助我們生成 commit message.
全域性安裝
npm install -g commitizen cz-conventional-changelog
echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc
複製程式碼
主要, 全域性模式下, 需要 ~/.czrc 配置檔案, 為 commitizen 指定 Adapter.
專案級安裝
npm install -D commitizen cz-conventional-changelog
複製程式碼
package.json中配置:
"script": {
...,
"commit": "git-cz",
},
"config": {
"commitizen": {
"path": "node_modules/cz-conventional-changelog"
}
}
複製程式碼
如果全域性安裝過 commitizen, 那麼在對應的專案中執行 git cz or npm run commit 都可以.
效果如下:
自定義 Adapter
也許 Angular 的那套規範我們不習慣, 那麼可以通過指定 Adapter cz-customizable 指定一套符合自己團隊的規範.
全域性 或 專案級別安裝:
npm i -g cz-customizable
or
npm i -D cz-customizable
複製程式碼
修改 .czrc 或 package.json 中的 config 為:
{ "path": "cz-customizable" }
or
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
}
}
複製程式碼
同時在~/ 或專案目錄下建立 .cz-config.js 檔案, 維護你想要的格式: 比如我的配置檔案: leohxj/.cz-config
效果如下:
Commitlint: 校驗你的 message
commitlint: 可以幫助我們 lint commit messages, 如果我們提交的不符合指向的規範, 直接拒絕提交, 比較狠.
同樣的, 它也需要一份校驗的配置, 這裡推薦 @commitlint/config-conventional (符合 Angular團隊規範).
安裝:
npm i -D @commitlint/config-conventional @commitlint/cli
複製程式碼
同時需要在專案目錄下建立配置檔案 .commitlintrc.js, 寫入:
module.exports = {
extends: [
''@commitlint/config-conventional''
],
rules: {
}
};
複製程式碼
針對自定義的 Adapter 進行 Lint
如果你像我一樣, 使用的是自定義的 commitizen adapter, 那麼你需要:
npm i -D commitlint-config-cz @commitlint/cli
複製程式碼
.commitlintrc.js 中寫入:
module.exports = {
extends: [
'cz'
],
rules: {
}
};
複製程式碼
結合 Husky
校驗 commit message 的最佳方式是結合 git hook, 所以需要配合 Husky.
npm i husky@next
複製程式碼
package.json 中新增:
"husky": {
"hooks": {
...,
"commit-msg": "commitlint -e $GIT_PARAMS"
}
},
複製程式碼
效果如下:
standard-version: 自動生成 CHANGELOG
通過以上工具的幫助, 我們的工程 commit message 應該是符合 Angular團隊那套, 這樣也便於我們藉助 standard-version 這樣的工具, 自動生成 CHANGELOG, 甚至是 語義化的版本號(Semantic Version).
安裝使用:
npm i -S standard-version
複製程式碼
package.json 配置:
"scirpt": {
...,
"release": "standard-version"
}
複製程式碼
PS: standard-version 有很多其他的特性, 這裡不過多涉及, 有興趣的同學自行嘗試.
最後
commit message 的規範性很重要, 但是是否需要像本文這樣強制限制, 每個團隊和個人都有自己的想法, 但是個人認為: 好的習慣, 受益終身.