代碼提交的commit info提個建議,fix的issue是哪個issue?都要有明確的鏈接。 推薦方式: 1.建立issue,說明問題的背景和原因。http://git./payment/paycenter/issues 2.提交代碼的時候commit info引入該issue 3.測試驗證回歸以后close 這個issue 這樣就可以做到每一次提交都能追根溯源。提交代碼的commit info信息是給自己看的,也是給別人看的。內(nèi)容翔實自然最好,最基本的是一定要讓別人看懂你提交的是什么。
寫issue和單元測試很浪費時間么?尤其是支付的代碼,到底是浪費時間還是節(jié)約時間。
英文原文地址 https://chris./posts/git-commit/
導(dǎo)論:為什么說commit messages 很重要
如果你翻看某個git repo的log信息,你可能會發(fā)現(xiàn)它的commit messages是一團毛線,比如,看看我在早期在Spring項目中提交的「稀世珍寶」:
$ git log --oneline -5 --author cbeams --before "Fri Mar 26 2009"
e5f4b49 Re-adding ConfigurationPostProcessorTests after its brief removal in r814. @Ignore-ing the testCglibClassesAreLoadedJustInTimeForEnhancement() method as it turns out this was one of the culprits in the recent build breakage. The classloader hacking causes subtle downstream effects, breaking unrelated tests. The test method is still useful, but should only be run on a manual basis to ensure CGLIB is not prematurely classloaded, and should not be run as part of the automated build. 2db0f12 fixed two build-breaking issues: + reverted ClassMetadataReadingVisitor to revision 794 + eliminated ConfigurationPostProcessorTests until further investigation determines why it causes downstream tests to fail (such as the seemingly unrelated ClassPathXmlApplicationContextTests) 147709f Tweaks to package-info.java files 22b25e0 Consolidated Util and MutableAnnotationUtils classes into existing AsmUtils 7f96f57 polishing
噫。比較一下最近提交的commit messages吧:
$ git log --oneline -5 --author pwebb --before "Sat Aug 30 2014"
5ba3db6 Fix failing CompositePropertySourceTests 84564a0 Rework @PropertySource early parsing logic e142fd1 Add tests for ImportSelector meta-data 887815f Update docbook dependency and generate epub ac8326d Polish mockito usage
你想讀哪一種呢?
前一種又臭又長;后一種精準一致。前一種來自「不假思索」,而后一種來自「精心組織」。
很多的repo的log信息都是前一種風(fēng)格,然而很多卻不是。比如Linux kernel 和 git 本身都是很好的例子。再看看Spring Boot項目,以及所有Tim Pope領(lǐng)導(dǎo)的項目吧。
這些項目的貢獻者都清楚,與項目開發(fā)者們(當(dāng)然也包括了自己)溝通的最好方式是構(gòu)建一個精巧的 commit messages 結(jié)構(gòu)。diff 會告訴你哪些文件改動了,但只有commit message能告訴你其中的原因。Peter Hutterer 很好地抓住了要點:
重構(gòu)代碼是很浪費時間的。這一點我們完全無法避免,所以我們應(yīng)該盡可能地減少它,commit messages 就是為了解決這個問題而誕生,而且,它能看出一個開發(fā)者是不是一個很好的合作者。
如果你還沒有好好想過一個好的commit message是什么樣子,那可能是因為你沒在git log以及相關(guān)的工具上花很多時間。有一個這樣的怪圈:因為commit的歷史沒有結(jié)構(gòu)性、連續(xù)性,沒有人使用或關(guān)注這個項目。而又因為沒有人使用、關(guān)注這個項目,commit messages的歷史一直保持著無結(jié)構(gòu)、不連續(xù)的。
但一個細心維護的log具有美感,并且能起作用。git blame, revert, rebase, log, shortlog 以及其他的子命令來源于生活。審查別人的commits,pull request是很有價值的事情,現(xiàn)在卻變成了獨立的行為。理解幾個月或幾年前這些是怎么發(fā)生的不僅是有可能的,也是有作用的。
一個項目的長時期成功依賴于它的維護性,而項目維護者找不到比項目log更有用的工具了?;〞r間學(xué)習(xí)、針對性地實踐是很有用的,萬事開頭難,但一旦成為了習(xí)慣,它會成為所有參與者榮耀和生產(chǎn)力的源泉。
在這篇博客中,我提出的是維護一個健康 commit 歷史信息的基本要素: 怎么寫一個commit message。這里我不會寫其他的重要實踐,比如commit squashing。我可能會在隨后的博文中寫這些。
大多數(shù)編程語言有固有的慣例,形成了慣用的風(fēng)格,也就是命名,格式化這些。當(dāng)然這些慣例中有很多變數(shù),但大多數(shù)程序員都同意堅持一種風(fēng)格比每個人干自己的、一片混亂要好得多。
一個團隊 commit 的方法也是一樣。為了維護一個有效的版本歷史,團隊首先要在commit message慣例上達成共識,最少要有下面的三項:
-
風(fēng)格。 標(biāo)記語法,折行長度, 語法,大寫規(guī)則,標(biāo)點符號。明確規(guī)定這些,不留下猜測空間,盡可能的簡潔。最終的結(jié)果是極其一致的log,它讓人樂于閱讀,當(dāng)然,也實現(xiàn)了基本的功能。
-
內(nèi)容。commit message的內(nèi)容應(yīng)該包含何種信息,不應(yīng)該包含何種信息。
-
元數(shù)據(jù)。 issue 的ID, pull request的數(shù)字應(yīng)該怎么記錄,索引等等。
幸運的是,有一些完善的慣例指導(dǎo)我們寫 git commit 信息。當(dāng)然,很多都是用git命令來解決的。你不需要重新造輪子。遵循下面的七條準則,你就可以像專業(yè)人士一樣commit了。
七條準則,寫給力的git commit message
記著, 這都是前人智慧
-
用空行分開主題和正文
-
限制主題在50個字母
-
主題行首字母要大寫
-
不要用句號結(jié)束主題行
-
主題行用祈使語氣
-
每行72個字
-
在正文部分解釋什么,為什么,以及怎么做的
舉個例子
用不超過50個字簡述一下有哪些改變
如果必要的話,寫更多的細節(jié)。每行不要超過72個字。第一行被視為 commit 信息以及余下正文的主題??招蟹珠_概要和正文是非常必要的(除非你不寫正文);如果你把 log, shortlog, rebase這樣的工具混著用會讓人迷惑。
解釋一下這個commit解決了什么問題。專注于為什么這么做而不是怎么做的(代碼已經(jīng)解釋了)。這個改變是否有副作用或其他不直觀的后果。這里就是解釋這些事情的地方。
空行之后還有段落。
- 要點符號也是可以的
- 通常用連字符,星號來表示要點符號。用一個空格起頭,用空行隔開,當(dāng)然,慣例沒有這么詳細
如果你用了 issue tracker, 把這些引用放在底部,就像這樣:
解決了:#123 參考: #456, #789
1. 用空行分開主題和正文
來自git commit的幫助文檔:
雖不強求,用一個單行(不超過50個字)概述一下改動,跟著一個空行,更多一點描述,這就很好。在第一個空行上的文字會被作為commit的標(biāo)題,git中會使用到。舉個例子,git-format-patch命令可以把commit轉(zhuǎn)為郵件,標(biāo)題就會作為郵件的主題,正文就會當(dāng)做郵件的正文。
首先,并不是每一個commit都需要標(biāo)題,正文。有時候一行也可以的,特別是改動比較小,不需要更多的信息的時候。舉個例子:
修改用戶導(dǎo)讀中的拼寫錯誤
不需要說太多;如果讀者想知道什么拼寫錯誤,他可以自己看改動,即,用git show,git diff 或 git log -p
如果你在命令行終端中提交,用git commit -m 就很簡單:
git commit -m"Fix typo in introduction to user guide"
但是,如果你的 commit 需要一點點解釋文字,你就需要寫正文了,比如:
Derezz the master control program
MCP turned out to be evil and had become intent on world domination. This commit throws Tron's disc into MCP (causing its deresolution) and turns it back into a chess game.
這個用 -m 就沒那么容易了。你需要一個合適的編輯器,如果你還沒有在終端中給 git 設(shè)置編輯器,讀Pro Git(https:///book/en/v2/Git-Tools-Revision-Selection#Basic-Client-Configuration)的這一章。
在任何情況下,看log的時候,主題和正文是分開的。這有個完整的log:
$ git log commit 42e769bdf4894310333942ffc5a15151222a87be Author: Kevin Flynn <kevin@flynnsarcade.com> Date: Fri Jan 01 00:00:00 1982 -0200
Derezz the master control program
MCP turned out to be evil and had become intent on world domination. This commit throws Tron's disc into MCP (causing its deresolution) and turns it back into a chess game.
如果是git log --oneline, 只輸出主題行:
$ git log --oneline 42e769 Derezz the master control program
或者,用git shortlog, 按照貢獻者分組,按行輸出主題:
$ git shortlog Kevin Flynn (1): Derezz the master control program
Alan Bradley (1): Introduce security program "Tron"
Ed Dillinger (3): Rename chess program to "MCP" Modify chess program Upgrade chess program
Walter Gibbs (1): Introduce protoype chess program
git中有一些命令可以將主題和正文區(qū)分開 ----但主題、正文沒有空行可不行。
2. 限制主題在50個字母
50個字不是硬性標(biāo)準,只是一個大致的準則。確保主題行是可讀的,讓開發(fā)者一眼就知道有哪些改變。
小技巧:如果你概述的時候發(fā)現(xiàn)很困難。可能是因為你一次 commit 太多改動了。盡可能做到 atomic commits(每次post一個主題)
GitHub 的用戶界面很注意這些慣例。如果你超過了50個字的限制它會警告你:
github_commit_changes
超過69個字的主題就會用省略號截斷:
truncate_subject
所以,盡可能不要超過50個字,把69個字符當(dāng)做上限。
3. 主題行首字母要大寫
就這么簡單。主題行首字母大寫。 比如:
4. 不要用句號結(jié)束主題行
主題行結(jié)尾的句號是不必要的。而且,要少于50個字符的話,空間是很寶貴的。
比如:
5. 主題行用祈使語氣
祈使語氣意味著,以命令或指示的語氣說話或?qū)懽?。舉幾個例子:
祈使語氣聽起來有點粗魯;所以我們不常用。但 git commit 的主題行就很合適,一個理由是:無論何時你創(chuàng)建commit,git 本身就是祈使語氣的
比如,git merge 創(chuàng)建的默認信息是:
Merge branch 'myfeature'
當(dāng)你用 git revert 時:
Revert "Add the thing with the stuff"
This reverts commit cc87791524aedd593cff5a74532befe7ab69ce9d.
在 GitHub 上pull request 點「Merge」按鈕的時候:
Merge pull request #123 from someuser/somebranch
所以,當(dāng)你以祈使語氣 commit messages 的時候,你遵循的正是 git 自身的傳統(tǒng)。 比如:
-
Refactor subsystem X for readability (重構(gòu)子系統(tǒng)X,增強可讀性)
-
Update getting started documentation (更新初始文檔)
-
Remove deprecated methods (移除將廢棄的函數(shù))
-
Release version 1.0.0 (發(fā)布 1.0.0 版本)
用這種方式一開始可能有點不適應(yīng)。我們更習(xí)慣于指示性的語氣,像是報告事實一樣。 因此,commit messages 經(jīng)常像這樣:
有時候 commit messages 只是在描述 commit 的內(nèi)容:
為了消除困惑,這有一條簡單的準則:
**一個合理格式化后的 git commit 主題行總能替換到下面的句子中: **
如果應(yīng)用了,這個 commit 會你的主題行 比如:
-
如果應(yīng)用了,這個 commit 會重構(gòu)子系統(tǒng)X,增強可讀性
-
如果應(yīng)用了,這個 commit 會更新初始文檔
-
如果應(yīng)用了,這個 commit 會移除將廢棄的函數(shù)
-
如果應(yīng)用了,這個 commit 會發(fā)布 1.0.0 版本
-
如果應(yīng)用了,這個 commit 會合并來自 user/branch 的pull request #123
注意,在非祈使的條件下就不適用了,如:
-
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 不會自動折行,當(dāng)你寫 commit message 的正文時,你必須考慮右邊的長度,人工地折行。
推薦每72個字就折行,讓 git 滿足80個字的限制的時候有足夠的空間縮進正文。
一個好的編輯器就起作用了。配置 Vim 是很簡單的, 比如,設(shè)置折行為72個字。一般來說,IDE在智能折行上表現(xiàn)就很糟糕了(在近期的版本中,IntelliJ IDEA 終于有了比較好的支持)
7. 在正文部分解釋什么,為什么,以及怎么做的
這一Bitcoin Core 的commit很好的說明了什么改動了,以及為什么改動:
commit eb0b56b19017ab5c16c745e6da39c53126924ed6 Author: Pieter Wuille <pieter.wuille@gmail.com> Date: Fri Aug 1 22:57:55 2014 +0200
Simplify serialize.h's exception handling
Remove the 'state' and 'exceptmask' from serialize.h's stream implementations, as well as related methods.
As exceptmask always included 'failbit', and setstate was always called with bits = failbit, all it did was immediately raise an exception. Get rid of those variables, and replace the setstate with direct exception throwing (which also removes some dead code).
As a result, good() is never reached after a failure (there are only 2 calls, one of which is in tests), and can just be replaced by !eof().
fail(), clear(n) and exceptions() are just never called. Delete them.
看看完整的 diff,想想這個 commit message 給隊友以及后繼的開發(fā)者節(jié)約了多少時間吧。如果他沒有這樣寫,這些變動可能就永遠都看不到了。
在大多數(shù)情況下,你可以忽略變動的細節(jié),代碼基本上是不言自明的(如果代碼很復(fù)雜,就需要文字解釋,這就需要注釋了),首先說清楚改動的原因----改動前代碼是怎么工作的(有什么問題),現(xiàn)在又是怎樣的,你為什么要解決這個問題,又是怎么解決的。
未來感謝你的軟件維護者可能就是你自己!
小技巧
享受命令行,遠離IDE
git 有很多子命令是不無理由的,擁抱命令行是明智的選擇。Git 太TM強大了;IDE 當(dāng)然也是,但每一種有不同的方式。我每天都用IDE(IntelliJ IDEA),也用其他(如Eclipse), 但我從沒見過能與強大、簡單的終端媲美的集成了git的IDE(你懂得)
誠然,集成了 git 的IDE 很難得,比如可以刪除文件時調(diào)用git rm,重命名文件是調(diào)用相關(guān)的git命令。但要完成 commit, merge, rebase,或復(fù)雜的歷史版本分析時,IDE就捉襟見肘了。
要想充分發(fā)揮 git 的威力,那就必須命令行滿屏幕飛了。
記著,不管是用 Bash 或是 Z shell,Tab 補全能讓你減輕記命令的痛苦。
讀《Pro Git》
Pro Git(https:///book/en/v2)是在線,免費的,真是極好的。好好利用!
|