設定與配置
取得與建立專案
基本快照
分支與合併
分享與更新專案
檢查與比較
修補
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
- 2.45.1 → 2.47.0 無變更
-
2.45.0
04/29/24
- 2.43.3 → 2.44.2 無變更
-
2.43.2
02/13/24
- 2.43.1 無變更
-
2.43.0
11/20/23
- 2.42.1 → 2.42.3 無變更
-
2.42.0
08/21/23
- 2.41.1 → 2.41.2 無變更
-
2.41.0
06/01/23
- 2.40.1 → 2.40.3 無變更
-
2.40.0
03/12/23
- 2.39.1 → 2.39.5 無變更
-
2.39.0
12/12/22
- 2.38.1 → 2.38.5 無變更
-
2.38.0
10/02/22
- 2.37.1 → 2.37.7 無變更
-
2.37.0
06/27/22
- 2.36.1 → 2.36.6 無變更
-
2.36.0
04/18/22
- 2.35.1 → 2.35.8 無變更
-
2.35.0
01/24/22
- 2.33.3 → 2.34.8 無變更
-
2.33.2
03/23/22
-
2.33.1
10/12/21
-
2.33.0
08/16/21
- 2.32.1 → 2.32.7 無變更
-
2.32.0
06/06/21
- 2.31.1 → 2.31.8 無變更
-
2.31.0
03/15/21
- 2.30.1 → 2.30.9 無變更
-
2.30.0
12/27/20
- 2.29.1 → 2.29.3 無變更
-
2.29.0
10/19/20
- 2.27.1 → 2.28.1 無變更
-
2.27.0
06/01/20
- 2.25.1 → 2.26.3 無變更
-
2.25.0
01/13/20
- 2.18.1 → 2.24.4 無變更
-
2.18.0
06/21/18
- 2.13.7 → 2.17.6 無變更
-
2.12.5
09/22/17
- 2.1.4 → 2.11.4 無變更
-
2.0.5
12/17/14
概要
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。如果 width 為
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/
中的所有 ref,以及HEAD
,都以 <commit> 的形式列在命令列上。 - --branches[=<pattern>]
-
假裝
refs/heads
中的所有 ref 都以 <commit> 的形式列在命令列上。如果給定 <pattern>,則將分支限制為符合給定的 shell glob 的分支。如果模式缺少 ?、* 或 [,則暗示結尾的 /*。 - --tags[=<pattern>]
-
假裝
refs/tags
中的所有 ref 都以 <commit> 的形式列在命令列上。如果給定 <pattern>,則將標籤限制為符合給定的 shell glob 的標籤。如果模式缺少 ?、* 或 [,則暗示結尾的 /*。 - --remotes[=<pattern>]
-
假裝
refs/remotes
中的所有 ref 都以 <commit> 的形式列在命令列上。如果給定 <pattern>,則將遠端追蹤分支限制為符合給定的 shell glob 的分支。如果模式缺少 ?、* 或 [,則暗示結尾的 /*。 - --glob=<glob-pattern>
-
假裝符合 shell glob <glob-pattern> 的所有 ref 都以 <commit> 的形式列在命令列上。如果缺少,則會自動在前面加上 refs/。如果模式缺少 ?、* 或 [,則暗示結尾的 /*。
- --exclude=<glob-pattern>
-
不要包含下一個
--all
、--branches
、--tags
、--remotes
或--glob
否則會考慮的符合 <glob-pattern> 的 ref。重複此選項會累積排除模式,直到下一個--all
、--branches
、--tags
、--remotes
或--glob
選項(其他選項或引數不會清除累積的模式)。當分別應用於
--branches
、--tags
或--remotes
時,給定的模式不應以refs/heads
、refs/tags
或refs/remotes
開頭,並且當應用於--glob
或--all
時,它們必須以refs/
開頭。如果預期結尾的 /*,則必須明確給定。 -
不要包含
git-fetch
、git-receive-pack
或git-upload-pack
會透過查詢適當的fetch.hideRefs
、receive.hideRefs
或uploadpack.hideRefs
組態以及transfer.hideRefs
隱藏的 ref(請參閱 git-config[1])。此選項會影響下一個虛擬 ref 選項--all
或--glob
,並在處理它們後清除。 - --reflog
-
假裝 reflog 中提及的所有物件都以
<commit>
的形式列在命令列上。 - --alternate-refs
-
假裝在替代儲存庫的 ref 提示中提及的所有物件都列在命令列上。替代儲存庫是指任何物件目錄在
objects/info/alternates
中指定的儲存庫。包含的物件集可能會由core.alternateRefsCommand
等修改。請參閱 git-config[1]。 - --single-worktree
-
預設情況下,當有多個工作樹時(請參閱 git-worktree[1]),後續選項將檢查所有工作樹:
--all
、--reflog
和--indexed-objects
。此選項會強制它們僅檢查目前的工作樹。 - --ignore-missing
-
當在輸入中看到無效的物件名稱時,假裝沒有提供錯誤的輸入。
- --bisect
-
假裝列出了錯誤的二分 ref
refs/bisect/bad
,並且後面跟著--not
以及命令列上正確的二分 refrefs/bisect/good-*
。 - --stdin
-
除了從命令列取得引數外,也從標準輸入讀取它們。這會接受提交和虛擬選項,例如
--all
和--glob=
。當看到--
分隔符號時,後續輸入會被視為路徑,並用於限制結果。透過標準輸入讀取的旗標(例如--not
)僅對以相同方式傳遞的引數有效,並且不會影響任何後續的命令列引數。 - --cherry-mark
-
類似於
--cherry-pick
(請參閱下文),但將等效的提交標記為=
而不是省略它們,並將不等效的提交標記為+
。 - --cherry-pick
-
當提交集合以對稱差異限制時,省略任何引入與「另一側」另一個提交相同變更的提交。
例如,如果您有兩個分支
A
和B
,則通常列出它們中只有一側的所有提交的方式是使用--left-right
(請參閱下文--left-right
選項的描述中的範例)。但是,它會顯示從另一個分支選取的提交(例如,「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
-
不走訪提交的祖先鏈,而是從最新的到較舊的依序走訪 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
中的第一個現有偽參考。僅當索引具有未合併的條目時才有效。此選項可用於在解析三向合併的衝突時顯示相關提交。 - --boundary
-
輸出排除的邊界提交。邊界提交以
-
作為前綴。
歷史簡化
有時您只對歷史的某些部分感興趣,例如修改特定 <path> 的提交。但是,歷史簡化有兩個部分,一部分是選擇提交,另一部分是如何進行,因為有多種策略可以簡化歷史。
以下選項選擇要顯示的提交
請注意,可能會顯示額外的提交以提供有意義的歷史記錄。
以下選項會影響簡化的執行方式
- 預設模式
-
將歷史簡化為最簡單的歷史,以解釋樹的最終狀態。之所以最簡單,是因為如果最終結果相同(即合併具有相同內容的分支),它會修剪一些側分支。
- --show-pulls
-
包含預設模式的所有提交,以及任何與第一個父提交不是 TREESAME,但與後來的父提交是 TREESAME 的合併提交。此模式有助於顯示「首次引入」分支變更的合併提交。
- --full-history
-
與預設模式相同,但不修剪某些歷史記錄。
- --dense
-
僅顯示選取的提交,加上一些以產生有意義的歷史記錄。
- --sparse
-
顯示簡化歷史中的所有提交。
- --simplify-merges
-
--full-history
的附加選項,可從產生的歷史記錄中移除一些不必要的合併,因為沒有選取的提交會促成此合併。 - --ancestry-path[=<commit>]
-
當給定要顯示的提交範圍時(例如 *commit1..commit2* 或 *commit2 ^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。 -
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
從考量中排除。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
引入的錯誤所污染,並且需要修復時,我們可能只想查看 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 \ 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
檔案。
GIT
屬於 git[1] 套件的一部分