用 Git 和 Angular 了解語意提交信息?
讓我們解釋一下語意提交一詞, 然后演示一個(gè)提交消息案例,最后談?wù)勔?guī)范的提交信息和 Angular 約定給予我們的啟發(fā)。
許多項(xiàng)目決定通過使用約定等方式對(duì)提交信息進(jìn)行標(biāo)準(zhǔn)化。這種實(shí)踐并不新穎,最近幾年也被越來越多的使用。你很有可能之前也在某些項(xiàng)目中遇到過此類提交信息。
最早出現(xiàn)規(guī)范的項(xiàng)目之一便是 AngularJS。團(tuán)隊(duì)創(chuàng)建了詳細(xì)的文檔,詳細(xì)說明了想要達(dá)成的目標(biāo)及應(yīng)當(dāng)采用的方法。這樣約定提交的方式非常流行,你們之中的一些人也可能通過?Karma?指南了解到。但是,?jQuery,?JSHint,?Ember,?Angular 等等(受 angularJS 啟發(fā)的增強(qiáng)版提交規(guī)范)的約定也有所不同。

可以很清楚的看到上面各種的提交約定,這無疑給了標(biāo)準(zhǔn)化正式規(guī)范的一個(gè)不錯(cuò)的理由。Conventional Commits 就是這樣的規(guī)范,在實(shí)踐中,簡(jiǎn)化了 Angular 約定,并且清晰的指出了提交約定信息的要點(diǎn)。
通過這篇文章中,我們將介紹“語意提交”背后的想法,并演示具體的示例,用 Git 和 Angular 規(guī)范提交。記錄中,我們僅使用它們來闡明概念,顯然,這就意味著版本控制工具和規(guī)范由你自己來決定。
我們開始吧!????????
動(dòng)機(jī)
讓我們從定義一般術(shù)語開始:
語意提交是人類和機(jī)器都可讀的提交信息,遵循特定的約定。
這意味著,它僅僅是提交信息的指南,因此:
提交信息是具有語意性的 - 因?yàn)檫@些消息的類型都是有意義的,表達(dá)提交的本質(zhì)。
提交信息是規(guī)范的 - 因?yàn)閷?duì)于開發(fā)者和工具,這些消息均采用一致和公認(rèn)的方式進(jìn)行格式化!
此外,通常我們執(zhí)行以下操作時(shí),語意提交可能會(huì)派上用場(chǎng):
1、允許維護(hù)者和貢獻(xiàn)者清楚的瀏覽項(xiàng)目歷史記錄并了解更改的本質(zhì),同時(shí)按照提交消息類型忽略不重要的更改。
2、強(qiáng)制執(zhí)行受限的提交,從而鼓勵(lì)針對(duì)特定目的執(zhí)行小的提交。
3、提交項(xiàng)目信息明確,不會(huì)混淆措辭。
4、根據(jù)提交信息類型自動(dòng)發(fā)布軟件包版本。
5、自動(dòng)生成 CHANGLOG 并發(fā)布注釋。
總結(jié)起來,語意提交致力于實(shí)現(xiàn)更好的可讀性,效率和自動(dòng)化。
話雖如此,有些人并不認(rèn)為這些約定的信息具有可讀性或信息性,或許也有充分的理由。如果我們不需要這些額外的便利,在項(xiàng)目中強(qiáng)制執(zhí)行這樣的規(guī)范顯然也是沒有意義的!
好了,是時(shí)候了解我們?nèi)绾卧趯?shí)踐中遵循這些約定了!
免責(zé)聲明:從現(xiàn)在開始,我們將參考 Angular 提交規(guī)范信息和它的便利。
提交信息格式
Angular 規(guī)范要求按照以下結(jié)構(gòu)來調(diào)整提交信息:

