git commit message格式
- git每次提交代碼,都必須寫commit message(提交說明),用來說明本次提交的目的,否則不允許提交。
git commit -m "hello world"
上面代碼的-m
參數,就是用來指定commit message的。
- commit message的寫法規范有許多,本文介紹目前使用最廣的,比較合理和系統化的一種規范:Angular 規范。
一、Commit message 格式
<type>(<scope>): <subject>
<空行>
<body>
<空行>
<footer>
其中,Header 是必需的,Body 和 Footer 可以省略。
1.1 Header(第一部分)
Header部分只有一行,包括三個字段:type
(必需)、scope
(可選)、subject
(必需)
- type
type 用於說明commit的類別,允許使用以下7個標識。
feat:新功能(feature)
fix:修補bug
docs:文檔(documentation)
style: 格式(不影響代碼運行的變動)
refactor:重構(即不是新增功能,也不是修改bug的代碼變動)
test:增加測試
chore:構建過程或輔助工具的變動
- scope
scope
用於說明 commit 影響的范圍,比如數據層、控制層、視圖層等等,視項目不同而不同。
- subject
subject
是 commit 目的的簡短描述,不超過50個字符。
注意事項:
- 以動詞開頭,使用第一人稱現在時,比如change,而不是changed或changes
- 第一個字母小寫
- 結尾不加句號(.)
1.2 Body()第二部分
Body 部分是對本次 commit 的詳細描述,可以分成多行。(換行用\n)
1.3 Footer(第三部分)
Footer 部分只用於兩種情況。
- 不兼容變動
如果當前代碼與上一個版本不兼容,則 Footer 部分以BREAKING CHANGE
開頭,后面是對變動的描述、以及變動理由和遷移方法。
- 關閉Issue
如果當前 commit 針對某個issue,那么可以在 Footer 部分關閉這個 issue。
Closes #234
也可以一次關閉多個 issue 。
Closes #123, #245, #992
二、Commitizen
我們知道了提交規范,就需要通過工具生成和約束。通過借助工具commitizen/cz-cli的安裝之后,就會產生規范性的提示語句,幫助我們形成規范的commit message。
Commitizen是一個撰寫合格 Commit message 的工具。
全局安裝,命令如下:
npm install -g commitizen cz-conventional-changelog
查看是否安裝成功
npm ls -g -depth=0
全局模式下, 需要 ~/.czrc 配置文件, 為 commitizen 指定 Adapter比如: cz-conventional-changelog (一個符合 Angular團隊規范的 preset)。
echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc
安裝成功后,在對應的git項目中,凡是用到git commit
命令,一律改為使用git cz
.這時,就會出現選項,用來生成符合格式的 Commit message。
三、校驗Commit message 是否符合規范
Commitlint
commitlint用於檢查我們的commit message是否符合提交規范,如果不符合,則直接拒絕提交。
全局安裝
npm install -g @commitlint/cli @commitlint/config-conventional
生成配置文件
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
你也可以在commitlint.config.js制定提交message規范
"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']
}
};
上面我們就完成了commitlint的安裝與提交規范的制定。但檢驗commit message的最佳方式是結合git hook,所以需要配合Husky。
Husky
husky繼承了Git下所有的鈎子,在觸發鈎子的時候,husky可以阻止不合法的commit,push等等。
創建package.json文件
進入到git項目中,執行
npm init --yes
會生成項目對應項目的package.json
進入項目中,安裝husky
npm install husky
安裝成功后需要在項目的package.json中配置:
"husky": {
"hooks": {
"commit-msg": "commitlint -e $GIT_PARAMS"
}
}
然后我們正常操作git
git add .
git commit -m "test"
上面message不符合提交規范,所以會報錯如下:
起到了校驗的作用。
四、生成Change Log
如果你的所有 Commit 都符合 Angular 格式,那么發布新版本時, Change log 就可以用腳本自動生成
生成的文檔包括以下三個部分。
- New features
- Bug fixes
- Breaking changes
每個部分都會羅列相關的 commit ,並且有指向這些 commit 的鏈接。當然,生成的文檔允許手動修改,所以發布前,你還可以添加其他內容。
conventional-changelog 就是生成 Change log 的工具。
安裝changelog
npm install -g conventional-changelog
npm install -g conventional-changelog-cli
進入git項目目錄下,執行命令:
conventional-changelog -p angular -i CHANGELOG.md -s
以上命令中參數-p angular用來指定使用的 commit message 標准為angular,參數-i CHANGELOG.md表示生成的 changelog輸出到 CHANGELOG.md 文件中。
命令執行完會在項目中生成CHANGELOG.md
文件

