Git系列之git log高級命令

原文地址git

使用任何版本控制工具的目的都在於記錄你代碼的變化。這能夠給予你查看項目歷史的能力,去發現誰作出了貢獻,弄清楚什麼時候產生了bug,回滾到錯誤的修改。可是,若是你沒法定位,獲取這些歷史記錄將變得毫無心義。這也是git log命令存在的理由。正則表達式

我想你因該能用基本的git log命令來顯示提交。可是,你能夠經過向其傳入不一樣的參數來控制輸出不一樣的結果。函數

git log的高級命令能夠被分爲兩類:格式化每條commit的展現與過濾展現出的commit。總之,這兩項技能讓你回到項目的任意位置,獲取到任何你可能須要的信息。工具

格式化日誌輸出

首先,本文將會介紹一些格式化git輸出的方法。多數都以標誌的形式出現,讓你能從git日誌中獲取更多/更少的信息。學習

若是你喜歡默認的git日誌輸出格式,你可使用git config的同名函數爲下面討論的任意一種格式化選項建立縮寫。請參閱git config命令如何設置別名。spa

Oneline

--oneline 標記的做用是把每個提交信息壓縮爲一行。默認狀況下只會展現提交 ID與提交信息的首行。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

多數狀況下,瞭解每條提交與與那個分支/標籤關聯是頗有用的。--decorate 標記讓git log展現全部指向每一個提交引用(如分支,標籤等)。code

這能夠與別的控制選項一塊兒使用。如執行git log --oneline --decorate命令建輝獲得下面格式的提交歷史:orm

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被檢出(用HEAD表示)同時它也位於主分支的末端。feature分支指向第二個提交,第四個提交被標記爲v0.9。

分支,標記,HEAD與提交歷史幾乎涵蓋了你Git倉庫中的全部信息,所以這樣能夠將你倉庫的結構以一個更有邏輯的方式展現出來。

Diffs

git log命令包含了多個用於展現每一個提交差別的選項。其中最經常使用的兩個選項是 --stat-p

--stat選項經過比較每一個提交展現了插入與刪除的數量(請注意,修改將被表示爲1行插入與1行刪除)。這在你想要得到每一個提交中變化的摘要時頗有用。例如,下面的提交向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(-)

其中在文件名邊上的-+記號表明通過比較後,相關變化的數量。他讓你知曉每一個提交的變化能在那裏找到。

若是你想要查看每一個提交實際的變化,你可使用帶-p 選項的git log命令,來展現全部描述該提交的差別:

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!")

對於有大量改變的提交,結果將變的冗長。一般,若是你須要展現全部的改變,你可能在找尋一個具體的變化。爲此,你須要使用 pickaxe

短日誌

git shortlog是用於建立發佈公告的一種特殊的git log命令。按做者對每一個提交分組,並展現每一個提交信息的第一行。這種方式能很容易看出誰參與了工做。

例如,兩個開發者向一個項目貢獻了五次提交,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會按照做者的名字來排序,但你也能夠經過-n選項來按照每一個做者的提交數量排序。

Graphs

添加--graph 選項將會繪製一幅表示分支結構提交歷史的ASCII圖。該選項一般會結合--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

星號表示分支中的一條提交,所以上表能夠看出23ad9ad與16b36c6位於一個分支上,而其餘提交位於主分支上。

雖然對於小倉庫這是一個不錯的選擇,可是你可能須要在擁有繁雜分支的項目中使用更加全面的可視化工具如gitkSourceTree

自定義格式

你全部其餘的git log格式的需求,均可以使用--pretty=format:"<string>"選項來實現。這可讓你使用 printf 風格的佔位符來展現每條提交。

例如,如下命令中分別使用 %cn,%h %cd 字符來替代提交者姓名,提交哈希的縮寫以及提交的時間。

git log --pretty=format:"%cn committed %h on %cd"

上述命令將會獲得如下格式的結果:

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

關於完整的佔位符列表能夠參閱 git log 手冊 美化樣式 一節

除了能讓你查看你感興趣的信息外,--pretty=format:"<string>" 還有特別的用途即能將結果做爲參數傳給另外一個git命令。

過濾提交歷史

學會如何格式化每一個提交的顯示方式咱們已經成功了一半。另外一半是要學會如何控制提交歷史。在本文的餘下部分將會介紹一些從項目歷史中篩選出特定提交的git log高級方法。全部這些方法均可以和上述的格式化選項結合使用。

按數量輸出