上圖向我們說明了提交信息由三部分組成,分別為 Header、Body 和 Footer。
讓我們?cè)敿?xì)說明每一部分。
Header
Header 是必填項(xiàng),簡(jiǎn)單描述做出更改的目的(最多一百個(gè)字符)。
更好的是,它本身就包含三個(gè)部分。
1、Type?- 代表更改類型的簡(jiǎn)短前綴。
2、Scope - 代表更改上下文的可選信息(附加到前綴)。
3、Subject - 代表對(duì)實(shí)際更改的簡(jiǎn)潔描述。
實(shí)際上,就 Git 而言,它僅僅只是提交消息的第一行:
git commit -m "fix(core): remove deprecated and defunct wtf* apis"
我們插入一條以 : 作為分割線的單行信息。假設(shè)我們將左分區(qū)稱為“前綴” - 即 fix 和 core(受影響的軟件包)分別是 type 和 scope。另一方面,右分區(qū)顯然構(gòu)成了 subject。
簡(jiǎn)而言之,以上消息的含義是“此更改通過刪除不推薦使用和不存在的 wtf* api 修復(fù)了 Core package 中的問題”。
The Body
Body 是可選項(xiàng),它介紹了做出更改背后的動(dòng)機(jī)或者僅僅粗略描述了更詳細(xì)的信息。
讓我們以剛才的示例為例,并添加一個(gè) body。
git commit -m "fix(core): remove deprecated and defunct wtf* apis" -m "These apis have been deprecated in v8, so they should stick around till v10, but since they are defunct we are removing them early so that they don't take up payload size."
現(xiàn)在我們?cè)谙⑸显黾恿藥拙湓?,詳?xì)的說明了目的。
請(qǐng)注意以下幾點(diǎn):
我們使用多個(gè) -m 來連接段落而不是簡(jiǎn)單的行。
?Header 和 Body 應(yīng)該用空白行分割(由于段落的緣故,這顯然是正確的)。
注意:盡管我們可以用其他的方式把消息分成幾行,但為了簡(jiǎn)單起見,后面的例子中我們依然會(huì)使用多個(gè) -m (并且可以展示一個(gè)不易察覺的解決方案)。
The Footer
Footer 是一個(gè)可選項(xiàng),其中提及了更改帶來的后果,例如宣布突破性的更改,鏈接已經(jīng)解決的問題,提及貢獻(xiàn)者等等。
這里對(duì)剛剛的消息添加了頁腳:
git commit -m "fix(core): remove deprecated and defunct wtf* apis" -m "These apis have been deprecated in v8, so they should stick around till v10, but since they are defunct we are removing them early so that they don't take up payload size." -m "PR Close #33949"
在這個(gè)例子中,很明顯,我們添加了對(duì)相關(guān)拉取組件的引用,而不是其他內(nèi)容。
最后,讓我們看看完整的提交日志:

你可能會(huì)推斷,此提交實(shí)際上是在 Angular 存儲(chǔ)庫(kù)中進(jìn)行的。
常見類型
除了定義提交信息格式之外,Angular 信息提交規(guī)范還指定了一系列有用的類型,涵蓋了各種更改。
在我們開始之前,我們應(yīng)該區(qū)分兩種類型的分類。
Development - 維持變更的分類類型,以供開發(fā)人員使用,這些更改實(shí)際上并不影響生產(chǎn)環(huán)境的代碼,是開發(fā)環(huán)境的工作流程。
Production?- 變更增強(qiáng)的分類類型,針對(duì)最終用戶,僅僅影響生產(chǎn)環(huán)境的代碼。
現(xiàn)在我們來介紹和解釋這些可用的類型。
注意:以下示例直接取自 Angular 存儲(chǔ)庫(kù)的提交日志。
??build
build 類型(以前稱之為 chore )用于標(biāo)識(shí)構(gòu)建系統(tǒng)(涉及腳本、配置和方法)軟件包依賴關(guān)系相關(guān)的開發(fā)和更改。

??CI
CI? 類型用于標(biāo)示持續(xù)集成和部署系統(tǒng)相關(guān)的開發(fā)和更改 - 涉及腳本、配置和方法。

??DOSC
DOSC 類型用于標(biāo)示與項(xiàng)目相關(guān)的文檔更改 - 無論是外部供最終用戶使用(如果是庫(kù)),還是內(nèi)部供開發(fā)人員使用。

?feat
feat 類型用于標(biāo)示新版向后兼容的能力或者功能對(duì)于生產(chǎn)環(huán)境的更改。

??fix
fix 類型用于標(biāo)示與向后兼容問題修復(fù)的相關(guān)生產(chǎn)環(huán)境的更改。

???perf
perf 類型用于標(biāo)示與向后兼容性能改進(jìn)有關(guān)的生產(chǎn)環(huán)境的更改。

??refactor
refactor 類型用于標(biāo)示與修改代碼庫(kù)相關(guān)的開發(fā)環(huán)境的更改,該修改既不添加功能也不修復(fù)錯(cuò)誤 - 例如刪除冗余代碼,簡(jiǎn)化代碼,重命名變量等。

?? style
style 類型用于標(biāo)示與代碼庫(kù)樣式相關(guān)的開發(fā)環(huán)境更改,不論含義如何 - 例如縮進(jìn)、分號(hào)、尾部逗號(hào)等等。

