Reputation: 130
I've faced a merge behavior I can't explain. The following script initializes the repository and makes some branches with modifications and renames.
$ git init
$ emacs file.txt
$ cat file.txt
1
2
3
4
$ git add file.txt && git ci -m "initial"
$ git branch A && git branch B && git branch C && git branch D
$ git checkout A
$ emacs file.txt
$ cat file.txt
1
added after 1
2
3
4
$ git add file.txt && git commit -m "edited in A"
$ git checkout B
$ emacs file.txt
$ cat file.txt
1
2
3
added after 3
4
$ git add -u && git commit -m "edited in B"
$ git checkout C
$ git mv file.txt f.txt
$ git commit -m "renamed in C"
$ git checkout D
$ git mv file.txt f.txt
$ git commit -m "renamed in D"
$ emacs f.txt
$ cat f.txt
1
2
3
added after 3
4
$ git add -u && git commit -m "edited in D (after rename)"
Having that:
CONFLICT (rename/delete): f.txt deleted in A and renamed in HEAD. Version HEAD of f.txt left in tree.
In case 2 git detects the rename in branch C and thus successfully merges changes from the branch A.
In case 3, I can't understand why git can't merge changes from both branches even after successfull rename detection.
$ git --version
git version 1.9.3 (Apple Git-50)
Upvotes: 2
Views: 273
Reputation: 388023
U2EF1’s comment is actually right:
If I recall the default is that 80% of the file content matches, but I would never expect this to work reasonably with such tiny files.
I just tested the same procedure with a file that has 100 lines (instead of 4), and Git correctly recognized all changes without a conflict so I ended up with a file f.txt
and both line additions.
The reason for this is that Git does not track file renames—or even changes—at all. It tracks content, and a git mv
is just a combination of a git rm
and a git add
of a different (albeit similar/identical) file. So in order to recognize file renames for merging strategies or other visual aid (e.g. in git status
), it looks at the similarity of content and then judges by the similarity of two files. If they are very similar and one was removed while the other file was added, then Git will recognize it as a rename (copy detection works the same way). Now, the more content a file has, the easier you will make it for Git to recognize identical content and as such a file rename.
Upvotes: 1