Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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)?

like image 627
Steve Kroon Avatar asked Mar 27 '17 08:03

Steve Kroon


People also ask

How do I compare files between two commits in git?

You can run the git diff HEAD command to compare the both staged and unstaged changes with your last commit. You can also run the git diff <branch_name1> <branch_name2> command to compare the changes from the first branch with changes from the second branch. Order does matter when you're comparing branches.

How do I compare files between two commits?

To see the changes between two commits, you can use git diff ID1.. ID2 , where ID1 and ID2 identify the two commits you're interested in, and the connector .. is a pair of dots. For example, git diff abc123.. def456 shows the differences between the commits abc123 and def456 , while git diff HEAD~1..

How do I compare files between two branches in GitHub?

The second command that you can use to compare branch differences is “log.” git log will show you all of the commit differences between the branches you specify, and, aside from the term diff being replaced with log, the syntax is exactly the same as the previous command.


2 Answers

You can always compare 2 files in 2 different commits:

git diff commit1:file1_path commit2:file2_path 
like image 70
Eugene Kaurov Avatar answered Sep 22 '22 00:09

Eugene Kaurov


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. (Note: @philh says that git diff commit1:file1_path file2_path works fine, but I haven't confirmed that myself.)

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.

like image 30
Jacob Kopczynski Avatar answered Sep 22 '22 00:09

Jacob Kopczynski