簡體中文 ▾ 主題 ▾ 最新版本 ▾ git-log 最後更新於 2.50.0

名稱

git-log - 顯示提交日誌

概要

git log [<options>] [<revision-range>] [[--] <path>…​]

描述

顯示提交日誌。

列出透過遵循給定提交的 parent 連結可達的提交,但排除那些前面帶有 ^ 的提交可達的提交。預設情況下,輸出按倒序時間順序給出。

你可以將其視為一個集合操作。從命令列上給出的任何提交可達的提交形成一個集合,然後從前面帶有 ^ 的提交可達的提交將從該集合中減去。剩餘的提交就是命令的輸出結果。還可以使用各種其他選項和路徑引數來進一步限制結果。

因此,以下命令

$ git log foo bar ^baz

表示“列出所有可從 foobar 到達,但不可從 baz 到達的提交”。

特殊符號“<commit1>..<commit2>”可用作“^<commit1> <commit2>”的簡寫。例如,以下任一形式都可以互換使用

$ git log origin..HEAD
$ git log HEAD ^origin

另一個特殊符號是“<commit1>…​<commit2>”,這對於合併很有用。產生的提交集合是兩個運算元之間的對稱差異。以下兩個命令是等效的

$ git log A B --not $(git merge-base --all A B)
$ git log A...B

此命令接受適用於 git-rev-list[1] 命令的選項,以控制顯示內容和方式,以及適用於 git-diff[1] 命令的選項,以控制如何顯示每個提交引入的更改。

選項

--follow

繼續列出檔案重新命名後的歷史(僅適用於單個檔案)。

--no-decorate
--decorate[=short|full|auto|no]

打印出所顯示任何提交的引用名稱。如果指定 short,則不列印引用名稱字首 refs/heads/refs/tags/refs/remotes/。如果指定 full,則列印完整的引用名稱(包括字首)。如果指定 auto,則如果輸出到終端,引用名稱將像指定 short 一樣顯示,否則不顯示引用名稱。選項 --decorate--decorate=short 的簡寫。如果已配置,則預設為 log.decorate 的配置值,否則預設為 auto

--decorate-refs=<pattern>
--decorate-refs-exclude=<pattern>

對於每個候選引用,如果它與提供給 --decorate-refs-exclude 的任何模式匹配,或者它不與提供給 --decorate-refs 的任何模式匹配,則不將其用於裝飾。log.excludeDecoration 配置選項允許從裝飾中排除引用,但顯式的 --decorate-refs 模式將覆蓋 log.excludeDecoration 中的匹配項。

如果沒有給出這些選項或配置設定,那麼如果引用匹配 HEADrefs/heads/refs/remotes/refs/stash/refs/tags/,則將它們用作裝飾。

--clear-decorations

指定此選項時,它會清除所有以前的 --decorate-refs--decorate-refs-exclude 選項,並放寬預設裝飾過濾器以包含所有引用。如果配置值 log.initialDecorationSet 設定為 all,則假定此選項。

--source

打印出命令列上給出的、透過它到達每個提交的引用名稱。

--[no-]mailmap
--[no-]use-mailmap

使用 mailmap 檔案將作者和提交者姓名及電子郵件地址對映到規範的真實姓名和電子郵件地址。參見 git-shortlog[1]

--full-diff

如果沒有此標誌,git log -p <path>... 會顯示修改了指定路徑的提交,以及關於相同指定路徑的差異。有了此標誌,對於修改了指定路徑的提交,將顯示完整的差異;這意味著“<path>…”只限制提交,而不限制這些提交的差異。

請注意,這會影響所有基於差異的輸出型別,例如 --stat 等產生的輸出。

--log-size

在每個提交的輸出中包含一行“log size <number>”,其中 <number> 是該提交訊息的位元組長度。旨在透過允許工具預先分配空間來加快從 git log 輸出中讀取日誌訊息的工具的速度。

-L<start>,<end>:<file>
-L:<funcname>:<file>

跟蹤由 <start>,<end> 或函式名正則表示式 <funcname><file> 中給出的行範圍的演變。您不能給出任何路徑規範限制符。這目前僅限於從單個修訂開始的遍歷,即,您只能給出零個或一個正修訂引數,並且 <start><end>(或 <funcname>)必須存在於起始修訂中。您可以多次指定此選項。這意味著 --patch。補丁輸出可以使用 --no-patch 抑制,但其他差異格式(即 --raw--numstat--shortstat--dirstat--summary--name-only--name-status--check)目前尚未實現。

<start><end> 可以採用以下形式之一

  • 數字

    如果 <start><end> 是一個數字,它指定一個絕對行號(行從 1 開始計數)。

  • /正則表示式/

    此形式將使用與給定 POSIX 正則表示式匹配的第一行。如果 <start> 是一個正則表示式,它將從上一個 -L 範圍的末尾開始搜尋(如果存在),否則從檔案開頭開始搜尋。如果 <start>^/regex/,它將從檔案開頭開始搜尋。如果 <end> 是一個正則表示式,它將從 <start> 給定的行開始搜尋。

  • +偏移量 或 -偏移量

    這僅對 <end> 有效,並將指定 <start> 給定行之前或之後的行數。

如果用 :<funcname> 替換 <start><end>,它是一個正則表示式,表示從第一個匹配 <funcname> 的函式名行到下一個函式名行的範圍。:<funcname> 從上一個 -L 範圍的末尾開始搜尋(如果存在),否則從檔案開頭開始搜尋。^:<funcname> 從檔案開頭開始搜尋。函式名確定方式與 git diff 處理補丁塊頭(參見 gitattributes[5]Defining a custom hunk-header)的方式相同。

<revision-range>

僅顯示指定修訂範圍內的提交。如果沒有指定 <revision-range>,則預設為 HEAD(即,導致當前提交的整個歷史記錄)。origin..HEAD 指定了從當前提交(即 HEAD)可達的所有提交,但不包括從 origin 可達的提交。有關拼寫 <revision-range> 的完整列表,請參閱 gitrevisions[7]Specifying Ranges 部分。

[--] <path>…​

只顯示足以解釋指定路徑匹配檔案是如何產生的提交。有關詳細資訊和其他簡化模式,請參見下面的 History Simplification

當出現混淆時,路徑可能需要在前面加上 --,以將其與選項或修訂範圍分開。

提交限制

除了使用描述中解釋的特殊符號指定應列出的提交範圍外,還可以應用額外的提交限制。

使用更多選項通常會進一步限制輸出(例如,--since=<date1> 將限制為比 <date1> 更新的提交,將其與 --grep=<pattern> 一起使用會進一步限制為日誌訊息中包含與 <pattern> 匹配的行的提交),除非另有說明。

請注意,這些是在提交排序和格式化選項(如 --reverse)之前應用的。

-<number>
-n <number>
--max-count=<number>

限制輸出的提交數量。

--skip=<number>

在開始顯示提交輸出之前跳過 number 個提交。

--since=<date>
--after=<date>

顯示特定日期之後的所有提交。

--since-as-filter=<date>

顯示特定日期之後的所有提交。這將遍歷範圍內的所有提交,而不是在遇到第一個位元定日期更舊的提交時停止。

--until=<date>
--before=<date>

顯示特定日期之前的所有提交。

--author=<pattern>
--committer=<pattern>

限制提交輸出為作者/提交者頭行與指定模式(正則表示式)匹配的提交。當有多個 --author=<pattern> 時,選擇作者匹配任何給定模式的提交(多個 --committer=<pattern> 同理)。

--grep-reflog=<pattern>

限制提交輸出為引用日誌條目與指定模式(正則表示式)匹配的提交。當有多個 --grep-reflog 時,選擇引用日誌訊息匹配任何給定模式的提交。除非使用 --walk-reflogs,否則使用此選項是錯誤的。

--grep=<pattern>

限制提交輸出為日誌訊息與指定模式(正則表示式)匹配的提交。當有多個 --grep=<pattern> 時,選擇訊息匹配任何給定模式的提交(但請參閱 --all-match)。

--notes 生效時,來自備註的訊息將像日誌訊息的一部分一樣進行匹配。

--all-match

限制提交輸出為匹配所有給定 --grep 的提交,而不是匹配至少一個的提交。

--invert-grep

限制提交輸出為日誌訊息不匹配由 --grep=<pattern> 指定的模式的提交。

-i
--regexp-ignore-case

匹配正則表示式限制模式時不區分字母大小寫。

--basic-regexp

將限制模式視為基本正則表示式;這是預設設定。

-E
--extended-regexp

將限制模式視為擴充套件正則表示式,而不是預設的基本正則表示式。

-F
--fixed-strings

將限制模式視為固定字串(不將模式解釋為正則表示式)。

-P
--perl-regexp

將限制模式視為 Perl 相容的正則表示式。

對這些型別的正則表示式的支援是一個可選的編譯時依賴項。如果 Git 在編譯時沒有支援這些功能,則提供此選項將導致其停止執行。

--remove-empty

當給定路徑從樹中消失時停止。

--merges

只打印合並提交。這與 --min-parents=2 完全相同。

--no-merges

不列印具有多個父提交的提交。這與 --max-parents=1 完全相同。

--min-parents=<number>
--max-parents=<number>
--no-min-parents
--no-max-parents

只顯示至少(或至多)具有那麼多父提交的提交。特別是,--max-parents=1--no-merges 相同,--min-parents=2--merges 相同。--max-parents=0 顯示所有根提交,--min-parents=3 顯示所有章魚合併。

--no-min-parents--no-max-parents 再次重置這些限制(無限制)。等效形式是 --min-parents=0(任何提交都有 0 個或更多父提交)和 --max-parents=-1(負數表示無上限)。

--first-parent

在查詢要包含的提交時,遇到合併提交時只遵循第一個父提交。此選項在檢視特定主題分支的演變時可以提供更好的概覽,因為合併到主題分支通常只是為了適應上游的更新,此選項允許您忽略此類合併帶入您歷史中的單個提交。

此選項還會將合併提交的預設差異格式更改為 first-parent,詳細資訊請參閱 --diff-merges=first-parent

--exclude-first-parent-only

在查詢要排除的提交(帶 ^)時,遇到合併提交時只遵循第一個父提交。這可用於查詢主題分支中從其與遠端分支分歧點開始的更改集,因為任意合併都可以是有效的主題分支更改。

--not

反轉所有後續修訂說明符的 ^ 字首(或其缺失)的含義,直到下一個 --not。在命令列上 --stdin 之前使用時,透過標準輸入傳遞的修訂不受其影響。反之,當透過標準輸入傳遞時,命令列上傳遞的修訂不受其影響。

--all

假裝 refs/ 中的所有引用以及 HEAD 都作為 <commit> 列在命令列上。

--branches[=<pattern>]

