Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
- 2.48.1 → 2.49.0 no changes
-
2.48.0
2025-01-10
- 2.43.1 → 2.47.2 no changes
-
2.43.0
2023-11-20
- 2.38.1 → 2.42.4 no changes
-
2.38.0
2022-10-02
- 2.31.1 → 2.37.7 no changes
-
2.31.0
2021-03-15
- 2.25.1 → 2.30.9 no changes
-
2.25.0
2020-01-13
- 2.20.1 → 2.24.4 no changes
-
2.20.0
2018-12-09
- 2.19.1 → 2.19.6 no changes
-
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] 中的指定范围
。 -
<rev1>...<rev2>
。这等同于<rev2>...<rev1> <rev1>...<rev2>
. -
<base> <rev1> <rev2>
: 等同于<base>..<rev1> <base>..<rev2>
.
选项
- --no-dual-color
-
当提交的差异不同时,`git range-diff`会重现原始差异的颜色,并添加外层的 -/+ 差异标记,背景 为红/绿色,以便于查看,例如,当具体添加了哪些行时。
此外,只出现在第一个提交范围内的提交差异行会显示为 "dimmed"(这可以使用
color.diff. <slot>
配置设置,其中<slot>
是`contextDimmed`、oldDimmed
和newDimmed
中的一个),而仅出现在第二个提交范围内的提交差异行以粗体显示(这可以通过配置设置color.diff.<slot>
来覆盖,其中<slot>
是contextBold
、oldBold
和newBold
中的一个)。这在
range-diff
中被称为 "双重着色"。使用--no-dual-color
可以还原为根据外部差异标记对所有线条着色(在着色时完全忽略内部差异)。 - --creation-factor=<百分比>
-
将创建/删除成本误差因子设置为
<百分比>
。 默认为 60。如果git range-diff
错误地认为一个大的改动是完全重写 (删除一个提交,增加另一个提交),可以使用较大的值,反之则使用较小的值。 请参阅下面的 ``算法`` 部分以了解为什么需要这个值。 - --left-only
-
忽略第一个指定范围(或使用
<rev1>...<rev2>
格式时的 "左侧范围")中丢失的提交。 - --right-only
-
忽略第二个指定范围(或使用
<rev1>...<rev2>
格式时的 "右侧范围")中丢失的提交。 - --diff-merges=<格式>
-
Instead of ignoring merge commits, generate diffs for them using the corresponding
--diff-merges=<format>
option of git-log[1], and include them in the comparison.Note: In the common case, the
remerge
mode will be the most natural one to use, as it shows only the diff on top of what Git’s merge machinery would have produced. In other words, if a merge commit is the result of a non-conflictinggit merge
, theremerge
mode will represent it with an empty diff. - --remerge-diff
-
Convenience option, equivalent to
--diff-merges=remerge
. - --[no-]notes[=<引用>]
-
这个标志将传递给生成补丁的
git log
程序(参见 git-log[1])。 - <范围1> <范围2>
-
比较两个范围指定的提交,其中
<range1>
被认为是<range2>
的旧版本。 - <修订 1>..<修订 2>
-
相当于传递
<rev2>...<rev1>
和<rev1>...<rev2>
。 - <基础> <修订 1> <修订 2>
-
等同于传递
<base>...<rev1>
和<base>...<rev2>
。 注意<base>
不需要是分支的确切分支点。例如: 在重定向分支my-topic
之后,git range-diff my-topic@{u} my-topic@{1} my-topic
将显示重定向带来的差异。
git range-diff
也接受常规的 diff 选项 (参见 git-diff[1]),特别是 --color=[<when>]
和 --no-color
选项。这些选项用于生成 “补丁间的差异”,即比较新旧提交的作者、提交信息和差异。目前还没有办法调整生成补丁时传递给 git log
的大部分 diff 选项。
输出稳定性
range-diff
命令的输出可能会改变。它的目的是提供人类可读的上层命令输出,而不是可以在不同版本的 Git 中使用以获得文本稳定的 range-diff
(与 git-patch-id[1] 的 --stable
选项不同)。对于 range-diff
来说,也没有与 git-apply[1] 等价的东西,其输出不是机器可读的。
当传递 diff 选项时尤其如此。目前,一些选项,例如 --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: 描述一个错误 +描述一个错误 @@ -324,5 +324,6 这是意料之中的。 -+出乎意料的是,它也会崩溃。 ++出乎意料的是,它也会崩溃。这是一个bug,陪审团还在讨论如何最好地修复它。 ++如何最好地修复它,还没有定论。详见 #314 号记录。 Contact 3: bedead < -: ------- TO-UNDO
在这个例子中,有 3 个旧提交和 3 个新提交,开发人员删除了第 3 个提交,在前两个提交之前添加了一个新提交,并修改了第 2 个提交的提交信息及其差异。
当输出到终端时,默认是用颜色编码的,就像普通的 git diff
输出一样。此外,第一行(添加提交)是绿色的,最后一行(删除提交)是红色的,第二行(完全匹配)是黄色的,就像 git show
输出的提交头一样,第三行旧提交是红色的,新提交是绿色的,其余的就像 git show
的提交头一样。
不过,用颜色编码的原 diff 实际上有点难读,因为它会把整行都染成红色或绿色。例如,在旧提交中添加了 "What is unexpected" 的那行就完全是红色的,即使旧提交的意图是添加一些东西。
为了解决这个问题,range
默认使用 --dual-color
模式。在这种模式下,diffs 的 diff 将保留原始的 diff 颜色,并在行的前缀加上 -/+ 标记,其 背景 为红色或绿色,以便更明显地描述 diff 本身是如何改变的。
算法
总体思路是这样的:我们在两个提交范围内的提交之间生成一个成本矩阵,然后求解最小成本分配。
成本矩阵是这样填充的:对于每一对提交,生成两个差异,并生成 “差异的差异”,其中包含 3 行上下文,然后将差异中的行数作为成本。
为了避免假阳性(例如,当一个补丁被删除,而在同一补丁系列的两次迭代之间又添加了一个不相关的补丁),成本矩阵通过为整体删除/添加添加固定成本条目进行扩展,以考虑到这一点。
示例: 假设 1--2
是补丁系列的第一次迭代,A--C`是第二次迭代。假设 `A`是从 `2
中挑选出来的,而 C
是从 1
中挑选出来的,但做了一点修改(比如,一个固定的错别字)。将提交可视化为一个二元图:
1 A 2 B C
我们正在寻找新系列对旧系列的 “最佳” 解释。我们可以将 “解释” 表示为图中的一条边:
1 A / 2 --------' B C
这个解释是 “免费” 的,因为没有任何改变。同样地,C
可以用 `1`来解释,但由于修改,这需要付出一定的代价 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
的代价是免费的。修正系数是必要的,因为即使 1
和 C
没有共同点,它们仍可能共享一些空行等,这可能会使赋值 1--C
, o--o
比 1--o
, o--C
稍微便宜一些,即使 1
和 C
没有共同点。有了模糊因子,我们需要更大的公共部分才能将补丁视为一对的。
计算该算法所需的总时间是计算 n+m 个提交差异和 n*m 个补丁差异所需的时间,再加上计算 n 和 m 个差异之间的最小成本赋值所需的时间。Git 使用 Jonker-Volgenant 算法来解决分配问题,该算法的运行复杂度为立方。在这种情况下找到的匹配结果是这样的 :
1 ----. A | / 2 ----+---' B .--+-----' o -' `----- C c>0 o ---------- o o ---------- o
GIT
属于 git[1] 文档