diff options
author | Dave Borowitz <dborowitz@google.com> | 2017-03-31 11:49:12 -0400 |
---|---|---|
committer | Jonathan Nieder <jrn@google.com> | 2017-04-05 17:50:54 -0400 |
commit | 4c3e274588060d9ab2e05d7919f506789bcbbc0b (patch) | |
tree | 241e54a6bfdba3a7036c030d094e3da5a5b733da /org.eclipse.jgit.test | |
parent | aec22e74cf76d7b7ea53d526b908613eaeac5b55 (diff) | |
download | jgit-4c3e274588060d9ab2e05d7919f506789bcbbc0b.tar.gz jgit-4c3e274588060d9ab2e05d7919f506789bcbbc0b.zip |
Support creating Mergers without a Repository
All that's really required to run a merge operation is a single
ObjectInserter, from which we can construct a RevWalk, plus a Config
that declares a diff algorithm. Provide some factory methods that don't
take Repository.
Change-Id: Ib884dce2528424b5bcbbbbfc043baec1886b9bbd
Diffstat (limited to 'org.eclipse.jgit.test')
-rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java | 133 | ||||
-rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java | 30 |
2 files changed, 162 insertions, 1 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java index 255262255a..d8b8750ba3 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java @@ -42,12 +42,17 @@ */ package org.eclipse.jgit.merge; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.util.Arrays; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.MergeResult; @@ -59,8 +64,14 @@ import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.errors.NoMergeBaseException; import org.eclipse.jgit.errors.NoMergeBaseException.MergeBaseFailureReason; import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevObject; +import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.FileUtils; @@ -408,7 +419,7 @@ public class ResolveMergerTest extends RepositoryTestCase { /** * Merging two equal subtrees with an incore merger should lead to a merged - * state (The 'Gerrit' use case). + * state. * * @param strategy * @throws Exception @@ -442,6 +453,43 @@ public class ResolveMergerTest extends RepositoryTestCase { } /** + * Merging two equal subtrees with an incore merger should lead to a merged + * state, without using a Repository (the 'Gerrit' use case). + * + * @param strategy + * @throws Exception + */ + @Theory + public void checkMergeEqualTreesInCore_noRepo(MergeStrategy strategy) + throws Exception { + Git git = Git.wrap(db); + + writeTrashFile("d/1", "orig"); + git.add().addFilepattern("d/1").call(); + RevCommit first = git.commit().setMessage("added d/1").call(); + + writeTrashFile("d/1", "modified"); + RevCommit masterCommit = git.commit().setAll(true) + .setMessage("modified d/1 on master").call(); + + git.checkout().setCreateBranch(true).setStartPoint(first) + .setName("side").call(); + writeTrashFile("d/1", "modified"); + RevCommit sideCommit = git.commit().setAll(true) + .setMessage("modified d/1 on side").call(); + + git.rm().addFilepattern("d/1").call(); + git.rm().addFilepattern("d").call(); + + try (ObjectInserter ins = db.newObjectInserter()) { + ThreeWayMerger resolveMerger = + (ThreeWayMerger) strategy.newMerger(ins, db.getConfig()); + boolean noProblems = resolveMerger.merge(masterCommit, sideCommit); + assertTrue(noProblems); + } + } + + /** * Merging two equal subtrees when the index and HEAD does not contain any * file in that subtree should lead to a merged state. * @@ -613,6 +661,35 @@ public class ResolveMergerTest extends RepositoryTestCase { } @Theory + public void checkContentMergeNoConflict_noRepo(MergeStrategy strategy) + throws Exception { + Git git = Git.wrap(db); + + writeTrashFile("file", "1\n2\n3"); + git.add().addFilepattern("file").call(); + RevCommit first = git.commit().setMessage("added file").call(); + + writeTrashFile("file", "1master\n2\n3"); + RevCommit masterCommit = git.commit().setAll(true) + .setMessage("modified file on master").call(); + + git.checkout().setCreateBranch(true).setStartPoint(first) + .setName("side").call(); + writeTrashFile("file", "1\n2\n3side"); + RevCommit sideCommit = git.commit().setAll(true) + .setMessage("modified file on side").call(); + + try (ObjectInserter ins = db.newObjectInserter()) { + ResolveMerger merger = + (ResolveMerger) strategy.newMerger(ins, db.getConfig()); + boolean noProblems = merger.merge(masterCommit, sideCommit); + assertTrue(noProblems); + assertEquals("1master\n2\n3side", + readBlob(merger.getResultTreeId(), "file")); + } + } + + @Theory public void checkContentMergeConflict(MergeStrategy strategy) throws Exception { Git git = Git.wrap(db); @@ -644,6 +721,49 @@ public class ResolveMergerTest extends RepositoryTestCase { assertEquals(expected, read("file")); } + @Theory + public void checkContentMergeConflict_noTree(MergeStrategy strategy) + throws Exception { + Git git = Git.wrap(db); + + writeTrashFile("file", "1\n2\n3"); + git.add().addFilepattern("file").call(); + RevCommit first = git.commit().setMessage("added file").call(); + + writeTrashFile("file", "1master\n2\n3"); + RevCommit masterCommit = git.commit().setAll(true) + .setMessage("modified file on master").call(); + + git.checkout().setCreateBranch(true).setStartPoint(first) + .setName("side").call(); + writeTrashFile("file", "1side\n2\n3"); + RevCommit sideCommit = git.commit().setAll(true) + .setMessage("modified file on side").call(); + + try (ObjectInserter ins = db.newObjectInserter()) { + ResolveMerger merger = + (ResolveMerger) strategy.newMerger(ins, db.getConfig()); + boolean noProblems = merger.merge(masterCommit, sideCommit); + assertFalse(noProblems); + assertEquals(Arrays.asList("file"), merger.getUnmergedPaths()); + + MergeFormatter fmt = new MergeFormatter(); + merger.getMergeResults().get("file"); + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + fmt.formatMerge(out, merger.getMergeResults().get("file"), + "BASE", "OURS", "THEIRS", UTF_8.name()); + String expected = "<<<<<<< OURS\n" + + "1master\n" + + "=======\n" + + "1side\n" + + ">>>>>>> THEIRS\n" + + "2\n" + + "3"; + assertEquals(expected, new String(out.toByteArray(), UTF_8)); + } + } + } + /** * Merging after criss-cross merges. In this case we merge together two * commits which have two equally good common ancestors @@ -875,4 +995,15 @@ public class ResolveMergerTest extends RepositoryTestCase { curMod >= lastMod); } } + + private String readBlob(ObjectId treeish, String path) throws Exception { + TestRepository<?> tr = new TestRepository<>(db); + RevWalk rw = tr.getRevWalk(); + RevTree tree = rw.parseTree(treeish); + RevObject obj = tr.get(tree, path); + if (obj == null) { + return null; + } + return new String(rw.getObjectReader().open(obj, OBJ_BLOB).getBytes(), UTF_8); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java index db9d87dd17..951568e7bb 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java @@ -72,6 +72,16 @@ public class SimpleMergeTest extends SampleDataRepositoryTestCase { } @Test + public void testOurs_noRepo() throws IOException { + try (ObjectInserter ins = db.newObjectInserter()) { + Merger ourMerger = MergeStrategy.OURS.newMerger(ins, db.getConfig()); + boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") }); + assertTrue(merge); + assertEquals(db.resolve("a^{tree}"), ourMerger.getResultTreeId()); + } + } + + @Test public void testTheirs() throws IOException { Merger ourMerger = MergeStrategy.THEIRS.newMerger(db); boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") }); @@ -80,6 +90,16 @@ public class SimpleMergeTest extends SampleDataRepositoryTestCase { } @Test + public void testTheirs_noRepo() throws IOException { + try (ObjectInserter ins = db.newObjectInserter()) { + Merger ourMerger = MergeStrategy.THEIRS.newMerger(db); + boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") }); + assertTrue(merge); + assertEquals(db.resolve("c^{tree}"), ourMerger.getResultTreeId()); + } + } + + @Test public void testTrivialTwoWay() throws IOException { Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db); boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") }); @@ -104,6 +124,16 @@ public class SimpleMergeTest extends SampleDataRepositoryTestCase { } @Test + public void testTrivialTwoWay_noRepo() throws IOException { + try (ObjectInserter ins = db.newObjectInserter()) { + Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(ins, db.getConfig()); + boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a^0^0^0"), db.resolve("a^0^0^1") }); + assertTrue(merge); + assertEquals(db.resolve("a^0^0^{tree}"), ourMerger.getResultTreeId()); + } + } + + @Test public void testTrivialTwoWay_conflict() throws IOException { Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db); boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("f"), db.resolve("g") }); |