Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do a git diff on moved/renamed file?

People also ask

How does git detect renamed files?

Git keeps track of changes to files in the working directory of a repository by their name. When you move or rename a file, Git doesn't see that a file was moved; it sees that there's a file with a new filename, and the file with the old filename was deleted (even if the contents remain the same).

How do I create a git diff file?

The git diff command displays the differences between files in two commits or between a commit and your current repository. You can see what text has been added to, removed from, and changed in a file. By default, the git diff command displays any uncommitted changes to your repository.

How do I use the diff command 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.

Why git diff does not show changes?

Your file is already staged to be committed. You can show it's diff using the --cached option of git. To unstage it, just do what git status suggests in it's output ;) You can check The Git Index For more info.


You need to use -M to let git autodetect the moved file when diffing. Using just git diff as knittl mentioned does not work for me.

So simply: git diff -M should do it.

The documentation for this switch is:

-M[<n>], --find-renames[=<n>]
       Detect renames. If n is specified, it is a threshold on the similarity index 
       (i.e. amount of addition/deletions compared to the file’s size). For example, 
       -M90% means git should consider a delete/add pair to be a rename if more than
       90% of the file hasn’t changed.

In addition to what knittl wrote, you can always use:

git diff HEAD:./oldfilename newfilename

where HEAD:./oldfilename means oldfilename in the last commit (in HEAD), relative to current directory.

If you don't have new enough git, you would have to use instead:

git diff HEAD:path/to/oldfilename newfilename

With git 2.9 (June 2016), you won't have to add -M anymore. git diff uses -M by default.

See commit 5404c11, commit 9501d19, commit a9276a6, commit f07fc9e, commit 62df1e6 (25 Feb 2016) by Matthieu Moy (moy).
(Merged by Junio C Hamano -- gitster -- in commit 5d2a30d, 03 Apr 2016)

diff: activate diff.renames by default

Rename detection is a very convenient feature, and new users shouldn't have to dig in the documentation to benefit from it.

Potential objections to activating rename detection are that it sometimes fail, and it is sometimes slow. But rename detection is already activated by default in several cases like "git status" and "git merge", so activating diff.renames does not fundamentally change the situation. When the rename detection fails, it now fails consistently between "git diff" and "git status".

This setting does not affect plumbing commands, hence well-written scripts will not be affected.

The new tests for this feature are here.


For whatever reason using HEAD:./oldfilename (or absolute path) didn’t work for me, but HEAD:oldfilename did (thanks cmn):

git diff HEAD:oldfilename newfilename
git diff 2a80f45:oldfilename f65f3b3:newfilename

HTH


git diff -M activates rename detection as others have said (and as @VonC pointed out, it is activated by default from git 2.9). But if you have a large changeset, inexact rename detection may still get turned off again. Git will display a warning like the following, which is easy to miss amidst the diff you are viewing:

warning: inexact rename detection was skipped due to too many files.
warning: you may want to set your diff.renameLimit variable to at least 450 and retry the command.

In that case, set the configuration option as suggested by git, for example

git config diff.renamelimit 450

and re-run your diff command.