最基礎的git log過濾選項就是限制輸出提交的數量。當你只在乎最近的一些提交時,它能夠幫你解決瀏覽全部提交的困擾。

經過使用 -<n> 選項能夠限制日誌的輸出數量。例以下面命令將會只展現最近三條提交:

git log -3

按日期

若是想要從某個特定的日期開始顯示提交,你可使用 --after --before 來按日期過濾提交。該參數接收多種日期格式。例以下面命令只顯示了2014年七月一日(含本日)以後建立的提交:

git log --after="2014-7-1"

你也能夠傳入像「1 week ago」或「 yesterday」這樣格式的參數:

get log --after="yesterday"

要搜索兩個時間點之間建立的提交,能夠同時提供 --before --after 日期。好比要展現在2014年七月一日到2014年七月四日之間的提交你可使用:

git log --after="2014-7-1" --before="2014-7-4"

另外,--since --after --until --before 用法一致。

按做者

當你只查看特定提交者的工做時,使用 --author 選項來過濾。該選項接受一個正則表達式,並返回全部匹配到格式的做者的提交。若是你明確地知道你須要查看誰的提交,你可使用簡單的傳統的字符串而沒必要使用正則:

git log --author="John"

這將展現全部做者名字中含「John」的提交。做者名字並不是須要徹底一致,僅須要包含便可。

經過正則表達式能夠搜索更復雜的結果。例以下面的代碼將搜索出「Mary」或「John」的提交。

git log --author="John\|Mary"

值得注意的是,做者的郵箱也被包含在做者名字中,因此也可使用該方式來按郵箱搜索。

若是您的工做流將提交者與做者分開,則須要使用 --committer 選項來到達到篩選的目的。

按消息

使用 --grep 選項來按提交信息篩選。該方法與上述 --author 一致,不過搜索內容換成了提交信息。

若是你的團隊在每一個提交信息中都包含了相關問題的編號,那麼你可使用下面命令來輸出關於該問題的提交:

git log --grep="JRA-224:"

經過 -i 參數能夠在篩選中忽略大小寫。

按文件

有些時候,你只對發生在某個特定文件中的變化感興趣時。爲了展現關於這個文件的歷史你所須要作的就是傳入文件路徑。例如,下面命令會返回影響foo.py/bar.py文件的提交:

git log -- foo.py bar.py

-- 標記用於告知git log命令隨後的參數是文件名而非分支名。若是命令中並不包含分支名,該標記也可省略。

按內容

也能夠搜索對特定代碼的添加或刪除的提交。這種採用 -S"<string>" 格式的方式被稱爲 pickaxe ,例如,你想要知道字符串「Hello, World!」被添加的提交你可使用如下命令:

git log -S"Hello, World!"

也可使用正則表達式,只須要用 -G"<regex>" 代替上述格式便可。

這是一個極其強大的糾錯工具,因其能夠定位全部影響特定代碼的提交。甚至能夠顯示覆制或移動到另外一個文件的提交。

按範圍

你能夠經過傳入一個範圍來查詢該範圍內的提交。該範圍由如下格式指定,其中<since>和<until>是提交引用:

git log <since>..<until>

當使用分支引用做爲參數時,此命令特別有用。 這是一個簡單的方法來顯示兩個分支之間的差別。 考慮如下命令:

git log master..feature

master..feature 包含全部不在主分支中的功能分支的提交。換句話說,這顯示了特性分支從主分支分離後的歷史進程。能夠用下圖理解:

圖片描述

注意若是你變換範圍種的順序(feature..master),你將獲得全部在主分支而不在特性分支上的提交。若是日誌輸出了這兩個版本的提交,則意味着你的歷史線有了分叉。

篩選合併提交

默認狀況下,日誌會輸出合併提交。可是若是你的團隊使用的是 always-merge 策略,那麼你的項目歷史中將會包含大量無用的提交。
(注: always-merge 策略指對於上游的更改合併(merge)到主題分支而非rebase)

你能夠經過 --no-merges 選項來過濾掉日誌中的合併提交:

git log --no-merges

另外,當你只對合併提交感興趣時,可使用 --merges 選項只輸出合併提交:

git log --merges

總結

如今你應該具有使用git log高級命令去按需展現日誌提交記錄的能力了。

該新技能將成爲你Git工具包中的重要組成部分,請記住git log命令常與其餘Git命令聯用。經過使用git log命令來找到你須要的提交後,經過git checkoutgit revert或其餘工具控制提交歷史。因此你要持續學習git高級命令。

相關文章
相關標籤/搜索