Issue 927: Losing data when merging renamed file
Status:  Released
Owner: ----
Closed:  May 2011
Reported by P.Przyby...@gmail.com, May 4, 2011
Affected Version:
2.1.6.1
What steps will reproduce the problem?
1. You have repository abc.git with file 'x' 
developer D1 clones abc.git 
developer D2 clones abc.git 
(at this point their origin/mater is on the same commit) 
2. Developer D1 does rename of file 'x' to 'y' (git mv x y) 
3. Developer D2 makes a change in file 'x' 
4. Both of them push their changes to gerrit. 

What is the expected output? What do you see instead?
Both scenario:
A. Rename of developer D1 gets merged first, developer D2 change to file 'x' gets merged second 
B. Rename of developer D1 gets merged second, developer D2 change to file 'x' gets merged first
are giving unexpected result: changes from developer D2 are not in the final 'y' file.

Please provide any additional information below.

In case A changes of D2 are lost (in some other case with files in subdirs x file was created).
In case B gerrit does not show differences in the file (except that it is rename) silently overwriting  changes made by D2.

If you try similar scenario with command line 'git merge' then the 
change of developer D2 to file 'x' would appear in file 'y' (correct and expected behaviour). 
The used merge strategy in Gerrit is 'Merge If Necessary' with 'Automaticaly resolve conflicts' enabled. The same results are achieved with cherry-pick strategy.


May 11, 2011
#1 christia...@gmail.com
I think this is a severe bug because we can silently loose modifications. The problem is not only for renamed files but in general when we have a deletion/modification conflict. If in changeset A you modify a file and in changeset B you delete that file you can submit both changesets. Gerrit will call JGit to merge A and B and because of a bug in JGit this succeeds without conflicts.

The Bug was fixed here: http://egit.eclipse.org/r/#change,3294 . I think gerrit should make use of a fixed version of jgit.

May 12, 2011
#2 sp3...@gmail.com
I'm not sure which merge strategy gerrit uses but I've tried the default one with jgit commandline. Before the #3294 change it used to be mismerge, now it is null pointer exception. Take a look at attached test-case.sh. 

$ ./test-case.sh
...

+ jgit merge d1/master
Fast-forward
+ jgit merge d2/master
java.lang.NullPointerException
        at org.eclipse.jgit.pgm.Merge.run(Merge.java:94)
        at org.eclipse.jgit.pgm.TextBuiltin.execute(TextBuiltin.java:148)
        at org.eclipse.jgit.pgm.Main.execute(Main.java:191)
        at org.eclipse.jgit.pgm.Main.run(Main.java:120)
        at org.eclipse.jgit.pgm.Main.main(Main.java:94)

test-case.sh
1007 bytes   View   Download
May 12, 2011
#3 christia...@gmail.com
I think gerrit is using the Resolve strategy. I know that there is one problem  with the last modification to the Resolve merge strategy which let org.eclipse.jgit.pgm.Merge crash (the merge strategy currently reports state CONFLICTING, but getConflicts() returns nothing) . I'll try to fix that today. But the gerrit code itself should not be affected by that because it doesn't process getConflicts())

May 13, 2011
#5 sp3...@gmail.com
Yes, this fixes the problem. See comments in gerrit:

I have verified that this works ok for my test case. On second merge we will get a conflict and that's way better than mismerge or null pointer exception. Command line git would merge this using recursive algorithm but that's another story.

$ ./test-case.sh
...
+ jgit merge d1/master
Fast-forward
+ jgit merge d2/master
CONFLICT(content): Merge conflict in x
Automatic merge failed; fix conflicts and then commit the result

May 16, 2011
#6 sop@google.com
2.1.7-rc1 updated to a newer version of JGit that contains the fix.
Status: Submitted
Labels: FixedIn-2.1.7
May 30, 2011
#7 Michal.S...@gmail.com
Normal Git can merge both branches and will report no conflict here. It's still not working properly, as of Gerrit 2.1.7-rc2.

Btw. doesn't reliable merging and conflict reporting deserve a bit higher priority?
May 31, 2011
#8 sop@google.com
If you have a case that isn't working, please share it.

If you can't share the example files, and you feel this is higher priority, please debug it yourself and send a patch upstream to JGit to fix the bug.
May 31, 2011
#9 Michal.S...@gmail.com
@Comment 8:
It isn't working using steps provided in initial report, when compared to command-line Git. Using command-line Git both branches are cleanly merged, but exactly the same branches pushed to Gerrit result in conflict when doing second merge.

Some time after adding comment 7 I've got information from colleague that this behavior is side-effect of JGit not yet supporting recursive merge strategy - adding it seems to be out of scope of this issue.
May 31, 2011
#10 sop@google.com
(No comment was entered for this change.)
Status: Released