Git 每次提交代碼, 都要寫 Commit message (提交說明), 否則就不允許提交
$ git commit -m "hello world"
上面的命令的-m參數(shù),就是用來指定 commit mesage 的, 如果一行不夠, 可以只執(zhí)行g(shù)it commit, 就會(huì)跳出文本編譯器, 讓你寫多行
$ git commit
基本上, 寫什么都行(Commit Logs From Last Night,Funny initial git commit messages和fixed errors in the previous commit )

但是, 一般來說, commit message 應(yīng)該清晰明了, 說明本次提交的目的

目前, 社區(qū)有多種 Commit message 的寫法規(guī)范, 此次介紹Angular 規(guī)范 ( 見上圖 ) , 這是目前使用最廣的寫法, 比較合理和系統(tǒng)化, 并且有配套的工具
</br>
一、Commit message 的作用
格式化的Commit message,有幾個(gè)好處
(1)提供更多的歷史信息,方便快速瀏覽
比如, 下面的命令顯示上次發(fā)布后的變動(dòng), 每個(gè)commit占據(jù)一行. 你只看行首, 就知道某次 commit 的目的
$ git log <last tag> HEAD --pretty=format:%s

(2)可以過濾某些commit(比如文檔改動(dòng)), 便于快速查找信息
比如, 下面的命令僅僅顯示本次發(fā)布新增加的功能
$ git log <last release> HEAD --grep feature
(3)可以直接從commit生成Change log
Change Log 是發(fā)布新版本時(shí), 用來說明與上一個(gè)版本差異的文檔, 詳見后文

二、Commit message 的格式
每次提交,Commit message 都包括三個(gè)部分:Header,Body 和Footer
<type>(<scope>): <subject>// 空一行<body>// 空一行<footer>
其中, Header 是必需的, Body 和 Footer 可以省略不管是哪一個(gè)部分, 任何一行都不得超過72個(gè)字符(或100個(gè)字符), 這是為了避免自動(dòng)換行影響美觀
2.1 Header
Header部分只有一行,包括三個(gè)字段:type(必需)、scope(可選)和subject(必需)
(1)type
type用于說明 commit 的類別,只允許使用下面7個(gè)標(biāo)識
feat:新功能(feature)
fix:修補(bǔ)bug
docs:文檔(documentation)
style: 格式(不影響代碼運(yùn)行的變動(dòng))
refactor:重構(gòu)(即不是新增功能,也不是修改bug的代碼變動(dòng))
test:增加測試
chore:構(gòu)建過程或輔助工具的變動(dòng)
如果type為feat和fix,則該 commit 將肯定出現(xiàn)在 Change log 之中. 其他情況(docs、chore、style、refactor、test)由你決定,要不要放入 Change log,建議是不要。
(2)scope
scope用于說明commit 影響的范圍,比如數(shù)據(jù)層、控制層、視圖層等等,視項(xiàng)目不同而不同。
(3)subject
subject 是 commit 目的的簡短描述,不超過50個(gè)字符以動(dòng)詞開頭,使用第一人稱現(xiàn)在時(shí),比如change , 而不是 changed 或 changes 第一個(gè)字母小寫, 結(jié)尾不加句號(.)
2.2 Body
Body 部分是對本次 commit 的詳細(xì)描述, 可以分成多行. 下面是一個(gè)范例
More detailed explanatory text, if necessary. Wrap it to about 72 characters or so. Further paragraphs come after blank lines.- Bullet points are okay, too- Use a hanging indent
有兩個(gè)注意點(diǎn):
(1)使用第一人稱現(xiàn)在時(shí), 比如使用change, 而不是changed或changes
(2)應(yīng)該說明代碼變動(dòng)的動(dòng)機(jī). 以及與以前行為的對比
2.3 Footer
Footer 部分只用于兩種情況。
(1)不兼容變動(dòng)
如果當(dāng)前代碼與上一個(gè)版本不兼容,則 Footer 部分以BREAKING CHANGE
開頭,后面是對變動(dòng)的描述、以及變動(dòng)理由和遷移方法。
BREAKING CHANGE: isolate scope bindings definition has changed. To migrate the code follow the example below: Before: scope: { myAttr: 'attribute', } After: scope: { myAttr: '@', } The removed
injectwasn't generaly useful for directives so there should be no code using it.
(2)關(guān)閉 Issue
如果當(dāng)前 commit 針對某個(gè)issue, 那么可以在 Footer 部分關(guān)閉這個(gè) issue
Closes #234
也可以一次關(guān)閉多個(gè) issue
Closes #123, #245, #992
2.4 Revert
還有一種特殊情況,如果當(dāng)前 commit 用于撤銷以前的 commit,則必須以revert:開頭,后面跟著被撤銷 Commit 的 Header。
revert: feat(pencil): add 'graphiteWidth' optionThis reverts commit 667ecc1654a317a13331b17617d973392f415f02.
Body部分的格式是固定的,必須寫成This reverts commit <hash>.其中的hash 是被撤銷 commit 的 SHA 標(biāo)識符。
如果當(dāng)前 commit 與被撤銷的 commit,在同一個(gè)發(fā)布(release)里面,那么它們都不會(huì)出現(xiàn)在 Change log 里面。如果兩者在不同的發(fā)布,那么當(dāng)前commit,會(huì)出現(xiàn)在 Change log 的Reverts 小標(biāo)題下面。
三、Commitizen
Commitizen是一個(gè)撰寫合格 Commit message 的工具。
安裝命令如下。
$ npm install -g commitizen
然后,在項(xiàng)目目錄里,運(yùn)行下面的命令,使其支持 Angular 的 Commit message 格式。
$ commitizen init cz-conventional-changelog --save --save-exact
以后,凡是用到git commit 命令,一律改為使用git cz。這時(shí),就會(huì)出現(xiàn)選項(xiàng),用來生成符合格式的 Commit message。

