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

Git: How to diff two different files in different commits?

我有一个存储库,其中许多文件已从 .html 重命名为 .php 并在我上次拉取后在许多提交中进一步编辑。使用 git diff 显示删除的所有 html 内容和添加的所有 php 内容。有没有一种巧妙的方法让 git diff 检测重命名(类似于 git log --follow ),或者直接比较不同提交中的不同文件名(类似于 Git: How to diff two different files in different branches? 中的解决方案,但用于提交) ?

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

git diff commit1:file1_path commit2:file2_path

如前所述,需要的格式是:

$ git diff commit1:file1_path commit2:file2_path

但是有几个陷阱:

XXX$ git diff file1_path commit2:file2_path

这将不起作用,即使 file1_path 在 HEAD 中也是如此;如果你想为一个文件指定一个提交,你必须为两个文件指定它。这将尝试将“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 工作。该版本有时会失败 silently - 我认为这是基于其他参数中使用的格式,但我不确定。绝对路径也不行; ~/repo/proj/tests/foo/bar.sh/home/username/repo/proj/tests/foo/bar.sh 将失败。 AFAICT 永远不会默默失败。