注意:上面這條命令產生的 changelog 是基於上次 tag 版本(本地的tag版本)之后的變更(Feature、Fix、Breaking Changes等等)所產生的,如果你想生成之前所有 commit 信息產生的 changelog 則需要使用這條命令:
conventional-changelog -p angular -i CHANGELOG.md -w -r 0
由於命令過長,可以在package.json中配置scripts
{
"scripts": {
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s"
}
}
以后,直接運行下面的命令即可。
npm run changelog
standard-version 也是生成 Change log 的工具。
正常情況下,版本發布流程如下:
- git pull origin master
- 根據 pacakage.json 中的 version 更新版本號,更新 changelog
- git add -A,然后git commit
- git tag打版本操作
- push版本tag和master分支到遠程倉庫
conventional-changelog工具需要在手動修改了pacakage.json版本號,生成了changelog之后,手動commit及打tag。但standard-version工具會自動完成2、3、4項的工作。如果再配合本地的shell腳本,則可以自動的完成一系列的版本發布工作。
安裝(推薦全局安裝)
npm i -g standard-version
在package.json中配置:
"scirpt": {
...,
"release": "standard-version"
}
使用:
npm run release
最終會在git項目中生成CHANGELOG.md
文件
跟conventional-changelog生成的文件差不多。
更詳細的用法:
--first-release, -f 第一次打版本
standard-version -f
生成與package.json中版本號一致的tag。本地不能存在一樣版本號的tag。
--release-as, -r 指定版本號
默認情況下,工具會自動根據 主版本(major),次版本( minor) or 修訂版(patch) 規則生成版本號,例如如果你package.json 中的version 為 4.3.1, 那么執行后版本號則是:4.4.0。
standard-version -r minor
查看生成的tag:自動生成v4.4.0
查看提交記錄:修改已經自動提交
最后提交本地代碼與tag
git push origin master
git push origin --tags
會在github上看到提交記錄與tag。
也可以固定版本:
standard-version -r 5.0.0
standard-version -r 5.0.0-test
會生成v5.0.0和5.0.0-test版本
--prerelease, -p 預發版本命名
用來生成預發版本, 如果當期的版本號是 4.4.0,例如
standard-version -p
standard-version -p alpha
standard-version -p test
會生成v4.4.1-0、v4.4.1-alpha.0、v4.4.1-test.0。其中alpha
、test
代表預發布版本的名稱。
--tag-prefix, -t 版本 tag 前綴
默認有一個前綴v,如果不想有任何前綴,直接用-t
即可。
當前版本4.4.1
standard-version -t "stable-"
standard-version -t "test-"
生成:test-5.0.0、stable-5.1.0,其中 test
是第一次作為前綴使用,所以會生成一個主版本。
綜合使用:
standard-version -t 'stable-' -r 6.1.0
生成 stable-6.1.0
--dry-run
standard-version --dry-run
此命令會在允許你在后台查看將運行哪些步驟,不會修改package.json、changlog,也不會提交任何代碼及生成tag。可以其他命令結合使用。
standard-version -r 9.0.0 --dry-run
可用於查看該命令是否滿足你的需求。
Lifecycle scripts 生命周期腳本
standard-version支持生命周期腳本。這些腳本允許你在發布期間去執行自己的補充命令。以下為生命周期的鈎子,並按照文檔順序執行:
prerelease
: executed before anything happens. If the prerelease script returns a non-zero exit code, versioning will be aborted, but it has no other effect on the process.prebump
/postbump
: executed before and after the version is bumped. If the prebump script returns a version #, it will be used rather than the version calculated by standard-version.prechangelog
/postchangelog
: executes before and after the CHANGELOG is generated.precommit
/postcommit
: called before and after the commit step.pretag
/posttag
: called before and after the tagging step.
在package.json中配置lifecycle scripts:
{
"standard-version": {
"scripts": {
"prebump": "echo 1.2.0"
}
}
}
執行standard-version
會生成v1.2.0的版本。
跳過生命周期步驟(Skipping lifecycle steps)
You can skip any of the lifecycle steps (bump, changelog, commit, tag), by adding the following to your package.json:
{
"standard-version": {
"skip": {
"changelog": true
}
}
}