Subject: rename detection

From: Gerlando Falauto <[email-masked]>
Date: Tue, 31 Jul 2012 10:39:43 +0200

Hi everyone,

I have some questions about rename detection.
The way I understand it, renames are not tracked in any way by GIT, at 
least not in the repository. Instead some detection algorithm is 
executed when data is extracted from the repository, prior to being 
presented to the user (i.e., git format-patch, git log, git show 
etc...), therefore depending on the command line and client used.

Some of those mechanisms are also in place when stuff gets commited. For 
instance, I get some rename indications when editing the commit message, 
and as the output of git commit itself.
I would assume the mechanisms would be exactly the same.

Things get a bit more complicated when you actually "merge" files (not 
in the git-tish sense, I mean physically move the content of one file 
into the other). Here is a test which includes a bigger file within a 
smaller file.

=================== SCRIPT BEGIN ========================
git --version
git init
hexdump -C -n 5120 /dev/urandom > file2
hexdump -C -n 2560 /dev/urandom > file1
echo "--------------------------"
git add file1 file2
git commit -m "first commit"
git log --summary -M10% -C -1
echo "--------------------------"
(head -n 40 file1; cat file2; tail -n+40 file1) > file3
git rm file1 file2
git add file3
git commit -m "including file2 within file1 as file3"
git log --summary -M10% -C -1
echo "--------------------------"
git mv file3 file1
git commit --amend -m "including file2 within file1 as file1"
git log --summary -M10% -C -1
echo "--------------------------"
git mv file1 file2
git commit --amend -m "including file2 within file1 as file2"
git log --summary -M10% -C -1
echo "--------------------------"

=================== SCRIPT END ========================

=================== OUTPUT BEGIN ========================
git version 1.7.10.4
Initialized empty Git repository in /home/chfalag1/tmp/gittest/.git/
--------------------------
[master (root-commit) 6d997f5] first commit
  2 files changed, 482 insertions(+)
  create mode 100644 file1
  create mode 100644 file2
commit 6d997f5bbed2e9452317991ca024a5a0e1715027
Author: Gerlando Falauto <[email-masked]>
Date:   Tue Jul 31 10:27:42 2012 +0200

     first commit

  create mode 100644 file1
  create mode 100644 file2
--------------------------
rm 'file1'
rm 'file2'
[master 424edab] including file2 within file1 as file3
  2 files changed, 162 insertions(+), 161 deletions(-)
  delete mode 100644 file1
  rename file2 => file3 (66%)
commit 424edab771495fc3a1b4c172b9fcef9418501266
Author: Gerlando Falauto <[email-masked]>
Date:   Tue Jul 31 10:27:42 2012 +0200

     including file2 within file1 as file3

  delete mode 100644 file1
  rename file2 => file3 (66%)
--------------------------
[master ca70367] including file2 within file1 as file1
  1 file changed, 162 insertions(+)
  rename file2 => file1 (66%)
commit ca7036705063adbbd3c8cd0b5bccd5fbf44075bf
Author: Gerlando Falauto <[email-masked]>
Date:   Tue Jul 31 10:27:42 2012 +0200

     including file2 within file1 as file1

  delete mode 100644 file2
--------------------------
[master d7fdea4] including file2 within file1 as file2
  2 files changed, 162 insertions(+), 161 deletions(-)
  delete mode 100644 file1
commit d7fdea4855efe8401562a53ec7093c80390ee274
Author: Gerlando Falauto <[email-masked]>
Date:   Tue Jul 31 10:27:42 2012 +0200

     including file2 within file1 as file2

  delete mode 100644 file1
--------------------------
=================== OUTPUT END ========================

So including file2 (bigger) within file1 (smaller):
a) gets always (commit+extraction) detected as a rename file2=>file1 if 
the merged file is file3 (new file).
b) gets detected as a rename ONLY during commit (but not while 
extracting) if the merged file is file1 (existing file)
c) doesn't ever get detected as a rename if the merged file is file2 
(which makes sense, being file2 more similar to itself than to file1)

So now my two questions:

1) Is the behavior in b) correct? Shouldn't it at least be made consistent?

2) Would it make any sense to track (or detect) such "inclusion" cases? 
Is there any recommended or standard practice for performing such 
operations as file merge/split (i.e. when refactoring code or something)?

Thanks!
Gerlando