Git
English ▾ 主题 ▾ 最新版本 ▾ 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命令的输出可能会更改。它旨在成为人类可读的瓷器输出,而不是跨 Git 版本用于获取文本稳定range-diff的内容(与 git-patch-id[1]--stable选项相反)。range-diff也没有等效于 git-apply[1],输出并非旨在供机器读取。

在传递差异选项时尤其如此。当前,某些选项(如--stat)可能会产生在range-diff上下文中毫无用处的输出。将来版本的range-diff可能会以特定于range-diff的方式来解释这些选项(例如,对于--stat生成总结差异统计信息如何更改的人类可读输出)。

配置

此命令使用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 <[email protected]>

    -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是第二次迭代。假设A2的 cherry-pick,而C1的 cherry-pick,但进行了少量修改(例如,修复了错别字)。将提交可视化为二部图

    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