我不知道有任何工具可以在一个大共享视图中执行此操作(我一开始不喜欢大共享视图),但您可以从命令行非常轻松地手动完成。
我们来看一个典型案例:
$ git fetch
...
1234567..fedcba9 feature/foo -> origin/feature/foo
...
$ git status
On branch feature/foo
Your branch and 'origin/feature/foo' have diverged,
and have 123 and 321 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working directory clean
呃,需要大合并或变基,差异时间。让我们看看他们在合并基地后做了什么:
$ git diff feature/foo...origin/feature/foo
...以及自合并基础以来我所做的事情:
$ git diff origin/feature/foo...feature/foo
这里有几件重要的事情需要注意:
-
三点语法A...B。通常——即,当不使用git diff 时——这个语法意味着你运行的任何 Git 命令都使用git rev-list(或者直接调用它的修订解析器代码,如果它在 C 中)并且得到 对称差异 一组提交:可以从A 或 B 访问的每个提交,但没有可以从A 和 B 访问的提交.对于具有单个合并基础的典型分支名称对,这是分支点任一“侧”上的所有提交,不包括合并基础本身和所有早期提交。图形化:
A1 - A2 - A3 <-- A
/
... - o - *
\
B1 - B2 <-- B
在这种情况下,总共有五个选定的提交,三个在A 分支上,两个在B 分支上。标记为* 的提交是合并基础,它和之前的所有提交(如* 之前的o)都在两个分支上。
-
此语法不特定于远程跟踪分支,也不特定于本地分支。它适用于标识提交的任何对标识符:分支名称、标签名称、HEAD~10 等。它只是做一个图操作,计算几个中间集来找到对称差:
SA = 祖先(A)
SB = 祖先(B)
S普通 = SA AND SB
结果 = (SA OR SB) - S普通
注意——假设只有一个合并基——两个分支的合并基是公共子集中最新的(图中最右边)提交S常见。如果(在某些复杂的 DAG 中就是这种情况)存在 多个 合并基,则它们在 Scommon 中是 all 并因此从对称差分结果中删除 all(这通常是我们想要的,但见下文)。
对于git rev-list 或其客户端,我们通常想知道提交来自哪个“侧”,因此有--left-right,它标记了它们。另请参阅--cherry-mark、--left-only、--right-only、--cherry-pick 等。
git diff 使用合并基础
但是,对于git diff,三点语法被盗用于不同的目的。它不是计算对称差异,而是选择合并基础:在我们的绘图中标记为 * 的提交。
diff 命令集只会比较两个项目(两个提交,一个提交和工作树,一个提交和索引,等等)。三点对称差分语法主要用于获取两个(通常很大)提交列表,SA-Scommon 和 SB-Scommon。我们可以将此类列表提供给git log -p,这在检查大型合并或变基集时可能会有所帮助(如在原始问题中),例如,当我们想要隔离为什么发生某些特定更改时.不过,对于git diff,我们只是比较两个特定的提交。
比较明显的两个是A 的合并基和尖端(合并的一侧),以及B 的合并基和尖端(合并的另一侧)。这就是三点语法在这里的作用:找到合并基,然后与右边的项目进行比较。因此git diff B...A 将合并基础提交(A 和B)与(提示提交)A 进行比较。由于B 和A 的合并基础与A 和B 的合并基础相同,git diff B...A 将同一提交与B 的(提示)进行比较。
当有一个合并基础时,结果效果最好。对于具有多个合并基础的复杂 DAG,您只需以明显随机的方式选择一个。 (recursive 合并策略选择所有这些合并基并首先合并它们,然后将生成的树与两个分支提示合并。其他 Git 命令,包括 git diff 和 git merge-base,一般只是选择从合并基查找算法中弹出的第一个。1 多个合并基并不常见,理想情况下,当它们确实发生时,它们都具有相同的树,因此没有一个这很重要,但值得牢记。)
1我在写这篇文章时突然想到,没有正式保证为A...B 选择的合并基础与为B...A 选择的合并基础相同。我认为我们得到相同的合并基础,当有多个候选时,但如果算法对我们输入两个提示提交的顺序敏感,我们可以想象选择两个不同的 /em> 提交,当合并基集包含多个时。最终,我将不得不去看看代码,但现在我没有足够的时间......