1

假设我在 git 中有这种情况:

  B---D---F---H---J---K--->topic
 /       /       /
A---C---E---G---I--->master

在提交 F 之后,我提交主题分支以供审核。审稿人提出了一些建议,世界继续前进,因此完成了另一次合并。正如在此回答的主题分支上的 Git diff,不包括同时发生的合并提交?简单地生成从 A 到 F 的差异的方法git diff master..topic。然而,现在已经对修订 B 和 D 进行了审查,我想将它们从新的差异中排除以供审查。git diff E..topic然而,包括 G 和 I。

我如何获得 H、J 和 K 的差异,不包括通过 G 和 I 引入的东西?

4

2 回答 2

1

除了一些涉及合并差异的特殊情况(当你可以使用时--combined),提交差异总是成对的。这改变了x..y被解释的方式。不是这个意思“所有可以到达的 revs 不能到达yx”,而是“比较 revx和 rev y”。

(这里值得注意的是,链接问题中的答案掩盖了与其他 git 命令x..y不同的解释这一事实。)git diff

当你请求时E..topic,git 会解析topic到一个特定的提交——在这种情况下K——然后将 in 中的树与 inE中的树进行比较K。这就是为什么您会看到来自GandI的更改,因为这些更改是J通过合并引入的。

您可以比较Fand K,但这仍然会显示 and 中的变化GI因为同样,这些变化实际上是在 中J

事实上,只有一种方法可以在J保持不变的同时忽略发生的事情FH那就是建立一棵树,要么跳过它,要么恢复它。例如,从 开始,您可以根据和H之间的差异添加补丁:JK

                K'        <-- HEAD[detached]
               /
  B---D---F---H---J---K   <-- topic
 /       /       /
A---C---E---G---I         <-- master

(要做到这一点,git checkout topic~2在 commit 时分离H,然后git cherry-pick topic添加,到你现在分离的,从到HEAD所做的更改)。JK

现在您可以将提交E中的树与HEAD(提交时K')中的树进行比较:

git diff E HEAD   # or   git diff E..HEAD   or   git diff E..

但总的来说,这不是人们想要审查的。事实上,由于您几乎可以肯定随后会K'完全放弃 rev(生成它仅用于审查目的),他们将审查一个从未使用过的代码版本!

这就是为什么对链接问题的公认答案是git diff master..topic- 这意味着与 完全相同的东西git diff master topic,并且在这种情况下将树I与树进行比较K。您提议在分支上提交topic一棵看起来像 的树K。这就是将在topic. 它与 rev Iin 中的代码有些不同master。它所要做的不同IF, H,K和为适应而进行的任何垫片工作的总和J。它确实进行了更改G(当然还有这些I更改本身),但这些不是 I, 这些仅仅是合并 I.

审查代码的更彻底的方法是展示四个差异以供审查:

  1. E对比F
  2. F对比H
  3. Hvs J(也许是组合的差异,H-and- Ivs J
  4. J对比K

第一个差异告诉您的审阅者,如果他们接受它,就可以检查出看起来像的树F(这当然是真的,只是git checkout F)。第二个差异告诉您的审阅者,F在他们的存储库中,将有可能签出H(如果他们接受的话)等等。显然,四个审查比一个更难,这就是为什么人们接受比较IK.

于 2013-10-28T15:19:57.123 回答
0

torek 的建议(进行多次审查)是一种可能性,但有一个不幸的副作用,即需要改进F和修复的代码H必须被审查两次:一次处于低于标准的状态,一次是在已经完成。好处是它压扁了这些,只是git diff master..topic给出了分支之间的最终区别。

我为解决这个问题所做的就是从 中创建一个分支F,合并master到那里,然后在我的新临时分支和topic分支之间进行比较。这样一来,所有的更改master都被掩盖了,并且只使用了topic自上一个审查点以来对分支的更改。

于 2013-10-29T16:37:48.470 回答