Getting Git to follow renamed and edited files

Robin Winslow picture Robin Winslow · Oct 8, 2012 · Viewed 9.6k times · Source

Questions about renaming files in Git have been asked before, but I can't work out a solution to my specific problem.

I have moved and edited multiple files (I didn't use git mv - unfortunately it's now too late for that). Now I want it so when my colleague pulls from my repository, having made his own edits to those same files (without moving them), it successfully merges my changes with his in the file's new location. To successfully merge, Git clearly needs to know that these are the same files.

Is Git clever enough to work this out on its own? It seems hard to believe. And if so, how can I be sure that a particular file move will be picked up by Git - even if the contents has changed?

Answer

Edward Thomson picture Edward Thomson · Oct 8, 2012

Git doesn't actually track renames in the repository, it uses a diff heuristic to determine if you renamed a file to another. That is to say, if you git mv a file and then replace the contents completely, it is not considered a rename, and you do not need to use git mv for it to detect renames.

For example:

% mv d.txt e.txt
% git rm d.txt
rm 'd.txt'
% git add e.txt
% git commit -m"rename without git mv"
[master f70ae76] rename without git mv
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename d.txt => e.txt (100%)
% git diff --summary --find-renames HEAD~1 HEAD
 rename d.txt => e.txt (100%)

Similarly, git mv doesn't mean that the file will be renamed, it will still use the diff algorithm:

% git mv e.txt f.txt
% echo "Completely replacing f.txt" > f.txt
% git add f.txt
% git commit -m"git mv doesn't help here"
[master 068d19c] git mv doesn't help here
 2 files changed, 1 insertion(+), 14 deletions(-)
 delete mode 100644 e.txt
 create mode 100644 f.txt
% git diff --summary --find-renames HEAD~1 HEAD
 delete mode 100644 e.txt
 create mode 100644 f.txt