設定和配置
獲取和建立專案
基本快照
分支與合併
共享和更新專案
檢查和比較
打補丁
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
-
2.52.0
2025-11-17
-
2.51.2
2025-10-27
- 2.51.1 無更改
-
2.51.0
2025-08-18
- 2.50.1 無更改
-
2.50.0
2025-06-16
- 2.49.1 無更改
-
2.49.0
2025-03-14
- 2.48.1 → 2.48.2 無更改
-
2.48.0
2025-01-10
- 2.45.1 → 2.47.3 無更改
-
2.45.0
2024-04-29
- 2.43.3 → 2.44.4 無更改
-
2.43.2
2024-02-13
- 2.43.1 無變更
-
2.43.0
2023-11-20
- 2.42.1 → 2.42.4 無更改
-
2.42.0
2023-08-21
- 2.41.1 → 2.41.3 無更改
-
2.41.0
2023-06-01
- 2.40.1 → 2.40.4 無更改
-
2.40.0
2023-03-12
- 2.39.1 → 2.39.5 無變化
-
2.39.0
2022-12-12
- 2.38.1 → 2.38.5 無更改
-
2.38.0
2022-10-02
- 2.37.1 → 2.37.7 無更改
-
2.37.0
2022-06-27
- 2.36.1 → 2.36.6 無更改
-
2.36.0
2022-04-18
- 2.35.1 → 2.35.8 無更改
-
2.35.0
2022-01-24
- 2.33.3 → 2.34.8 無變更
-
2.33.2
2022-03-23
-
2.33.1
2021-10-12
-
2.33.0
2021-08-16
- 2.32.1 → 2.32.7 無變更
-
2.32.0
2021-06-06
- 2.31.1 → 2.31.8 無更改
-
2.31.0
2021-03-15
- 2.30.1 → 2.30.9 無更改
-
2.30.0
2020-12-27
- 2.29.1 → 2.29.3 無更改
-
2.29.0
2020-10-19
- 2.27.1 → 2.28.1 無變更
-
2.27.0
2020-06-01
- 2.25.1 → 2.26.3 無更改
-
2.25.0
2020-01-13
- 2.18.1 → 2.24.4 無更改
-
2.18.0
2018-06-21
- 2.13.7 → 2.17.6 無更改
-
2.12.5
2017-09-22
- 2.1.4 → 2.11.4 無更改
-
2.0.5
2014-12-17
概要
git shortlog [<options>] [<revision-range>] [[--] <path>…] git log --pretty=short | git shortlog [<options>]
描述
以適合包含在釋出公告中的格式彙總 git log 輸出。每個提交將按作者和標題分組。
此外,“[PATCH]”將從提交描述中剝離。
如果在命令列中未傳遞任何修訂版本,並且標準輸入不是終端,或者當前不存在分支,git shortlog 將輸出從標準輸入讀取的日誌摘要,而不引用當前儲存庫。
選項
- -n
- --numbered
-
按每位作者的提交次數對輸出進行排序,而不是按作者字母順序排序。
- -s
- --summary
-
禁止顯示提交描述,僅提供提交計數摘要。
- -e
-
顯示每位作者的電子郵件地址。
- --format[=<format>]
-
代替提交主題,使用其他資訊來描述每個提交。<format> 可以是 git log 的
--format選項接受的任何字串,例如 * [%h] %s。(參見 git-log[1] 的“PRETTY FORMATS”部分。)每個美化列印的提交在顯示前都將被重新包裝。
- --date=<format>
-
按照給定的日期字串格式化日期。(參見 git-log[1] 的“Commit Formatting”部分的
--date選項)。與--group=format:<format> 結合使用很有用。 - --group=<type>
-
根據 <type> 對提交進行分組。如果未指定
--group選項,則預設為author。<type> 是以下之一:-
author,按作者分組提交 -
committer,按提交者分組提交(與-c相同) -
trailer:<field>,<field> 被解釋為不區分大小寫的提交訊息尾註(參見 git-interpret-trailers[1])。例如,如果你的專案使用Reviewed-by尾註,你可能想透過git shortlog -ns --group=trailer:reviewed-by檢視誰在審查。 -
format:<format>,git log 的--format選項接受的任何字串。(參見 git-log[1] 的“PRETTY FORMATS”部分。)請注意,不包含該尾註的提交將不會被計算。同樣,具有多個尾註的提交(例如,多個籤核)可能會被計算多次(但在該提交中僅按唯一的尾註值計算一次)。
Shortlog 會嘗試將每個尾註值解析為
name <email>身份。如果成功,將應用 mailmap,除非指定了--email選項,否則電子郵件將被省略。如果值不能被解析為身份,它將被字面地、完整地接受。
如果多次指定
--group,提交將在每個值下進行計數(但同樣,在提交中僅按唯一的組合值計算一次)。例如,git shortlog --group=author --group=trailer:co-authored-by會同時計算作者和協作者。 -
- -c
- --committer
-
這是
--group=committer的別名。 - -w[<width>[,<indent1>[,<indent2>]]]
-
透過將每行包裝到
width來包裝輸出。每條條目的第一行縮排indent1個空格,第二行及後續行縮排indent2個空格。width、indent1和indent2預設分別為 76、6 和 9。如果 width 為
0(零),則縮排輸出行而不進行換行。 - <revision-range>
-
僅顯示指定修訂範圍內的提交。當未指定 <revision-range> 時,預設為
HEAD(即直到當前提交的整個歷史)。origin..HEAD指定了所有可從當前提交(即HEAD)到達但不能從origin到達的提交。有關指定 <revision-range> 的完整列表,請參閱 gitrevisions[7] 的“Specifying Ranges”部分。 - [--] <path>…
-
僅考慮足以解釋匹配指定路徑的檔案如何形成的提交。
當出現混淆時,路徑可能需要用
--作為字首,以將其與選項或修訂範圍分開。
提交限制
除了使用描述中解釋的特殊符號指定應列出的提交範圍外,還可以應用額外的提交限制。
使用更多選項通常會進一步限制輸出(例如,--since=<date1> 限制為比 <date1> 更新的提交,並且將其與 --grep=<pattern> 一起使用會進一步限制為其日誌訊息中有一行與 <pattern> 匹配的提交),除非另有說明。
請注意,這些是在提交排序和格式化選項(如 --reverse)之前應用的。
-<number>-n<number>--max-count=<number>-
將輸出限制為 <number> 個提交。
--skip=<number>-
在開始顯示提交輸出之前,跳過 <number> 個提交。
--since=<date>--after=<date>-
顯示比 <date> 更新的提交。
--since-as-filter=<date>-
顯示所有比 <date> 更新的提交。這會遍歷範圍內的所有提交,而不是在第一個比 <date> 舊的提交處停止。
--until=<date>--before=<date>-
顯示比 <date> 舊的提交。
--author=<pattern>--committer=<pattern>-
將提交輸出限制為作者/提交者標題行與 <pattern> 正則表示式匹配的提交。使用多個
--author=<pattern> 時,會選擇作者匹配任何 <pattern> 的提交(對多個--committer=<pattern> 類似)。 --grep-reflog=<pattern>-
將提交輸出限制為 reflog 條目與 <pattern> 正則表示式匹配的提交。使用多個
--grep-reflog時,會選擇 reflog 訊息匹配任何給定模式的提交。使用此選項但未同時使用--walk-reflogs是錯誤的。 --grep=<pattern>-
將提交輸出限制為其日誌訊息匹配 <pattern> 正則表示式的提交。使用多個
--grep=<pattern> 時,會選擇訊息匹配任何 <pattern> 的提交(但請參閱--all-match)。當
--notes生效時,來自備註的訊息將像日誌訊息的一部分一樣進行匹配。 --all-match-
限制提交輸出為匹配所有給定
--grep的提交,而不是匹配至少一個的提交。 --invert-grep-
將提交輸出限制為其日誌訊息不匹配使用
--grep=<pattern> 指定的 <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-
在查詢要包含的提交時,遇到合併提交時僅跟隨第一個父提交。此選項在檢視特定主題分支的演變時可能提供更好的概覽,因為合併到主題分支通常只是為了調整上游的更新,並且此選項允許您忽略此類合併帶來的歷史中的單個提交。
--exclude-first-parent-only-
在查詢要排除的提交(使用 ^)時,遇到合併提交時僅跟隨第一個父提交。當給定任意合併可以是有效主題分支更改時,這可用於查詢主題分支從其與遠端分支分叉的點開始的更改集。
--not-
反轉所有後續修訂說明符中的 ^ 字首(或缺乏字首)的含義,直到下一個
--not。當在命令列上使用 --stdin 之前時,透過 stdin 傳遞的修訂不會受其影響。反之,當透過標準輸入傳遞時,在命令列上透過的修訂不會受其影響。 --all-
假裝 refs/ 中的所有引用以及
HEAD都已在命令列上列為 <commit>。 --branches[=<pattern>]-
假裝 refs/heads 中的所有引用都已在命令列上列為 <commit>。如果給出了 <pattern>,則將分支限制為與給定 shell glob 匹配的分支。如果 <pattern> 缺少 ?、* 或 [,則在末尾隱含 /*。
--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>-
不包括與下一個
--all、--branches、--tags、--remotes或--glob將要考慮的 <glob-pattern> 匹配的引用。此選項的重複使用會累積排除模式,直到下一個--all、--branches、--tags、--remotes或--glob選項(其他選項或引數不會清除累積的模式)。當應用於
--branches、--tags或--remotes時,給出的模式不應分別以refs/heads、refs/tags或refs/remotes開頭,並且當應用於--glob或--all時,它們必須以refs/開頭。如果要匹配結尾的 /*,則必須顯式給出。 -
透過查閱適當的
fetch.hideRefs、receive.hideRefs或uploadpack.hideRefs配置以及transfer.hideRefs(請參閱 git-config[1]),不包括會被git-fetch、git-receive-pack或git-upload-pack隱藏的引用。此選項會影響下一個偽引用選項--all或--glob,並在處理它們之後清除。 --reflog-
假裝由 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=。當看到--分隔符時,後面的輸入被視為路徑並用於限制結果。透過 stdin 讀取的標誌(如--not)僅對以相同方式傳遞的引數有效,並且不會影響任何後續命令列引數。 --cherry-mark-
類似於
--cherry-pick(見下文),但用=標記等效提交而不是省略它們,用+標記不等效提交。 --cherry-pick-
當提交集合透過對稱差異限制時,省略與“另一側”的另一個提交引入相同更改的任何提交。
例如,如果您有兩個分支
A和B,列出它們其中一個分支上所有提交的常用方法是使用--left-right(請參閱下面的--left-right選項的說明中的示例)。但是,它會顯示從另一個分支 cherry-pick 的提交(例如,“b 上的第 3 個”可能從分支 A cherry-pick)。使用此選項,將從輸出中排除此類提交對。 --left-only--right-only-
僅列出對稱差集一側的提交,即僅那些由
--left-right標記為 < 或 > 的提交。例如,
--cherry-pick--right-onlyA...B將 B 中在 A 中或與 A 中的提交補丁等效的提交從 B 中省略。換句話說,這列出了gitcherryAB中的 + 提交。更精確地說,--cherry-pick--right-only--no-merges提供了確切列表。 --cherry-
是
--right-only--cherry-mark--no-merges的同義詞;對於限制我們這邊的提交很有用,並標記那些已被應用於分叉歷史的另一邊,使用gitlog--cherryupstream...mybranch,類似於gitcherryupstreammybranch。 -g--walk-reflogs-
不是遍歷提交祖先鏈,而是從最近的一個到較舊的一個遍歷 reflog 條目。使用此選項時,您不能指定要排除的提交(即,不能使用
^<commit>、<commit1>..<commit2> 和 <commit1>...<commit2> 表示法)。使用
--pretty格式(oneline和reference除外,原因顯而易見),這會導致輸出包含來自 reflog 的兩行額外資訊。輸出中的 reflog 識別符號可能顯示為ref@{<Nth>}(其中 <Nth> 是 reflog 中按時間倒序的索引)或ref@{<timestamp>}(帶有該條目的 <timestamp>),具體取決於一些規則。-
如果起始點指定為
ref@{<Nth>},則顯示索引格式。 -
如果起始點指定為
ref@{now},則顯示時間戳格式。 -
如果兩者都未用,但命令列上給出了
--date,則以--date請求的格式顯示時間戳。 -
否則,顯示索引格式。
在
--pretty=oneline下,提交訊息在該行上以這些資訊為字首。此選項不能與--reverse結合使用。另請參閱 git-reflog[1]。在
--pretty=reference模式下,此資訊將完全不顯示。 -
--merge-
顯示在
HEAD...<other> 範圍內接觸已衝突路徑的提交,其中 <other> 是MERGE_HEAD、CHERRY_PICK_HEAD、REVERT_HEAD或REBASE_HEAD中的第一個存在的偽引用。僅當索引包含未合併條目時才有效。此選項可用於在解決 3 路合併衝突時顯示相關提交。 --boundary-
輸出排除的邊界提交。邊界提交字首為
-。
歷史簡化
有時您只對歷史的一部分感興趣,例如修改特定 <path> 的提交。但是,"歷史簡化" 有兩個部分,一部分是選擇提交,另一部分是如何選擇,因為存在各種簡化歷史的策略。
以下選項選擇要顯示的提交
請注意,可以顯示額外的提交以提供有意義的歷史記錄。
以下選項影響簡化執行的方式
預設模式-
將歷史簡化為解釋樹最終狀態的最簡單歷史。之所以最簡單,是因為如果最終結果相同(即合併內容相同的分支),它會修剪一些旁支。
--show-pulls-
包含預設模式中的所有提交,但也包括任何與第一個父提交不 TREESAME 但與較晚的父提交 TREESAME 的合併提交。此模式有助於顯示“首次引入”更改到分支的合併提交。
--full-history-
與預設模式相同,但不會修剪某些歷史。
--dense-
只顯示選定的提交,以及一些具有有意義歷史的提交。
--sparse-
顯示簡化歷史中的所有提交。
--simplify-merges-
--full-history的附加選項,用於從結果歷史中刪除一些不必要的合併,因為沒有選定的提交對此合併有所貢獻。 --ancestry-path[=<commit>]-
當給定一個要顯示的提交範圍(例如 <commit1>
..<commit2> 或 <commit2>^<commit1>),以及該範圍內的提交 <commit> 時,只顯示在該範圍內是 <commit> 的祖先、<commit> 的後代,或者 <commit> 本身的提交。如果沒有指定提交,則將 <commit1>(範圍中排除的部分)用作 <commit>。可以多次傳遞;如果是這樣,如果一個提交是給定的任何提交之一,或者它是其中一個的祖先或後代,則包含該提交。
更詳細的解釋如下。
假設您指定了 foo 作為 <paths>。我們將呼叫修改 foo 的提交為 !TREESAME,其餘的為 TREESAME。(在為 foo 過濾的 diff 中,它們分別看起來不同和相同。)
在下文中,我們將始終引用相同的歷史示例來闡述簡化設定之間的差異。我們假設您正在此提交圖中過濾檔案 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)。 -
D將foo設定為baz。其合併O將N和D的字串合併為foobarbaz;即,它與任何父項都不同(!TREESAME)。 -
E將quux更改為xyzzy,其合併P將字串合併為quuxxyzzy。P與O是 TREESAME,但與E不是。 -
X是一個獨立的根提交,它添加了一個新檔案side,而Y修改了它。Y與X是 TREESAME。其合併Q將side新增到P,而Q與P是 TREESAME,但與Y不是。
rev-list 向後遍歷歷史記錄,根據是否使用了 --full-history 和/或父項重寫(透過 --parents 或 --children)來包含或排除提交。以下是可用的設定。
- 預設模式
-
包含的提交是那些與任何父項都不同的提交(儘管這可以改變,請參見下文的
--sparse)。如果提交是合併,並且它與一個父項是 TREESAME,則只跟隨該父項。(即使有多個 TREESAME 父項,也只跟隨其中一個。)否則,跟隨所有父項。這導致
.-A---N---O / / / I---------D
請注意,如果存在 TREESAME 父項,則只跟隨該 TREESAME 父項的規則如何使
B完全被排除。C是透過N考慮的,但它是 TREESAME。根提交與空樹進行比較,因此I是 !TREESAME。父/子關係僅在
--parents選項下可見,但這不影響預設模式下選擇的提交,因此我們已顯示父行。 --full-history無父重寫-
此模式與預設模式僅有一處不同:總是跟隨合併的所有父項,即使它與其中一個父項是 TREESAME。即使合併的多個分支都包含提交,這也不意味著合併本身會被包含!在示例中,我們得到:
I A B N D O P Q
M被排除是因為它與兩個父項都是 TREESAME。E、C和B都被遍歷,但只有B是 !TREESAME,因此其他的不出現。請注意,如果沒有父級重寫,很難真正談論提交之間的父/子關係,因此我們將它們顯示為斷開連線。
--full-history帶父重寫-
普通提交僅在它們是 !TREESAME 時才包含(儘管這可以更改,請參閱下面的
--sparse)。合併總是被包含。然而,它們的父列表被重寫:沿每個父列表,修剪掉本身未包含的提交。這導致
.-A---M---N---O---P---Q / / / / / I B / D / \ / / / / `-------------'
與上面的“不進行父項重寫的
--full-history”進行比較。請注意,E被刪除了,因為它本身是 TREESAME,但 P 的父項列表被重寫為包含E的父項I。對於C和N,以及X、Y和Q,也發生了同樣的情況。
除了上述設定之外,您還可以更改 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 \ / / `---------'
注意
N、P和Q相對於--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 中不存在的什麼”的意義上來說。在此示例中的結果將是所有提交,除了 A 和 B(以及 D 本身,當然)。
然而,當我們想找出 M 中的哪些提交受到了 D 引入的 bug 的汙染並需要修復時,我們可能只想檢視 D..M 中實際上是 D 的後代的提交子集,即排除 C 和 K。這正是 `--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=KD..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,該檔案被 A、B 和 X 以不同的方式修改。單父提交 C、Z 和 Y 不會改變 file.txt。合併提交 M 是透過解析合併衝突而建立的,以包含來自 A 和 B 的所有更改,因此它與兩者都不同(不是 TREESAME)。然而,合併提交 R 是透過忽略 M 時的 file.txt 內容而建立的,只取 X 時的 file.txt 內容。因此,R 與 X 是 TREESAME,但與 M 不是。最後,建立 N 的自然合併解析是採用 R 時的 file.txt 內容,所以 N 與 R 是 TREESAME,但與 C 不是。合併提交 O 和 P 分別與它們的第一個父提交(Z 和 Y)是 TREESAME,但與它們的第二個父提交(Z 和 Y)不是。
在使用預設模式時,N 和 R 都具有一個 TREESAME 父級,因此那些邊緣被遍歷,而其他的則被忽略。生成的歷史圖是
I---X
使用 `--full-history` 時,Git 會遍歷每個邊。這將發現提交 A 和 B 以及合併 M,但也會顯示合併提交 O 和 P。使用父項重寫後,生成的圖是:
.-A---M--------N---O---P / / \ \ \/ / / I B \ R-'`--' / \ / \/ / \ / /\ / `---X--' `------'
在這裡,合併提交 O 和 P 貢獻了額外的噪音,因為它們實際上沒有為 `file.txt` 貢獻更改。它們只是合併了一個基於舊版本 `file.txt` 的主題。這是在許多貢獻者並行工作並將主題分支合併到單條主線的工作流中常見的儲存庫問題:許多不相關的合併出現在 `--full-history` 的結果中。
當使用 `--simplify-merges` 選項時,提交 O 和 P 將從結果中消失。這是因為 O 和 P 的重寫後的第二個父項可以從它們的第一個父項到達。這些邊被移除,然後這些提交看起來像單父提交,並且與它們的父項是 TREESAME。提交 N 也發生這種情況,導致歷史檢視如下:
.-A---M--. / / \ I B R \ / / \ / / `---X--'
在此檢視中,我們看到了 A、B 和 X 的所有重要的單父提交更改。我們還看到了仔細解析的合併 M 和不太仔細解析的合併 R。這通常足以確定為什麼提交 A 和 B 在預設檢視中“消失”了。但是,此方法存在一些問題。
第一個問題是效能。與之前的任何選項不同,`--simplify-merges` 選項在返回單個結果之前需要遍歷整個提交歷史。這使得該選項對於非常大的儲存庫難以使用。
第二個問題是審計。當許多貢獻者在同一個儲存庫中工作時,哪個合併提交將更改引入重要分支是很重要的。上面的有問題的合併 R 很可能不是用於將 R 合併到重要分支的合併提交。相反,合併 N 用於將 R 和 X 合併到重要分支。該提交可能包含有關 X 的更改覆蓋 A 和 B 的更改原因的資訊。
--show-pulls-
除了預設歷史中顯示的提交外,顯示每個與其第一個父級不是 TREESAME 但與其後續父級是 TREESAME 的合併提交。
當合並提交被 `--show-pulls` 包含時,合併被視為“拉取”了另一個分支的更改。當在此示例上使用 `--show-pulls`(且沒有其他選項)時,生成的圖是:
I---X---R---N
在這裡,合併提交 R 和 N 被包含,因為它們分別拉取了提交 X 和 R 到主分支。這些合併是提交 A 和 B 不出現在預設歷史記錄中的原因。
當
--show-pulls與--simplify-merges配對使用時,圖表包含所有必要的資訊.-A---M--. N / / \ / I B R \ / / \ / / `---X--'
請注意,由於 M 可以從 R 到達,因此從 N 到 M 的邊被簡化掉了。然而,N 仍然作為重要的提交出現在歷史記錄中,因為它將更改 R “拉取”到了主分支。
`--simplify-by-decoration` 選項允許您僅檢視歷史拓撲的大圖,透過省略未被標籤引用的提交。當(1)它們被標籤引用,或(2)它們更改了命令列上給定的路徑的內容時,提交被標記為 !TREESAME(換句話說,在上述歷史簡化規則後保留)。所有其他提交被標記為 TREESAME(可能被簡化掉)。
作者對映
請參閱 gitmailmap[5]。
注意,如果在儲存庫外部執行 git shortlog(用於處理標準輸入上的日誌內容),它會在當前目錄中查詢 .mailmap 檔案。