緣由
爲什麼要對commit進行規範化,每一次commit msg寫啥,又不會影響我的代碼運行?
確實,Commit的頻率和信息多少,並不會影響你代碼的執行,但是當你遇到需要上線分支中的一部分功能,想要cherry-pick的時候,就會很難受,commit msg清一色都是update xxx
,也不知道要把哪些commit 找出來。
在項目開發開發中或許我們能經常看到
- 說不出所以然的一連串的 commit 提交日誌
- commit 信息寫的很簡單,根本沒有辦法從 commit 信息中獲知該 commit 用意的
- commit 信息寫的很隨意,commit 信息和變更代碼之間不能建立聯繫的
- commit 信息寫的過於冗餘的
相信或多或少大家都曾碰到過。一旦涉及代碼回滾,issue 回溯,changelog,語義化版本發佈等操作時,你基本是無從下手的。
那,我們要做的是什麼呢?
將commit 和 代碼之間能建立起聯繫,並和相關的 issue 予以關聯,做到任何代碼都能區域性的解決問題。而 changelog,語義化版本發佈這更像是合理化 commit 後水到渠成之事。
最佳實踐
1) One Thing,One Commit;
在提交 commit 的時候儘量保證這個 commit 只做一件事情,比如實現某個功能或者修改了配置文件。
2)不要commit一半的工作;
當開發任務沒有完整的完成的時候,不要commit。這不是說每次commit都需要開發完成一個非常完整的大功能,而是當把功能切分成許多小的但仍然具備完整性的功能點的時候,開發人員需要完整完成這個功能點之後才能commit。必要時可以使用stash命令對修改進行記錄。
3)經常commit;
經常使用commit能夠使你的commit(裏的修改內容)越小,並且能使你commit相關的修改,多次commit允許你推送自己代碼到遠程分支上的頻率增加,能有效的減少merge代碼時出現的代碼衝突問題,因爲多次 commit能使你的同事的代碼庫得到及時的更新。
4)commit之前的測試;
保證你所開發的功能是完整無誤的。在commit代碼之前的對代碼充分測試是非常重要的,可以避免有問題的代碼被其他開發人員使用。
5)編寫規範的commit message;
規範的Commit Message,就是奧利給!
規範
Angular Commit 規範
參考資料:Commit message 和 Change log 編寫指南
每次提交,Commit message 都包括三個部分:Header,Body 和 Footer。
<type>(<scope>): <subject>
// 空一行
<body>
// 空一行
<footer>
Header部分只有一行,包括三個字段:type
(必需)、scope
(可選)和subject
(必需)。
Body 部分是對本次 commit 的詳細描述,可以分成多行。
Footer 部分是對不兼容變動和關聯的issue進行描述。
thoughtbot 規範
地址:https://github.com/thoughtbot/dotfiles/blob/master/gitmessage
# 50-character subject line
#
# 72-character wrapped longer description. This should answer:
#
# * Why was this change necessary?
# * How does it address the problem?
# * Are there any side effects?
#
# Include a link to the ticket, if any.
- 第一行不超過 50 個字符
- 第二行空一行
- 第三行開始是描述信息,每行長度不超過 72 個字符,超過了自己換行。
- 描述信息主要說明:
- 這個改動爲什麼是必要的?
- 這個改動解決了什麼問題?
- 會影響到哪些其他的代碼?
- 最後最好有一個相應 ticket 的鏈接
Commit 這種格式有點類似郵件,主題不超過50個字符,然後空一行,這樣顯示的下面的部分都會摺疊起來,類似下面的樣子。我們使用命令 git log --oneline的時候就只顯示第一行。
工具
參考資料:commitizen + husky 規範git提交信息
輸入提示信息
lint工具
@commitlint/config-conventional
自定義lint
捕獲commit
生成changelog
方案1
交互式提交+Commit規範
第一步:安裝
yarn add -D commitizen cz-conventional-changelog @commitlint/config-conventional @commitlint/cli husky
第二步:配置
package.json
"scripts": {
"commit":"git-cz",
},
"config":{
"commitizen":{
"path":"node_modules/cz-conventional-changelog"
}
},
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
commitlint.config.js
module.exports = {
extents:[
"@commitlint/config-conventional"
],
rules:{
'body-leading-blank': [1, 'always'],
'footer-leading-blank': [1, 'always'],
'header-max-length': [2, 'always', 72],
'scope-case': [2, 'always', 'lower-case'],
'subject-case': [
2,
'never',
['sentence-case', 'start-case', 'pascal-case', 'upper-case']
],
'subject-empty': [2, 'never'],
'subject-full-stop': [2, 'never', '.'],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
'type-enum': [
2,
'always',
[
'build',
'chore',
'ci',
'docs',
'feat',
'fix',
'improvement',
'perf',
'refactor',
'revert',
'style',
'test'
]
]
}
}
方案2
交互式提交+自定義提示文案+Commit規範
第一步:安裝
yarn add -D commitizen cz-conventional-changelog @commitlint/config-conventional @commitlint/cli commitlint-config-cz cz-customizable husky
第二步:配置
和方案1類似,只是在其基礎上修改如下配置:
package.json
"scripts": {
"commit":"git-cz",
},
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
}
},
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
commitlint.config.js
// 增加cz
{
extends: ["@commitlint/config-conventional", "cz"],
}
.cz-config.js
module.exports = {
types: [
{ value: 'init', name: 'init: 初始提交' },
{ value: 'feat', name: 'feat: 增加新功能' },
{ value: 'fix', name: 'fix: 修復bug' },
{ value: 'ui', name: 'ui: 更新UI' },
{ value: 'refactor', name: 'refactor: 代碼重構' },
{ value: 'release', name: 'release: 發佈' },
{ value: 'deploy', name: 'deploy: 部署' },
{ value: 'docs', name: 'docs: 修改文檔' },
{ value: 'test', name: 'test: 增刪測試' },
{ value: 'chore', name: 'chore: 更改配置文件' },
{ value: 'style', name: 'style: 代碼樣式修改不影響邏輯' },
{ value: 'revert', name: 'revert: 版本回退' },
{ value: 'add', name: 'add: 添加依賴' },
{ value: 'minus', name: 'minus: 版本回退' },
{ value: 'del', name: 'del: 刪除代碼/文件' }
],
scopes: [],
messages: {
type: '選擇更改類型:\n',
scope: '更改的範圍:\n',
// 如果allowcustomscopes爲true,則使用
// customScope: 'Denote the SCOPE of this change:',
subject: '簡短描述:\n',
body: '詳細描述. 使用"|"換行:\n',
breaking: 'Breaking Changes列表:\n',
footer: '關閉的issues列表. E.g.: #31, #34:\n',
confirmCommit: '確認提交?'
},
allowCustomScopes: true,
allowBreakingChanges: ["feat", "fix"]
};
交互界面
方案3
交互式提交+emoji表情包
第一步:安裝
yarn add -D commitizen cz-conventional-emoji
第二步:配置package.json,增加以下配置
"scripts": {
"commit":"git-cz",
},
"config":{
"commitizen":{
"path":"node_modules/cz-conventional-emoji"
}
},
方案4
全局模式,等同於方案1,只是cz全局安裝
第一步:安裝
# 全局安裝
npm install -g commitizen cz-conventional-changelog
# 項目內安裝
yarn add -D @commitlint/config-conventional @commitlint/cli husky
第二步:配置
.czrc
需要在全局根目錄(在命令行工具,輸入cd ~
,就可以找到)下建立.czrc文件,然後文件中輸入內容{“path”:"cz-conventional-changelog"}
或者鍵入如下命令:
echo '{"path":"cz-conventional-changelog"}' > ~/.czrc
package.json
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
commitlint.config.js 配置等同於方案1.
方案5
基於方案2再擴展
如果我們希望使用emoji,可以接受部分commitlint規範關閉,我們其實可以基於方案二直接擴展emoji。
第一步:安裝
# 全局安裝
npm install -g commitizen cz-conventional-changelog
# 項目內安裝
yarn add -D @commitlint/config-conventional @commitlint/cli commitlint-config-cz cz-customizable husky
第二步:配置
package.json
# 配置自定義commit
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
}
},
# 配置commit信息校驗
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
.czrc
需要在全局根目錄下建立.czrc文件,然後文件中輸入內容{“path”:"cz-conventional-changelog"}
或者鍵入如下命令:
echo '{"path":"cz-conventional-changelog"}' > ~/.czrc
.cz-config.js
module.exports = {
types: [
{ value: "✨feat", name: "feat: 增加新功能" },
{ value: "🐛fix", name: "fix: 修復bug" },
{ value: "📝docs", name: "docs: 修改文檔" },
{ value: "⚡️perf", name: "perf: 性能優化" },
{ value: "🎉init", name: "init: 初始提交" },
{ value: "➕add", name: "add: 添加依賴" },
{ value: "🔨build", name: "build: 打包" },
{ value: "🔧chore", name: "chore: 更改配置文件" },
{ value: "👷ci", name: "ci: CI部署" },
{ value: "🔥del", name: "del: 刪除代碼/文件" },
{ value: "♻️refactor", name: "refactor: 代碼重構" },
{ value: "⏪revert", name: "revert: 版本回退" },
{ value: "🍱style", name: "style: 樣式修改不影響邏輯" },
{ value: "✅test", name: "test: 增刪測試" },
],
scopes: [],
messages: {
type: "選擇更改類型:\n",
scope: "更改的範圍:\n",
// 如果allowcustomscopes爲true,則使用
// customScope: 'Denote the SCOPE of this change:',
subject: "簡短描述:\n",
body: '詳細描述. 使用"|"換行:\n',
breaking: "Breaking Changes列表:\n",
footer: "關閉的issues列表. E.g.: #31, #34:\n",
confirmCommit: "確認提交?",
},
allowCustomScopes: true,
allowBreakingChanges: ["feat", "fix"],
};
commitlint.config.js
module.exports = {
extends: ["@commitlint/config-conventional", "cz"],
rules: {
"body-leading-blank": [1, "always"],
"footer-leading-blank": [1, "always"],
"header-max-length": [2, "always", 72],
"scope-case": [2, "always", "lower-case"],
"subject-case": [
2,
"never",
["sentence-case", "start-case", "pascal-case", "upper-case"],
],
"subject-empty": [0],
"subject-full-stop": [2, "never", "."],
"type-case": [0],
"type-empty": [0],
"type-enum": [0],
},
};
使用
我們採用了 方案5 作爲最終方案。
本地模式
git add
後,執行 npm run commit
或者 yarn commit
,就可以開始使用了。
全局模式
git add
後,執行 git cz
,就可以開始使用了。
常用type
feat: 新功能(feature)
fix: 修改Bug
refactor: 重構(即不是新增功能,也不是修改bug的代碼變動)
docs: 文檔修改
style: 代碼格式(風格)修改, 注意不是 css 修改(不影響代碼運行的變動)
test: 測試用例修改
chore: 其他修改, 比如構建流程, 依賴管理.
standard-version
第一步:安裝
yarn add standard-version -D
第二步:配置
配置package.json
"scripts": {
"release": "standard-version"
}
第三步:運行
執行 yarn release
生成CHANGELOG.md。
參考
http://legendtkl.com/2016/12/22/git-good-practice-commit-msg/
https://juejin.im/post/5cc7be8bf265da036c579597