“git diff topic1 topic2 ^master” 和 “git diff topic1..topic2 ^master” 有什么不同?

3
我正在尝试比较两个分支的更改,这两个分支在master的不同提交点上进行了分叉。因此,我不想看到在这两个分支之间在master上所做的更改。
我已经尝试了git diff topic1 topic2 ^mastergit diff topic1..topic2 ^master,但我发现我得到了不同的结果,具体来说是一组不同的更改文件,尽管文档说明git diff a bgit diff a..b是相同的。(https://www.git-scm.com/docs/git-diff#_examples
这两个命令有什么区别,哪一个可以信任?或者,我是否只是做错了?是否有更好的方法?

正确的 man 手册是 git rev-list。第一个示例恰好是您问题的第一部分,附有解释,而第二个示例则涉及第二部分。 - user3159253
谢谢,user3159253!虽然这并没有完全回答我的问题,但是它提醒了我关于git rev-list命令以及它的工作方式。 - Louis Pace
1个回答

7
git diff的修订解析代码过于宽容,因此在处理多个参数时会出现错误。如果您提供了两个以上的提交ID,并且其中至少有一个是否定的(如您所做的那样),则在某些情况下,它会误解其参数。特别是,它会将(正引用、正引用、负引用)三元组视为三点语法。
几周前,我提交了专门针对此问题的Git修复程序,但通常被忽略了(叹气)。即使使用了这个修复程序,你也无法得到想要的结果。除了更特殊的组合差异情况之外(这仍然不是您想要的),您只能让Git比较存储在仓库中的最多两个现有树:

我正在尝试比较从主分支在两个不同提交处派生的两个不同分支上所做的更改。因此,我不想看到在这两个分支之间在主分支上所做的更改。

换句话说,您有一个提交图,大致如下:
          a--a--A      <-- feature-A
         /
...--o--*--o--o-...    <-- master
               \
                b--B   <-- feature-B

如果您想将feature-A的最顶端提交(即提交A)与仅存在于feature-B分支上的两个提交(提交bB)应用于标有*的提交 (即feature-Amaster分支分叉的位置),以便比较它们的差异,那么您需要一些特殊的操作。

您可以很容易地让Git比较提交A的树和提交B的树。这就是git diff feature-A feature-Bgit diff feature-A..feature-B所做的。但这并不是您想要的。

要获取提交A的树与一个(当前虚拟的)树B'之间的差异,您必须创建一个临时分支1,然后将两个只存在于feature-B分支上的提交合并到*中:

          a--a--A      <-- feature-A
         /
...--o--*--o--o-...    <-- master
         \     \
          \     b--B   <-- feature-B
           \
            b'-B'      <-- temporary branch

现在,您真正拥有一个提交 B',其中包含如果“删除”两个中间的master提交所得到的树,并且现在可以将A的树与这个新提交的树进行比较。
1 在不使用临时分支的情况下完成所有操作在技术上是可能的,通过在工作目录中构建假设的树B',而不是使用git cherry-pick在临时分支上连续提交的方式。但是,在Git中,包括在临时分支上的临时提交,速度足够快并且成本足够低廉,这样做没有太多收益-并且如果某些cherry-pick步骤需要解决合并冲突,则会使一切变得更加困难。

1
我对这个问题感到困惑。又是一个令人惊叹的回答,torek。每次阅读你的回答,我都会学到一些东西。 - David Neiss
@DavidN:我在几周前折腾 a...b 语法时碰巧遇到了这个 bug。当两个分支尖端之间没有合并基础时,它的行为非常糟糕。 - torek
1
也许如果附上一个实现了测试并展示了问题(并且失败了)的补丁,然后再附上你的补丁(使之前的测试通过),http://www.spinics.net/lists/git/msg280490.html 就不会被忽视了(同样适用于 http://www.spinics.net/lists/git/msg216943.html)。 - VonC
@VonC:嗯,我确实有一个针对stash修复的实际测试用例,但我想我应该将其转换为Git自己的测试用例格式。至于Git自己的测试用例,我还没有深入研究过,因为我唯一确定的是其中一些在我的主系统上失败,导致测试运行无法继续。 :-) - torek
你可以将它们制作成PR,然后通过submitgit为您发送这些补丁:https://submitgit.herokuapp.com/ - VonC
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接