【譯】如何撰寫Git提交訊息
• Git, Commit Message
這篇筆記、翻譯自博文:How to Write a Git Commit Message,作者Chris Beams。尊重他人勞動果實,轉載請註明!
引言:為什麼好的提交訊息很重要
如果你隨意瀏覽一些Git存儲庫的日誌,你可能會發現提交訊息或多或少都亂成一團。例如,看看我早些時候向Spring提交的一些gems:
呀!相比之下,再看看這一存儲庫近些時候的提交訊息:
你更願意看到哪一種?
前者長短不一、格式各異;後者簡潔明了、前後一致。前者天然雕飾;後者精心構築。
雖然許多存儲庫日誌看起來像前者,但凡事皆有例外。Linux內核和Git本身都是很好的例子。看看Spring Boot,或任何由Tim Pope管理的存儲庫。
這些存儲庫的貢獻者們知道,一條精心撰寫的Git提交訊息是和其他開發人員就一個改動的上下文進行溝通的最佳方式(實際上也是和未來的他們自己)。一個diff會告訴你作了哪些改動,但只有提交訊息能正確地告訴你為什麼。Peter Hutterer做了很好的詮釋:
重建一段程式碼的上下文是一種浪費。我們不能完全避免,所以我們應竭盡所能去減少它、越多越好。提交訊息完全可以做到這點,因此,提交訊息顯示了這個開發人員是否是一個好的協作者。
如果你還不曾考慮過如何更好地撰寫Git提交訊息的話,這可能是因為你沒有花多少時間使用git log
和相關工具。這是一個惡性循環:因為提交歷史是結構混亂、前後矛盾的,人們不會在使用或打理它上花太多時間。而且,因為不被常用或打理,它將保持結構混亂、前後矛盾的。
但精心打理的日誌是優雅和有用的。 git blame
、revert
、rebase
、log
、shortlog
等子指令都會復活。查看其他人的提交和拉取請求成為值得做的事,並可獨立完成。理解數月或數年前所發生的原委就變得不僅可能,而且高效。
一個專案的長期成功取決於(和其他方面相比)維護工作,而對於維護人員來說、鮮有比專案日誌功能更強大的工具。花時間去學習如何正確地打理是值得的。起初可能是個麻煩、不久變成習慣,最後成為所有參與者自豪感和生產力的來源。
在這篇文章中,我將探討保持一個健康的提交歷史的最基本的要點:如何撰寫個人提交訊息。其他重要實踐如壓縮提交則不會涉及。也許我會在隨後的文章裡進行探討。
大多數編程語言都有完善的構成慣用風格的慣例,例如,命名、格式等等。當然,這些慣例千差萬別;但大多數開發者都同意:選擇一種並堅持下去、遠比各行其是而混亂不堪強的多。
一個團隊訪問提交日誌的方式應當相同。為了創建有用的修訂版本歷史記錄,團隊應首先在提交訊息的慣例上達成一致,並至少確定以下三樣事情:
樣式。標記語法、自動換行間距、語法、大小寫、標點符號。把這些東西都寫出來,而不是靠臆測,並讓這一切盡可能的簡單。最終的結果將是一個非常一致的日誌,不僅讀來引人入勝,而且確實會定期進行審閱。
內容。哪些信息應當包含在提交訊息的正文(如果有的話)中?哪些不應包含?
元資料。應當如何引用議題跟踪ID、拉取請求編號等等?
幸運的是,如何生成規範的Git提交訊息已經有完善的慣例。事實上,它們中相當一部分業已內置於Git命令中。你並不需要重新造輪子。只要遵循以下七條規則,你就可以撰寫出合乎規範的提交日誌。
好的Git提交訊息的七條規則
1.以空行隔開主題與正文
2.限制主題行長度在50個字符以內
3.主題行首字母大寫
4.主題行結尾不要使用句號
5.在主題行使用祈使語氣
6.正文在72個字符處換行
7.用正文來解釋是什麼以及為什麼,而不是怎麼樣
例如:
1.以空行隔開主題與正文
援引git commit
手冊頁:
雖然不是必需的,在提交訊息中、以簡短(少於50個字符)的一行文字來概述改動、緊接著空一行、然後再接上更為詳盡的描述,不失為一個好主意。在提交訊息中,空行前的文本被視為提交的標題,並且這個標題會在Git中到處使用。例如,git-format-patch(1)將提交轉換為電子郵件,會將標題作為主題,而提交的其餘部分則為正文。
首先,並非所有提交都需要主題正文俱全。有時單獨一行即可,特別是當改動非常簡單、並不需要上下文時。例如:
無需多言;如果讀者想知道哪裡拼寫錯了,她只需查看下改動即可,例如,使用git show
或git diff
或git log -p
。
如果你在命令列下進行類似的提交時,只需在git commit
時使用開關-m
即可:
但是,當提交需要一些解釋和上下文時,你需要撰寫正文。例如:
這時使用開關-m
進行提交就不那麼容易了。你真的需要一個適當的編輯器。如果你還沒有設置在命令列下配合Git使用的編輯器,請閱讀Pro Git的這個章節。
在任何情況下,隔開主題與正文會在瀏覽日誌時得到回報。下面是完整的日誌條目:
現在git log --oneline
,僅僅只會打印出主題行:
或者,git shortlog
,將提交以使用者進行分組,同樣也只簡潔地顯示了主題行:
區分開主題行與正文,在git中還有其他若干應用場景——但若兩者間沒有空行、它們都不會正常工作。
2.限制主題行長度在50個字符以內
50個字符並不是硬性的限制,而只是經驗法則【Rule of thumb,拇指規則,又作:經驗法則】。保持主題行在這個長度內可確保其可讀性,並迫使作者花點時間考慮下以最簡潔的方式來闡述發生了什麼。
建議:如果你難於概述主題,那可能是你一次提交了太多的改動。爭取原子提交(一個提交一個議題)。
GitHub的使用者介面充分照顧了這些慣例。如果你超過了50個字符的限制,它會給予警告:
而且、會以省略號截斷任何長度超過69個字符的主題行:
所以爭取50個字符以內,但以69為硬性限制。
3.主題行首字母大寫
這正如聽起來那麼簡單。所有主題行起始於大寫字母。
例如:
- Accelerate to 88 miles per hour
而不是:
- accelerate to 88 miles per hour
4.主題行結尾不要使用句號
主題行結尾處的標點符號是沒有必要的。再說,當你試圖將其保持在50個字符以內時,空間就很珍貴。
例如:
- Open the pod bay doors
而不是:
- Open the pod bay doors.
5.在主題行使用祈使語氣
祈使語氣僅僅表示「如發號施令般發言或書寫」。舉幾個例子:
- Clean your room
- Close the door
- Take out the trash
你現在讀到的七條規則的每一條都是以祈使語氣書寫(「正文在72個字符處換行」,等等)。
祈使語氣聽起來稍顯失禮;因而我們並不常用。但它卻很適合於Git提交的主題行。原因之一、Git本身在代替你創建提交時使用了祈使語氣。
例如,當使用git merge
時默認創建的訊息讀起來就像這樣:
而使用git revert
時:
或者點擊GitHub拉取請求上的「合併」按鈕時:
所以,當你使用祈使語氣撰寫提交訊息時,你在遵循git本身內置的慣例。例如:
- Refactor subsystem X for readability
- Update getting started documentation
- Remove deprecated methods
- Release version 1.0.0
起初這麼撰寫可能有點彆扭。我們更習慣於以陳述語氣發言、如同報告事實一般。這就是為什麼提交訊息最終讀起來經常像這樣:
- Fixed bug with Y
- Changing behavior of X
並且有時、提交訊息被撰寫成了內容的描述:
- More fixes for broken stuff
- Sweet new API methods
為了消除困惑,這裡有一條簡單的屢試不爽的規則。
格式正確的git提交的主題行應該總是能夠完成下面的句子:
- If applied, this commit will 你的主題行在這
例如:
- If applied, this commit will refactor subsystem X for readability
- If applied, this commit will update getting started documentation
- If applied, this commit will remove deprecated methods
- If applied, this commit will release version 1.0.0
- If applied, this commit will merge pull request #123 from user/branch
請注意,這對於其他非祈使語氣的格式是行不通的:
- If applied, this commit will fixed bug with Y
- If applied, this commit will changing behavior of X
- If applied, this commit will more fixes for broken stuff
- If applied, this commit will sweet new API methods
謹記:使用祈使語氣很重要這一點、僅限於主題行。當你撰寫正文時,可以放寬這個限制。
6.正文在72個字符處換行
Git從不會自動換行。當你撰寫提交訊息正文時,你得留意右邊距,並手動換行。
推薦在72個字符處換行,這樣git在保持長度在80個字符以內的同時有足夠的空間來縮進文本。
這裡一個好的文本編輯器可以有所幫助。例如,當你撰寫git提交時,配置Vim在72個字符處換行是很容易的。不過,通常IDE們對於提交訊息的文本換行所提供的智能支持都很糟糕(儘管在最近的版本中,IntelliJ IDEA 終於 變得 好多 了)。
7.用正文來解釋是什麼以及為什麼,而不是怎麼樣
來自Bitcoin Core的提交是一個解釋改動內容和原因的很好的例子:
看看完整的diff,並想想作者當時花時間去提供的這個上下文節約了同事和未來的提交者多少時間。如果他沒有這麼做,那麼它可能永遠丟失了。
在大多數情況下,你可以略去改動的具體細節。在這方面程式碼一般都是自解釋的(如果程式碼複雜到需要額外的解釋,那就是源碼註釋的工作了)。僅專注於把改動原因言明擺在首位——改動前它們如何工作(那樣有什麼問題),現在如何工作,以及為什麼你決定以這種方式解決問題。
在未來感謝你的維護者也許就是你自己!
建議
學著去熱愛命令列。把IDE丟在一邊吧。
明智的做法是去擁抱命令行,理由如git子指令那樣多。Git極其強大;IDE們同樣也是,但卻各不相同。我每天都在用IDE (IntelliJ IDEA)、其它用的也比較多 (Eclipse),但我從未見過有整合git的IDE能夠匹敵命令列的易用與強大(一旦你了解它)。
某些git相關的IDE功能是極好的,比如呼叫git rm
刪除一個檔案,以及用git
重命名檔案。當你開始嘗試通過IDE去提交、合併、重訂、或做複雜的歷史分析時,一切都將分崩離析。
當談到充分發揮git的強大功能時,那就非命令列莫屬了。
謹記,不管你用Bash或Z Shell,都有tab補齊腳本來減輕記住子指令和開關的痛苦。
閱讀Pro Git
Pro Git這本書是網上免費提供的,寫的也非常棒。好好使用吧!