I have a file a.txt
.
cat a.txt
> hello
The contents of a.txt
is "hello".
I make a commit.
git add a.txt
git commit -m "first commit"
I then move a.txt
into a test
dir.
mkdir test
mv a.txt test
I then make my second commit.
git add -A
git commit -m "second commit"
Finally, I edit a.txt
to say "goodbye" instead.
cat a.txt
> goodbye
I make my last commit.
git add a.txt
git commit -m "final commit"
Now here is my question:
How do I diff the contents of a.txt
between my last commit and my first commit?
I've tried:
git diff HEAD^^..HEAD -M a.txt
, but that didn't work. git log --follow a.txt
properly detects the rename, but I can't find an equivalent for git diff
. Is there one?
To diff across a rename of a specific file, use
-M -- <old-path> <new-path>
(-C
also works).So if you both renamed and changed a file in the last commit, you can see the changes with:
This produces:
(
// a.txt
lines added to help git detect the rename)If git isn't detecting the rename, you can specify a low similarity threshold with
-M[=n]
, say 1%:From the git diff docs:
The issue with the difference between
HEAD^^
andHEAD
is that you have ana.txt
in both commits, so just considering those two commits (which is what diff does), there is no rename, there is a copy and a change.To detect copies, you can use
-C
:Result:
Incidentally, if you restrict your diff to just one path (as you do in
git diff HEAD^^ HEAD a.txt
you aren't ever going to see the renames or copies because you've excluded the everything apart from a single path and renames or copies - by definition - involve two paths.If your rename commit is staged but not committed yet, you can use:
You can also do:
git diff rev1:file1 rev2:file2
which, for your example, would be
git diff HEAD^^:./a.txt HEAD:./test/a.txt
Note the explicit
./
-- this format otherwise assumes the paths to be relative to the root of the repo. (If you're in the root of the repo, you can of course omit that.)This doesn't depend on the rename detection at all, as the user is explicitly stating exactly what to compare. (Therefore, it also comes in handy in some other circumstances, such as comparing files between different svn branches in a git-svn environment.)