如何获取 git 中分支的完整差异?

Lui*_*lli 7 git

我的目标是在 git 中获取整个分支的完整差异。假设我的分支名为 name ,那么查看整个差异foo/bar的适当命令(即 args to ,我假设)是什么?git diff(该分支从其他分支接收了许多不同的合并)。

编辑:也许我对整个分支 diff的要求不太清楚,但我的意思是进行两次提交:

  1. 分支的最后一次提交。
  2. 分支的父提交。

我需要将这两个参数传递给git diff命令。有没有一种快捷方式来指定这两个提交?

tor*_*rek 5

diff ...与什么相比?

\n\n

不存在“分支差异”这样的东西。只有提交的差异。1 选择任意两个提交,您可以对它们进行比较。但是一个分支......好吧,看看“分支”到底是什么意思? 一个分支不是两次提交。分支名称可以选择一个提交,也可以将分支名称与其他名称结合使用来选择多个提交。但一次提交还不够,多次提交就太多了。您必须恰好选择两个提交。

\n\n

请注意,git diff branch1 branch2和 的git diff branch1..branch2含义完全相同:将名称翻译branch1为一个特定提交,将名称翻译branch2为一个特定提交,然后比较这两个特定提交。再次参见“分支”到底是什么意思?

\n\n
\n\n

1您还可以根据您的工作树或索引来比较提交;您可以将索引与工作树进行比较。除此之外,还有一些特殊形式的差异可以只查看一个文件,甚至是 Git 存储库之外的文件;你可以让 Git 计算几个不同的 diff,然后将它们组合成一个组合 diff。然而,组合差异被设计为仅与合并提交一起使用,并将最终合并结果与每个父项进行比较。它对于查看许多任意提交没有用,仅用于检查合并的最终结果。

\n\n
\n\n

编辑后

\n\n

您也许能够得到您想要的\xe2\x80\x94,但也没有真正的“分支的父提交”。例如,考虑这个图表片段:

\n\n
...--o--A--o--o--o    <-- br1\n         \\\n          o--B--o     <-- br2\n              \\\n               o--o   <-- feature\n
Run Code Online (Sandbox Code Playgroud)\n\n

每个分支的最新提交是最右边的o,并且每个提交都连接回较早的父提交。(这些连接在内部存储为那些又大又难看的 SHA-1 哈希 ID,每次提交都会保存其父 ID。父母不知道他们的孩子,因为当父母被创建时,孩子还不存在,并且一旦做出后,任何承诺都不能更改。因此孩子们知道他们的父母,但反之则不然。)

\n\n

什么是“父”提交feature?是提交A还是提交B?(它可能不是任何剩余的提交,这就是为什么我只给这两个提交特定的单字母名称。)或者:

\n\n
...--A--o--o--B--o--C--o    <-- devel\n      \\      /     /\n       o----o--o--D--E--F   <-- feat\n
Run Code Online (Sandbox Code Playgroud)\n\n

这里feat已经多次提到devel,分BC。可以再次带入;E如果是这样,这将引入与F相关的更改D。但从这张图表中可以明显看出,它feat最初是“从” commit 中“衍生出来的” A,那么A您想要的父级是您想要的,还是与Bor更相关C?如果不是C,你就会遇到问题,因为 Git 不会在任何地方独立记录AB(它也不会C独立记录,但我们有一个简单的方法可以找到,好吧,不是C但是D;但D也许是你要)。此外,虽然这似乎是明显的A起点,但这仅仅是因为我绘制该图片段的方式。不同的观点可能同样清楚地表明存在一个更早的起点\xe2\x80\x94,事实上,除非您专门记录一个(标签非常适合此目的),否则根本不存在真正的“起点”。

\n\n

合并碱基:如何在第一个图中找到Aor和BD第二个图中

\n\n

Git 支持\xe2\x80\x94 因为它必须,因为git merge需要\xe2\x80\x94合并基的概念。如果您像我们上面那样绘制提交图表,则可以很容易地看到两个提交的合并基础。提交通常是两个不同的分支提示提交(如果不是,我们就假装它们是)。您只需从每个尖端开始,然后沿着其连接线向左/向后移动即可。最终,这需要在一些共同的提交中“见面” 。这是这两个分支上的第一个提交,该提交是合并基础

\n\n

这又是第一张图:

\n\n
...--o--A--o--o--o    <-- br1\n         \\\n          o--B--o     <-- br2\n              \\\n               o--o   <-- feature\n
Run Code Online (Sandbox Code Playgroud)\n\n

从 的提示feature 的提示开始br1,检查是否有共同的提交。没有\xe2\x80\x94所以回顾一下。回顾过去,br1有一个点是在 commit 处出现的A。我们可以A从提交feature吗?是的:我们从 的尖端开始feature,后退两步到B,然后再后退两步到A。这是第一个共享提交\xe2\x80\x94第一个提交 br1 feature的第一个提交。这就是合并基础。

\n\n

br1和 的合并基础br2同样是 commit ,并且和 的A合并基础是 commit 。因此,给定两个分支名称\xe2\x80\x94,甚至只是两个提交ID\xe2\x80\x94,我们可以找到它们的合并基础。br2featureB

\n\n

第二张图的合并基础比较棘手。提交C合并提交。这意味着它有两个父箭头,一个指向仅在分支上的提交devel,另一个指向在分支D上提交feat。(顺便说一下,请注意,这意味着我们在进行commitD 之前C进行了 commit 。这里的图形字母有点误导!抱歉。)这使得 commit可从 的 尖端D 到达devel,因此 commitD位于两个分支上\xe2 \x80\x94and 加上它与分支提示的“最接近”性,使得提交和D的合并基础。develfeat

\n\n

git merge-base

\n\n

该命令git merge-base A B将找到两个命名分支的合并基础。理想情况下,这将是单个提交 ID。(可能没有ID,如果两个分支实际上没有任何共同点\xe2\x80\x94它们有不相关的历史;这是罕见的\xe2\x80\x94或者可能有多个合并基础,在这种情况下只选择git merge-base一个,有点随意。不过,很难获得多个合并基础,因此通常您不必担心这一点。)

\n\n

因此,如果此时的目标是在第二个图中找到提交D,并将其与 的提示进行比较feat,则可以执行以下操作:

\n\n
git merge-base devel feat    # and note the commit ID\ngit diff <hash> feat\n
Run Code Online (Sandbox Code Playgroud)\n\n

因为这是一个相对常见的东西,所以将其内置git diff。其语法借用了三点语法,对于每个其他Git 命令来说,这意味着其他含义:

\n\n
git diff devel...feat\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意两个名字之间的三个(而不是两个)点。对于git diff并且对于git diff,这意味着“找到这两个分支提示提交之间的合并基础,然后将其与第二个提交进行比较。”

\n\n

在第一个图表中,您可以选择br1br2来查找AB并将其与 的提示进行比较feature

\n\n
git diff br1...feature\n
Run Code Online (Sandbox Code Playgroud)\n\n

例如。

\n