本文翻譯自atlassian的git教程船逮,原文地址是 git log
任何版本控制器都是用來記錄代碼的變動歷史。這能幫助你在項(xiàng)目中找到誰提交了什么代碼粤铭,bug在哪次提交被引入的挖胃,并且能幫助你回滾有問題的改動。但是,只是存儲這些信息而不知道怎么去引導(dǎo)和分類酱鸭,也是沒有用的吗垮。這就是git log這條命令被引入的原因。
你應(yīng)該已經(jīng)知道可以使用git log來展示提交歷史凹髓。但是你可能不知道烁登,通過傳入不同的參數(shù),能夠改變git log的輸出蔚舀。
git log的高級特性可以分為兩種:1.控制輸出的格式饵沧;2.控制輸出的內(nèi)容。合理使用這些高級特性能讓你找到項(xiàng)目中需要的信息赌躺。
輸出格式化
我們先來看看如何通過傳入一些參數(shù)狼牺,將git log的輸出格式化。
如果你不喜歡git log默認(rèn)的格式礼患,可以用git config創(chuàng)建一個git log的別名是钥,The git config Command
Oneline
--oneline參數(shù)將每次提交記錄匯總成一行,默認(rèn)情況下缅叠,會展示commit的id和commit信息的第一行悄泥。
git log --oneline
一個事例輸出如下
0e25143 Merge branch 'feature'
ad8621a Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad Add the initial code base
這對了解工程的大概情況很有幫助。
Decorating
很多時候需要了解每次commit的關(guān)聯(lián)的分支或者是標(biāo)簽肤粱。--decorate參數(shù)會展示每次commit對象的相關(guān)信息弹囚。
這個參數(shù)和可以和其他參數(shù)配合使用,比如领曼,使用
git log --oneline --decorate
這個命令會對輸出進(jìn)行如下格式化
0e25143 (HEAD, master) Merge branch 'feature'
ad8621a (feature) Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad (tag: v0.9) Add the initial code base
從上面的輸出可以看出余寥,第一個commit是master分支的最后一條提交(HEAD)。第二條commit有一個叫feature的分支也指向了它悯森。第4條commit被打上了v0.9的標(biāo)簽。
分支绪撵,標(biāo)簽瓢姻,HEAD,commit歷史幾乎就是你git版本庫里的信息音诈,這個命令能讓你了解項(xiàng)目完整的邏輯結(jié)構(gòu)幻碱。
Diffs
git log命令提供了很多參數(shù)用于展示每個commit的更改的信息。最常用的有--stat和-p
--stat參數(shù)將會顯示每次提交中细溅,每個文件加入和刪除的行數(shù)(修改一行等同于加入一行和刪除一行)褥傍。如果想要簡單了解每個commit大致的改動,這個參數(shù)是很有用的喇聊。舉個例子恍风,下面這個commit中,hello.py這個文件添加了67行,刪除了38行朋贬。
commit f2a238924e89ca1d4947662928218a06d39068c3
Author: John <john@example.com>
Date: Fri Jun 25 17:30:28 2014 -0500
Add a new feature hello.py | 105 ++++++++++++++++++++++++-----------------
1 file changed, 67 insertion(+), 38 deletions(-)
“+”和“-”數(shù)量顯示的是添加和刪除行數(shù)的占比凯楔。
如果想要知道改動的詳細(xì)信息,可以使用
git log -p
這個命令會將補(bǔ)丁的信息完整輸出
commit 16b36c697eb2d24302f89aa22d9170dfe609855b
Author: Mary <mary@example.com>
Date: Fri Jun 25 17:31:57 2014 -0500
Fix a bug in the feature
diff --git a/hello.py b/hello.py
index 18ca709..c673b40 100644
--- a/hello.py
+++ b/hello.py
@@ -13,14 +13,14 @@ B
-print("Hello, World!")
+print("Hello, Git!")
如果提交中包含了大量改動锦募,輸出信息可能會很長并且很復(fù)雜摆屯。通常,你會在完整的補(bǔ)丁信息中尋找特定的改動糠亩,這種情況下虐骑,可以使用pickaxe參數(shù)。
Shortlog
git shortlog是git log的一個特別版本赎线,用于生成發(fā)布的通告廷没。它會將每個開發(fā)者提交的信息匯總敲街,并且展示出來苟鸯。使用這個命令可以可以很快看到各自做的事情放典。
舉個例子极祸,如果兩個開發(fā)者提交了5次commit觉吭,git shortlog會輸出這樣的信息
Mary (2):
Fix a bug in the feature
Fix a serious security hole in our framework
John (3):
Add the initial code base
Add a new feature
Merge branch 'feature'
git shortlog默認(rèn)會按提交者名字排序有勾,也可以傳入-n參數(shù)按每個人的提交次數(shù)排序
Graphs
--graph 參數(shù)會根據(jù)分枝提交歷史繪出圖像誓竿。這個命令通常和--oneline辨泳,--decorate一起使用
git log --graph --oneline --decorate
如果版本庫中有兩個分支蓖扑,會有如下輸出
* 0e25143 (HEAD, master) Merge branch 'feature'
|\
| * 16b36c6 Fix a bug in the new feature
| * 23ad9ad Start a new feature
* | ad8621a Fix a critical security issue
|/
* 400e4b7 Fix typos in the documentation
* 160e224 Add the initial code base
*號的意思是commit在哪個分支上唉铜,所以上面的圖像告訴我們23ad9ad和16b36c6者兩個commit提交在了topic分支上,其他的commit提交在master分支上律杠。
如果代碼庫分支少潭流,這個命令還是不錯的,不過如果分支很多的話柜去,最好還是使用gitk和SourceTree這樣的工具灰嫉。
自定義格式化
可以使用--pretty=format:"<string>"來自定義輸出的格式。輸出格式有點(diǎn)像printf中的占位符嗓奢。
舉個例子讼撒,下面的命令中,%cn,%h和%cd會被提交者姓名股耽,commit的hash縮寫根盒,提交的日期占據(jù)
git log --pretty=format:"%cn committed %h on %cd"
這會產(chǎn)生如下的輸出
John committed 400e4b7 on Fri Jun 24 12:30:04 2014 -0500
John committed 89ab2cf on Thu Jun 23 17:09:42 2014 -0500
Mary committed 180e223 on Wed Jun 22 17:21:19 2014 -0500
John committed f12ca28 on Wed Jun 22 13:50:31 2014 -0500
占位符的說明可以在 Pretty Formats找到。
需要將git log信息重定向作為其他命令的輸出時物蝙,這個命令尤其有用炎滞。
過濾提交提交歷史
格式化輸出只是git log強(qiáng)大功能的一部分。git log還能夠根據(jù)需求篩選commit诬乞。下面就來看看這部分的功能册赛,上面提交的格式化功能也可以配合這部分使用钠导。
根據(jù)數(shù)量過濾
最基本的過濾就是限制輸出的commit個數(shù)。如果你只對最近的幾次commit感興趣击奶,就不用講所有commit歷史輸出辈双。
使用-<n>參數(shù)可以做到這一點(diǎn)。舉個例子柜砾,下面的命令只輸出最近3條提交
git log -3
根據(jù)日期過濾
如果想找特定時間段的提交記錄湃望,可以使用--after或者是--before參數(shù)。這兩個參數(shù)接受很多種日期格式痰驱,舉個例子证芭,下面的命令只顯示2014年7月1號后的提交
git log --after="2014-7-1"
也可以傳入相對的時間概念,像"1 week ago"担映,或者是"yesterday"
git log --after="yesterday"
如果想找某個時間區(qū)間的提交記錄废士,可以同時傳入--before和--after參數(shù)。
舉個例子蝇完,可以用下面的命令找到2014年7月1號到4號之間的提交官硝。
git log --after="2014-7-1" --before="2014-7-4"
--since,--until和--after短蜕,--before是同義的
按照提交者過濾
如果想找某個開發(fā)者提交的commit氢架,可以使用--auther參數(shù),傳入一個正則表達(dá)式朋魔,返回所有符合表達(dá)式的開發(fā)者提交的commit岖研。如果知道想找的人是誰,直接傳入字符也可以
git log --author="John"
上面的命令會篩選出所有名字里包含"John"的作者提交的commit警检。
也可以用正則來滿足更復(fù)雜的需求孙援,比如篩選出名字里包含了John和Mary的開發(fā)者的提交。
git log --author="John\|Mary"
根據(jù)commit信息過濾
使用--grep可以根據(jù)commit提交的信息過濾扇雕。這個和上面的--author差不多拓售,只不過匹配的是commit信息,比如說可以這樣
git log --grep="JRA-224:"
也可以使用-i參數(shù)忽略大小寫镶奉。
根據(jù)文件過濾
有很多時候础淤,你只對某個文件的改動感興趣。傳入文件路徑腮鞍,就能找到所有和這個文件相關(guān)的提交記錄,比如莹菱,下面的命令會篩出foo.py 和bar.py相關(guān)的提交
git log -- foo.py bar.py
-- 參數(shù)是告訴git log移国,后面?zhèn)魅氲膮?shù)是文件路徑,而不是分支的名字道伟。如果傳入的文件路徑不可能是分支名的話迹缀,可以省略掉它使碾。
根據(jù)改動過濾
根據(jù)代碼中加入或者移除的某一行代碼,也能篩選出相應(yīng)的commit祝懂。這個叫做pickaxe票摇,它接受形如-S"<string>"的參數(shù)。如果你想知道Hello, World!這行代碼是何時加入到文件中的砚蓬,可以使用下面的命令
git log -S"Hello, World!"
如果想查找匹配某個正則表達(dá)式的代碼矢门,可以傳入這樣子的參數(shù)-G"<regex>"。
這個功能在debug的時候是很有用的灰蛙,因?yàn)樗軌蚝Y選出所有影響某一行代碼的提交祟剔。它甚至能告訴你這一行代碼是什么時候移到另外一個文件中的
根據(jù)提交范圍過濾
可以傳入提交的范圍來篩選出范圍內(nèi)的commit。范圍的格式如下摩梧,其中<since>和<until>是指向某個commit
git log <since>..<until>
當(dāng)傳入分支是物延,這個命令尤其有用。比如展示兩個分支的不同仅父,命令如下
git log master..feature
master..feature范圍中包含了feature分支中所有不在master分支上的commit叛薯。換句話說,是feature分支從master分支上切出來后的進(jìn)度笙纤。如圖所示耗溜。
注意如果交換順序(即feature..master),會得到所有不在feature上的master上的commit粪糙。
過濾Merge信息
git log輸出包含merge信息强霎。但是,如果開發(fā)組總是把上游分支里的更新mege到feature分支蓉冈,而不是將feature分支rebase到上游分支城舞,就會在代碼庫中看到非常多的merge信息。
可以使用--no-merges來過濾掉這個merge信息
git log --no-merges
另一方面寞酿,如果只想看到merge信息家夺,可以使用--merges
git log --merges
總結(jié)
現(xiàn)在你應(yīng)該能夠使用git log的高級特性,來篩選commit伐弹,并且格式化輸出了拉馋。
這些技巧在使用git的時候是非常有用的,但是記住惨好,git log經(jīng)常和其他的git命令一起使用煌茴。一旦你找到了想要的commit,就可以使用git checkout日川,git revert蔓腐,或者其他的命令來控制項(xiàng)目的歷史了。所以掌握其他git的高級特性也是必要的龄句。