?test
test 類型用于標(biāo)示開發(fā)環(huán)境測(cè)試相關(guān)的更改 - 例如重構(gòu)現(xiàn)有測(cè)試或添加新的測(cè)試。

Benefit
現(xiàn)在我們已經(jīng)熟悉了規(guī)范 - 讓我們來看看兩種從中受益的方法。
瀏覽記錄
Git 為我們提供了瀏覽存儲(chǔ)庫(kù)提交歷史的功能 - 因此我們能夠弄清楚實(shí)際發(fā)生了什么以及貢獻(xiàn)者等等。
讓我們看看這些約定如何簡(jiǎn)化瀏覽:
git log --oneline --grep "^feat\|^fix\|^perf"
我們對(duì)提交消息的類型進(jìn)行過濾,因此僅顯示生產(chǎn)環(huán)境的更改(所有以 feat、fix、 perf 開頭的消息)。
另一個(gè)例子:
git log --oneline --grep "^feat" | wc -l
我們只打印出 feat 類型變更的總數(shù)。
需要指出的是 - 提交消息的格式非常結(jié)構(gòu)化,我們?cè)跒g覽或過濾提交歷史記錄的時(shí)候可以有效的利用該格式。
簡(jiǎn)而言之,高效能!?????
自動(dòng)發(fā)布
提交信息的格式化對(duì)于自動(dòng)執(zhí)行發(fā)布過程的步驟同樣有效。
事實(shí)上,這是有可能的,諸如?Standard Version? 和 ?Semantic Release 等工具嚴(yán)格的遵循 Semantic Versioning?這一提交規(guī)范(Conventional Commits 和 Angular conventions respectively)。他們之間主要的區(qū)別在于方法,但是讓我們把關(guān)注點(diǎn)放在語意發(fā)布上。
因此,基于提交信息(尤其是類型)- 語意發(fā)布能夠:
切換至下一個(gè)語意包版本(當(dāng) fix 導(dǎo)致補(bǔ)丁,feat 和 perf 切換分支,以及明顯的 - 切換到主進(jìn)程)。
生成 CHANGLOG 文件并發(fā)布包含相關(guān)生產(chǎn)環(huán)境變更的說明。
為新版本創(chuàng)建 Git 標(biāo)簽。
發(fā)版和部署會(huì)排版至 npm 注冊(cè)表中。
是不是非常酷呢?
例如, lonic 的angular-toolkit?項(xiàng)目,集成了Semantic Release?用于自動(dòng)執(zhí)行發(fā)布過程(因此遵循了 Angular 約定的提交)。

我們注意到,生成了帶有正確的標(biāo)簽和說明的發(fā)行版 - 但這是自動(dòng)完成的。???
Miscellaneous
讓我們看一些東西,用于充分利用語意提交方式。
使用表情符號(hào)
將表情符號(hào)附加到提交信息中可能會(huì)進(jìn)一步提高可讀性,因?yàn)檫@樣我們可以在瀏覽歷史提交記錄中快速、輕松的識(shí)別它們。???
查看以下的鏈接:
CLI 工具
Commitizen?這種工具可以使用命令行強(qiáng)制格式化提交信息。

Linter
commitlint這種工具可以確保哪種提交信息格式符合約定。

VS Code 擴(kuò)展工具
如果你想使用自定義的VS code 擴(kuò)展名,你可能會(huì)對(duì)以下內(nèi)容感興趣。
Summary
今天我們通過遵循 Angular 提交信息約定的具體實(shí)例介紹了“語音提交”一詞,并解釋了此類消息的結(jié)構(gòu)。
要點(diǎn)匯總:
語意提交是提交有意義信息,對(duì)于開發(fā)者和工具,都要遵循特定的約定。
語意提交(及其基于工具的幫助)可以增加可讀性,效率和自動(dòng)化程度。
常規(guī)提交是一種規(guī)范,詳細(xì)說明了遵循輕量級(jí)約定的語意提交。
Angular 的指南詳細(xì)說明了遵循項(xiàng)目約定的提交,包括:
? ??????一個(gè)格式化的信息包括 header、body 和 footer。
? ? ? ? 提交類型的不同,取決于是生產(chǎn)或者開發(fā)。
在瀏覽提交歷史記錄方面,我們可以方便的從約定的提交信息中獲益。
針對(duì)自動(dòng)發(fā)布,我們也可以從約定的提交信息中獲益。
最后,無論你是否接受這樣的約定 - 你都可能偶爾遇到它們,因此請(qǐng)記住以上幾點(diǎn)。???