在专题分支上执行Git diff,排除期间发生的合并提交?

16

假设我有以下情况:

    B---D---F---G topic
   /       /
--A---C---E master
为了进行代码审查,我想从提交A到提交G中提取差异,但不包括主分支上发生的提交E和C,也不包括合并提交F。
换句话说,我想生成一个差异,其中包含从F到G的更改,并将这些更改与从A到D的更改聚合在一起。
换句话说,我希望审查差异仅包含来自主题分支的更改,而不包括期间在主分支上发生的一堆代码。
这是否可能?如果git无法处理这样的“差异聚合”,那么如果有人可以提供一些指针,告诉我如何使用某些外部命令来执行此操作(以便我可以尝试编写一个Bash脚本来完成这项任务),我将非常感激。

要不分别在A和G提交中检出文件,然后进行vim差异比较呢? - TheOneTeam
我需要所有文件的差异,而不是单个文件。此外,我认为您建议的内容也将包括合并提交引入的更改。 - Vladimir Mitrovic
三个点对我来说似乎很有帮助。https://dev59.com/YWMm5IYBdhLWcg3wdeua#17618008 - Ben Creasy
3个回答

10

Karl的回答是误导性的:

git diff从不适用于正确的范围(例如多个提交), 只适用于两个提交之间的比较!

对于git diff,范围语法有特殊的意义。

git diff E..G始终等同于git diff E G (并且
在这种情况下,git diff E...G等同于git diff E G ,因为E是两者之间的合并基础)。

git diff master...topic 在这种情况下以及一般情况下都是你想要的: 它显示了主题分支的所有更改,将其与最后一个合并基础进行比较(即与上次合并时的master进行对比,忽略后来在master中的所有未包含在您的主题分支中的更改)。

注意: 不幸的是(巧合吗?) git log等中的x..y效果最好由git diff中的x...y表示,反之亦然!


1
是的,这是正确的答案。根据手册:“git diff A...B” 等同于 “git diff $(git-merge-base A B) B”。 - jmiserez

4
如果您不关心差异的“上下文”部分,那么git diff master..topic将给您想要的结果。在CE引入的任何更改都被视为差异的“基础”,因此来自master的更改将在上下文中出现,但是只有在您的主题分支中实际进行的更改将标记为+-作为更改。这通常是人们进行代码审查所需的内容。
如果您想要像合并从未发生一样操作,您将不得不对其进行变基:
git rebase --onto A master

3
谢谢Karl,git diff master..topic解决了问题。原来在运行差异脚本之前,我需要将master合并到topic分支中。 - Vladimir Mitrovic

1

关于下列操作:

  1. git checkout topic

  2. git checkout -b temp

  3. git revert F

  4. git diff A

之后,您可以愉快地删除临时分支。


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