假设我在git中有这种情况:
B---D---F---H---J---K--->topic
/ / /
A---C---E---G---I--->master
在提交F之后,我提交主题分支以供审核。审稿人提出了一些建议,世界继续前进,因此完成了另一次合并。正如Git diff on topic branch, excluding merge commits that happened in the meantime?所述,从A到F生成差异的方法只是git diff master..topic
。然而,现在已经审查了修订版B和D,我想将它们从新的差异中排除以供审查。 git diff E..topic
包括G和我。
如何获得H,J和K的差异,排除通过G和I拉入的东西?
答案 0 :(得分:1)
除了涉及合并差异的一些特殊情况(当你可以使用--combined
)时,提交差异总是成对的。这会改变x..y
的解释方式。取而代之的是“y
无法从x
到达的所有转速”,这意味着“将转化x
与转化y
进行比较”。
(值得注意的是,链接问题中的答案掩盖了x..y
在git diff
中的解释与其他git命令不同的事实。)
当您要求E..topic
时,git会将topic
解析为特定提交 - 在这种情况下为K
- 然后将E
中的树与K
中的树进行比较{1}}。这就是为什么您会看到G
和I
的更改,因为这些更改是通过合并通过J
引入的。
您可以比较F
和K
,但这仍会显示G
和I
中的更改,因为这些更改实际上都在{{1} }。
实际上,只有一种方法可以忽略J
中发生的事情,同时保持J
和F
完整无缺,那就是建立一个跳过的树它,或恢复它。例如,从H
开始,您可以根据H
和J
之间的差异添加补丁:
K
(要执行此操作, K' <-- HEAD[detached]
/
B---D---F---H---J---K <-- topic
/ / /
A---C---E---G---I <-- master
要在提交git checkout topic~2
处分离,然后H
要添加到您现在已分离的git cherry-pick topic
,那么所做的更改将从{ {1}}到HEAD
)。
现在,您可以将提交J
中的树与K
中的树(提交E
)进行比较:
HEAD
但总的来说,这不是人们想要审查的内容。事实上,由于您几乎肯定会完全放弃转速K'
(仅为审核目的而生成它),因此他们将审核一个从未使用过的代码版本!
这是为什么链接问题的接受答案只是git diff E HEAD # or git diff E..HEAD or git diff E..
- 这意味着与K'
完全相同,并且在这种情况下比较树的git diff master..topic
git diff master topic
的树I
。您建议在分支K
上提交一个看起来像topic
的树。那是K
中的代码。它与topic
中的转化I
中的代码有所不同。 与master
之间的差异是I
,F
,H
中所做的更改以及所做的任何垫片工作的总和让K
适合。 对J
(当然还有G
本身的更改)进行了更改,但这些更改到 I
,这些只是在 I
中合并的更改。
审核代码的更彻底的方法是提供四个差异以供审核:
I
vs E
F
vs F
H
vs H
(可能是组合差异,J
- 和 - H
vs I
)J
vs J
第一个差异告诉你的评论者,如果他们接受了,那么就可以查看一个看起来像K
的树(这当然是真的,只是F
)。第二个差异告诉您的评论者,在他们的回购中git checkout F
,可以查看F
(如果他们接受),等等。显然,四个评论比一个评论更难,这是为什么人们会接受像H
vs I
那样的捷径。
答案 1 :(得分:0)
F
之后需要改进并在H
中修复的代码必须经过两次审核:一旦处于低于标准状态,一旦完成。关于git diff master..topic
的好处是,它压扁了这些,并给出了分支之间的最终差异。
我为解决问题所做的是从F
创建一个分支,将master
合并到那里,然后在我的新临时分支和topic
分支之间进行差异。这样,master
的所有更改都被隐藏了,只使用了自上一个审核点以来对topic
分支的更改。