四、validate-commit-msg
validate-commit-msg 用于檢查 Node 項(xiàng)目的 Commit message 是否符合格式。
它的安裝是手動(dòng)的。首先,拷貝下面這個(gè)JS文件,放入你的代碼庫。文件名可以取為validate-commit-msg.js。
接著,把這個(gè)腳本加入 Git 的 hook。下面是在package.json 里面使用 ghooks,把這個(gè)腳本加為commit-msg 時(shí)運(yùn)行。
"config": { "ghooks": { "commit-msg": "./validate-commit-msg.js" } }
然后,每次git commit 的時(shí)候,這個(gè)腳本就會(huì)自動(dòng)檢查 Commit message 是否合格。如果不合格,就會(huì)報(bào)錯(cuò)。
$ git add -A
$ git commit -m "edit markdown" INVALID COMMIT MSG: does not match "<type>(<scope>): <subject>" ! was: edit markdown
五、生成 Change log
如果你的所有 Commit 都符合 Angular 格式,那么發(fā)布新版本時(shí), Change log 就可以用腳本自動(dòng)生成(例1,例2,例3)。生成的文檔包括以下三個(gè)部分。
- New features
- Bug fixes
- Breaking changes.
每個(gè)部分都會(huì)羅列相關(guān)的 commit ,并且有指向這些 commit 的鏈接。當(dāng)然,生成的文檔允許手動(dòng)修改,所以發(fā)布前,你還可以添加其他內(nèi)容。
conventional-changelog 就是生成 Change log 的工具,運(yùn)行下面的命令即可。
$ npm install -g conventional-changelog
$ cd my-project
$ conventional-changelog -p angular -i CHANGELOG.md -w
上面命令不會(huì)覆蓋以前的 Change log,只會(huì)在CHANGELOG.md 的頭部加上自從上次發(fā)布以來的變動(dòng)。
如果你想生成所有發(fā)布的 Change log,要改為運(yùn)行下面的命令。
$ conventional-changelog -p angular -i CHANGELOG.md -w -r 0
為了方便使用,可以將其寫入package.json的 scripts 字段。
{ "scripts": { "changelog": "conventional-changelog -p angular -i CHANGELOG.md -w -r 0" }}
以后,直接運(yùn)行下面的命令即可。
$ npm run changelog