From 5adef23365a8704b64efb25e49fcf85326beee40 Mon Sep 17 00:00:00 2001 From: Christian Halstrick Date: Mon, 22 Nov 2010 22:41:25 +0100 Subject: [PATCH] Fix bug regarding handling of non-versioned files during merge There was a bug introduced by commit 0e815fe. For non-versioned files the merge algorithm detected an incoming deletion from THEIRS. Consequently such files were deleted. That's a severe bug which was fixed by more precisely detecting incoming deletions. Change-Id: I4385d3c990db11d62e371a385dc8ee89841db84a Signed-off-by: Christian Halstrick Signed-off-by: Philipp Thun Signed-off-by: Matthias Sohn --- .../eclipse/jgit/api/MergeCommandTest.java | 50 +++++++++++++++++++ .../org/eclipse/jgit/merge/ResolveMerger.java | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java index 231b00976..141f330bf 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java @@ -197,6 +197,56 @@ public class MergeCommandTest extends RepositoryTestCase { assertEquals(RepositoryState.MERGING, db.getRepositoryState()); } + public void testMergeNonVersionedPaths() throws Exception { + Git git = new Git(db); + + writeTrashFile("a", "1\na\n3\n"); + writeTrashFile("b", "1\nb\n3\n"); + writeTrashFile("c/c/c", "1\nc\n3\n"); + git.add().addFilepattern("a").addFilepattern("b") + .addFilepattern("c/c/c").call(); + RevCommit initialCommit = git.commit().setMessage("initial").call(); + + createBranch(initialCommit, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + + writeTrashFile("a", "1\na(side)\n3\n"); + writeTrashFile("b", "1\nb(side)\n3\n"); + git.add().addFilepattern("a").addFilepattern("b").call(); + RevCommit secondCommit = git.commit().setMessage("side").call(); + + assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b"))); + checkoutBranch("refs/heads/master"); + assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b"))); + + writeTrashFile("a", "1\na(main)\n3\n"); + writeTrashFile("c/c/c", "1\nc(main)\n3\n"); + git.add().addFilepattern("a").addFilepattern("c/c/c").call(); + git.commit().setMessage("main").call(); + + writeTrashFile("d", "1\nd\n3\n"); + assertTrue(new File(db.getWorkTree(), "e").mkdir()); + + MergeResult result = git.merge().include(secondCommit.getId()) + .setStrategy(MergeStrategy.RESOLVE).call(); + assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus()); + + assertEquals( + "1\n<<<<<<< HEAD\na(main)\n=======\na(side)\n>>>>>>> 86503e7e397465588cc267b65d778538bffccb83\n3\n", + read(new File(db.getWorkTree(), "a"))); + assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b"))); + assertEquals("1\nc(main)\n3\n", + read(new File(db.getWorkTree(), "c/c/c"))); + assertEquals("1\nd\n3\n", read(new File(db.getWorkTree(), "d"))); + File dir = new File(db.getWorkTree(), "e"); + assertTrue(dir.isDirectory()); + + assertEquals(1, result.getConflicts().size()); + assertEquals(3, result.getConflicts().get("a")[0].length); + + assertEquals(RepositoryState.MERGING, db.getRepositoryState()); + } + public void testSuccessfulContentMerge() throws Exception { Git git = new Git(db); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java index 1b6ec23ba..a6119edfa 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java @@ -390,7 +390,7 @@ public class ResolveMerger extends ThreeWayMerger { if (e != null) toBeCheckedOut.put(tw.getPathString(), e); return true; - } else if (modeT == 0) { + } else if ((modeT == 0) && (modeB != 0)) { // we want THEIRS ... but THEIRS contains the deletion of the // file toBeCheckedOut.put(tw.getPathString(), null);