Git: How to diff two different files in different

2020-08-09 08:43发布

问题:

I have a repository where a number of files have been renamed from .html to .php and further edited in a number of commits since my last pull. Using git diff to shows all the html contents removed and all the php content added. Is there a neat way to have git diff detect the renames (something like git log --follow does), or directly compare different filenames across different commits (something like the solution in Git: How to diff two different files in different branches? , but for commits)?

回答1:

You can always compare 2 files in 2 different commits:

git diff commit1:file1_path commit2:file2_path


回答2:

As said previously, the format needed is:

$ git diff commit1:file1_path commit2:file2_path

But there are a couple gotchas:

XXX$ git diff file1_path commit2:file2_path

This will not work, even if file1_path is in HEAD; if you want to specify a commit for one file you must specify it for both. This will attempt to interpret "commit2:file2_path" as a file path with the first directory it steps into being, e.g., HEAD^:foo/. This will rarely exist so it generally gives an informative error message.

file1_path format: The paths given will be treated as relative to the repository's root. Absolute paths are not permitted, and relative paths must be explicit. For a concrete example; say your directory structure looks like the below, and your working directory is ~/repo/proj:

~/repo
  .git
  proj
    tests
      foo
        bar.sh
    utils
      baz
        quux.sh

If you are trying to compare HEAD^:(...)/bar.sh to HEAD:(...)/quux.sh, the only permissible paths for bar.sh are:

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

The explicit relative path with ./ works, but the more common implicit path tests/foo/bar.sh will not work. That version will sometimes fail silently - I think this is based on the format used in the other arguments but I'm not sure. Absolute paths will also not work; ~/repo/proj/tests/foo/bar.sh and /home/username/repo/proj/tests/foo/bar.sh will fail. AFAICT that will never fail silently.



标签: git diff commit