Git:如何在不同的提交中比较两个不同的文件?

27

我有一个仓库,其中一些文件已经从.html重命名为.php,并在上次拉取以来进行了多次编辑。使用git diff显示所有html内容已被删除,而所有php内容已添加。是否有一种巧妙的方式让git diff检测到重命名(类似于git log --follow所做的),或者直接比较不同提交之间的不同文件名(类似于Git:如何比较不同分支中的两个不同文件?的解决方案,但是用于提交)?


你在最初更改文件时使用了 git mv 吗? - dave
9
git diff commit1:file1_path commit2:file2_path - ElpieKay
这个方法很有效,谢谢。请将其转换为答案,以便我可以接受。(不幸的是,它只适用于单个文件级别,但我现在可以处理它所需的操作。) - Steve Kroon
@dave:其实我不确定——是其他人移动了这些文件。 - Steve Kroon
1
@dave:那其实并不重要。Git通常通过进行树比较来检测重命名(而不是记录它们)。然而,这需要您对两个完整的树进行差异比较,而不是树中的两个特定文件。 - torek
2个回答

34

您可以始终比较两个不同提交中的2个文件:

git diff commit1:file1_path commit2:file2_path

1
仅回答代码的答案会被标记为“低质量帖子”,请尝试解释您的答案,以避免其被删除。 - piman314
@ElpieKay在一年前作为对我的问题的评论提供了这个答案 - 在此标记他,以便提供它作为答案。如果我在一周内没有得到他的回复,Eugene,请在此处提醒我,我会接受你的答案。 - Steve Kroon
@SteveKroon 从明天起,你的评论已经过去了3个星期。我感谢ElpieKay的意见,他确实提供了很好的评论,但看起来他不在。如果你愿意,可以接受我的答案。 - Eugene Kaurov

6

如前所述,所需格式为:

$ git diff commit1:file1_path commit2:file2_path

但是有两个需要注意的地方:

XXX$ git diff file1_path commit2:file2_path

即使file1_pathHEAD中,这也无法起作用;如果要为一个文件指定提交,则必须同时为两个文件指定提交。这将尝试将“commit2:file2_path”解释为带有第一个目录的文件路径,并进入该目录,例如:HEAD^:foo/。这很少存在,因此通常会给出信息性错误消息。(注意:@philh表示git diff commit1:file1_path file2_path可以正常工作,但我自己没有确认过。) file1_path格式:给定的路径将被视为相对于存储库的根路径。不允许使用绝对路径,而相对路径必须是明确的。以具体示例说明;假设您的目录结构如下图所示,并且您的工作目录为~/repo/proj
~/repo
  .git
  proj
    tests
      foo
        bar.sh
    utils
      baz
        quux.sh

如果你想比较 HEAD^:(...)/bar.shHEAD:(...)/quux.sh,对于bar.sh所允许的路径只有:

  • proj/tests/foo/bar.sh
  • ./tests/foo/bar.sh

使用./明确指定的相对路径是可以的,但更常见的隐式路径 tests/foo/bar.sh不能使用的。该版本有时会默默失败 - 我认为这基于其他参数中使用的格式,但我不确定。绝对路径也无法使用; ~/repo/proj/tests/foo/bar.sh/home/username/repo/proj/tests/foo/bar.sh 会失败。据我所知,这永远不会默默失败。


2
如果您想为一个文件指定提交,那么您必须同时为两个文件指定。但是并非完全如此 - 似乎 git diff path1 foo:path2 不起作用,但 git diff foo:path2 path1 可以。 - philh
哎呀,我以为我测试过了,结果失败了。 - Jacob Kopczynski

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