You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SimpleMergeTest.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /*
  2. * Copyright (C) 2009, Google Inc.
  3. * Copyright (C) 2008, Robin Rosenberg and others
  4. *
  5. * This program and the accompanying materials are made available under the
  6. * terms of the Eclipse Distribution License v. 1.0 which is available at
  7. * https://www.eclipse.org/org/documents/edl-v10.php.
  8. *
  9. * SPDX-License-Identifier: BSD-3-Clause
  10. */
  11. package org.eclipse.jgit.merge;
  12. import static org.junit.Assert.assertEquals;
  13. import static org.junit.Assert.assertFalse;
  14. import static org.junit.Assert.assertTrue;
  15. import java.io.IOException;
  16. import org.eclipse.jgit.dircache.DirCache;
  17. import org.eclipse.jgit.dircache.DirCacheBuilder;
  18. import org.eclipse.jgit.lib.CommitBuilder;
  19. import org.eclipse.jgit.lib.FileMode;
  20. import org.eclipse.jgit.lib.ObjectId;
  21. import org.eclipse.jgit.lib.ObjectInserter;
  22. import org.eclipse.jgit.lib.PersonIdent;
  23. import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
  24. import org.eclipse.jgit.treewalk.TreeWalk;
  25. import org.junit.Test;
  26. public class SimpleMergeTest extends SampleDataRepositoryTestCase {
  27. @Test
  28. public void testOurs() throws IOException {
  29. Merger ourMerger = MergeStrategy.OURS.newMerger(db);
  30. boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") });
  31. assertTrue(merge);
  32. assertEquals(db.resolve("a^{tree}"), ourMerger.getResultTreeId());
  33. }
  34. @Test
  35. public void testOurs_noRepo() throws IOException {
  36. try (ObjectInserter ins = db.newObjectInserter()) {
  37. Merger ourMerger = MergeStrategy.OURS.newMerger(ins, db.getConfig());
  38. boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") });
  39. assertTrue(merge);
  40. assertEquals(db.resolve("a^{tree}"), ourMerger.getResultTreeId());
  41. }
  42. }
  43. @Test
  44. public void testTheirs() throws IOException {
  45. Merger ourMerger = MergeStrategy.THEIRS.newMerger(db);
  46. boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") });
  47. assertTrue(merge);
  48. assertEquals(db.resolve("c^{tree}"), ourMerger.getResultTreeId());
  49. }
  50. @Test
  51. public void testTheirs_noRepo() throws IOException {
  52. try (ObjectInserter ins = db.newObjectInserter()) {
  53. Merger ourMerger = MergeStrategy.THEIRS.newMerger(db);
  54. boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") });
  55. assertTrue(merge);
  56. assertEquals(db.resolve("c^{tree}"), ourMerger.getResultTreeId());
  57. }
  58. }
  59. @Test
  60. public void testTrivialTwoWay() throws IOException {
  61. Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
  62. boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") });
  63. assertTrue(merge);
  64. assertEquals("02ba32d3649e510002c21651936b7077aa75ffa9",ourMerger.getResultTreeId().name());
  65. }
  66. @Test
  67. public void testTrivialTwoWay_disjointhistories() throws IOException {
  68. Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
  69. boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c~4") });
  70. assertTrue(merge);
  71. assertEquals("86265c33b19b2be71bdd7b8cb95823f2743d03a8",ourMerger.getResultTreeId().name());
  72. }
  73. @Test
  74. public void testTrivialTwoWay_ok() throws IOException {
  75. Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
  76. boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a^0^0^0"), db.resolve("a^0^0^1") });
  77. assertTrue(merge);
  78. assertEquals(db.resolve("a^0^0^{tree}"), ourMerger.getResultTreeId());
  79. }
  80. @Test
  81. public void testTrivialTwoWay_noRepo() throws IOException {
  82. try (ObjectInserter ins = db.newObjectInserter()) {
  83. Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(ins, db.getConfig());
  84. boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a^0^0^0"), db.resolve("a^0^0^1") });
  85. assertTrue(merge);
  86. assertEquals(db.resolve("a^0^0^{tree}"), ourMerger.getResultTreeId());
  87. }
  88. }
  89. @Test
  90. public void testTrivialTwoWay_conflict() throws IOException {
  91. Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
  92. boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("f"), db.resolve("g") });
  93. assertFalse(merge);
  94. }
  95. @Test
  96. public void testTrivialTwoWay_validSubtreeSort() throws Exception {
  97. DirCache treeB = db.readDirCache();
  98. DirCache treeO = db.readDirCache();
  99. DirCache treeT = db.readDirCache();
  100. DirCacheBuilder bTreeBuilder = treeB.builder();
  101. DirCacheBuilder oTreeBuilder = treeO.builder();
  102. DirCacheBuilder tTreeBuilder = treeT.builder();
  103. bTreeBuilder.add(createEntry("libelf-po/a", FileMode.REGULAR_FILE));
  104. bTreeBuilder.add(createEntry("libelf/c", FileMode.REGULAR_FILE));
  105. oTreeBuilder.add(createEntry("Makefile", FileMode.REGULAR_FILE));
  106. oTreeBuilder.add(createEntry("libelf-po/a", FileMode.REGULAR_FILE));
  107. oTreeBuilder.add(createEntry("libelf/c", FileMode.REGULAR_FILE));
  108. tTreeBuilder.add(createEntry("libelf-po/a", FileMode.REGULAR_FILE));
  109. tTreeBuilder
  110. .add(createEntry("libelf/c", FileMode.REGULAR_FILE, "blah"));
  111. bTreeBuilder.finish();
  112. oTreeBuilder.finish();
  113. tTreeBuilder.finish();
  114. ObjectInserter ow = db.newObjectInserter();
  115. ObjectId b = commit(ow, treeB, new ObjectId[] {});
  116. ObjectId o = commit(ow, treeO, new ObjectId[] { b });
  117. ObjectId t = commit(ow, treeT, new ObjectId[] { b });
  118. Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
  119. boolean merge = ourMerger.merge(new ObjectId[] { o, t });
  120. assertTrue(merge);
  121. try (TreeWalk tw = new TreeWalk(db)) {
  122. tw.setRecursive(true);
  123. tw.reset(ourMerger.getResultTreeId());
  124. assertTrue(tw.next());
  125. assertEquals("Makefile", tw.getPathString());
  126. assertCorrectId(treeO, tw);
  127. assertTrue(tw.next());
  128. assertEquals("libelf-po/a", tw.getPathString());
  129. assertCorrectId(treeO, tw);
  130. assertTrue(tw.next());
  131. assertEquals("libelf/c", tw.getPathString());
  132. assertCorrectId(treeT, tw);
  133. assertFalse(tw.next());
  134. }
  135. }
  136. @Test
  137. public void testTrivialTwoWay_concurrentSubtreeChange() throws Exception {
  138. DirCache treeB = db.readDirCache();
  139. DirCache treeO = db.readDirCache();
  140. DirCache treeT = db.readDirCache();
  141. DirCacheBuilder bTreeBuilder = treeB.builder();
  142. DirCacheBuilder oTreeBuilder = treeO.builder();
  143. DirCacheBuilder tTreeBuilder = treeT.builder();
  144. bTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
  145. bTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
  146. oTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE, "o !"));
  147. oTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
  148. tTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
  149. tTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "t !"));
  150. bTreeBuilder.finish();
  151. oTreeBuilder.finish();
  152. tTreeBuilder.finish();
  153. ObjectInserter ow = db.newObjectInserter();
  154. ObjectId b = commit(ow, treeB, new ObjectId[] {});
  155. ObjectId o = commit(ow, treeO, new ObjectId[] { b });
  156. ObjectId t = commit(ow, treeT, new ObjectId[] { b });
  157. Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
  158. boolean merge = ourMerger.merge(new ObjectId[] { o, t });
  159. assertTrue(merge);
  160. try (TreeWalk tw = new TreeWalk(db)) {
  161. tw.setRecursive(true);
  162. tw.reset(ourMerger.getResultTreeId());
  163. assertTrue(tw.next());
  164. assertEquals("d/o", tw.getPathString());
  165. assertCorrectId(treeO, tw);
  166. assertTrue(tw.next());
  167. assertEquals("d/t", tw.getPathString());
  168. assertCorrectId(treeT, tw);
  169. assertFalse(tw.next());
  170. }
  171. }
  172. @Test
  173. public void testTrivialTwoWay_conflictSubtreeChange() throws Exception {
  174. DirCache treeB = db.readDirCache();
  175. DirCache treeO = db.readDirCache();
  176. DirCache treeT = db.readDirCache();
  177. DirCacheBuilder bTreeBuilder = treeB.builder();
  178. DirCacheBuilder oTreeBuilder = treeO.builder();
  179. DirCacheBuilder tTreeBuilder = treeT.builder();
  180. bTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
  181. bTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
  182. oTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
  183. oTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "o !"));
  184. tTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE, "t !"));
  185. tTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "t !"));
  186. bTreeBuilder.finish();
  187. oTreeBuilder.finish();
  188. tTreeBuilder.finish();
  189. ObjectInserter ow = db.newObjectInserter();
  190. ObjectId b = commit(ow, treeB, new ObjectId[] {});
  191. ObjectId o = commit(ow, treeO, new ObjectId[] { b });
  192. ObjectId t = commit(ow, treeT, new ObjectId[] { b });
  193. Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
  194. boolean merge = ourMerger.merge(new ObjectId[] { o, t });
  195. assertFalse(merge);
  196. }
  197. @Test
  198. public void testTrivialTwoWay_leftDFconflict1() throws Exception {
  199. DirCache treeB = db.readDirCache();
  200. DirCache treeO = db.readDirCache();
  201. DirCache treeT = db.readDirCache();
  202. DirCacheBuilder bTreeBuilder = treeB.builder();
  203. DirCacheBuilder oTreeBuilder = treeO.builder();
  204. DirCacheBuilder tTreeBuilder = treeT.builder();
  205. bTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
  206. bTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
  207. oTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE));
  208. tTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
  209. tTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "t !"));
  210. bTreeBuilder.finish();
  211. oTreeBuilder.finish();
  212. tTreeBuilder.finish();
  213. ObjectInserter ow = db.newObjectInserter();
  214. ObjectId b = commit(ow, treeB, new ObjectId[] {});
  215. ObjectId o = commit(ow, treeO, new ObjectId[] { b });
  216. ObjectId t = commit(ow, treeT, new ObjectId[] { b });
  217. Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
  218. boolean merge = ourMerger.merge(new ObjectId[] { o, t });
  219. assertFalse(merge);
  220. }
  221. @Test
  222. public void testTrivialTwoWay_rightDFconflict1() throws Exception {
  223. DirCache treeB = db.readDirCache();
  224. DirCache treeO = db.readDirCache();
  225. DirCache treeT = db.readDirCache();
  226. DirCacheBuilder bTreeBuilder = treeB.builder();
  227. DirCacheBuilder oTreeBuilder = treeO.builder();
  228. DirCacheBuilder tTreeBuilder = treeT.builder();
  229. bTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
  230. bTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
  231. oTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
  232. oTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "o !"));
  233. tTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE));
  234. bTreeBuilder.finish();
  235. oTreeBuilder.finish();
  236. tTreeBuilder.finish();
  237. ObjectInserter ow = db.newObjectInserter();
  238. ObjectId b = commit(ow, treeB, new ObjectId[] {});
  239. ObjectId o = commit(ow, treeO, new ObjectId[] { b });
  240. ObjectId t = commit(ow, treeT, new ObjectId[] { b });
  241. Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
  242. boolean merge = ourMerger.merge(new ObjectId[] { o, t });
  243. assertFalse(merge);
  244. }
  245. @Test
  246. public void testTrivialTwoWay_leftDFconflict2() throws Exception {
  247. DirCache treeB = db.readDirCache();
  248. DirCache treeO = db.readDirCache();
  249. DirCache treeT = db.readDirCache();
  250. DirCacheBuilder bTreeBuilder = treeB.builder();
  251. DirCacheBuilder oTreeBuilder = treeO.builder();
  252. DirCacheBuilder tTreeBuilder = treeT.builder();
  253. bTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE));
  254. oTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE, "o !"));
  255. tTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
  256. bTreeBuilder.finish();
  257. oTreeBuilder.finish();
  258. tTreeBuilder.finish();
  259. ObjectInserter ow = db.newObjectInserter();
  260. ObjectId b = commit(ow, treeB, new ObjectId[] {});
  261. ObjectId o = commit(ow, treeO, new ObjectId[] { b });
  262. ObjectId t = commit(ow, treeT, new ObjectId[] { b });
  263. Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
  264. boolean merge = ourMerger.merge(new ObjectId[] { o, t });
  265. assertFalse(merge);
  266. }
  267. @Test
  268. public void testTrivialTwoWay_rightDFconflict2() throws Exception {
  269. DirCache treeB = db.readDirCache();
  270. DirCache treeO = db.readDirCache();
  271. DirCache treeT = db.readDirCache();
  272. DirCacheBuilder bTreeBuilder = treeB.builder();
  273. DirCacheBuilder oTreeBuilder = treeO.builder();
  274. DirCacheBuilder tTreeBuilder = treeT.builder();
  275. bTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE));
  276. oTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
  277. tTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE, "t !"));
  278. bTreeBuilder.finish();
  279. oTreeBuilder.finish();
  280. tTreeBuilder.finish();
  281. ObjectInserter ow = db.newObjectInserter();
  282. ObjectId b = commit(ow, treeB, new ObjectId[] {});
  283. ObjectId o = commit(ow, treeO, new ObjectId[] { b });
  284. ObjectId t = commit(ow, treeT, new ObjectId[] { b });
  285. Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
  286. boolean merge = ourMerger.merge(new ObjectId[] { o, t });
  287. assertFalse(merge);
  288. }
  289. private static void assertCorrectId(DirCache treeT, TreeWalk tw) {
  290. assertEquals(treeT.getEntry(tw.getPathString()).getObjectId(), tw
  291. .getObjectId(0));
  292. }
  293. private static ObjectId commit(ObjectInserter odi, DirCache treeB,
  294. ObjectId[] parentIds) throws Exception {
  295. CommitBuilder c = new CommitBuilder();
  296. c.setTreeId(treeB.writeTree(odi));
  297. c.setAuthor(new PersonIdent("A U Thor", "a.u.thor", 1L, 0));
  298. c.setCommitter(c.getAuthor());
  299. c.setParentIds(parentIds);
  300. c.setMessage("Tree " + c.getTreeId().name());
  301. ObjectId id = odi.insert(c);
  302. odi.flush();
  303. return id;
  304. }
  305. }