Git log高級用法
BY 童仲毅(geeeeeeeeek@github)
這是一篇在原文(BY atlassian)基礎上演繹的譯文。除非另行注明,頁面上所有內容采用知識共享-署名(CC BY 2.5 AU)協議共享。
</blockquote>每一個版本控制系統的出現都是為了讓你記錄代碼的變化。你可以看到項目的歷史記錄——誰貢獻了什么、bug是什么時候引入的,還可以撤回有問題的更改。但是,首先你得知道如何使用它。這也就是為什么會有git log這個命令。
到現在為止,你應該已經知道如何用git log命令來顯示最基本的提交信息。但除此之外,你還可以傳入各種不同的參數來獲得不一樣的輸出。
git log有兩個高級用法:一是自定義提交的輸出格式,二是過濾輸出哪些提交。這兩個用法合二為一,你就可以找到你項目中你需要的任何信息。
格式化Log輸出
首先,這篇文章會展示幾種git log格式化輸出的例子。大多數例子只是通過標記向git log請求或多或少的信息。
如果你不喜歡默認的git log格式,你可以用git config的別名功能來給你想要的格式創建一個快捷方式。
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它對于獲得項目的總體情況很有幫助。
Decorate
很多時候,知道每個提交關聯的分支或者標簽很有用。--decorate標記讓git log顯示指向這個提交的所有引用(比如說分支、標簽等)。
這可以和另一個配置項一起使用。比如,執行git log --oneline --decorate會將提交歷史格式化成這樣:
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在這個例子中,你(通過HEAD標記)可以看到最上面那個提交已經被checkout了,而且它還是master分支的尾端。第二個提交有另一個feature分支指向它,以及最后那個提交帶有v0.9標簽。
分支、標簽、HEAD還有提交歷史是你Git倉庫中包含的所有信息。因此,這個命令讓你更完整地觀察項目結構。
Diff
git log提供了很多選項來顯示兩個提交之間的差異。其中最常用的兩個是--stat和-p。
--stat選項顯示每次提交的文件增刪數量(注意:修改一行記作增加一行且刪去一行),當你想要查看提交引入的變化時這會非常有用。比如說,下面這個提交在hello.py文件中增加了67行,刪去了38行。
commit f2a238924e89ca1d4947662928218a06d39068c3 Author: John <john@example.com> Date: Fri Jun 25 17:30:28 2014 -0500Add a new feature
hello.py | 105 ++++++++++++++++++++++++----------------- 1 file changed, 67 insertion(+), 38 deletions(-)</pre>
文件名后面+和-的數量是這個提交造成的更改中增刪的相對比例。它給你一個直觀的感覺,關于這次提交有多少改動。如果你想知道每次提交刪改的絕對數量,你可以將-p選項傳入git log。這樣提交所有的刪改都會被輸出:
commit 16b36c697eb2d24302f89aa22d9170dfe609855b Author: Mary <mary@example.com> Date: Fri Jun 25 17:31:57 2014 -0500Fix 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!")</pre>
對于改動很多的提交來說,這個輸出會變得又長又大。一般來說,當你輸出所有刪改的時候,你是想要查找某一具體的改動,這時你就要用到pickaxe選項。
Shortlog
git shortlog是一種特殊的git log,它是為創建發布聲明設計的。它把每個提交按作者分類,顯示提交信息的第一行。這樣可以容易地看到誰做了什么。
比如說,兩個開發者為項目貢獻了5個提交,那么git shortlog輸出會是這樣的:
Mary (2): Fix a bug in the feature Fix a serious security hole in our frameworkJohn (3): Add the initial code base Add a new feature Merge branch 'feature'</pre>
默認情況下,git shortlog把輸出按作者名字排序,但你可以傳入-n選項來按每個作者提交數量排序。
Graph
--graph選項繪制一個ASCII圖像來展示提交歷史的分支結構。它經常和--oneline和--decorate兩個選項一起使用,這樣會更容易查看哪個提交屬于哪個分支:
git log --graph --oneline --decorate For a simple repository with just 2 branches, this will produce the following:
- 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</pre>
星號表明這個提交所在的分支,所以上圖的意思是23ad9ad和16b36c6這兩個提交在topic分支上,其余的在master分支上。
雖然這對簡單的項目來說是個很好用的選擇,但你可能會更喜歡gitk或SourceTree這些更強大的可視化工具來分析大型項目。
自定義格式
對于其他的git log格式需求,你都可以使用--pretty=format:"<string>"選項。它允許你使用像printf一樣的占位符來輸出提交。
比如,下面命令中的%cn、%h和%cd這三種占位符會被分別替換為作者名字、縮略標識和提交日期。
git log --pretty=format:"%cn committed %h on %cd" This results in the following format for each commit: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</pre>
完整的占位符清單可以在文檔中找到。
除了讓你只看到關注的信息,這個--pretty=format:"<string>"選項在你想要在另一個命令中使用日志內容是尤為有用的。
過濾提交歷史
格式化提交輸出只是git log其中的一個用途。另一半是理解如何瀏覽整個提交歷史。接下來的文章會介紹如何用git log選擇項目歷史中的特定提交。所有的用法都可以和上面討論過的格式化選項結合起來。
按數量
git log最基礎的過濾選項是限制顯示的提交數量。當你只對最近幾次提交感興趣時,它可以節省你一頁一頁查看的時間。
你可以在后面加上-<n>選項。比如說,下面這個命令會顯示最新的3次提交:
git log -3按日期
如果你想要查看某一特定時間段內的提交,你可以使用--after或--before標記來按日期篩選。它們都接受好幾種日期格式作為參數。比如說,下面的命令會顯示2014年7月1日后(含)的提交:
git log --after="2014-7-1"你也可以傳入相對的日期,比如一周前("1 week ago")或者昨天("yesterday"):
get log --after="yesterday"你可以同時提供--before和--after來檢索兩個日期之間的提交。比如,為了顯示2014年7月1日到2014年7月4日之間的提交,你可以這么寫:
git log --after="2014-7-1" --before="2014-7-4"注意--since、--until標記和--after、--before標記分別是等價的。
按作者
當你只想看某一特定作者的提交的時候,你可以使用--author標記。它接受正則表達式,返回所有作者名字滿足這個規則的提交。如果你知道那個作者的確切名字你可以直接傳入文本字符串:
git log --author="John"它會顯示所有作者叫John的提交。作者名不一定是全匹配,只要包含那個子串就會匹配。
你也可以用正則表達式來創建更復雜的檢索。比如,下面這個命令檢索名叫Mary或John的作者的提交。
git log --author="John\|Mary"注意作者的郵箱地址也算作是作者的名字,所以你也可以用這個選項來按郵箱檢索。
如果你的工作流區分提交者和作者,--committer也能以相同的方式使用。
按提交信息
按提交信息來過濾提交,你可以使用--grep標記。它和上面的--author標記差不多,只不過它搜索的是提交信息而不是作者。
比如說,你的團隊規范要求在提交信息中包括相關的issue編號,你可以用下面這個命令來顯示這個issue相關的所有提交:
git log --grep="JRA-224:"你也可以傳入-i參數來忽略大小寫匹配。
按文件
很多時候,你只對某個特定文件的更改感興趣。為了顯示某個特定文件的歷史,你只需要傳入文件路徑。比如說,下面這個命令返回所有和foo.py和bar.py文件相關的提交:
git log -- foo.py bar.py--告訴git log接下來的參數是文件路徑而不是分支名。如果分支名和文件名不可能沖突,你可以省略--。
按內容
我們還可以根據源代碼中某一行的增加和刪除來搜索提交。這被稱為pickaxe,它接受形如-S"<string>"的參數。比如說,當你想要知道Hello, World!字符串是什么時候加到項目中哪個文件中去的,你可以使用下面這個命令:
git log -S "Hello, World!"如果你想用正則表達式而不是字符串來搜索,你可以使用-G"<regex>"標記。
這是一個非常強大的調試工具,它能讓你定位到所有影響代碼中特定一行的提交。它甚至可以讓你看到某一行是什么時候復制或者移動到另一個文件中去的。
按范圍
你可以傳入范圍來篩選提交。這個范圍由下面這樣的格式指定,其中<since>和<until>是提交的引用:
git log <since>..<until>這個命令在你使用分支引用作為參數時特別有用。這是顯示兩個分支之間區別最簡單的方式。看看下面這個命令:
git log master..feature其中的master..feature范圍包含了在feature分支而不在master分支中所有的提交。換句話說,這個命令可以看出從master分支fork到feature分支后發生了哪些變化。它可以這樣可視化:
注意如果你更改范圍的前后順序(feature..master),你會獲取到master分支而非feature分支上的所有提交。如果git log輸出了全部兩個分支的提交,這說明你的提交歷史已經分叉了。
過濾合并提交
git log輸出時默認包括合并提交。但是,如果你的團隊采用強制合并策略(意思是merge你修改的上游分支而不是將你的分支rebase到上游分支),你的項目歷史中會有很多外來的提交。
你可以通過--no-merges標記來排除這些提交:
git log --no-merges另一方面,如果你只對合并提交感興趣,你可以使用--merges標記:
git log --merges它會返回所有包含兩個父節點的提交。
總結
你現在應該對使用git log來格式化輸出和選擇你要顯示的提交的用法比較熟悉了。它允許你查看你項目歷史中任何需要的內容。
這些技巧是你Git工具箱中重要的部分,不過注意git log往往和其他Git命令連著使用。當你找到了你要的提交,你把它傳給git checkout、git revert或是其他控制提交歷史的工具。所以,請繼續堅持Git高級用法的學習。
這篇文章是『git-recipes』的一部分,點擊目錄查看所有章節。
如果你覺得文章對你有幫助,歡迎點擊右上角的Star
或Fork
。
如果你發現了錯誤,或是想要加入協作,請參閱Wiki協作說明。
</blockquote> 來自:https://github.com/geeeeeeeeek/git-recipes/blob/master/sources/Git_log高級用法.md