Git
英文 ▾ 主題 ▾ 最新版本 ▾ git-range-diff 最後更新於 2.43.0

名稱

git-range-diff - 比較兩個提交範圍 (例如,一個分支的兩個版本)

概要

git range-diff [--color=[<when>]] [--no-color] [<diff-options>]
	[--no-dual-color] [--creation-factor=<factor>]
	[--left-only | --right-only]
	( <range1> <range2> | <rev1>…​<rev2> | <base> <rev1> <rev2> )
	[[--] <path>…​]

描述

此命令顯示兩個修補程式系列版本之間的差異,或者更廣泛地說,兩個提交範圍之間的差異(忽略合併提交)。

在存在 <path> 引數的情況下,這些提交範圍會相應地受到限制。

為此,它首先會找到兩個提交範圍中彼此對應的提交配對。當兩個提交的修補程式之間的差異(即作者資訊、提交訊息和提交差異)與修補程式的大小相比合理地小時,就說它們彼此對應。請參閱下方的「演算法」以了解詳細資訊。

最後,匹配的提交列表會依照第二個提交範圍的順序顯示,未匹配的提交會插入到它們的所有祖先顯示之後。

有三種方式可以指定提交範圍

  • <range1> <range2>:任一提交範圍的形式可以是 <base>..<rev><rev>^!<rev>^-<n>。請參閱 gitrevisions[7] 中的 SPECIFYING RANGES 以了解更多詳細資訊。

  • <rev1>...<rev2>。這等同於 <rev2>..<rev1> <rev1>..<rev2>

  • <base> <rev1> <rev2>:這等同於 <base>..<rev1> <base>..<rev2>

選項

--no-dual-color

當提交差異不同時,git range-diff 會重新建立原始差異的色彩,並加上外部的 -/+ 差異標記,其背景為紅色/綠色,以便更容易查看(例如,當新增的確切行發生變更時)。

此外,僅存在於第一個提交範圍中的提交差異行會以「變暗」的方式顯示(這可以使用 color.diff.<slot> 配置設定覆寫,其中 <slot>contextDimmedoldDimmednewDimmed 其中之一),而僅存在於第二個提交範圍中的提交差異行會以粗體顯示(這可以使用 color.diff.<slot> 配置設定覆寫,其中 <slot>contextBoldoldBoldnewBold 其中之一)。

這在 range-diff 中稱為「雙重著色」。使用 --no-dual-color 可以還原為依照外部差異標記為所有行著色(並在顏色方面完全忽略內部差異)。

--creation-factor=<percent>

將建立/刪除成本的調整係數設定為 <percent>。預設值為 60。如果 git range-diff 錯誤地將大型變更視為完全重寫(刪除一個提交並新增另一個提交),請嘗試使用較大的值;反之,則使用較小的值。請參閱下方的「演算法」章節,以了解為什麼需要這樣做。

--left-only

抑制第一個指定範圍中遺失的提交(或在使用 <rev1>...<rev2> 格式時的「左範圍」)。

--right-only

抑制第二個指定範圍中遺失的提交(或在使用 <rev1>...<rev2> 格式時的「右範圍」)。

--[no-]notes[=<ref>]

此旗標會傳遞給產生修補程式的 git log 程式(請參閱 git-log[1])。

<range1> <range2>

比較兩個範圍指定的提交,其中 <range1> 被視為 <range2> 的較舊版本。

<rev1>…​<rev2>

等同於傳遞 <rev2>..<rev1><rev1>..<rev2>

<base> <rev1> <rev2>

等同於傳遞 <base>..<rev1><base>..<rev2>。請注意,<base> 不一定是分支的確切分支點。範例:在重新定基分支 my-topic 後,git range-diff my-topic@{u} my-topic@{1} my-topic 會顯示由重新定基引入的差異。

git range-diff 也接受常規差異選項(請參閱 git-diff[1]),最值得注意的是 --color=[<when>]--no-color 選項。這些選項用於產生「修補程式之間的差異」,即比較對應的新舊提交的作者、提交訊息和差異。目前沒有方法可以調整在產生這些修補程式時傳遞給 git log 的大多數差異選項。

輸出穩定性

range-diff 命令的輸出可能會變更。它旨在成為人類可讀的 porcelain 輸出,而不是可以在不同 Git 版本之間使用的東西,以取得文本上穩定的 range-diff(與 git-patch-id[1]--stable 選項不同)。range-diff 也沒有類似於 git-apply[1] 的功能,輸出不應為機器可讀。

當傳遞差異選項時尤其如此。目前,某些選項(例如 --stat)可能會以突發效應的方式產生在 range-diff 環境中相當無用的輸出。未來的 range-diff 版本可能會學習以特定於 range-diff 的方式解釋這些選項(例如,對於 --stat,產生摘要說明 diffstat 如何變更的人類可讀輸出)。

配置

