設定與配置
取得與建立專案
基本快照
分支與合併
分享與更新專案
檢查與比較
修補
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
- 2.45.1 → 2.47.0 無變更
-
2.45.0
04/29/24
- 2.44.1 → 2.44.2 無變更
-
2.44.0
02/23/24
概要
(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance <branch>) <revision-range>…
描述
取得提交的範圍並將它們重播到新的位置。不會動到工作目錄和索引,也不會更新任何參考。此命令的輸出旨在用作 git update-ref --stdin
的輸入,這將更新相關的分支(請參閱下方的輸出章節)。
此命令為實驗性功能。行為可能會變更。
選項
- --onto <newbase>
-
建立新提交的起點。可以是任何有效的提交,而不僅僅是現有的分支名稱。
當指定
--onto
時,輸出中的 update-ref 命令將更新修訂範圍中的分支,使其指向新的提交,類似於git rebase --update-refs
更新受影響範圍內多個分支的方式。 - --advance <branch>
-
建立新提交的起點;必須是分支名稱。
當指定
--advance
時,輸出中的 update-ref 命令將更新作為--advance
引數傳遞的分支,使其指向新的提交(換句話說,這模仿了 cherry-pick 操作)。 - <revision-range>
-
要重播的提交範圍。可以傳遞多個 <revision-range>,但在
--advance <branch>
模式下,它們應該只有一個尖端,以便清楚 <branch> 應該指向哪裡。請參閱 git-rev-parse[1] 中的「指定範圍」以及下方的「提交限制」選項。
提交限制
除了使用描述中解釋的特殊符號來指定應該列出的提交範圍之外,還可以套用額外的提交限制。
除非另有說明,否則使用更多選項通常會進一步限制輸出(例如,--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/
開頭。如果打算加上結尾的 /*,則必須明確給定。 -
不要包含會被
git-fetch
、git-receive-pack
或git-upload-pack
隱藏的參考,它們會參考適當的fetch.hideRefs
、receive.hideRefs
或uploadpack.hideRefs
設定,以及transfer.hideRefs
(請參閱 git-config[1])。此選項會影響下一個虛擬參考選項--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=
。當看到--
分隔符時,後續的輸入會被視為路徑,並用於限制結果。通過標準輸入讀取的標誌(例如--not
)僅對以相同方式傳遞的參數有效,並且不會影響任何後續的命令列參數。 - --cherry-mark
-
如同
--cherry-pick
(請參閱下方),但是用=
標記等效的提交,而不是省略它們,並用+
標記不等效的提交。 - --cherry-pick
-
當提交集合使用對稱差異進行限制時,省略任何引入與「另一側」另一個提交相同變更的提交。
例如,如果您有兩個分支
A
和B
,通常列出它們的單側提交的方式是使用--left-right
(請參閱下方--left-right
選項描述中的範例)。但是,它會顯示從另一個分支 cherry-pick 的提交(例如,「b 上的第三次提交」可能從分支 A cherry-pick)。使用此選項,此類提交對會從輸出中排除。 - --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 條目到較舊的條目走訪 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
的 commit 稱為 !TREESAME,其餘則為 TREESAME。(在針對 foo
過濾的 diff 中,它們分別看起來不同和相等。)
在以下內容中,我們將始終參考相同的歷史範例,以說明簡化設定之間的差異。 我們假設您正在此 commit 圖表中為檔案 foo
進行過濾
.-A---M---N---O---P---Q / / / / / / I B C D E Y \ / / / / / `-------------' X
歷史記錄 A---Q 的水平線被視為每個合併的第一個父節點。 commit 為
-
I
是初始 commit,其中foo
的內容為「asdf」,並且檔案quux
的內容為「quux」。 初始 commit 會與空的樹狀結構進行比較,因此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
是一個獨立的根 commit,它新增了一個新檔案side
,而Y
修改了它。Y
對X
是 TREESAME。 其合併Q
將side
新增至P
,而Q
對P
是 TREESAME,但對Y
不是。
rev-list
向後遍歷歷史記錄,根據是否使用 --full-history
和/或父節點重寫(透過 --parents
或 --children
)來包含或排除 commit。 提供下列設定。
- 預設模式
-
如果 commit 對任何父節點都不是 TREESAME,則包含該 commit(雖然這可以變更,請參閱下方的
--sparse
)。 如果 commit 是合併,並且對一個父節點是 TREESAME,則只追蹤該父節點。(即使有數個 TREESAME 父節點,也只追蹤其中一個。)否則,追蹤所有父節點。這會導致
.-A---N---O / / / I---------D
請注意,如果有一個可用的 TREESAME 父節點,則只追蹤該父節點的規則如何完全移除了
B
的考量。C
是透過N
考量的,但是 TREESAME。 根 commit 會與空的樹狀結構進行比較,因此I
是 !TREESAME。父/子關係僅在
--parents
的情況下才可見,但這不會影響預設模式中選取的 commit,因此我們已顯示父節點行。 - --full-history 沒有父節點重寫
-
此模式與預設模式的不同之處在於:始終追蹤合併的所有父節點,即使它對其中一個父節點是 TREESAME。 即使合併的兩側都有包含的 commit,這並不表示合併本身也包含! 在範例中,我們得到
I A B N D O P Q
M
被排除,因為它對兩個父節點都是 TREESAME。E
、C
和B
都已遍歷,但只有B
是 !TREESAME,因此其他 commit 不會出現。請注意,如果沒有父節點重寫,則實際上無法談論 commit 之間的父/子關係,因此我們將它們顯示為已中斷連線。
- --full-history 具有父節點重寫
-
只有當一般 commit 為 !TREESAME 時才會包含(雖然這可以變更,請參閱下方的
--sparse
)。合併總是會被包含。 但是,其父節點清單會被重寫:沿著每個父節點,修剪掉本身未包含的 commit。 這會導致
.-A---M---N---O---P---Q / / / / / I B / D / \ / / / / `-------------'
與上方沒有重寫的
--full-history
比較。 請注意,E
因為 TREESAME 而被修剪掉,但 P 的父節點清單被重寫為包含E
的父節點I
。C
和N
以及X
、Y
和Q
也發生了相同的情況。
除了上述設定之外,您還可以變更 TREESAME 是否會影響包含
- --dense
-
如果遍歷的 commit 對任何父節點都不是 TREESAME,則包含該 commit。
- --sparse
-
包含所有已遍歷的 commit。
請注意,如果沒有
--full-history
,這仍然會簡化合併:如果其中一個父節點是 TREESAME,我們只追蹤該父節點,因此永遠不會遍歷合併的其他側。 - --simplify-merges
-
首先,以與使用父節點重寫的
--full-history
相同的方式建立歷史圖表(請參閱上方)。然後,根據下列規則將最終歷史記錄中的每個 commit
C
簡化為其取代項C'
-
將
C'
設定為C
。 -
使用其簡化項
P'
取代C'
的每個父節點P
。 在此過程中,捨棄其他父節點的祖先或對空樹狀結構為 TREESAME 的根 commit,並移除重複項,但請注意,永遠不要捨棄所有我們為 TREESAME 的父節點。 -
如果在此父節點重寫之後,
C'
是根或合併 commit(具有零個或 >1 個父節點)、邊界 commit 或 !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> 的後代,或者 commit 本身。
作為一個範例使用案例,請考慮以下 commit 歷史記錄
D---E-------F / \ \ B---C---G---H---I---J / \ A-------K---------------L--M
常規的 D..M 會計算
M
的祖先的 commit 集,但排除D
的祖先的 commit。 這對於了解自D
以來導致M
的歷史記錄發生了什麼很有用,就「M
有什麼D
中不存在的」而言。 在此範例中的結果將是所有 commit,但A
和B
(當然還有D
本身)。但是,當我們想要找出
M
中哪些 commit 已受到D
引入的錯誤污染且需要修正時,我們可能只想檢視實際上是D
的後代的 D..M 子集,也就是排除C
和K
。 這正是--ancestry-path
選項的作用。 應用於 D..M 範圍時,會產生E-------F \ \ G---H---I---J \ L--M
我們也可以使用
--ancestry-path=D
來取代--ancestry-path
,這表示當應用於 D..M 範圍時,意義相同,但只是更明確。如果我們對此範圍內的特定主題感興趣,以及受到該主題影響的所有 commit,我們可能只想檢視
D..M
中其祖先路徑包含該主題的子集。 因此,例如針對--ancestry-path=H D..M
會產生E \ G---H---I---J \ L--M
而
--ancestry-path=K D..M
會產生K---------------L--M
在討論另一個選項 --show-pulls
之前,我們需要建立新的歷史記錄範例。
使用者在查看簡化的歷史記錄時遇到的一個常見問題是,他們知道 commit 以某種方式變更了檔案,但該 commit 不會出現在檔案的簡化歷史記錄中。 讓我們示範一個新的範例,並展示 --full-history
和 --simplify-merges
等選項在該案例中如何運作
.-A---M-----C--N---O---P / / \ \ \/ / / I B \ R-'`-Z' / \ / \/ / \ / /\ / `---X--' `---Y--'
對於此範例,假設 I
建立了 file.txt
,該檔案由 A
、B
和 X
以不同的方式修改。 單一父節點 commit C
、Z
和 Y
不會變更 file.txt
。 合併 commit M
是透過解決合併衝突來建立的,以包含來自 A
和 B
的兩個變更,因此對兩者都不是 TREESAME。 但是,合併 commit R
是透過忽略 M
處的 file.txt
內容並僅採用 X
處的 file.txt
內容來建立的。 因此,R
對 X
是 TREESAME,但對 M
不是。 最後,建立 N
的自然合併解決方案是採用 R
處的 file.txt
內容,因此 N
對 R
是 TREESAME,但對 C
不是。 合併 commit O
和 P
對其第一個父節點是 TREESAME,但對其第二個父節點 Z
和 Y
不是。
當使用預設模式時,N
和 R
都有一個 TREESAME 父節點,因此會遍歷這些邊緣,而忽略其他邊緣。 產生的歷史圖表為
I---X
當使用 --full-history
時,Git 會遍歷每個邊緣。 這會探索 commit A
和 B
以及合併 M
,但也會顯示合併 commit O
和 P
。 使用父節點重寫時,產生的圖表為
.-A---M--------N---O---P / / \ \ \/ / / I B \ R-'`--' / \ / \/ / \ / /\ / `---X--' `------'
在此,合併 commit O
和 P
會產生額外的雜訊,因為它們實際上並未對 file.txt
產生變更。 它們僅合併了一個基於舊版 file.txt
的主題。 在使用工作流程的存放庫中,許多參與者同時工作並沿著單一主幹合併其主題分支時,這是一個常見的問題:許多不相關的合併會出現在 --full-history
結果中。
當使用 --simplify-merges
選項時,commit O
和 P
會從結果中消失。 這是因為 O
和 P
的重寫第二個父節點可以從其第一個父節點存取。 這些邊緣會被移除,然後 commit 看起來像是對其父節點為 TREESAME 的單一父節點 commit。 N
的 commit 也會發生這種情況,導致歷史記錄檢視如下
.-A---M--. / / \ I B R \ / / \ / / `---X--'
在此檢視中,我們會看到來自 A
、B
和 X
的所有重要單一父節點變更。 我們還會看到經過仔細解決的合併 M
和未經過仔細解決的合併 R
。 這通常足以判斷為何 commit A
和 B
在預設檢視中從歷史記錄中「消失」。 但是,此方法存在一些問題。
第一個問題是效能。 與任何先前的選項不同,--simplify-merges
選項需要在傳回單一結果之前遍歷整個 commit 歷史記錄。 這可能會使該選項難以用於非常大的存放庫。
第二個問題是稽核。 當許多參與者在同一個存放庫中工作時,哪個合併 commit 將變更引入重要分支是很重要的。 上方有問題的合併 R
不太可能是用於合併到重要分支中的合併 commit。 相反地,合併 N
用於將 R
和 X
合併到重要分支中。 此 commit 可能在其 commit 訊息中包含有關為何變更 X
會覆寫來自 A
和 B
的變更的資訊。
- --show-pulls
-
除了預設歷史記錄中顯示的 commit 之外,還會顯示每個對其第一個父節點不是 TREESAME 但對稍後父節點為 TREESAME 的合併 commit。
當
--show-pulls
包含合併 commit 時,該合併會被視為從另一個分支「提取」變更。 當在此範例中使用--show-pulls
(且沒有其他選項)時,產生的圖表為I---X---R---N
在此,合併 commit
R
和N
會被包含,因為它們分別將 commitX
和R
提取到基礎分支中。 這些合併是預設歷史記錄中沒有出現 commitA
和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 (可以被簡化移除)。
提交排序
預設情況下,提交會以反向時間順序顯示。
- --date-order
-
在顯示任何子提交之前,不顯示任何父提交,但除此之外,按照提交時間戳記順序顯示提交。
- --author-date-order
-
在顯示任何子提交之前,不顯示任何父提交,但除此之外,按照作者時間戳記順序顯示提交。
- --topo-order
-
在顯示任何子提交之前,不顯示任何父提交,並避免顯示來自多個歷史線的混合提交。
例如,在像這樣的提交歷史中
---1----2----4----7 \ \ 3----5----6----8---
其中數字表示提交時間戳記的順序,使用
--date-order
的git rev-list
和相關指令會按照時間戳記順序顯示提交: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
組合使用。
提交格式化
- --pretty[=<format>]
- --format=<format>
-
以給定的格式漂亮地列印提交日誌的內容,其中 <format> 可以是 oneline、short、medium、full、fuller、reference、email、raw、format:<string> 和 tformat:<string> 之一。當 <format> 不是以上任何一個,並且其中包含 %placeholder 時,它的行為就像給定了 --pretty=tformat:<format> 一樣。
請參閱「PRETTY FORMATS」章節,了解每種格式的一些其他詳細資訊。當省略 =<format> 部分時,預設為 medium。
注意:您可以在儲存庫組態中指定預設的漂亮格式 (請參閱 git-config[1])。
- --abbrev-commit
-
不顯示完整的 40 位元組十六進制提交物件名稱,而是顯示一個唯一命名該物件的前綴。可以使用「--abbrev=<n>」選項 (如果顯示,它也會修改 diff 輸出) 來指定前綴的最小長度。
這應該讓使用 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
-
在輸出中顯示日誌訊息之前,執行 Tab 擴展 (將每個 Tab 替換為足夠的空格,以填滿下一個顯示列,該顯示列是 <n> 的倍數)。
--expand-tabs
是--expand-tabs=8
的簡寫,而--no-expand-tabs
是--expand-tabs=0
的簡寫,它會停用 Tab 擴展。預設情況下,Tab 會在以 4 個空格縮排日誌訊息的漂亮格式中展開 (即 medium (預設值)、full 和 fuller)。
- --notes[=<ref>]
-
在顯示提交日誌訊息時,顯示註解提交的註解 (請參閱 git-notes[1])。當命令列上沒有給定
--pretty
、--format
或--oneline
選項時,這是git log
、git show
和git whatchanged
指令的預設行為。預設情況下,顯示的註解來自
core.notesRef
和notes.displayRef
變數 (或對應的環境覆寫) 中列出的註解 ref。請參閱 git-config[1],以取得更多詳細資訊。使用可選的 <ref> 引數,使用 ref 來尋找要顯示的註解。當 ref 以
refs/notes/
開頭時,可以指定完整的 refname;當它以notes/
開頭時,會加上refs/
,否則會加上refs/notes/
以形成 ref 的完整名稱。可以組合多個 --notes 選項,以控制顯示哪些註解。範例:「--notes=foo」將僅顯示來自「refs/notes/foo」的註解;「--notes=foo --notes」將顯示來自「refs/notes/foo」和預設註解 ref 的註解。
- --no-notes
-
不顯示註解。這會否定上述的
--notes
選項,方法是重設顯示註解的註解 ref 清單。選項會按照在命令列上給定的順序解析,因此例如「--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 小時前」。-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"),後接 4 位數字的年份,加上時區資訊,除非使用本地時區,例如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>
,則會顯示該字串,而不是預設的字串。
輸出
當沒有衝突時,此命令的輸出可用作 git update-ref --stdin
的輸入。其格式如下:
update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH}
其中更新的參考數量取決於傳遞的參數和正在重播的歷史形狀。當使用 --advance
時,更新的參考數量始終為一個,但是對於 --onto
,它可以是一個或多個(支援同時變基多個分支)。
範例
要簡單地將 mybranch
變基到 target
上
$ git replay --onto target origin/main..mybranch update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH}
要將 mybranch 中的提交 cherry-pick 到 target 上
$ git replay --advance target origin/main..mybranch update refs/heads/target ${NEW_target_HASH} ${OLD_target_HASH}
請注意,前兩個範例重播完全相同的提交,並且在完全相同的新基礎之上,它們的唯一區別在於,第一個範例提供了使 mybranch 指向新提交的指令,而第二個範例提供了使 target 指向新提交的指令。
如果您有一堆分支,一個分支依賴於另一個分支,並且您真的想對整個集合進行變基,該怎麼辦?
$ git replay --contained --onto origin/main origin/main..tipbranch update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} update refs/heads/tipbranch ${NEW_tipbranch_HASH} ${OLD_tipbranch_HASH}
在呼叫 git replay
時,不需要使用 A..B
語法指定要重播的提交範圍;任何範圍表示式都可以
$ git replay --onto origin/main ^base branch1 branch2 branch3 update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH}
這將同時對 branch1
、branch2
和 branch3
進行變基,它們自 base
以來的所有提交都將在 origin/main
之上進行重播。這三個分支可能在 base
之上有它們共有的提交,但情況不一定如此。
GIT
屬於 git[1] 套件的一部分