JD White
JD White

Reputation: 927

Git rebase - remote deletes a file and local rebase applies changes to another file

Simple scenario:

Remote:

git init
touch a.py && git add a.py && git commit -am "Add a.py"
touch b.py && git add b.py && git commit -am "Add b.py"

Local:

git clone REMOTE_URL
echo "Bob Loblaw" >> a.py && git commit -am "Append to a.py"

Remote:

git rm a.py && git commit -am "Remove a.py"

Local:

git fetch origin
git rebase origin/master

Output:

$ cat b.py
Bob Loblaw

Why are my local changes to a.py applied to b.py instead of getting a rebase conflict, e.g.

CONFLICT (delete/modify): a.py deleted in HEAD and modified in Append to a.py. Version Append to a.py of a.py left in tree.

If it makes a difference, I'm using git version 1.7.4.1.

Upvotes: 2

Views: 336

Answers (2)

Gabriele Petronella
Gabriele Petronella

Reputation: 108151

I heard of this weird issue before.

The problems arises from the fact that a.py and b.py are identical in their content.

Git uses heuristics based on the contents in order to detect a file renaming, and in your case the heuristic confused the deletion of a.py with a renaming of the same to b.py, since they were both empty and the change applied is very small.

This happened because the default recursive merge strategy, according to the documentation,

can detect and handle merges involving renames

Apparently this was fixed/improved in modern versions of git, since on my machine I cannot reproduce the problem with Git v1.8.1.3.

You can update your Git (strongly suggested) or try with a different merge strategy, which doesn't handle renames, like resolve (though it has some drawbacks, read the doc for more info).

EDIT

A further alternative would be to play with the --rename-threshold option of the recursive merge strategy, setting it to M100%, which according to the doc of git-diff will

limit detection to exact renames

The git command would be

git rebase -Xrename-threshold=M100% origin/master

Upvotes: 1

sleske
sleske

Reputation: 83638

When following your steps, I do get a merge conflict during the rebase (as it should be):

gittest/loc$ git rebase origin/master
[...]
CONFLICT (modify/delete): a.py deleted in HEAD and modified in Append to a.py.
Version Append to a.py of a.py left in tree.
Failed to merge in the changes.

You probably did something subtly different - or maybe there is a problem with your git installation or a bug in your git (though that seems unlikely).

I used git 1.8.1.1 on Debian Linux.

Upvotes: 0

Related Questions