此命令會使用 diff.color.*pager.range-diff 設定(後者預設為開啟)。請參閱 git-config[1]

範例

當重新定基需要解決合併衝突時,請直接使用以下命令比較重新定基之後引入的變更

$ git range-diff @{u} @{1} @

git range-diff 的典型輸出如下所示

-:  ------- > 1:  0ddba11 Prepare for the inevitable!
1:  c0debee = 2:  cab005e Add a helpful message at the start
2:  f00dbal ! 3:  decafe1 Describe a bug
    @@ -1,3 +1,3 @@
     Author: A U Thor <author@example.com>

    -TODO: Describe a bug
    +Describe a bug
    @@ -324,5 +324,6
      This is expected.

    -+What is unexpected is that it will also crash.
    ++Unexpectedly, it also crashes. This is a bug, and the jury is
    ++still out there how to fix it best. See ticket #314 for details.

      Contact
3:  bedead < -:  ------- TO-UNDO

在此範例中,有 3 個舊提交和 3 個新提交,其中開發人員移除第 3 個提交,在頭兩個提交之前新增一個新提交,並修改第 2 個提交的提交訊息及其差異。

當輸出傳送到終端機時,預設會像常規 git diff 的輸出一樣進行顏色編碼。此外,第一行(新增提交)為綠色,最後一行(刪除提交)為紅色,第二行(完全匹配)為黃色,類似於 git show 輸出的提交標頭,而第三行會將舊提交著色為紅色,新提交著色為綠色,其餘則類似於 git show 的提交標頭。

然而,樸素的差異之差異顏色編碼實際上有點難以閱讀,因為它會將整行著色為紅色或綠色。例如,在舊提交中新增「What is unexpected」的那一行完全為紅色,即使舊提交的目的是新增內容。

為了協助解決這個問題,range 預設會使用 --dual-color 模式。在此模式下,差異的差異會保留原始的差異顏色,並在行前面加上具有背景紅色或綠色的 -/+ 標記,以更清楚地顯示它們描述差異本身如何變更。

演算法

一般概念如下:我們在兩個提交範圍中的提交之間產生一個成本矩陣,然後求解最小成本分配。

成本矩陣的填入方式如下:對於每一對提交,會產生兩個差異,並產生「差異的差異」,其中包含 3 行上下文,然後使用該差異中的行數作為成本。

為了避免誤報(例如,當修補程式已移除,並且在同一個修補程式系列的兩個反覆運算之間新增了一個不相關的修補程式時),成本矩陣會加以延伸以允許這樣做,方法是為整批刪除/新增新增固定成本項目。

範例:假設提交記錄 1--2 是修補程式系列的第一個迭代,而 A--C 是第二個迭代。假設 A 是從 2 挑選的提交記錄(cherry-pick),而 C 是從 1 挑選的提交記錄,但有小的修改(例如,修正了一個錯字)。將提交記錄視覺化為一個二分圖

    1            A

    2            B

		 C

我們正在尋找一個「最佳」方式,以舊的修補程式系列來解釋新的修補程式系列。我們可以將「解釋」表示為圖中的一條邊

    1            A
	       /
    2 --------'  B

		 C

這個解釋是「免費」的,因為沒有任何變更。同樣地,可以使用 1 來解釋 C,但這會產生一些成本 c>0,因為有修改

    1 ----.      A
	  |    /
    2 ----+---'  B
	  |
	  `----- C
	  c>0

在數學術語中,我們正在尋找某種最小成本二分匹配;1 以某種成本與 C 匹配,依此類推。底層圖實際上是一個完整的二分圖;我們與每條邊關聯的成本是兩個提交記錄的修補程式之間的差異大小。為了也能解釋新的提交記錄,我們在兩側都引入了虛擬節點

    1 ----.      A
	  |    /
    2 ----+---'  B
	  |
    o     `----- C
	  c>0
    o            o

    o            o

o--C 的成本是 C 的差異大小,並以一個應小於 100% 的微調因子修改。邊 o--o 的成本為零。微調因子是必要的,因為即使 1C 沒有任何共同之處,它們仍可能共享一些空行之類的,這可能會使 1--Co--o 的賦值稍微比 1--oo--C 更便宜,即使 1C 沒有任何共同之處。使用微調因子,我們需要更大的共同部分來考慮修補程式是否對應。

計算此演算法所需的總時間是計算 n+m 個提交記錄差異,然後計算 n*m 個修補程式差異所需的時間,再加上計算 n 和 m 個差異之間最小成本賦值所需的時間。Git 使用 Jonker-Volgenant 演算法的實作來解決賦值問題,該演算法具有三次方的執行時間複雜度。在這種情況下找到的匹配將如下所示

    1 ----.      A
	  |    /
    2 ----+---'  B
       .--+-----'
    o -'  `----- C
	  c>0
    o ---------- o

    o ---------- o

參見

GIT

屬於 git[1] 套件的一部分

scroll-to-top