假裝 refs/heads 中的所有引用都作為 <commit> 列在命令列上。如果給定 <pattern>,則將分支限制為匹配給定 shell glob 的分支。如果模式缺少 ?*[,則隱含末尾的 /*

--tags[=<pattern>]

假裝 refs/tags 中的所有引用都作為 <commit> 列在命令列上。如果給定 <pattern>,則將標籤限制為匹配給定 shell glob 的標籤。如果模式缺少 ?*[,則隱含末尾的 /*

--remotes[=<pattern>]

假裝 refs/remotes 中的所有引用都作為 <commit> 列在命令列上。如果給定 <pattern>,則將遠端跟蹤分支限制為匹配給定 shell glob 的分支。如果模式缺少 ?*[,則隱含末尾的 /*

--glob=<glob-pattern>

假裝所有匹配 shell glob <glob-pattern> 的引用都作為 <commit> 列在命令列上。如果缺少前導 refs/,則會自動新增。如果模式缺少 ?*[,則隱含末尾的 /*

--exclude=<glob-pattern>

不包含與 <glob-pattern> 匹配的引用,否則下一個 --all--branches--tags--remotes--glob 將會考慮這些引用。此選項的重複使用會累積排除模式,直到下一個 --all--branches--tags--remotes--glob 選項(其他選項或引數不會清除累積的模式)。

給定模式應用於 --branches--tags--remotes 時,不應以 refs/headsrefs/tagsrefs/remotes 開頭;應用於 --glob--all 時,必須以 refs/ 開頭。如果意圖使用尾隨的 /*,則必須明確給出。

--exclude-hidden=[fetch|receive|uploadpack]

透過查閱相應的 fetch.hideRefsreceive.hideRefsuploadpack.hideRefs 配置以及 transfer.hideRefs(參見 git-config[1]),不包含會被 git-fetchgit-receive-packgit-upload-pack 隱藏的引用。此選項影響下一個偽引用選項 --all--glob,並在處理它們後清除。

--reflog

假裝引用日誌中提及的所有物件都作為 <commit> 列在命令列上。

--alternate-refs

假裝所有在備用倉庫中作為引用尖端提及的物件都列在命令列上。備用倉庫是指其物件目錄在 objects/info/alternates 中指定的任何倉庫。包含的物件集可能會被 core.alternateRefsCommand 等修改。參見 git-config[1]

--single-worktree

預設情況下,當存在多個工作樹時(參見 git-worktree[1]),以下選項將檢查所有工作樹:--all--reflog--indexed-objects。此選項強制它們只檢查當前工作樹。

--ignore-missing

在輸入中遇到無效物件名稱時,假裝沒有給出錯誤的輸入。

--bisect

假裝壞的二分查詢引用 refs/bisect/bad 已列出,並且其後跟著 --not 和好的二分查詢引用 refs/bisect/good-* 在命令列上。

--stdin

除了從命令列獲取引數外,也從標準輸入讀取引數。這接受提交和偽選項,如 --all--glob=。當看到 -- 分隔符時,後續輸入將被視為路徑並用於限制結果。透過標準輸入讀取的標誌(如 --not)僅對以相同方式傳遞的引數有效,並且不會影響任何後續命令列引數。

--cherry-mark

類似於 --cherry-pick(見下文),但用 = 標記等效提交而不是省略它們,用 + 標記不等效提交。

--cherry-pick

當提交集合透過對稱差異限制時,省略與“另一側”的另一個提交引入相同更改的任何提交。

例如,如果您有兩個分支,AB,列出其中一側的所有提交的常用方法是使用 --left-right(參見下面 --left-right 選項描述中的示例)。但是,它會顯示從另一個分支揀選(cherry-picked)的提交(例如,“b 上的第 3 個”可能是從分支 A 揀選的)。使用此選項,此類成對的提交將從輸出中排除。

--left-only
--right-only

只列出對稱差異各自一側的提交,即,只有那些會被 --left-right 標記為 <> 的提交。

例如,--cherry-pick --right-only A...B 會省略 B 中那些在 A 中或與 A 中某個提交補丁等效的提交。換句話說,這列出了 git cherry A B 中的 + 提交。更精確地說,--cherry-pick --right-only --no-merges 給出了確切的列表。

--cherry

它是 --right-only --cherry-mark --no-merges 的同義詞;有助於將輸出限制在己方提交,並用 git log --cherry upstream...mybranch 標記那些已應用於分叉歷史另一側的提交,類似於 git cherry upstream mybranch

-g
--walk-reflogs

不遍歷提交祖先鏈,而是從最新引用日誌條目遍歷到較舊條目。使用此選項時,不能指定要排除的提交(即,不能使用 ^commitcommit1..commit2commit1...commit2 符號)。

除了 onelinereference 之外(出於顯而易見的原因),使用 --pretty 格式時,這將導致輸出包含取自引用日誌的兩行額外資訊。輸出中的引用日誌指示符可以顯示為 ref@{<Nth>}(其中 <Nth> 是引用日誌中的倒序時間索引)或顯示為 ref@{<timestamp>}(帶有該條目的 <timestamp>),具體取決於一些規則

  1. 如果起始點指定為 ref@{<Nth>},則顯示索引格式。

  2. 如果起始點指定為 ref@{now},則顯示時間戳格式。

  3. 如果兩者都未用,但命令列上給出了 --date,則以 --date 請求的格式顯示時間戳。

  4. 否則,顯示索引格式。

--pretty=oneline 模式下,提交訊息會與此資訊字首在同一行。此選項不能與 --reverse 結合使用。另請參見 git-reflog[1]

--pretty=reference 模式下,此資訊將完全不顯示。

--merge

顯示範圍 HEAD...<other> 中涉及衝突路徑的提交,其中 <other>MERGE_HEADCHERRY_PICK_HEADREVERT_HEADREBASE_HEAD 中第一個存在的偽引用。僅當索引有未合併條目時有效。此選項可用於在解決三向合併衝突時顯示相關提交。

--boundary

輸出排除的邊界提交。邊界提交字首為 -

歷史簡化

有時您只對歷史的一部分感興趣,例如修改特定 <path> 的提交。但是歷史簡化有兩部分,一部分是選擇提交,另一部分是如何進行,因為有各種策略可以簡化歷史。

以下選項選擇要顯示的提交

<paths>

選擇修改給定 <paths> 的提交。

--simplify-by-decoration

選擇被某些分支或標籤引用的提交。

請注意,可以顯示額外的提交以提供有意義的歷史記錄。

以下選項影響簡化執行的方式

預設模式

將歷史簡化為解釋樹最終狀態的最簡單歷史。之所以最簡單,是因為如果最終結果相同(即合併內容相同的分支),它會修剪一些旁支。

--show-pulls

包含預設模式中的所有提交,但也包括任何與第一個父提交不 TREESAME 但與較晚的父提交 TREESAME 的合併提交。此模式有助於顯示“首次引入”更改到分支的合併提交。

--full-history

與預設模式相同,但不會修剪某些歷史。

--dense

只顯示選定的提交,以及一些具有有意義歷史的提交。

--sparse

顯示簡化歷史中的所有提交。

--simplify-merges

--full-history 的附加選項,用於從結果歷史中刪除一些不必要的合併,因為沒有選定的提交對此合併有所貢獻。

--ancestry-path[=<commit>]

當給定一個要顯示的提交範圍(例如 commit1..commit2commit2 ^commit1),以及該範圍內的提交 <commit> 時,只顯示該範圍內是 <commit> 的祖先、後代或 <commit> 本身的提交。如果未指定提交,則使用 commit1(範圍中被排除的部分)作為 <commit>。可以多次傳遞;如果是,如果提交是給定提交中的任何一個,或者它是其中一個的祖先或後代,則包含該提交。

更詳細的解釋如下。

假設您指定 foo 作為 <paths>。我們將修改 foo 的提交稱為 !TREESAME,其餘的稱為 TREESAME。(在為 foo 過濾的差異中,它們分別看起來不同和相同。)

在下文中,我們將始終引用相同的歷史示例來闡述簡化設定之間的差異。我們假設您正在此提交圖中過濾檔案 foo

	  .-A---M---N---O---P---Q
	 /     /   /   /   /   /
	I     B   C   D   E   Y
	 \   /   /   /   /   /
	  `-------------'   X

歷史記錄的水平線 A---Q 被視為每個合併的第一個父級。提交是

  • I 是初始提交,其中 foo 存在內容為“asdf”,檔案 quux 存在內容為“quux”。初始提交與空樹進行比較,因此 I 為 !TREESAME。

  • A 中,foo 只包含“foo”。

  • B 包含與 A 相同的更改。其合併 M 是微不足道的,因此與所有父級 TREESAME。

  • C 沒有改變 foo,但其合併 N 將其更改為“foobar”,因此它與任何父級都不是 TREESAME。

  • Dfoo 設定為“baz”。其合併 OND 中的字串組合為“foobarbaz”;即,它與任何父級都不是 TREESAME。

  • Equux 更改為“xyzzy”,其合併 P 將字串組合為“quux xyzzy”。PO 是 TREESAME,但與 E 不是。

  • X 是一個獨立的根提交,它添加了一個新檔案 sideY 修改了它。YX 是 TREESAME。其合併 Qside 新增到 PQP 是 TREESAME,但與 Y 不是。

rev-list 倒序遍歷歷史,根據是否使用 --full-history 和/或父提交重寫(透過 --parents--children)來包含或排除提交。以下是可用的設定。

預設模式

如果提交與任何父提交不屬於 TREESAME(儘管這可以更改,請參閱下面的 --sparse),則包含該提交。如果提交是合併,並且與一個父提交屬於 TREESAME,則只跟蹤該父提交。(即使有多個 TREESAME 父提交,也只跟蹤其中一個。)否則,跟蹤所有父提交。

這會產生

	  .-A---N---O
	 /     /   /
	I---------D

請注意,只跟蹤 TREESAME 父提交(如果可用)的規則如何完全排除了 BC 是透過 N 考慮的,但它是 TREESAME。根提交與空樹進行比較,因此 I 是 !TREESAME。

父/子關係只有在使用 --parents 時才可見,但這不影響預設模式下選擇的提交,因此我們展示了父提交行。

--full-history 不帶父提交重寫

此模式與預設模式有一點不同:始終跟蹤合併的所有父提交,即使它與其中一個屬於 TREESAME。即使合併的多個側面都包含提交,這也不意味著合併本身會被包含!在示例中,我們得到

	I  A  B  N  D  O  P  Q

M 被排除,因為它與兩個父提交都屬於 TREESAME。 ECB 都被遍歷了,但只有 B 是 !TREESAME,所以其他提交不顯示。

請注意,在不進行父提交重寫的情況下,實際上無法談論提交之間的父/子關係,因此我們顯示它們是斷開的。

--full-history 帶父提交重寫

普通提交僅在它們是 !TREESAME 時才包含(儘管這可以更改,請參閱下面的 --sparse)。

合併總是包含在內。但是,它們的父提交列表會被重寫:沿著每個父提交,剪除那些未包含的提交本身。這會產生

	  .-A---M---N---O---P---Q
	 /     /   /   /   /
	I     B   /   D   /
	 \   /   /   /   /
	  `-------------'

與上面不帶重寫的 --full-history 進行比較。請注意,E 被剪除了,因為它屬於 TREESAME,但 P 的父提交列表被重寫為包含 E 的父提交 ICN,以及 XYQ 也發生了同樣的情況。

除了上述設定之外,您還可以更改 TREESAME 是否影響包含

--dense

遍歷到的提交如果與任何父提交不屬於 TREESAME,則包含該提交。

--sparse

所有遍歷到的提交都包含在內。

請注意,在沒有 --full-history 的情況下,這仍然會簡化合並:如果其中一個父提交是 TREESAME,我們只跟蹤那一個,因此合併的其他側面永遠不會被遍歷。

--simplify-merges

首先,以與帶父提交重寫的 --full-history 相同的方式構建歷史圖(參見上文)。

然後根據以下規則,將最終歷史記錄中的每個提交 C 簡化為它的替代 C'

  • C' 設定為 C

  • C' 的每個父提交 P 替換為其簡化版本 P'。在此過程中,刪除作為其他父提交祖先的父提交,或者與空樹屬於 TREESAME 的根提交,並刪除重複項,但要確保永遠不要刪除所有與我們屬於 TREESAME 的父提交。

  • 如果在此父提交重寫之後,C' 是一個根提交或合併提交(有零個或大於 1 個父提交)、一個邊界提交,或 !TREESAME,則它保持不變。否則,它將替換為其唯一的父提交。

其效果最好透過與帶父提交重寫的 --full-history 進行比較來展示。示例變為

	  .-A---M---N---O
	 /     /       /
	I     B       D
	 \   /       /
	  `---------'

請注意 NPQ--full-history 的主要差異

  • N 的父提交列表移除了 I,因為它屬於另一個父提交 M 的祖先。儘管如此,N 仍然保留,因為它不是 TREESAME。

  • P 的父提交列表也類似地移除了 I。然後 P 被完全移除,因為它有一個父提交併且是 TREESAME。

  • Q 的父提交列表將 Y 簡化為 X。然後 X 被移除,因為它是一個 TREESAME 根。然後 Q 被完全移除,因為它有一個父提交併且是 TREESAME。

還有另一種簡化模式可用

--ancestry-path[=<commit>]

將顯示的提交限制為 <commit> 的祖先、<commit> 的後代或 <commit> 本身。

作為一個用例,考慮以下提交歷史

	    D---E-------F
	   /     \       \
	  B---C---G---H---I---J
	 /                     \
	A-------K---------------L--M

常規的 D..M 計算 M 的祖先提交集合,但排除 D 的祖先提交。這對於檢視自 D 以來導致 M 的歷史發生了什麼很有用,即“M 有什麼在 D 中不存在的東西”。在此示例中,結果將是所有提交,除了 AB(當然還有 D 本身)。

然而,當我們想找出 M 中哪些提交被 D 引入的錯誤汙染並需要修復時,我們可能只想檢視 D..M 中實際是 D 後代的子集,即排除 CK。這正是 --ancestry-path 選項的作用。應用於 D..M 範圍,它產生

		E-------F
		 \       \
		  G---H---I---J
			       \
				L--M

我們還可以使用 --ancestry-path=D 代替 --ancestry-path,當應用於 D..M 範圍時,它們含義相同,但前者更明確。

如果我們轉而對該範圍內的給定主題以及受該主題影響的所有提交感興趣,我們可能只想檢視其祖先路徑中包含該主題的 D..M 子集。因此,例如使用 --ancestry-path=H D..M 將產生

		E
		 \
	      C---G---H---I---J
			       \
				L--M

--ancestry-path=K D..M 將產生

		K---------------L--M

在討論另一個選項 --show-pulls 之前,我們需要建立一個新的示例歷史。

使用者在檢視簡化歷史時面臨的一個常見問題是,他們知道更改了檔案的某個提交卻沒有出現在該檔案的簡化歷史中。讓我們展示一個新示例,並說明 --full-history--simplify-merges 等選項在這種情況下如何工作

	  .-A---M-----C--N---O---P
	 /     / \  \  \/   /   /
	I     B   \  R-'`-Z'   /
	 \   /     \/         /
	  \ /      /\        /
	   `---X--'  `---Y--'

在這個例子中,假設 I 建立了 file.txt,它被 ABX 以不同方式修改。單父提交 CZY 不改變 file.txt。合併提交 M 是透過解決合併衝突以包含來自 AB 的更改而建立的,因此它與兩者都不屬於 TREESAME。然而,合併提交 R 是透過忽略 M 處的 file.txt 內容並只取 X 處的 file.txt 內容而建立的。因此,RX 屬於 TREESAME 但不與 M 屬於 TREESAME。最後,建立 N 的自然合併解決方案是取 R 處的 file.txt 內容,因此 NR 屬於 TREESAME 但不與 C 屬於 TREESAME。合併提交 OP 與它們的第一父提交屬於 TREESAME,但不與它們的第二父提交 ZY 屬於 TREESAME。

當使用預設模式時,NR 都有一個 TREESAME 父提交,因此這些邊被遍歷,而其他邊被忽略。生成的歷史圖是

	I---X

當使用 --full-history 時,Git 會遍歷每一條邊。這將發現提交 AB 以及合併 M,同時也會揭示合併提交 OP。透過父提交重寫,生成的圖是

	  .-A---M--------N---O---P
	 /     / \  \  \/   /   /
	I     B   \  R-'`--'   /
	 \   /     \/         /
	  \ /      /\        /
	   `---X--'  `------'

在這裡,合併提交 OP 增加了額外的噪音,因為它們實際上並沒有對 file.txt 貢獻任何更改。它們只是合併了一個基於舊版本 file.txt 的主題。這在許多貢獻者並行工作並將他們的主題分支合併到單個主幹的工作流中是一個常見問題:許多不相關的合併會出現在 --full-history 結果中。

當使用 --simplify-merges 選項時,提交 OP 會從結果中消失。這是因為 OP 重寫後的第二父提交可以從它們的第一父提交到達。這些邊被移除,然後這些提交看起來就像與它們的父提交屬於 TREESAME 的單父提交。提交 N 也發生了同樣的情況,從而產生了如下歷史檢視

	  .-A---M--.
	 /     /    \
	I     B      R
	 \   /      /
	  \ /      /
	   `---X--'

在此檢視中,我們看到了來自 ABX 的所有重要單父提交更改。我們還看到了仔細解決的合併 M 和不太仔細解決的合併 R。這通常足以解釋為什麼提交 AB 在預設檢視中從歷史記錄中“消失”了。但是,這種方法存在一些問題。

第一個問題是效能。與之前的任何選項不同,--simplify-merges 選項需要遍歷整個提交歷史才能返回單個結果。這使得該選項對於非常大的倉庫來說難以使用。

第二個問題是審計。當許多貢獻者在同一個倉庫上工作時,哪個合併提交將更改引入重要分支是很重要的。上面有問題的合併 R 不太可能是用於合併到重要分支的合併提交。相反,合併 N 用於將 RX 合併到重要分支。此提交的訊息中可能包含關於更改 X 為何會覆蓋來自 AB 的更改的資訊。

--show-pulls

除了預設歷史中顯示的提交外,顯示每個與其第一父提交不屬於 TREESAME 但與後來的某個父提交屬於 TREESAME 的合併提交。

當合並提交被 --show-pulls 包含時,該合併被視為“拉取”了另一個分支的更改。在此示例中使用 --show-pulls(且沒有其他選項)時,生成的圖是

	I---X---R---N

在這裡,合併提交 RN 被包含,因為它們分別將提交 XR 拉入主分支。這些合併是提交 AB 不出現在預設歷史中的原因。

--show-pulls--simplify-merges 結合使用時,圖包含所有必要的資訊

	  .-A---M--.   N
	 /     /    \ /
	I     B      R
	 \   /      /
	  \ /      /
	   `---X--'

請注意,由於 M 可以從 R 到達,因此從 NM 的邊被簡化掉了。然而,N 仍然作為重要提交出現在歷史中,因為它將更改 R“拉取”到主分支。

--simplify-by-decoration 選項允許您僅檢視歷史拓撲的概況,透過省略未被標籤引用的提交。如果提交 (1) 被標籤引用,或者 (2) 更改了命令列上給定路徑的內容,則它們被標記為 !TREESAME(換句話說,在上述歷史簡化規則之後保留)。所有其他提交都被標記為 TREESAME(可能會被簡化掉)。

提交排序

預設情況下,提交按逆時間順序顯示。

--date-order

在顯示所有子提交之前不顯示任何父提交,但除此之外,按提交時間戳順序顯示提交。

--author-date-order

在顯示所有子提交之前不顯示任何父提交,但除此之外,按作者時間戳順序顯示提交。

--topo-order

在顯示所有子提交之前不顯示任何父提交,並避免將歷史記錄中多行的提交混合顯示。

例如,在這樣的提交歷史中

    ---1----2----4----7
	\	       \
	 3----5----6----8---

其中數字表示提交時間戳的順序,git rev-list 和其他帶有 --date-order 的命令會按時間戳順序顯示提交:8 7 6 5 4 3 2 1。

使用 --topo-order,它們將顯示 8 6 5 3 7 4 2 1(或 8 7 4 2 6 5 3 1);一些較舊的提交會顯示在較新的提交之前,以避免將來自兩個並行開發分支的提交混合在一起顯示。

--reverse

以相反順序輸出選擇要顯示的提交(參見上面的提交限制部分)。不能與 --walk-reflogs 結合使用。

物件遍歷

這些選項主要用於 Git 倉庫的打包。

--no-walk[=(sorted|unsorted)]

只顯示給定的提交,但不遍歷它們的祖先。如果指定了範圍,則此選項無效。如果給定了引數 unsorted,則提交將按照它們在命令列上給出的順序顯示。否則(如果給定了 sorted 或沒有給定引數),提交將按提交時間的逆時間順序顯示。不能與 --graph 結合使用。

--do-walk

覆蓋之前的 --no-walk 選項。

提交格式化

--pretty[=<format>]
--format=<format>

以給定格式美觀地列印提交日誌的內容,其中 <format> 可以是 onelineshortmediumfullfullerreferenceemailrawformat:<string>tformat:<string> 之一。當 <format> 不屬於上述任何一種,並且其中包含 %placeholder 時,它等同於給定了 --pretty=tformat:<format>

有關每種格式的更多詳細資訊,請參閱“PRETTY FORMATS”部分。當省略 =<format> 部分時,預設值為 medium

注意:您可以在倉庫配置中指定預設的美觀格式(參見 git-config[1])。

--abbrev-commit

不顯示完整的 40 位元組十六進位制提交物件名稱,而是顯示一個唯一標識該物件的字首。可以使用 "--abbrev=<n>" 選項(如果顯示差異輸出,此選項也會對其進行修改)來指定字首的最小長度。

這應該會使使用 80 列終端的人員更容易閱讀 "--pretty=oneline"。

--no-abbrev-commit

顯示完整的 40 位元組十六進位制提交物件名稱。這會抵消 --abbrev-commit,無論是顯式的還是由其他選項(例如 "--oneline")隱式指定的。它還會覆蓋 log.abbrevCommit 變數。

--oneline

這是 "--pretty=oneline --abbrev-commit" 同時使用的簡寫形式。

--encoding=<encoding>

提交物件在其編碼頭中記錄了用於日誌訊息的字元編碼;此選項可用於告訴命令以使用者首選的編碼重新編碼提交日誌訊息。對於非底層命令,預設值為 UTF-8。請注意,如果一個物件聲稱以 X 編碼,並且我們正在以 X 輸出,我們將按原樣輸出該物件;這意味著原始提交中的無效序列可能會被複制到輸出中。同樣,如果 iconv(3) 無法轉換提交,我們將靜默地按原樣輸出原始物件。

--expand-tabs=<n>
--expand-tabs
--no-expand-tabs

在輸出日誌訊息之前,對其執行製表符擴充套件(將每個製表符替換為足夠的空格,以填充到 <n> 的倍數的下一個顯示列)。--expand-tabs--expand-tabs=8 的簡寫,而 --no-expand-tabs--expand-tabs=0 的簡寫,後者停用製表符擴充套件。

預設情況下,在將日誌訊息縮排 4 個空格的美觀格式(即預設的 mediumfullfuller)中,製表符會被擴充套件。

--notes[=<ref>]

當顯示提交日誌訊息時,顯示註釋提交的註解(參見 git-notes[1])。當命令列中沒有給出 --pretty--format--oneline 選項時,這是 git loggit showgit whatchanged 命令的預設行為。

預設情況下,顯示的註解來自 core.notesRefnotes.displayRef 變數中列出的註解引用(或相應的環境變數覆蓋)。有關更多詳細資訊,請參閱 git-config[1]

如果帶有可選的 <ref> 引數,則使用該引用來查詢要顯示的註解。當引用以 refs/notes/ 開頭時,它可以指定完整的引用名稱;當它以 notes/ 開頭時,以 refs/ 為字首,否則以 refs/notes/ 為字首來形成引用的完整名稱。

多個 --notes 選項可以組合使用以控制顯示哪些註解。示例:"--notes=foo" 將只顯示來自 "refs/notes/foo" 的註解;"--notes=foo --notes" 將顯示來自 "refs/notes/foo" 和預設註解引用(一個或多個)的註解。

--no-notes

不顯示註解。這會透過重置顯示註解的引用列表來抵消上述 --notes 選項。選項按照命令列上給出的順序解析,因此例如 "--notes --notes=foo --no-notes --notes=bar" 將只顯示來自 "refs/notes/bar" 的註解。

--show-notes-by-default

顯示預設註解,除非給出了顯示特定註解的選項。

--show-notes[=<ref>]
--[no-]standard-notes

這些選項已棄用。請改用上面的 --notes/--no-notes 選項。

--show-signature

透過將簽名傳遞給 gpg --verify 並顯示輸出來檢查已簽名提交物件的有效性。

--relative-date

等同於 --date=relative

--date=<format>

僅對以人類可讀格式顯示的日期生效,例如使用 --pretty 時。log.date 配置變數設定了 log 命令的 --date 選項的預設值。預設情況下,日期以原始時區(提交者或作者的時區)顯示。如果將 -local 附加到格式(例如 iso-local),則使用使用者的本地時區。

--date=relative 顯示相對於當前時間的日期,例如“2 hours ago”。-local 選項對 --date=relative 沒有影響。

--date=local--date=default-local 的別名。

--date=iso(或 --date=iso8601)以類似 ISO 8601 的格式顯示時間戳。與嚴格 ISO 8601 格式的區別在於

  • 用空格代替日期/時間分隔符 T

  • 時間與時區之間有一個空格

  • 時區的小時和分鐘之間沒有冒號

--date=iso-strict(或 --date=iso8601-strict)以嚴格的 ISO 8601 格式顯示時間戳。

--date=rfc(或 --date=rfc2822)以 RFC 2822 格式顯示時間戳,這種格式常見於電子郵件中。

--date=short 只顯示日期,不顯示時間,格式為 YYYY-MM-DD

--date=raw 將日期顯示為自 epoch(1970-01-01 00:00:00 UTC)以來的秒數,後跟一個空格,然後是作為 UTC 偏移量的時區(一個帶四個數字的 +-;前兩位是小時,後兩位是分鐘)。即,如同時間戳用 strftime("%s %z") 格式化一樣。請注意,-local 選項不影響自 epoch 以來的秒數值(該值始終以 UTC 衡量),但會切換隨附的時區值。

--date=human 在時區與當前時區不匹配時顯示時區,如果匹配則不列印整個日期(即,對於“今年”的日期跳過列印年份,但如果日期在最近幾天並且我們可以直接說出是星期幾,則跳過整個日期本身)。對於較舊的日期,小時和分鐘也被省略。

--date=unix 將日期顯示為 Unix epoch 時間戳(自 1970 年以來的秒數)。與 --raw 一樣,這始終是 UTC 時間,因此 -local 沒有效果。

--date=format:... 將格式 ... 傳遞給您的系統 strftime 函式,但 %s、%z 和 %Z 除外,它們在內部處理。使用 --date=format:%c 以您系統區域設定的首選格式顯示日期。有關格式佔位符的完整列表,請參閱 strftime 手冊。當使用 -local 時,正確的語法是 --date=format-local:...

--date=default 是預設格式,基於 ctime(3) 輸出。它顯示一行,包含三字母的星期幾、三字母的月份、日期、"HH:MM:SS" 格式的小時-分鐘-秒,後跟四位數年份,以及時區資訊,除非使用本地時區,例如 Thu Jan 1 00:00:00 1970 +0000

--parents

同時列印提交的父提交(格式為 "commit parent…​")。也啟用父提交重寫,參見上文的 歷史簡化

--children

同時列印提交的子提交(格式為 "commit child…​")。也啟用父提交重寫,參見上文的 歷史簡化

--left-right

標記提交可從對稱差異的哪一側到達。來自左側的提交字首為 <,來自右側的提交字首為 >。如果與 --boundary 結合使用,則這些提交字首為 -

例如,如果您有此拓撲

	     y---b---b  branch B
	    / \ /
	   /   .
	  /   / \
	 o---x---a---a  branch A

您將得到如下輸出

	$ git rev-list --left-right --boundary --pretty=oneline A...B

	>bbbbbbb... 3rd on b
	>bbbbbbb... 2nd on b
	<aaaaaaa... 3rd on a
	<aaaaaaa... 2nd on a
	-yyyyyyy... 1st on b
	-xxxxxxx... 1st on a
--graph

在輸出的左側繪製提交歷史的基於文字的圖形表示。這可能會導致在提交之間列印額外的行,以便正確繪製圖形歷史。不能與 --no-walk 結合使用。

這會啟用父提交重寫,參見上文的 歷史簡化

這預設隱含了 --topo-order 選項,但也可以指定 --date-order 選項。

--show-linear-break[=<barrier>]

當不使用 --graph 時,所有歷史分支都會被展平,這可能導致難以看出兩個連續的提交不屬於同一個線性分支。在這種情況下,此選項會在它們之間放置一個分隔符。如果指定了 <barrier>,則它是將代替預設分隔符顯示的字串。

美觀格式 (PRETTY FORMATS)

如果提交是合併提交,並且美觀格式不是 onelineemailraw,則會在 Author: 行之前插入額外一行。此行以 "Merge: " 開頭,並列印祖先提交的雜湊值,用空格分隔。請注意,如果您限制了歷史檢視,列出的提交可能不一定是直接父提交的列表:例如,如果您只對與特定目錄或檔案相關的更改感興趣。

有幾種內建格式,您可以透過將 pretty.<name> 配置選項設定為另一個格式名稱或 format: 字串來定義其他格式,如下所述(參見 git-config[1])。以下是內建格式的詳細資訊

  • oneline

    <hash> <title-line>

    這被設計為儘可能緊湊。

  • short

    commit <hash>
    Author: <author>
    <title-line>
  • medium

    commit <hash>
    Author: <author>
    Date:   <author-date>
    <title-line>
    <full-commit-message>
  • full

    commit <hash>
    Author: <author>
    Commit: <committer>
    <title-line>
    <full-commit-message>
  • fuller

    commit <hash>
    Author:     <author>
    AuthorDate: <author-date>
    Commit:     <committer>
    CommitDate: <committer-date>
    <title-line>
    <full-commit-message>
  • reference

    <abbrev-hash> (<title-line>, <short-author-date>)

    此格式用於在提交訊息中引用另一個提交,並且與 --pretty='format:%C(auto)%h (%s, %ad) 相同。預設情況下,日期使用 --date=short 格式化,除非明確指定了另一個 --date 選項。與任何帶有格式佔位符的 format: 一樣,其輸出不受 --decorate--walk-reflogs 等其他選項的影響。

  • email

    From <hash> <date>
    From: <author>
    Date: <author-date>
    Subject: [PATCH] <title-line>
    <full-commit-message>
  • mboxrd

    email 類似,但提交訊息中以 "From " 開頭(前面帶零個或多個 ">")的行會用 ">" 引用,這樣它們就不會被誤認為是新提交的開始。

  • raw

    raw 格式精確地顯示整個提交,正如它儲存在提交物件中一樣。值得注意的是,雜湊值會完整顯示,無論是否使用了 --abbrev 或 --no-abbrev,並且 parents 資訊顯示的是真實的父提交,不考慮嫁接或歷史簡化。請注意,此格式影響提交的顯示方式,但不影響差異的顯示方式,例如使用 git log --raw。要在原始差異格式中獲取完整的物件名稱,請使用 --no-abbrev

  • format:<format-string>

    format:<format-string> 格式允許您指定要顯示的資訊。它的工作方式有點像 printf 格式,但一個顯著的區別是,您使用 %n 而不是 \n 來獲取換行符。

    例如,format:"The author of %h was %an, %ar%nThe title was >>%s<<%n" 會顯示如下內容

    The author of fe6e0ee was Junio C Hamano, 23 hours ago
    The title was >>t4119: test autocomputing -p<n> for traditional diff input.<<

    佔位符有

    • 擴充套件為單個文字字元的佔位符

      %n

      換行

      %%

      一個原始的 %

      %x00

      %x 後跟兩位十六進位制數字會被替換為具有該十六進位制數字值的位元組(在本文件的其餘部分,我們將此稱為“字面格式程式碼”)。

    • 影響後續佔位符格式的佔位符

      %Cred

      切換顏色為紅色

      %Cgreen

      切換顏色為綠色

      %Cblue

      切換顏色為藍色

      %Creset

      重置顏色

      %C(…​)

      顏色規範,如 git-config[1] 的“配置檔案”部分的“值”下所述。預設情況下,顏色僅在為日誌輸出啟用時(透過 color.diffcolor.ui--color,並且如果我們將輸出到終端,則遵循前者的 auto 設定)才顯示。 %C(auto,...) 被接受為預設值的歷史同義詞(例如 %C(auto,red))。指定 %C(always,...) 將即使在顏色未被啟用時也顯示顏色(但考慮直接使用 --color=always 來為整個輸出啟用顏色,包括此格式和 Git 可能著色的任何其他內容)。單獨的 auto(即 %C(auto))將在下一個佔位符上啟用自動著色,直到顏色再次切換。

      %m

      左 (<)、右 (>) 或邊界 (-) 標記

      %w([<w>[,<i1>[,<i2>]]])

      切換行迴繞,類似於 git-shortlog[1] 的 -w 選項。

      %<( <N> [,trunc|ltrunc|mtrunc])

      使下一個佔位符至少佔據 N 列寬度,如有必要,在右側填充空格。如果輸出長於 N 列,可選地在左側(ltrunc)使用省略號 .. 截斷 ..ft,在中間(mtrunc)截斷 mi..le,或在末尾(trunc)截斷 rig..。注意1:截斷僅在 N >= 2 時正確工作。注意2:N 和 M 值(見下文)周圍的空格是可選的。注意3:表情符號和其他寬字元將佔據兩個顯示列,這可能超出列邊界。注意4:分解字元組合標記可能在填充邊界處錯位。

      %<|( <M> )

      使下一個佔位符至少佔據到第 M 個顯示列,如有必要,在右側填充空格。使用負值 M 表示從終端視窗右側邊緣測量的列位置。

      %>( <N> ), %>|( <M> )

      分別類似於 %<( <N> )%<|( <M> ),但在左側填充空格

      %>>( <N> ), %>>|( <M> )

      分別類似於 %>( <N> )%>|( <M> ),但如果下一個佔位符佔用的空間多於給定空間且其左側有空格,則使用這些空格

      %><( <N> ), %><|( <M> )

      分別類似於 %<( <N> )%<|( <M> ),但填充兩側(即文字居中)

    • 展開為從提交中提取的資訊的佔位符

      %H

      提交雜湊

      %h

      縮寫提交雜湊

      %T

      樹雜湊

      %t

      縮寫樹雜湊

      %P

      父雜湊

      %p

      縮寫父雜湊

      %an

      作者姓名

      %aN

      作者姓名(遵循 .mailmap,參見 git-shortlog[1]git-blame[1]

      %ae

      作者電子郵件

      %aE

      作者電子郵件(遵循 .mailmap,參見 git-shortlog[1]git-blame[1]

      %al

      作者電子郵件本地部分(@ 符號之前的部分)

      %aL

      作者本地部分(參見 %al,遵循 .mailmap,參見 git-shortlog[1]git-blame[1]

      %ad

      作者日期(格式遵循 --date= 選項)

      %aD

      作者日期,RFC2822 風格

      %ar

      作者日期,相對時間

      %at

      作者日期,UNIX 時間戳

      %ai

      作者日期,類似 ISO 8601 格式

      %aI

      作者日期,嚴格 ISO 8601 格式

      %as

      作者日期,短格式 (YYYY-MM-DD)

      %ah

      作者日期,人類可讀風格(如 git-rev-list[1]--date=human 選項)

      %cn

      提交者姓名

      %cN

      提交者姓名(遵循 .mailmap,參見 git-shortlog[1]git-blame[1]

      %ce

      提交者電子郵件

      %cE

      提交者電子郵件(遵循 .mailmap,參見 git-shortlog[1]git-blame[1]

      %cl

      提交者電子郵件本地部分(@ 符號之前的部分)

      %cL

      提交者本地部分(參見 %cl,遵循 .mailmap,參見 git-shortlog[1]git-blame[1]

      %cd

      提交者日期(格式遵循 --date= 選項)

      %cD

      提交者日期,RFC2822 風格

      %cr

      提交者日期,相對時間

      %ct

      提交者日期,UNIX 時間戳

      %ci

      提交者日期,類似 ISO 8601 格式

      %cI

      提交者日期,嚴格 ISO 8601 格式

      %cs

      提交者日期,短格式 (YYYY-MM-DD)

      %ch

      提交者日期,人類可讀風格(如 git-rev-list[1]--date=human 選項)

      %d

      引用名稱,類似於 git-log[1] 的 --decorate 選項

      %D

      引用名稱,不帶 " ("、")" 包裹。

      %(decorate[:<options>])

      帶有自定義裝飾的引用名稱。 decorate 字串後面可以跟一個冒號和零個或多個逗號分隔的選項。選項值可以包含字面格式程式碼。由於其在選項語法中的作用,必須使用這些程式碼來表示逗號 (%x2C) 和右括號 (%x29)。

      • prefix=<value>:在引用名稱列表之前顯示。預設為 " ("。

      • suffix=<value>:在引用名稱列表之後顯示。預設為 ")"。

      • separator=<value>:在引用名稱之間顯示。預設為 ", "。

      • pointer=<value>:如果 HEAD 指向某個分支,則在 HEAD 和該分支之間顯示。預設為 " -> "。

      • tag=<value>:在標籤名稱之前顯示。預設為 "tag: "。

    例如,生成不帶包裹或標籤註釋的裝飾,並使用空格作為分隔符

    + %(decorate:prefix=,suffix=,tag=,separator= )

    %(describe[:<options>])

    人類可讀的名稱,類似於 git-describe[1];對於不可描述的提交,為空字串。 describe 字串後面可以跟一個冒號和零個或多個逗號分隔的選項。當同時新增或刪除標籤時,描述可能不一致。

    • tags[=<bool-value>]:除了只考慮帶註釋的標籤,也考慮輕量級標籤。

    • abbrev=<number>:不使用縮寫物件名稱的預設十六進位制數字位數(將根據倉庫中的物件數量而變化,預設值為 7),而是使用 <number> 位數,或者根據需要使用足夠的位數來形成唯一的物件名稱。

    • match=<pattern>:只考慮匹配給定 glob(7) 模式的標籤,不包括 "refs/tags/" 字首。

    • exclude=<pattern>:不考慮匹配給定 glob(7) 模式的標籤,不包括 "refs/tags/" 字首。

    %S

    在命令列上給出的引用名稱,透過它到達了提交(如 git log --source),僅適用於 git log

    %e

    編碼

    %s

    主題

    %f

    淨化後的主題行,適合作為檔名

    %b

    正文

    %B

    原始正文(未迴繞的主題和正文)

    %N

    提交註釋

    %GG

    來自 GPG 的原始驗證訊息,用於已簽名提交

    %G?

    對於有效簽名顯示 "G",對於無效簽名顯示 "B",對於有效但未知有效性的簽名顯示 "U",對於已過期的有效簽名顯示 "X",對於由已過期金鑰建立的有效簽名顯示 "Y",對於由已撤銷金鑰建立的有效簽名顯示 "R",如果無法檢查簽名(例如缺少金鑰)顯示 "E",如果沒有簽名顯示 "N"

    %GS

    顯示已簽名提交的簽名者姓名

    %GK

    顯示用於簽署已簽名提交的金鑰

    %GF

    顯示用於簽署已簽名提交的金鑰指紋

    %GP

    顯示其子金鑰用於簽署已簽名提交的主金鑰指紋

    %GT

    顯示用於簽署已簽名提交的金鑰的信任級別

    %gD

    引用日誌選擇器,例如 refs/stash@{1}refs/stash@{2 minutes ago};格式遵循 -g 選項描述的規則。 @ 之前的部分是命令列上給出的引用名稱(因此 git log -g refs/heads/master 將產生 refs/heads/master@{0})。

    %gd

    縮短的引用日誌選擇器;與 %gD 相同,但引用名稱部分被縮短以提高人類可讀性(因此 refs/heads/master 變為 master)。

    %gn

    引用日誌身份名稱

    %gN

    引用日誌身份名稱(遵循 .mailmap,參見 git-shortlog[1]git-blame[1]

    %ge

    引用日誌身份電子郵件

    %gE

    引用日誌身份電子郵件(遵循 .mailmap,參見 git-shortlog[1]git-blame[1]

    %gs

    引用日誌主題

    %(trailers[:<options>])

    顯示 git-interpret-trailers[1] 解析的正文尾註。 trailers 字串後面可以跟一個冒號和零個或多個逗號分隔的選項。如果任何選項提供了多次,則以最後一次出現為準。

    • key=<key>:僅顯示指定 <key> 的尾註。匹配不區分大小寫,並且尾隨冒號是可選的。如果多次給定此選項,則顯示與任何鍵匹配的尾註行。此選項會自動啟用 only 選項,以便隱藏尾註塊中的非尾註行。如果不需要此行為,可以使用 only=false 停用它。例如,%(trailers:key=Reviewed-by) 顯示鍵為 Reviewed-by 的尾註行。

    • only[=<bool>]:選擇是否包含尾註塊中的非尾註行。

    • separator=<sep>:指定插入在尾註行之間的分隔符。預設為換行符。字串 <sep> 可以包含上面描述的字面格式程式碼。要使用逗號作為分隔符,必須使用 %x2C,否則它將被解析為下一個選項。例如,%(trailers:key=Ticket,separator=%x2C ) 顯示所有鍵為 "Ticket" 的尾註行,並用逗號和空格分隔。

    • unfold[=<bool>]:使其行為類似於給定 interpret-trailer 的 --unfold 選項。例如,%(trailers:only,unfold=true) 展開並顯示所有尾註行。

    • keyonly[=<bool>]:僅顯示尾註的鍵部分。

    • valueonly[=<bool>]:僅顯示尾註的值部分。

    • key_value_separator=<sep>:指定插入在每個尾註的鍵和值之間的分隔符。預設為 ": "。否則,它與上面的 separator=<sep> 具有相同的語義。

注意
某些佔位符可能取決於修訂版本遍歷引擎給出的其他選項。例如,除非我們正在遍歷引用日誌條目(例如,透過 git log -g),否則 %g* 引用日誌選項將插入一個空字串。如果命令列上尚未提供 --decorate,則 %d%D 佔位符將使用“短”裝飾格式。

布林選項接受可選值 [=<bool-value>]git-config[1]--type=bool 接受的值,如 yesoff,都接受。不帶 =<value> 地給出布林選項等同於帶 =true 地給出它。

如果在佔位符的 % 之後新增 +(加號),則僅當佔位符展開為非空字串時,才會在展開之前立即插入一個換行符。

如果在佔位符的 % 之後新增 -(減號),則僅當佔位符展開為空字串時,才會刪除緊接在展開之前的所有連續換行符。

如果在佔位符的 % 之後新增 ` `(空格),則僅當佔位符展開為非空字串時,才會在展開之前立即插入一個空格。

  • tformat

    tformat: 格式的工作方式與 format: 完全相同,不同之處在於它提供“終止符”語義而不是“分隔符”語義。換句話說,每個提交都會附加訊息終止符字元(通常是換行符),而不是在條目之間放置分隔符。這意味著單行格式的最後一個條目將正確地以換行符終止,就像“oneline”格式一樣。例如:

    $ git log -2 --pretty=format:%h 4da45bef \
      | perl -pe '$_ .= " -- NO NEWLINE\n" unless /\n/'
    4da45be
    7134973 -- NO NEWLINE
    
    $ git log -2 --pretty=tformat:%h 4da45bef \
      | perl -pe '$_ .= " -- NO NEWLINE\n" unless /\n/'
    4da45be
    7134973

    此外,任何包含 % 的無法識別的字串都被解釋為在其前面帶有 tformat:。例如,以下兩個是等效的:

    $ git log -2 --pretty=tformat:%h 4da45bef
    $ git log -2 --pretty=%h 4da45bef

差異格式化

預設情況下,git log 不生成任何差異輸出。以下選項可用於顯示每個提交所做的更改。

請注意,除非明確給出 --diff-merges 變體之一(包括短選項 -m-c--cc--dd),否則合併提交不會顯示差異,即使選擇了像 --patch 這樣的差異格式,也不會匹配像 -S 這樣的搜尋選項。例外情況是使用 --first-parent 時,在這種情況下,first-parent 是合併提交的預設格式。

-p
-u
--patch

生成補丁(參見 使用 -p 生成補丁文字)。

-s
--no-patch

抑制差異機制的所有輸出。對於像 git show 這樣預設顯示補丁的命令,它可用於抑制其輸出,或在別名中取消命令列上早期選項(如 --patch--stat)的效果。

-m

以預設格式顯示合併提交的差異。這類似於 --diff-merges=on,不同之處在於,除非同時給出 -p,否則 -m 不會產生任何輸出。

-c

為合併提交生成組合差異輸出。是 --diff-merges=combined -p 的快捷方式。

--cc

為合併提交生成緊湊組合差異輸出。是 --diff-merges=dense-combined -p 的快捷方式。

--dd

對於合併提交和常規提交,生成相對於第一個父提交的差異。是 --diff-merges=first-parent -p 的快捷方式。

--remerge-diff

為合併提交生成重新合併差異輸出。是 --diff-merges=remerge -p 的快捷方式。

--no-diff-merges

--diff-merges=off 的同義詞。

--diff-merges=<format>

指定用於合併提交的差異格式。除非使用 --first-parent,否則預設為 `off`,在這種情況下,first-parent 是預設值。

支援以下格式:

off, none

停用合併提交的差異輸出。用於覆蓋隱含值。

on, m

使合併提交的差異輸出以預設格式顯示。預設格式可以透過 log.diffMerges 配置變數更改,其預設值為 separate

first-parent, 1

顯示相對於第一個父提交的完整差異。這與 --patch 為非合併提交生成的格式相同。

separate

顯示相對於每個父提交的完整差異。為每個父提交生成單獨的日誌條目和差異。

combined, c

同時顯示每個父提交與合併結果之間的差異,而不是一次顯示一個父提交與結果之間的成對差異。此外,它只列出從所有父提交中修改過的檔案。

dense-combined, cc

透過省略不重要的程式碼塊進一步壓縮 --diff-merges=combined 生成的輸出,這些程式碼塊在父提交中的內容只有兩種變體,並且合併結果未經修改地選擇了其中一種。

remerge, r

重新合併兩個父提交的合併提交以建立臨時樹物件——可能包含帶有衝突標記等的檔案。然後顯示該臨時樹與實際合併提交之間的差異。

使用此選項時發出的輸出可能會更改,並且它與其他選項的互動也會更改(除非有明確文件說明)。

--combined-all-paths

使組合差異(用於合併提交)列出所有父提交的檔名。因此,它僅在 --diff-merges=[dense-]combined 使用時生效,並且可能僅在檢測到檔名更改時有用(即在請求了重新命名或複製檢測時)。

-U<n>
--unified=<n>

生成包含 <n> 行上下文(而不是通常的三行)的 diff。隱含 --patch

--output=<file>

輸出到特定檔案而不是標準輸出。

--output-indicator-new=<char>
--output-indicator-old=<char>
--output-indicator-context=<char>

指定用於指示生成補丁中新行、舊行或上下文行的字元。通常它們分別是 +- 和 ' '。

--raw

對於每個提交,使用原始差異格式顯示更改摘要。參見 git-diff[1] 的“原始輸出格式”部分。這與以原始格式顯示日誌本身不同,後者可以透過 --format=raw 實現。

--patch-with-raw

-p --raw 的同義詞。

-t

在差異輸出中顯示樹物件。

--indent-heuristic

啟用啟發式演算法,該演算法會移動差異塊邊界,使補丁更易於閱讀。這是預設設定。

--no-indent-heuristic

停用縮排啟發式演算法。

--minimal

花費額外時間以確保生成最小的差異。

--patience

使用“patience diff”演算法生成差異。

--histogram

使用“histogram diff”演算法生成差異。

--anchored=<text>

使用“anchored diff”演算法生成差異。

此選項可以多次指定。

如果一行在源和目標中都存在,只存在一次,並且以 <text> 開頭,則此演算法會嘗試阻止其在輸出中顯示為刪除或新增。它內部使用“patience diff”演算法。

--diff-algorithm=(patience|minimal|histogram|myers)

選擇一種差異演算法。變體如下:

default
myers

基本的貪婪差異演算法。目前,這是預設值。

minimal

花費額外時間以確保生成最小的差異。

patience

生成補丁時使用“patience diff”演算法。

histogram

此演算法擴充套件了 patience 演算法以“支援低出現率的常見元素”。

例如,如果您將 diff.algorithm 變數配置為非預設值,但希望使用預設值,則必須使用 --diff-algorithm=default 選項。

--stat[=<width>[,<name-width>[,<count>]]]

生成差異統計(diffstat)。預設情況下,檔名部分將使用盡可能多的空間,其餘部分用於圖形部分。最大寬度預設為終端寬度,如果未連線到終端則為 80 列,可以透過 <width> 覆蓋。檔名部分的寬度可以透過在逗號後給出另一個寬度 <name-width> 或設定 diff.statNameWidth=<name-width> 來限制。圖形部分的寬度可以透過使用 --stat-graph-width=<graph-width> 或設定 diff.statGraphWidth=<graph-width> 來限制。使用 --stat--stat-graph-width 會影響所有生成統計圖的命令,而設定 diff.statNameWidthdiff.statGraphWidth 不會影響 git format-patch。透過給出第三個引數 <count>,您可以將輸出限制為前 <count> 行,如果還有更多,則後面跟 ...

這些引數也可以透過 --stat-width=<width>--stat-name-width=<name-width>--stat-count=<count> 單獨設定。

--compact-summary

在差異統計中輸出擴充套件頭資訊的精簡摘要,例如檔案建立或刪除(“new”或“gone”,可選 +l 如果是符號連結)和模式更改(新增或移除可執行位的 +x-x)。這些資訊放置在檔名部分和圖形部分之間。暗示 --stat

--numstat

類似於 --stat,但顯示新增和刪除的行數以十進位制表示,並且路徑名不縮寫,使其更具機器友好性。對於二進位制檔案,輸出兩個 - 而不是顯示 0 0

--shortstat

僅輸出 --stat 格式的最後一行,其中包含修改檔案的總數,以及新增和刪除的行數。

-X [<param>,...]
--dirstat[=<param>,...]

輸出每個子目錄的相對改動量分佈。 --dirstat 的行為可以透過傳遞逗號分隔的引數列表進行自定義。預設值由 diff.dirstat 配置變數控制(參見 git-config[1])。以下引數可用:

changes

透過計算已從源中刪除或已新增到目標中的行數來計算目錄統計數字。這會忽略檔案內純程式碼移動的數量。換句話說,檔案內行的重新排列不會像其他更改那樣被大量計數。這是未給出引數時的預設行為。

lines

透過執行常規的基於行的差異分析並彙總刪除/新增的行數來計算目錄統計數字。(對於二進位制檔案,而是計算 64 位元組塊,因為二進位制檔案沒有自然的行概念)。這比 changes 行為更昂貴,但它會將檔案內重新排列的行與其他更改一樣進行計數。結果輸出與您從其他 --*stat 選項獲得的輸出一致。

files

透過計算更改的檔案數量來計算目錄統計數字。在目錄統計分析中,每個更改的檔案都同等計數。這是計算成本最低的 --dirstat 行為,因為它根本不需要檢視檔案內容。

cumulative

也計算子目錄中更改對父目錄的影響。請注意,使用 cumulative 時,報告的百分比總和可能超過 100%。預設(非累積)行為可以透過 noncumulative 引數指定。

<limit>

一個整數引數,指定一個截止百分比(預設為 3%)。對更改貢獻低於此百分比的目錄不會顯示在輸出中。

示例:例如,以下命令將統計更改的檔案,同時忽略更改檔案總量少於10%的目錄,並將子目錄的計數累加到父目錄中: --dirstat=files,10,cumulative

--cumulative

--dirstat=cumulative 的同義詞。

--dirstat-by-file[=<param>,...]

--dirstat=files,<param>,... 的同義詞。

--summary

輸出擴充套件頭資訊的精簡摘要,例如建立、重新命名和模式更改。

--patch-with-stat

-p --stat 的同義詞。

-z

使用NUL字元而非換行符來分隔提交。

此外,當--raw--numstat給定後,不要混淆路徑名,並使用NUL字元作為輸出欄位終止符。

如果沒有此選項,包含“不尋常”字元的路徑名將按照配置變數 core.quotePath 的解釋進行引用(參見 git-config[1])。

--name-only

僅顯示後像樹中每個已更改檔案的名稱。檔名通常以 UTF-8 編碼。有關更多資訊,請參閱 git-log[1] 手冊頁中關於編碼的討論。

--name-status

只顯示每個更改檔案的名稱和狀態。有關狀態字母的含義,請參閱--diff-filter選項的說明。與--name-only類似,檔名通常以UTF-8編碼。

--submodule[=<format>]

指定如何顯示子模組的差異。當指定--submodule=short時,使用short格式。此格式僅顯示範圍內提交的起始和結束名稱。當指定--submodule--submodule=log時,使用log格式。此格式列出範圍內的提交,就像git-submodule[1]summary一樣。當指定--submodule=diff時,使用diff格式。此格式顯示提交範圍內子模組內容的行內差異。如果未設定配置選項,則預設為diff.submoduleshort格式。

--color[=<when>]

顯示彩色差異。--color(即不帶=<when>時)等同於--color=always<when>可以是alwaysneverauto之一。

--no-color

關閉彩色 diff。它與 --color=never 相同。

--color-moved[=<mode>]

移動的程式碼行會以不同顏色顯示。如果未指定選項,<mode>預設為no;如果給定不帶模式的選項,則預設為zebra。模式必須是以下之一:

no

移動的行不進行高亮顯示。

default

zebra 的同義詞。未來可能會更改為更合理的模式。

plain

在某個位置新增又在另一個位置刪除的任何行將使用color.diff.newMoved顏色顯示。類似地,color.diff.oldMoved將用於差異中在其他位置新增的已刪除行。此模式會捕獲任何移動的行,但在審查時,若要確定程式碼塊是否未經過置換而移動,則此模式用處不大。

blocks

至少20個字母數字字元的移動文字塊會被貪婪地檢測到。檢測到的塊將使用color.diff.(old|new)Moved顏色進行著色。相鄰的塊無法區分。

zebra

移動文字塊的檢測方式與blocks模式相同。這些塊將使用color.diff.(old|new)Moved顏色或color.diff.(old|new)MovedAlternative顏色進行著色。兩種顏色之間的變化表示檢測到了新的塊。

dimmed-zebra

zebra類似,但會對移動程式碼中不重要的部分進行額外變暗處理。兩個相鄰塊的邊界行被視為重要,其餘則不重要。dimmed_zebra是一個已棄用的同義詞。

--no-color-moved

關閉移動檢測。這可以用於覆蓋配置設定。它與 --color-moved=no 相同。

--color-moved-ws=<mode>,...

這配置了在執行 --color-moved 的移動檢測時如何忽略空白。這些模式可以作為逗號分隔的列表給出:

no

執行移動檢測時不忽略空白。

ignore-space-at-eol

忽略行尾空格的更改。

ignore-space-change

忽略空格數量的變化。這會忽略行尾的空格,並將所有其他一個或多個空格序列視為等效。

ignore-all-space

比較行時忽略空格。即使一行有空格而另一行沒有,這也忽略了差異。

allow-indentation-change

在移動檢測中最初忽略所有空白,然後僅當每行的空白更改相同時,才將移動的程式碼塊分組為一個塊。這與其他模式不相容。

--no-color-moved-ws

執行移動檢測時不忽略空白。這可以用於覆蓋配置設定。它與 --color-moved-ws=no 相同。

--word-diff[=<mode>]

預設情況下,單詞由空白分隔;參見下面的 --word-diff-regex<mode> 預設為 plain,並且必須是以下之一:

color

僅使用顏色高亮顯示更改的單詞。隱含 --color

plain

將單詞顯示為[-removed-]{added}。如果分隔符出現在輸入中,它不會嘗試轉義,因此輸出可能會有歧義。

porcelain

使用一種特殊的、面向指令碼消費的基於行的格式。新增/刪除/未更改的行以通常的統一差異格式列印,行首以+/-/` `字元開頭,並延伸到行尾。輸入中的換行符由單獨一行上的波浪號~表示。

none

再次停用單詞 diff。

請注意,儘管第一個模式的名稱如此,如果啟用,所有模式都使用顏色高亮顯示更改的部分。

--word-diff-regex=<regex>

使用 <regex> 來決定什麼是單詞,而不是將非空白字元的連續序列視為一個單詞。除非已啟用,否則這也隱含 --word-diff

<regex>的每個不重疊匹配都被視為一個單詞。這些匹配之間的任何內容都被視為空白並被忽略(!)以查詢差異。您可能希望在正則表示式中附加|[^[:space:]]以確保它匹配所有非空白字元。包含換行符的匹配會在換行符處被靜默截斷(!)

例如,--word-diff-regex=. 會將每個字元視為一個單詞,並相應地逐字元顯示差異。

正則表示式也可以透過差異驅動程式或配置選項設定,請參閱gitattributes[5]git-config[1]。顯式指定它會覆蓋任何差異驅動程式或配置設定。差異驅動程式會覆蓋配置設定。

--color-words[=<regex>]

相當於 --word-diff=color 加上(如果指定了正則表示式)--word-diff-regex=<regex>

--no-renames

關閉重新命名檢測,即使配置檔案預設開啟。

--[no-]rename-empty

是否使用空 blob 作為重新命名源。

--check

如果更改引入了衝突標記或空白錯誤,則發出警告。哪些被認為是空白錯誤由core.whitespace配置控制。預設情況下,行尾空白(包括僅由空白組成的行)以及行初始縮排內緊跟製表符的空格字元都被視為空白錯誤。如果發現問題,則以非零狀態退出。與--exit-code不相容。

--ws-error-highlight=<kind>

高亮顯示差異的contextoldnew行中的空白錯誤。多個值用逗號分隔,none會重置先前的值,default會將列表重置為newallold,new,context的簡寫。如果未給定此選項且未設定配置變數diff.wsErrorHighlight,則僅高亮顯示new行中的空白錯誤。空白錯誤會使用color.diff.whitespace著色。

--full-index

在生成補丁格式輸出時,不在“index”行上顯示前幾個字元,而是顯示完整的原影像和後圖像 blob 物件名稱。

--binary

除了 --full-index 之外,還輸出一個二進位制 diff,該 diff 可以用 git-apply 應用。隱含 --patch

--abbrev[=<n>]

在diff-raw格式輸出和diff-tree頭行中,不顯示完整的40位元組十六進位制物件名稱,而是顯示最短的、至少<n>位十六進位制數字的唯一標識物件的短字首。在diff-patch輸出格式中,--full-index具有更高的優先順序,即如果指定了--full-index,則無論--abbrev如何,都將顯示完整的blob名稱。非預設的位數可以透過--abbrev=<n>指定。

-B[<n>][/<m>]
--break-rewrites[=[<n>][/<m>]]

將完整的重寫更改分解為刪除和建立對。這有兩個目的:

它影響檔案完全重寫時的變更顯示方式:不顯示為一連串刪除和插入(其中只有極少數行與上下文文字匹配),而是顯示為一次性刪除所有舊內容,然後一次性插入所有新內容,數字<m>控制-B選項的這一方面(預設為60%)。-B/70%指定,如果結果中保留的原始內容少於30%,Git會將其視為完全重寫(即,否則生成的補丁將是一系列刪除和插入與上下文行混合在一起)。

當與-M一起使用時,完全重寫的檔案也被視為重新命名的源(通常-M只將已消失的檔案視為重新命名的源),數字<n>控制-B選項的這一方面(預設為50%)。-B20%指定,與檔案大小的20%或更多進行增刪的更改,有資格被視為重新命名到另一個檔案的可能來源。

-M[<n>]
--find-renames[=<n>]

如果生成差異,則為每個提交檢測並報告重新命名。有關遍歷歷史記錄時跨重新命名跟蹤檔案的資訊,請參閱--follow。如果<n>是指定的,它是相似性指數的閾值(即與檔案大小相比的新增/刪除量)。例如,-M90%表示如果檔案有90%以上未更改,Git應將刪除/新增對視為重新命名。不帶%符號時,該數字應理解為小數,小數點位於數字之前。例如,-M5變為0.5,因此與-M50%相同。類似地,-M05-M5%相同。若要將檢測限制為精確重新命名,請使用-M100%。預設相似性指數為50%。

-C[<n>]
--find-copies[=<n>]

檢測複製和重新命名。另請參見 --find-copies-harder。如果指定了 <n>,其含義與 -M<n> 相同。

--find-copies-harder

出於效能原因,預設情況下,-C選項僅在複製的原始檔案在同一變更集中被修改時才查詢副本。此標誌使命令檢查未修改的檔案作為複製源的候選檔案。這對於大型專案來說是一個非常昂貴的操作,因此請謹慎使用。給定多個-C選項具有相同的效果。

-D
--irreversible-delete

刪除時省略原始影像(preimage),即只打印頭資訊,而不列印原始影像與/dev/null之間的差異。生成的補丁不適用於patchgit apply;這僅適用於那些只想專注於審查更改後文本的人。此外,輸出顯然缺乏足夠的資訊來逆向應用此類補丁,即使是手動操作也不行,因此得名此選項。

-B 一起使用時,也會省略刪除/建立對的刪除部分中的原始影像。

-l<num>

-M-C選項包含一些初步步驟,可以廉價地檢測重新命名/複製的子集,然後是窮舉回退部分,將所有剩餘的未配對目標與所有相關源進行比較。(對於重新命名,只有剩餘的未配對源是相關的;對於複製,所有原始源都是相關的。)對於N個源和目標,這種窮舉檢查的時間複雜度為O(N^2)。如果涉及的源/目標檔案數量超過指定值,此選項可阻止重新命名/複製檢測的窮舉部分執行。預設為diff.renameLimit。請注意,值0被視為無限制。

--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]

只選擇那些已新增(A)、已複製(C)、已刪除(D)、已修改(M)、已重新命名(R)、型別(即普通檔案、符號連結、子模組等)已更改(T)、未合併(U)、未知(X)或配對已損壞(B)的檔案。可以使用過濾字元的任意組合(包括不使用任何字元)。當*(全選或不選)新增到組合中時,如果比較中有任何檔案匹配其他條件,則選擇所有路徑;如果沒有檔案匹配其他條件,則不選擇任何內容。

此外,這些大寫字母可以小寫以進行排除。例如,--diff-filter=ad 會排除已新增和已刪除的路徑。

請注意,並非所有 diff 都能包含所有型別。例如,如果停用對這些型別的檢測,則不會出現已複製和已重新命名條目。

-S<string>

查詢更改檔案中指定 <string> 出現次數(即新增/刪除)的差異。供指令碼編寫者使用。

當您正在尋找一個精確的程式碼塊(如結構體)並希望瞭解該程式碼塊自首次出現以來的歷史記錄時,它非常有用:迭代使用此功能,將原始影像中感興趣的程式碼塊重新輸入到-S中,並持續操作直到找到該程式碼塊的最初版本。

二進位制檔案也會被搜尋。

-G<regex>

查詢其補丁文字包含與 <regex> 匹配的新增/刪除行的差異。

為了說明-S<regex> --pickaxe-regex-G<regex>之間的區別,請考慮同一個檔案中包含以下差異的提交

+    return frotz(nitfol, two->ptr, 1, 0);
...
-    hit = frotz(nitfol, mf2.ptr, 1, 0);

雖然git log -G"frotz\(nitfol"會顯示此提交,但git log -S"frotz\(nitfol" --pickaxe-regex不會(因為該字串的出現次數沒有變化)。

除非提供了 --text,否則沒有 textconv 過濾器的二進位制檔案的補丁將被忽略。

有關更多資訊,請參見 gitdiffcore[7] 中的 *pickaxe* 條目。

--find-object=<object-id>

查詢更改指定物件出現次數的差異。類似於 -S,只是引數不同,它不搜尋特定字串,而是搜尋特定物件 ID。

該物件可以是 blob 或子模組提交。它隱含了 git-log 中的 -t 選項,以也查詢樹。

--pickaxe-all

-S-G 找到更改時,顯示該變更集中所有更改,而不僅僅是包含 <string> 更改的檔案。

--pickaxe-regex

將提供給 -S<string> 視為擴充套件的 POSIX 正則表示式進行匹配。

-O<orderfile>

控制檔案在輸出中出現的順序。這會覆蓋diff.orderFile配置變數(參見git-config[1])。要取消diff.orderFile,請使用-O/dev/null

輸出順序由<orderfile>中的glob模式順序決定。所有路徑名匹配第一個模式的檔案首先輸出,所有路徑名匹配第二個模式(但不匹配第一個)的檔案其次輸出,依此類推。所有路徑名不匹配任何模式的檔案最後輸出,就像檔案末尾有一個隱式匹配所有模式一樣。如果多個路徑名具有相同的級別(它們匹配相同的模式但沒有匹配更早的模式),則它們相對於彼此的輸出順序是正常順序。

<orderfile> 解析如下:

  • 空行被忽略,因此它們可以用作分隔符以提高可讀性。

  • 以井號("#")開頭的行被忽略,因此它們可以用作註釋。如果模式以井號開頭,請在模式開頭新增反斜槓("\")。

  • 其他每行包含一個模式。

模式具有與fnmatch(3)中使用的模式相同的語法和語義,但不帶FNM_PATHNAME標誌,例外是如果刪除最終路徑名的任意數量的元件後匹配模式,則路徑名也會匹配該模式。例如,模式"foo*bar"匹配"fooasdfbar"和"foo/bar/baz/asdf"但不匹配"foobarx"。

--skip-to=<file>
--rotate-to=<file>

從輸出中丟棄在命名檔案<file>之前的檔案(即跳過到),或將其移動到輸出末尾(即旋轉到)。這些選項主要為git difftool命令而設計,否則可能用處不大。

-R

交換兩個輸入;即,顯示從索引或磁碟檔案到樹內容的差異。

--relative[=<path>]
--no-relative

在專案子目錄中執行時,可以使用此選項排除目錄外的更改並顯示相對於該目錄的路徑名。當您不在子目錄中(例如在裸倉庫中)時,可以透過提供<path>作為引數來指定輸出相對於哪個子目錄。--no-relative可用於撤銷diff.relative配置選項和先前的--relative

-a
--text

將所有檔案視為文字。

--ignore-cr-at-eol

進行比較時忽略行尾的回車符。

--ignore-space-at-eol

忽略行尾空格的更改。

-b
--ignore-space-change

忽略空格數量的變化。這會忽略行尾的空格,並將所有其他一個或多個空格序列視為等效。

-w
--ignore-all-space

比較行時忽略空格。即使一行有空格而另一行沒有,這也忽略了差異。

--ignore-blank-lines

忽略所有空行的更改。

-I<regex>
--ignore-matching-lines=<regex>

忽略所有行都匹配 <regex> 的更改。此選項可以多次指定。

--inter-hunk-context=<number>

在差異塊之間顯示上下文,最多達指定行數 <number>,從而合併彼此接近的塊。預設為 diff.interHunkContext,如果未設定配置選項則為 0。

-W
--function-context

為每個更改顯示整個函式作為上下文行。函式名稱的確定方式與git diff確定補丁塊頭(patch hunk headers)的方式相同(請參閱gitattributes[5]中的“定義自定義塊頭”)。

--ext-diff

允許執行外部差異輔助程式。如果您使用 gitattributes[5] 設定了外部差異驅動程式,則需要與 git-log[1] 等命令一起使用此選項。

--no-ext-diff

禁止外部差異驅動程式。

--textconv
--no-textconv

允許(或不允許)在比較二進位制檔案時執行外部文字轉換過濾器。有關詳細資訊,請參閱gitattributes[5]。由於文字轉換過濾器通常是單向轉換,因此生成的差異適合人工閱讀,但無法應用。因此,文字轉換過濾器預設只對git-diff[1]git-log[1]啟用,而不對git-format-patch[1]或diff底層命令啟用。

--ignore-submodules[=(none|untracked|dirty|all)]

在生成差異時忽略對子模組的更改。all是預設值。使用none會在子模組包含未跟蹤或已修改檔案,或者其HEAD與超級專案中記錄的提交不同時,將其視為已修改,並且可以覆蓋git-config[1]gitmodules[5]ignore選項的任何設定。使用untracked時,如果子模組只包含未跟蹤內容,則不將其視為髒(但仍會掃描已修改內容)。使用dirty會忽略對子模組工作樹的所有更改,僅顯示超級專案中所儲存提交的更改(這是1.7.0之前的行為)。使用all會隱藏對子模組的所有更改。

--src-prefix=<prefix>

顯示給定的源字首 <prefix> 而不是 "a/"。

--dst-prefix=<prefix>

顯示給定的目標字首 <prefix> 而不是 "b/"。

--no-prefix

不顯示任何源或目標字首。

--default-prefix

使用預設的源和目標字首("a/"和"b/")。這會覆蓋配置變數,例如diff.noprefixdiff.srcPrefixdiff.dstPrefixdiff.mnemonicPrefix(參見git-config[1])。

--line-prefix=<prefix>

在每行輸出前面新增一個額外的 <prefix>

--ita-invisible-in-index

預設情況下,透過git add -N新增的條目在git diff中顯示為已存在的空檔案,在git diff --cached中顯示為新檔案。此選項使該條目在git diff中顯示為新檔案,在git diff --cached中顯示為不存在。此選項可以透過--ita-visible-in-index恢復。這兩個選項都是實驗性的,將來可能會被移除。

有關這些通用選項的更詳細說明,另請參見 gitdiffcore[7]

使用 -p 生成補丁文字

使用-p選項執行git-diff[1]git-log[1]git-show[1]git-diff-index[1]git-diff-tree[1]git-diff-files[1]會生成補丁文字。您可以透過GIT_EXTERNAL_DIFFGIT_DIFF_OPTS環境變數(參見git[1])以及diff屬性(參見gitattributes[5])自定義補丁文字的建立。

-p 選項生成的輸出與傳統的 diff 格式略有不同:

  1. 它前面是“git diff”頭,看起來像這樣:

    diff --git a/file1 b/file2

    除非涉及重新命名/複製,否則a/b/檔名是相同的。特別是,即使是建立或刪除,也不會使用/dev/null代替a/b/檔名。

    當涉及重新命名/複製時,file1file2 分別顯示重新命名/複製的原始檔名稱和重新命名/複製生成的檔名稱。

  2. 後面跟著一個或多個擴充套件頭行:

    old mode <mode>
    new mode <mode>
    deleted file mode <mode>
    new file mode <mode>
    copy from <path>
    copy to <path>
    rename from <path>
    rename to <path>
    similarity index <number>
    dissimilarity index <number>
    index <hash>..<hash> <mode>

    檔案模式 <mode> 以 6 位八進位制數字列印,包括檔案型別和檔案許可權位。

    擴充套件頭中的路徑名不包含 a/b/ 字首。

    相似性指數是未更改行的百分比,而相異性指數是已更改行的百分比。它是一個向下取整的整數,後面跟著一個百分號。因此,相似性指數100%的值保留給兩個相同的檔案,而100%的相異性意味著舊檔案中沒有一行進入新檔案。

    索引行包括更改前後的 blob 物件名稱。如果檔案模式沒有更改,則包含 <mode>;否則,單獨的行指示舊模式和新模式。

  3. 包含“不尋常”字元的路徑名將按照配置變數 core.quotePath 的解釋進行引用(參見 git-config[1])。

  4. 輸出中所有的file1檔案指代提交前的檔案,而所有的file2檔案指代提交後的檔案。按順序將每個更改應用到每個檔案是錯誤的。例如,這個補丁將交換a和b

    diff --git a/a b/b
    rename from a
    rename to b
    diff --git a/b b/a
    rename from b
    rename to a
  5. Hunk 頭會提及 hunk 應用到的函式名稱。有關如何根據特定語言進行調整的詳細資訊,請參見 gitattributes[5] 中的“定義自定義 hunk-header”。

組合 diff 格式

任何生成差異的命令都可以接受-c--cc選項,以便在顯示合併時生成合併差異。這是使用git-diff[1]git-show[1]顯示合併時的預設格式。另請注意,您可以為這些命令中的任何一個提供適當的--diff-merges選項,以強制生成特定格式的差異。

“組合 diff”格式如下所示:

diff --combined describe.c
index fabadb8,cc95eb0..4866510
--- a/describe.c
+++ b/describe.c
@@@ -98,20 -98,12 +98,20 @@@
	return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
  }

- static void describe(char *arg)
 -static void describe(struct commit *cmit, int last_one)
++static void describe(char *arg, int last_one)
  {
 +	unsigned char sha1[20];
 +	struct commit *cmit;
	struct commit_list *list;
	static int initialized = 0;
	struct commit_name *n;

 +	if (get_sha1(arg, sha1) < 0)
 +		usage(describe_usage);
 +	cmit = lookup_commit_reference(sha1);
 +	if (!cmit)
 +		usage(describe_usage);
 +
	if (!initialized) {
		initialized = 1;
		for_each_ref(get_name);
  1. 它前面是“git diff”頭,看起來像這樣(使用 -c 選項時):

    diff --combined file

    或者像這樣(使用 --cc 選項時):

    diff --cc file
  2. 後面跟著一個或多個擴充套件頭行(此示例顯示了一個包含兩個父級的合併):

    index <hash>,<hash>..<hash>
    mode <mode>,<mode>..<mode>
    new file mode <mode>
    deleted file mode <mode>,<mode>

    mode <mode>,<mode>..<mode>行僅在至少一個<mode>與其他模式不同時出現。包含檢測到的內容移動(重新命名和複製檢測)資訊的擴充套件頭旨在與兩個<tree-ish>的差異配合使用,並且不用於合併差異格式。

  3. 後面跟著一個兩行的“原始檔/目標檔案”頭:

    --- a/file
    +++ b/file

    類似於傳統 unified diff 格式的兩行頭,/dev/null 用於指示已建立或已刪除的檔案。

    然而,如果提供了 --combined-all-paths 選項,您將得到一個 N+1 行的“原始檔/目標檔案”頭,而不是兩行的“原始檔/目標檔案”頭,其中 N 是合併提交中父級的數量:

    --- a/file
    --- a/file
    --- a/file
    +++ b/file

    如果重新命名或複製檢測處於活動狀態,這種擴充套件格式會很有用,可以讓您檢視不同父級中檔案的原始名稱。

  4. 塊頭格式已修改,以防止人們意外將其提供給patch -p1。合併差異格式是為審查合併提交更改而建立的,並非用於應用。此更改類似於擴充套件索引頭中的更改

    @@@ <from-file-range> <from-file-range> <to-file-range> @@@

    組合 diff 格式的塊頭中有(父級數量 + 1)個 @ 字元。

與傳統的統一差異格式不同,傳統格式顯示兩個檔案A和B,帶有一個單列字首,其中-表示(減號 — 出現在A中但在B中被刪除),+表示(加號 — 在A中缺失但在B中新增),或者" "表示(空格 — 未更改);此格式將兩個或多個檔案 file1、file2 等與一個檔案 X 進行比較,並顯示 X 與每個 fileN 的差異。輸出行前會為每個fileN新增一個列,以表示X的行與它的差異。

列N中的-字元表示該行出現在fileN中,但未出現在結果中。列N中的+字元表示該行出現在結果中,而fileN沒有該行(換句話說,從該父級的角度來看,該行是新增的)。

在上述示例輸出中,函式簽名從兩個檔案都發生了更改(因此 file1 和 file2 中都有兩個-被刪除,加上++表示新增的一行未出現在 file1 或 file2 中)。此外,其他八行與 file1 相同,但未出現在 file2 中(因此以+為字首)。

當由 git diff-tree -c 顯示時,它會將合併提交的父節點與合併結果進行比較(即 file1..fileN 是父節點)。當由 git diff-files -c 顯示時,它會將兩個未解決的合併父節點與工作區檔案進行比較(即 file1 是階段 2,也稱為“我們的版本”;file2 是階段 3,也稱為“他們的版本”)。

示例

git log --no-merges

顯示完整的提交歷史,但跳過任何合併。

git log v2.6.12.. include/scsi drivers/scsi

顯示從版本 v2.6.12 開始,更改了 include/scsidrivers/scsi 子目錄中任何檔案的所有提交。

git log --since="2 weeks ago" -- gitk

顯示過去兩週內對檔案 gitk 的更改。使用 -- 是為了避免與名為 gitk 的 **分支** 混淆。

git log --name-status release..test

顯示在“test”分支中但尚未在“release”分支中的提交,以及每個提交修改的路徑列表。

git log --follow builtin/rev-list.c

顯示更改了 builtin/rev-list.c 的提交,包括在該檔案被賦予當前名稱之前發生的提交。

git log --branches --not --remotes=origin

顯示存在於任何本地分支中但不存在於 origin 的任何遠端跟蹤分支中的所有提交(即你擁有而 origin 沒有的)。

git log master --not --remotes=*/master

顯示存在於本地 master 分支中但不存在於任何遠端倉庫的 master 分支中的所有提交。

git log -p -m --first-parent

顯示歷史記錄,包括更改差異,但僅從“主分支”的角度,跳過來自已合併分支的提交,並顯示由合併引入的更改的完整差異。這僅在遵循嚴格策略,即在保持單個整合分支時合併所有主題分支時才有意義。

git log -L /int main/',/^}/:main.c

顯示檔案 main.c 中函式 main() 如何隨時間演變。

git log -3

將要顯示的提交數量限制為 3。

討論

Git 在某種程度上是字元編碼無關的。

  • blob 物件的內容是未經解釋的位元組序列。核心層面沒有編碼轉換。

  • 路徑名採用 UTF-8 C 規範化形式編碼。這適用於樹物件、索引檔案、引用名稱,以及命令列引數、環境變數和配置檔案(.git/config(參見 git-config[1])、gitignore[5]gitattributes[5]gitmodules[5])中的路徑名。

    請注意,Git 在核心層面將路徑名簡單地視為非 NUL 位元組序列,沒有路徑名編碼轉換(Mac 和 Windows 除外)。因此,即使在使用傳統擴充套件 ASCII 編碼的平臺和檔案系統上,使用非 ASCII 路徑名也大多可以正常工作。但是,在此類系統上建立的倉庫在基於 UTF-8 的系統(例如 Linux、Mac、Windows)上將無法正常工作,反之亦然。此外,許多基於 Git 的工具簡單地假定路徑名為 UTF-8,並且無法正確顯示其他編碼。

  • 提交日誌訊息通常以 UTF-8 編碼,但也支援其他擴充套件 ASCII 編碼。這包括 ISO-8859-x、CP125x 以及許多其他編碼,但 *不* 包括 UTF-16/32、EBCDIC 和 CJK 多位元組編碼(GBK、Shift-JIS、Big5、EUC-x、CP9xx 等)。

儘管我們鼓勵提交日誌訊息使用 UTF-8 編碼,但核心 Git 和 Git Porcelain 都設計為不強制專案使用 UTF-8。如果某個專案的所有參與者覺得使用傳統編碼更方便,Git 並不會禁止。但是,有幾點需要記住。

  1. git commitgit commit-tree 會發出警告,如果提交日誌訊息看起來不像有效的 UTF-8 字串,除非您明確指出您的專案使用傳統編碼。表示此意的方式是在 .git/config 檔案中設定 i18n.commitEncoding,如下所示

    [i18n]
    	commitEncoding = ISO-8859-1

    使用上述設定建立的提交物件會在其 encoding 頭中記錄 i18n.commitEncoding 的值。這有助於以後檢視它們的人。缺少此頭則意味著提交日誌訊息以 UTF-8 編碼。

  2. git loggit showgit blame 等命令會檢視提交物件的 encoding 頭,並嘗試將日誌訊息重新編碼為 UTF-8,除非另有指定。您可以透過在 .git/config 檔案中設定 i18n.logOutputEncoding 來指定所需的輸出編碼,如下所示

    [i18n]
    	logOutputEncoding = ISO-8859-1

    如果您沒有此配置變數,則會使用 i18n.commitEncoding 的值。

請注意,我們故意選擇在提交時不對提交日誌訊息進行重新編碼以強制在提交物件級別使用 UTF-8,因為重新編碼為 UTF-8 不一定是可逆操作。

配置

有關核心變數,請參閱 git-config[1];有關差異生成設定,請參閱 git-diff[1]

format.pretty

--format 選項的預設值。(參見上文的 Pretty Formats)。預設為 medium

i18n.logOutputEncoding

顯示日誌時使用的編碼。(參見上文的 Discussion)。如果設定了 i18n.commitEncoding,則預設為其值;否則為 UTF-8。

本節中此行以上的所有內容均未包含在 git-config[1] 文件中。以下內容與該文件中的內容相同

log.abbrevCommit

如果為 true,則使 git-log[1]git-show[1]git-whatchanged[1] 假定使用 --abbrev-commit 選項。您可以使用 --no-abbrev-commit 選項覆蓋此設定。

log.date

設定 log 命令的預設日期時間模式。為 log.date 設定值類似於使用 git log--date 選項。詳見 git-log[1]

如果格式設定為 "auto:foo" 且正在使用分頁器,則日期格式將使用 "foo" 格式。否則,將使用 "default"。

log.decorate

打印出 log 命令顯示的任何提交的引用名稱。如果指定了 short,則不會列印引用名稱字首 refs/heads/refs/tags/refs/remotes/。如果指定了 full,則會列印完整的引用名稱(包括字首)。如果指定了 auto,那麼如果輸出到終端,引用名稱將以 short 模式顯示,否則不顯示引用名稱。這與 git log 命令的 --decorate 選項相同。

log.initialDecorationSet

預設情況下,git log 僅顯示某些已知引用名稱空間的裝飾。如果指定了 all,則顯示所有引用作為裝飾。

log.excludeDecoration

從日誌裝飾中排除指定的模式。這類似於 --decorate-refs-exclude 命令列選項,但此配置選項可被 --decorate-refs 選項覆蓋。

log.diffMerges

設定當指定 --diff-merges=on 時使用的差異格式,詳見 git-log[1] 中的 --diff-merges 選項。預設為 separate

log.follow

如果為 true,則當給定單個 <path> 時,git log 將表現得如同使用了 --follow 選項。這與 --follow 具有相同的限制,即它不能用於跟蹤多個檔案,並且在非線性歷史記錄上效果不佳。

log.graphColors

一個以逗號分隔的顏色列表,可用於在 git log --graph 中繪製歷史線條。

log.showRoot

如果為 true,則初始提交將顯示為一個大型建立事件。這相當於與一個空樹進行差異比較。像 git-log[1]git-whatchanged[1] 這樣通常會隱藏根提交的工具現在將顯示它。預設為 true。

log.showSignature

如果為 true,則使 git-log[1]git-show[1]git-whatchanged[1] 假定使用 --show-signature 選項。

log.mailmap

如果為 true,則使 git-log[1]git-show[1]git-whatchanged[1] 假定使用 --use-mailmap 選項,否則假定使用 --no-use-mailmap 選項。預設為 true。

notes.mergeStrategy

解決備註衝突時預設選擇的合併策略。必須是 manualourstheirsunioncat_sort_uniq 之一。預設為 manual。有關每種策略的更多資訊,請參閱 git-notes[1] 的“NOTES MERGE STRATEGIES”部分。

此設定可以透過向 git-notes[1] 傳遞 --strategy 選項來覆蓋。

notes.<name>.mergeStrategy

將備註合併到 refs/notes/<name> 時選擇的合併策略。這會覆蓋更通用的 notes.mergeStrategy 設定。有關可用策略的更多資訊,請參閱 git-notes[1] 的“NOTES MERGE STRATEGIES”部分。

notes.displayRef

在顯示提交訊息時,除了由 core.notesRefGIT_NOTES_REF 設定的預設引用外,還從哪個引用(或多個引用,如果是 glob 模式或多次指定)讀取備註,在使用 git log 系列命令時。

此設定可以透過 GIT_NOTES_DISPLAY_REF 環境變數覆蓋,該變數必須是一個以冒號分隔的引用或 glob 列表。

對於不存在的引用將發出警告,但與任何引用不匹配的 glob 將被靜默忽略。

此設定可透過 git-log[1] 系列命令的 --no-notes 選項停用,或透過這些命令接受的 --notes=<ref> 選項停用。

core.notesRef 的有效值(可能被 GIT_NOTES_REF 覆蓋)也會隱式新增到要顯示的引用列表中。

notes.rewrite.<command>

當使用 <command>(當前為 amendrebase)重寫提交時,如果此變數為 false,git 將不會從原始提交複製備註到重寫後的提交。預設為 true。另請參閱下面的 notes.rewriteRef

此設定可以透過 GIT_NOTES_REWRITE_REF 環境變數覆蓋,該變數必須是一個以冒號分隔的引用或 glob 列表。

notes.rewriteMode

在重寫期間複製備註時(參見 notes.rewrite.<command> 選項),確定如果目標提交已有備註時該怎麼做。必須是 overwriteconcatenatecat_sort_uniqignore 之一。預設為 concatenate

此設定可以透過 GIT_NOTES_REWRITE_MODE 環境變數覆蓋。

notes.rewriteRef

在重寫期間複製備註時,指定(完全限定的)要複製備註的引用。可以是一個 glob,在這種情況下,所有匹配引用中的備註都將被複制。您也可以多次指定此配置。

沒有預設值;您必須配置此變數才能啟用備註重寫。將其設定為 refs/notes/commits 以啟用預設提交備註的重寫。

可以透過 GIT_NOTES_REWRITE_REF 環境變數覆蓋。有關其格式的進一步描述,請參見上面的 notes.rewrite.<command>

GIT

Git[1] 套件的一部分

scroll-to-top