如何在两个提交之间查看更改,而这两个提交之间没有其他提交?

818

如何让git diff只显示两个提交之间的差异,而不包括中间的其他提交?


19
"git diff" 始终显示两个提交(或提交和工作目录等)之间的差异。 - Jakub Narębski
41
@JakubNarębski问如何查看一个命令引入的更改与另一个提交引入的更改之间的差异,换句话说,即差异的差异或interdiff。 - psusi
1
如果您在diff命令中添加--dirstat=files参数,您将获得一个非常漂亮的截图,显示确切的项目和文件更改以及更改百分比。就像这样:git diff [commit-number] [commit-number] --dirstat=files - Óscar Ibáñez Fernández
1
如果您能添加示例git历史ASCII艺术并解释要从该图中区分/排除哪些提交,那么这个问题会更清晰明了。 - Thomas Guyot-Sionnest
@simpleuser 我指的是一般情况下的 "git diff" 命令,而不是没有任何参数的 git diff;无论如何,重要的是 "git diff" 始终涉及两个端点,并且始终跳过中间的提交。 - Jakub Narębski
显示剩余3条评论
15个回答

678

你可以简单地将两个提交传递给git diff:

-> git diff 0da94be  59ff30c > my.patch
-> git apply my.patch

3
@git checkout other-branch && git apply my.patch && git add . && git commit -am "Message" 意思是切换到另一个分支(other-branch),然后应用一个补丁文件(my.patch),添加所有更改并提交一个新的版本,并在提交时附带一条消息("Message")。 - Felix Rabe
124
这个答案完全没有回答问题,所以我不知道为什么它会得到这么多赞。原帖中明确询问如何避免第一个命令被执行,而第二个命令与此毫无关系。 - psusi
5
这个答案并没有完全没有回答任何问题,它是完全有效的。如果你分支出两个提交中较后面的那个,然后将这个差异应用到新分支上,你就可以看到这两个提交之间的更改内容,而不必头痛中间提交的问题。 - Craig Labenz
2
@Mr.Hyde,我不确定我完全理解了,使用它将包括2个提交之间的所有更改。 - OneOfOne
2
@ynn 如果我在这里添加了所有的git命令,那么这也会有所帮助吗?回答应该在上下文中有所帮助。 - Farid
显示剩余9条评论

167

仅比较两个提交之间的差异,而不包括它们之间的提交,其意义不大。提交只是存储库内容的快照;要求两个提交之间的差异必然包括它们。那么问题就是,你真正想找什么?

正如William所建议的,cherry-picking可以让你获得一个单独提交的增量,在另一个提交之上重新进行了基础变更。也就是说:

$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached

这个过程会取出提交 'abcdef',将其与其直接祖先进行比较,然后将该差异应用于 '012345' 之上。然后展示这个新差异 - 唯一的变化是上下文来自于 '012345' 而不是 'abcdef' 的直接祖先。当然,可能会出现冲突等问题,因此在大多数情况下这个过程并不是非常有用。

如果您只对 abcdef 本身感兴趣,可以执行以下操作:

$ git log -u -1 abcdef

这比较了abcdef与其直接祖先,仅此而已,并且通常是您想要的。

当然了

$ git diff 012345..abcdef

此命令会给出这两个提交之间的所有差异。

更好地了解您想要实现的目标将有所帮助-正如我提到的,如果没有介于两个提交之间的内容,要求两个提交之间的区别实际上是没有意义的。


