设置和配置
获取和创建项目
基本快照
分支和合并
共享和更新项目
检查和比较
打补丁
调试
邮件
外部系统
服务器管理
指南
管理
底层命令
- 2.48.1 → 2.49.0 无更改
-
2.48.0
2025-01-10
- 2.43.1 → 2.47.2 无更改
-
2.43.0
2023-11-20
- 2.38.1 → 2.42.4 无更改
-
2.38.0
2022-10-02
- 2.31.1 → 2.37.7 无更改
-
2.31.0
2021-03-15
- 2.25.1 → 2.30.9 无更改
-
2.25.0
2020-01-13
- 2.20.1 → 2.24.4 无更改
-
2.20.0
2018-12-09
- 2.19.1 → 2.19.6 无更改
-
2.19.0
2018-09-10
概要
git range-diff [--color=[<when>]] [--no-color] [<diff-options>] [--no-dual-color] [--creation-factor=<factor>] [--left-only | --right-only] [--diff-merges=<format>] [--remerge-diff] ( <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>
是contextDimmed
,oldDimmed
和newDimmed
之一),并且仅存在于第二个提交范围中的提交差异行以粗体显示(可以使用配置设置color.diff.<slot>
覆盖此行为,其中<slot>
是contextBold
,oldBold
或newBold
之一)。这被称为
range-diff
的“双重着色”。 使用--no-dual-color
恢复根据外部差异标记对所有行进行着色(并且在颜色方面完全忽略内部差异)。 - --creation-factor=<percent>
-
将创建/删除成本调整因子设置为
<percent>
。 默认为 60。 如果git range-diff
错误地将较大的更改视为完全重写(删除一个提交并添加另一个提交),请尝试使用较大的值,反之亦然。 有关为什么需要此操作的说明,请参见下面的“算法”部分。 - --left-only
-
禁止显示第一个指定范围中缺失的提交(或使用
<rev1>...<rev2>
格式时为“左范围”)。 - --right-only
-
禁止显示第二个指定范围中缺失的提交(或使用
<rev1>...<rev2>
格式时为“右范围”)。 - --diff-merges=<format>
-
不要忽略合并提交,而是使用 git-log[1] 的相应
--diff-merges=<format>
选项为它们生成差异,并将其包含在比较中。注意:在常见情况下,
remerge
模式将是最自然的使用模式,因为它仅显示 Git 的合并机制会产生的差异。 换句话说,如果合并提交是非冲突git merge
的结果,则remerge
模式将用空差异表示它。 - --remerge-diff
-
方便选项,等效于
--diff-merges=remerge
。 - --[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>
不需要是分支的精确分支点。 示例:在 rebase 分支my-topic
之后,git range-diff my-topic@{u} my-topic@{1} my-topic
将显示 rebase 引入的差异。
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
,产生总结 diffstat 如何变化的人类可读输出)。
配置
此命令使用 diff.color.*
和 pager.range-diff
设置(后者默认启用)。 请参阅 git-config[1]。
示例
当 rebase 需要解决合并冲突时,请使用以下命令直接比较 rebase 后引入的更改
$ 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
的 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
的差异的大小,并由一个 fudge factor(可以理解为调整因子)修改,该因子应小于 100%。边 o--o
的成本是免费的。fudge factor 是必要的,因为即使 1
和 C
没有什么共同之处,它们仍然可能共享一些空行等等,甚至可能使分配 1--C
、o--o
比 1--o
、o--C
略便宜,即使 1
和 C
没有任何共同之处。使用 fudge factor,我们需要一个更大的公共部分来将补丁视为对应的。
计算此算法所需的总时间是计算 n+m 个提交差异所需的时间,然后是计算 n*m 个补丁差异所需的时间,加上计算 n 和 m 个差异之间最小成本分配所需的时间。Git 使用 Jonker-Volgenant 算法的实现来解决分配问题,该算法具有三次运行时间复杂度。在这种情况下找到的匹配将如下所示
1 ----. A | / 2 ----+---' B .--+-----' o -' `----- C c>0 o ---------- o o ---------- o
GIT
属于 git[1] 套件的一部分