設定和配置
獲取和建立專案
基本快照
分支與合併
共享和更新專案
檢查和比較
打補丁
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
- 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”部分。)Each pretty-printed commit will be rewrapped before it is shown.
- --date=<format>
-
按給定日期字串格式顯示日期。(請參閱 git-log[1] 的“提交格式化”部分的
--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> 身份。如果成功,則應用郵件對映,並且除非指定了--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。如果寬度為
0
(零),則縮排輸出行而不對其進行包裝。 - <revision-range>
-
僅顯示指定修訂範圍內的提交。當未指定 <revision-range> 時,預設為
HEAD
(即導致當前提交的整個歷史)。origin..HEAD
指定所有從當前提交(即HEAD
)可達,但不可從origin
可達的提交。有關指定 <revision-range> 的完整方法列表,請參閱 gitrevisions[7] 的“指定範圍”部分。 - [--] <path>…
-
僅考慮足以解釋指定路徑匹配的檔案是如何形成的提交。
當可能發生混淆時,路徑可能需要加上
--
字首,以將其與選項或修訂範圍分隔開。
提交限制
除了使用描述中解釋的特殊符號指定應列出的提交範圍外,還可以應用額外的提交限制。
使用更多選項通常會進一步限制輸出(例如,--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>
-
限制輸出提交,使其 reflog 條目與指定模式(正則表示式)匹配。當有多個
--grep-reflog
時,選擇 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
-
查詢要包含的提交時,在遇到合併提交時只跟蹤第一個父提交。當檢視特定主題分支的演變時,此選項可以提供更好的概覽,因為合併到主題分支通常只是為了不時調整到更新的上游,此選項允許您忽略此類合併帶入歷史的單獨提交。
- --exclude-first-parent-only
-
查詢要排除的提交時(使用 ^),在遇到合併提交時只跟蹤第一個父提交。這可用於查詢主題分支從其與遠端分支分歧點以來的更改集,前提是任意合併可以是有效的主題分支更改。
- --not
-
反轉所有後續修訂說明符的 ^ 字首(或缺少字首)的含義,直到下一個
--not
。當在命令列上--stdin
之前使用時,透過 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/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
-
假裝引用日誌中提及的所有物件都作為 <commit> 列在命令列上。
- --alternate-refs
-
假裝所有在備用倉庫的引用提示中提到的物件都列在命令列上。備用倉庫是其物件目錄在
objects/info/alternates
中指定的任何倉庫。包含的物件集可以透過core.alternateRefsCommand
等修改。請參閱 git-config[1]。 - --single-worktree
-
預設情況下,當有多個工作樹時(參見 git-worktree[1]),以下選項將檢查所有工作樹:
--all
、--reflog
和--indexed-objects
。此選項強制它們僅檢查當前工作樹。 - --ignore-missing
-
在輸入中遇到無效物件名稱時,假裝沒有給出錯誤的輸入。
- --bisect
-
假裝 bad bisection 引用
refs/bisect/bad
已列出,並且其後跟著--not
和 good bisection 引用refs/bisect/good-*
在命令列上。 - --stdin
-
除了從命令列獲取引數外,也從標準輸入讀取。這接受提交和偽選項,如
--all
和--glob=
。當看到--
分隔符時,後續輸入將被視為路徑,並用於限制結果。透過標準輸入讀取的標誌(如--not
)僅對以相同方式傳遞的引數生效,並且不會影響任何後續的命令列引數。 - --cherry-mark
-
類似於
--cherry-pick
(見下文),但用=
標記等效提交而不是省略它們,用+
標記不等效提交。 - --cherry-pick
-
當提交集合透過對稱差異限制時,省略與“另一側”的另一個提交引入相同更改的任何提交。
例如,如果您有兩個分支
A
和B
,通常只列出其中一側的所有提交的方法是使用--left-right
(參見下面--left-right
選項描述中的示例)。但是,它會顯示從另一個分支揀選(cherry-picked)的提交(例如,“3rd on b”可能從分支 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
-
不遍歷提交祖先鏈,而是從最新條目到舊條目遍歷 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
模式下,提交訊息會以 reflog 資訊作為同一行的字首。此選項不能與--reverse
結合使用。另請參閱 git-reflog[1]。在
--pretty=reference
模式下,此資訊將完全不顯示。 -
- --merge
-
顯示在
HEAD...
<other> 範圍內觸及衝突路徑的提交,其中 <other> 是MERGE_HEAD
、CHERRY_PICK_HEAD
、REVERT_HEAD
或REBASE_HEAD
中第一個存在的偽引用。僅當索引有未合併條目時才有效。此選項可用於在解決三方合併衝突時顯示相關提交。 - --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
過濾的差異中,它們分別看起來不同和相同。)
在下文中,我們將始終引用相同的歷史示例來闡述簡化設定之間的差異。我們假設您正在此提交圖中過濾檔案 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
將字串組合為“quux xyzzy”。P
與O
是 TREESAME,但與E
不是。 -
X
是一個獨立的根提交,它添加了一個新檔案side
,Y
修改了它。Y
與X
是 TREESAME。它的合併Q
將side
新增到P
,Q
與P
是 TREESAME,但與Y
不是。
rev-list
反向遍歷歷史記錄,根據是否使用 --full-history
和/或父重寫(透過 --parents
或 --children
)來包含或排除提交。以下設定可用。
- 預設模式
-
如果提交與任何父級都不是 TREESAME,則包含它們(儘管這可以更改,請參閱下面的
--sparse
)。如果提交是合併,並且它與一個父級是 TREESAME,則只跟蹤該父級。(即使有幾個 TREESAME 父級,也只跟蹤其中一個。)否則,跟蹤所有父級。這導致
.-A---N---O / / / I---------D
請注意,只跟蹤 TREESAME 父級(如果存在)的規則如何完全排除了
B
。透過N
考慮了C
,但它是 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
引入的錯誤汙染並且需要修復時,我們可能只想檢視 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=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
,它被 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
與它們的第一個父級是 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
不太可能是用於合併到重要分支的合併提交。相反,合併 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
檔案。