58
我同意通常来说比较两个提交并不是非常有意义。但是 Git 很擅长不对你进行思考方式的规定。假设你有两个分支,每个分支都有独特的提交,看起来它们正在对同一组文件进行相同的更改。我想使用 Git 来告诉我这两个补丁是否相同,而无需全凭我的眼睛。我认为这样做是有用的。 - Chris Cleeland
9
在这种情况下,@ChrisCleeland,interdiff工具可能会很有用。使用git diff获取每个提交相对于其直接父提交的差异,然后使用interdiff比较这些差异。 - bdonlan
3
@ChrisCleeland,Git并不存储补丁(patch),它存储文件内容。它有一种使用增量(delta)的压缩方案,但是增量源并不一定与文件的实际历史相关联。 - bdonlan
23
两个提交的区别除了它们各自分支上的其他提交之外,这是有意义的:一个提交从另一个提交中被挑选出来,但可能存在一些微妙的差异。你希望看到它们之间的差异,而不会被两个分支之间的所有其他无关内容所干扰。 - psusi
4
或者说你将主分支(master)变基到一个特性分支(feature branch)上,必须解决冲突。之后比较 origin/featurebranch#HEADlocal/featurebranch#HEAD 可以帮助你确保在解决冲突期间没有出现问题。 - lefnire
显示剩余3条评论

149
要将两个git提交(12345和abcdef)作为补丁进行比较,可以使用diff命令。
diff -u <(git show 123456) <(git show abcdef)

8
为什么要在git中使用GNU diff? - OneOfOne
7
git diff <(git show 123456) <(git show abcdef)不能正常工作;diff <(...) <(...)可以。(我刚试过了)。 - Menachem
24
@OneOfOne那个并不是做同样的事情。你所建议的会比较每个提交的,显示一个“单一的补丁”。我(以及@plexoos)正在比较两个补丁,每个补丁都是由独立的提交引入的——换句话说,从两个diff的输出进行差异比较。这涉及到读取和比较两个输入流。diff(GNU或Unix的diff)可以做到这一点,而git diff则不能。有些人可能会想知道为什么要这样做。我现在正在处理这个问题,清理一个出现问题的合并。 - Menachem
2
这不会包括git diff中的所有元数据的gnu diff吗? - joel
7
这应该是对提问者问题的认可答案! - esskov
显示剩余2条评论

74
git diff <a-commit> <another-commit> path

例子:

git diff commit1 commit2 config/routes.rb

它显示了这个文件在那些提交之间的差异。


49

检查完整的更改:

  git diff <commit_Id_1> <commit_Id_2>

仅检查已更改/添加/删除的文件:

  git diff <commit_Id_1> <commit_Id_2> --name-only

注意: 如果想在提交之间检查差异,您无需放置提交 ID。


26

假设你有这个

A
|
B    A0
|    |
C    D
\   /
  |
 ...

你希望确保AA0相同。

这样做就可以了:

$ git diff B A > B-A.diff
$ git diff D A0 > D-A0.diff
$ diff B-A.diff D-A0.diff

5
也可以缩短为一行代码,就像@plexoos的答案一样:diff <(git diff B A) <(git diff D A0)(与使用git show得到的结果相同)。 - pogosama
3
你想要的是 git range-diff B..A D..A0 - Thomas Guyot-Sionnest
这就是我一直在寻找的。 - Sunil Kumar Singh

18
自Git 2.19以来,您可以简单地使用: git range-diff rev1...rev2 - 比较两个提交树,从它们的共同祖先开始 或 git range-diff rev1~..rev1 rev2~..rev2 - 比较由两个给定提交引入的更改

即使使用stash也可以工作。只需创建一个小的shell包装器,就可以轻松使用。 - Et7f3XIV

14

假设你想要查看提交记录012345和abcdef之间的差异。你可以执行以下命令:

$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached

谢谢,检查压缩提交后的结果是一个好主意。例如,您可以检出具有未压缩提交的分支,并挑选您压缩的提交以查看交互式重置是否顺利完成。此外,当主分支超前于分支时。 - akostadinov

9

GitHub 上直接检查差异;你可以使用以下链接 - https://github.com/<username>/<reponame>/compare/<commit1>..<commit2>

commit1commit2 可以是分支名称提交哈希值

例如:

了解更多请参阅比较提交


6
这样怎么样呢:
git diff abcdef 123456 | less

如果你想比较多个不同的diff,只需将它们通过管道传递给less工具即可。


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