設定和配置
獲取和建立專案
基本快照
分支與合併
共享和更新專案
檢查和比較
打補丁
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
- 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.44.1 → 2.44.4 無更改
-
2.44.0
2024-02-23
概要
(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 操作)。 - <修訂範圍>
-
要重放的提交範圍。可以傳遞多個 <修訂範圍>,但在
--advance
<branch> 模式下,它們應該有一個單一的尖端,以便清楚 <branch> 應該指向何處。請參閱 git-rev-parse[1] 中的“指定範圍”和下面的“限制提交”選項。
提交限制
除了使用描述中解釋的特殊符號指定應列出的提交範圍外,還可以應用額外的提交限制。
通常,使用更多選項會進一步限制輸出(例如,--since=
<date1> 將提交限制在比 <date1> 更新的提交,並且將其與 --grep=
<pattern> 一起使用會進一步限制到日誌訊息中有一行與 <pattern> 匹配的提交),除非另有說明。
請注意,這些是在提交排序和格式化選項(如 --reverse
)之前應用的。
- -<數量>
- -n <數量>
- --max-count=<數量>
-
限制輸出的提交數量。
- --skip=<數量>
-
在開始顯示提交輸出之前跳過 number 個提交。
- --since=<日期>
- --after=<日期>
-
顯示特定日期之後的所有提交。
- --since-as-filter=<日期>
-
顯示特定日期之後的所有提交。這將遍歷範圍內的所有提交,而不是在遇到第一個位元定日期更舊的提交時停止。
- --until=<日期>
- --before=<日期>
-
顯示特定日期之前的所有提交。
- --author=<模式>
- --committer=<模式>
-
限制提交輸出為作者/提交者頭行與指定模式(正則表示式)匹配的提交。如果使用多個
--author=
<pattern>,則選擇作者與任一給定模式匹配的提交(對於多個--committer=
<pattern> 類似)。 - --grep-reflog=<模式>
-
限制提交輸出為 reflog 條目與指定模式(正則表示式)匹配的提交。如果使用多個
--grep-reflog
,則選擇 reflog 訊息與任一給定模式匹配的提交。除非正在使用--walk-reflogs
,否則使用此選項是錯誤的。 - --grep=<模式>
-
限制提交輸出為日誌訊息與指定模式(正則表示式)匹配的提交。如果使用多個
--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=<數量>
- --max-parents=<數量>
- --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 之前使用時,透過標準輸入傳遞的修訂版本不會受其影響。相反,當透過標準輸入傳遞時,命令列中傳遞的修訂版本不會受其影響。 - --all
-
假裝
refs/
中的所有引用以及HEAD
都作為 <commit> 列在命令列上。 - --branches[=<模式>]
-
假裝
refs/heads
中的所有引用都以 <commit> 的形式在命令列中列出。如果給出 <pattern>,則將分支限制為匹配給定 shell glob 的分支。如果模式缺少 ?、* 或 [,則隱含在末尾新增 /*。 - --tags[=<模式>]
-
假裝
refs/tags
中的所有引用都以 <commit> 的形式在命令列中列出。如果給出 <pattern>,則將標籤限制為匹配給定 shell glob 的標籤。如果模式缺少 ?、* 或 [,則隱含在末尾新增 /*。 - --remotes[=<模式>]
-
假裝
refs/remotes
中的所有引用都以 <commit> 的形式在命令列中列出。如果給出 <pattern>,則將遠端跟蹤分支限制為匹配給定 shell glob 的分支。如果模式缺少 ?、* 或 [,則隱含在末尾新增 /*。 - --glob=<全域性模式>
-
假裝所有匹配 shell glob <glob-pattern> 的引用都以 <commit> 的形式在命令列中列出。如果缺少前導 refs/,則會自動新增。如果模式缺少 ?、* 或 [,則隱含在末尾新增 /*。
- --exclude=<全域性模式>
-
不包括與 <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
-
假裝不良二分查詢引用
refs/bisect/bad
已列出,並且其後是--not
和命令列上的良好二分查詢引用refs/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 符號)。
除了
oneline
和reference
(原因顯而易見)之外,使用--pretty
格式時,輸出將包含從 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[=<提交>]
-
當給定要顯示的提交範圍(例如 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> 本身。
作為一個示例用例,考慮以下提交歷史:
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
後代的 D..M 子集,即排除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(可能會被簡化掉)。
提交排序
預設情況下,提交按逆時間順序顯示。
- --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
結合使用。
提交格式化
- --pretty[=<格式>]
- --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>" 選項(如果顯示差異輸出,此選項也會對其進行修改)來指定字首的最小長度。
這應該會使使用 80 列終端的人員更容易閱讀 "--pretty=oneline"。
- --no-abbrev-commit
-
顯示完整的 40 位元組十六進位制提交物件名稱。這會取消
--abbrev-commit
的效果,無論是顯式的還是由其他選項(例如 "--oneline")隱含的。它還會覆蓋log.abbrevCommit
變數。 - --oneline
-
這是 "--pretty=oneline --abbrev-commit" 同時使用的簡寫形式。
- --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 個空格的美觀格式(即預設的 medium、full 和 fuller)中,製表符會被擴充套件。
- --notes[=<引用>]
-
在顯示提交日誌訊息時,顯示註釋提交的附註(參見 git-notes[1])。當命令列上沒有給定
--pretty
、--format
或--oneline
選項時,這是git
log
、git
show
和git
whatchanged
命令的預設行為。預設情況下,顯示的附註來自
core.notesRef
和notes.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[=<引用>]
- --[no-]standard-notes
-
這些選項已棄用。請改用上面的 --notes/--no-notes 選項。
- --show-signature
-
透過將簽名傳遞給
gpg
--verify
並顯示輸出來檢查已簽名提交物件的有效性。 - --relative-date
-
等同於
--date=relative
。 - --date=<格式>
-
僅對以人類可讀格式顯示的日期有效,例如使用
--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" 格式的小時-分鐘-秒,後跟 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[=<分隔符>]
-
當不使用 --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 的提交挑選到 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
之上有共同的提交,但這並非必須如此。