1
2
3
4
5
6
7
8
9
10
11
12 package org.eclipse.jgit.merge;
13
14 import static org.junit.Assert.assertEquals;
15 import static org.junit.Assert.assertFalse;
16 import static org.junit.Assert.assertTrue;
17
18 import java.io.IOException;
19
20 import org.eclipse.jgit.dircache.DirCache;
21 import org.eclipse.jgit.dircache.DirCacheBuilder;
22 import org.eclipse.jgit.lib.CommitBuilder;
23 import org.eclipse.jgit.lib.FileMode;
24 import org.eclipse.jgit.lib.ObjectId;
25 import org.eclipse.jgit.lib.ObjectInserter;
26 import org.eclipse.jgit.lib.PersonIdent;
27 import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
28 import org.eclipse.jgit.treewalk.TreeWalk;
29 import org.junit.Test;
30
31 public class SimpleMergeTest extends SampleDataRepositoryTestCase {
32
33 @Test
34 public void testOurs() throws IOException {
35 Merger ourMerger = MergeStrategy.OURS.newMerger(db);
36 boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") });
37 assertTrue(merge);
38 assertEquals(db.resolve("a^{tree}"), ourMerger.getResultTreeId());
39 }
40
41 @Test
42 public void testOurs_noRepo() throws IOException {
43 try (ObjectInserter ins = db.newObjectInserter()) {
44 Merger ourMerger = MergeStrategy.OURS.newMerger(ins, db.getConfig());
45 boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") });
46 assertTrue(merge);
47 assertEquals(db.resolve("a^{tree}"), ourMerger.getResultTreeId());
48 }
49 }
50
51 @Test
52 public void testTheirs() throws IOException {
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 testTheirs_noRepo() throws IOException {
61 try (ObjectInserter ins = db.newObjectInserter()) {
62 Merger ourMerger = MergeStrategy.THEIRS.newMerger(db);
63 boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") });
64 assertTrue(merge);
65 assertEquals(db.resolve("c^{tree}"), ourMerger.getResultTreeId());
66 }
67 }
68
69 @Test
70 public void testTrivialTwoWay() throws IOException {
71 Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
72 boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") });
73 assertTrue(merge);
74 assertEquals("02ba32d3649e510002c21651936b7077aa75ffa9",ourMerger.getResultTreeId().name());
75 }
76
77 @Test
78 public void testTrivialTwoWay_disjointhistories() throws IOException {
79 Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
80 boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c~4") });
81 assertTrue(merge);
82 assertEquals("86265c33b19b2be71bdd7b8cb95823f2743d03a8",ourMerger.getResultTreeId().name());
83 }
84
85 @Test
86 public void testTrivialTwoWay_ok() throws IOException {
87 Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
88 boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a^0^0^0"), db.resolve("a^0^0^1") });
89 assertTrue(merge);
90 assertEquals(db.resolve("a^0^0^{tree}"), ourMerger.getResultTreeId());
91 }
92
93 @Test
94 public void testTrivialTwoWay_noRepo() throws IOException {
95 try (ObjectInserter ins = db.newObjectInserter()) {
96 Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(ins, db.getConfig());
97 boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a^0^0^0"), db.resolve("a^0^0^1") });
98 assertTrue(merge);
99 assertEquals(db.resolve("a^0^0^{tree}"), ourMerger.getResultTreeId());
100 }
101 }
102
103 @Test
104 public void testTrivialTwoWay_conflict() throws IOException {
105 Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
106 boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("f"), db.resolve("g") });
107 assertFalse(merge);
108 }
109
110 @Test
111 public void testTrivialTwoWay_validSubtreeSort() throws Exception {
112 DirCache treeB = db.readDirCache();
113 DirCache treeO = db.readDirCache();
114 DirCache treeT = db.readDirCache();
115
116 DirCacheBuilder bTreeBuilder = treeB.builder();
117 DirCacheBuilder oTreeBuilder = treeO.builder();
118 DirCacheBuilder tTreeBuilder = treeT.builder();
119
120 bTreeBuilder.add(createEntry("libelf-po/a", FileMode.REGULAR_FILE));
121 bTreeBuilder.add(createEntry("libelf/c", FileMode.REGULAR_FILE));
122
123 oTreeBuilder.add(createEntry("Makefile", FileMode.REGULAR_FILE));
124 oTreeBuilder.add(createEntry("libelf-po/a", FileMode.REGULAR_FILE));
125 oTreeBuilder.add(createEntry("libelf/c", FileMode.REGULAR_FILE));
126
127 tTreeBuilder.add(createEntry("libelf-po/a", FileMode.REGULAR_FILE));
128 tTreeBuilder
129 .add(createEntry("libelf/c", FileMode.REGULAR_FILE, "blah"));
130
131 bTreeBuilder.finish();
132 oTreeBuilder.finish();
133 tTreeBuilder.finish();
134
135 ObjectInserter ow = db.newObjectInserter();
136 ObjectId b = commit(ow, treeB, new ObjectId[] {});
137 ObjectId o = commit(ow, treeO, new ObjectId[] { b });
138 ObjectId t = commit(ow, treeT, new ObjectId[] { b });
139
140 Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
141 boolean merge = ourMerger.merge(new ObjectId[] { o, t });
142 assertTrue(merge);
143
144 try (TreeWalk tw = new TreeWalk(db)) {
145 tw.setRecursive(true);
146 tw.reset(ourMerger.getResultTreeId());
147
148 assertTrue(tw.next());
149 assertEquals("Makefile", tw.getPathString());
150 assertCorrectId(treeO, tw);
151
152 assertTrue(tw.next());
153 assertEquals("libelf-po/a", tw.getPathString());
154 assertCorrectId(treeO, tw);
155
156 assertTrue(tw.next());
157 assertEquals("libelf/c", tw.getPathString());
158 assertCorrectId(treeT, tw);
159
160 assertFalse(tw.next());
161 }
162 }
163
164 @Test
165 public void testTrivialTwoWay_concurrentSubtreeChange() throws Exception {
166 DirCache treeB = db.readDirCache();
167 DirCache treeO = db.readDirCache();
168 DirCache treeT = db.readDirCache();
169
170 DirCacheBuilder bTreeBuilder = treeB.builder();
171 DirCacheBuilder oTreeBuilder = treeO.builder();
172 DirCacheBuilder tTreeBuilder = treeT.builder();
173
174 bTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
175 bTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
176
177 oTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE, "o !"));
178 oTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
179
180 tTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
181 tTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "t !"));
182
183 bTreeBuilder.finish();
184 oTreeBuilder.finish();
185 tTreeBuilder.finish();
186
187 ObjectInserter ow = db.newObjectInserter();
188 ObjectId b = commit(ow, treeB, new ObjectId[] {});
189 ObjectId o = commit(ow, treeO, new ObjectId[] { b });
190 ObjectId t = commit(ow, treeT, new ObjectId[] { b });
191
192 Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
193 boolean merge = ourMerger.merge(new ObjectId[] { o, t });
194 assertTrue(merge);
195
196 try (TreeWalk tw = new TreeWalk(db)) {
197 tw.setRecursive(true);
198 tw.reset(ourMerger.getResultTreeId());
199
200 assertTrue(tw.next());
201 assertEquals("d/o", tw.getPathString());
202 assertCorrectId(treeO, tw);
203
204 assertTrue(tw.next());
205 assertEquals("d/t", tw.getPathString());
206 assertCorrectId(treeT, tw);
207
208 assertFalse(tw.next());
209 }
210 }
211
212 @Test
213 public void testTrivialTwoWay_conflictSubtreeChange() throws Exception {
214 DirCache treeB = db.readDirCache();
215 DirCache treeO = db.readDirCache();
216 DirCache treeT = db.readDirCache();
217
218 DirCacheBuilder bTreeBuilder = treeB.builder();
219 DirCacheBuilder oTreeBuilder = treeO.builder();
220 DirCacheBuilder tTreeBuilder = treeT.builder();
221
222 bTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
223 bTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
224
225 oTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
226 oTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "o !"));
227
228 tTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE, "t !"));
229 tTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "t !"));
230
231 bTreeBuilder.finish();
232 oTreeBuilder.finish();
233 tTreeBuilder.finish();
234
235 ObjectInserter ow = db.newObjectInserter();
236 ObjectId b = commit(ow, treeB, new ObjectId[] {});
237 ObjectId o = commit(ow, treeO, new ObjectId[] { b });
238 ObjectId t = commit(ow, treeT, new ObjectId[] { b });
239
240 Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
241 boolean merge = ourMerger.merge(new ObjectId[] { o, t });
242 assertFalse(merge);
243 }
244
245 @Test
246 public void testTrivialTwoWay_leftDFconflict1() throws Exception {
247 DirCache treeB = db.readDirCache();
248 DirCache treeO = db.readDirCache();
249 DirCache treeT = db.readDirCache();
250
251 DirCacheBuilder bTreeBuilder = treeB.builder();
252 DirCacheBuilder oTreeBuilder = treeO.builder();
253 DirCacheBuilder tTreeBuilder = treeT.builder();
254
255 bTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
256 bTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
257
258 oTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE));
259
260 tTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
261 tTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "t !"));
262
263 bTreeBuilder.finish();
264 oTreeBuilder.finish();
265 tTreeBuilder.finish();
266
267 ObjectInserter ow = db.newObjectInserter();
268 ObjectId b = commit(ow, treeB, new ObjectId[] {});
269 ObjectId o = commit(ow, treeO, new ObjectId[] { b });
270 ObjectId t = commit(ow, treeT, new ObjectId[] { b });
271
272 Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
273 boolean merge = ourMerger.merge(new ObjectId[] { o, t });
274 assertFalse(merge);
275 }
276
277 @Test
278 public void testTrivialTwoWay_rightDFconflict1() throws Exception {
279 DirCache treeB = db.readDirCache();
280 DirCache treeO = db.readDirCache();
281 DirCache treeT = db.readDirCache();
282
283 DirCacheBuilder bTreeBuilder = treeB.builder();
284 DirCacheBuilder oTreeBuilder = treeO.builder();
285 DirCacheBuilder tTreeBuilder = treeT.builder();
286
287 bTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
288 bTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
289
290 oTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
291 oTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "o !"));
292
293 tTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE));
294
295 bTreeBuilder.finish();
296 oTreeBuilder.finish();
297 tTreeBuilder.finish();
298
299 ObjectInserter ow = db.newObjectInserter();
300 ObjectId b = commit(ow, treeB, new ObjectId[] {});
301 ObjectId o = commit(ow, treeO, new ObjectId[] { b });
302 ObjectId t = commit(ow, treeT, new ObjectId[] { b });
303
304 Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
305 boolean merge = ourMerger.merge(new ObjectId[] { o, t });
306 assertFalse(merge);
307 }
308
309 @Test
310 public void testTrivialTwoWay_leftDFconflict2() throws Exception {
311 DirCache treeB = db.readDirCache();
312 DirCache treeO = db.readDirCache();
313 DirCache treeT = db.readDirCache();
314
315 DirCacheBuilder bTreeBuilder = treeB.builder();
316 DirCacheBuilder oTreeBuilder = treeO.builder();
317 DirCacheBuilder tTreeBuilder = treeT.builder();
318
319 bTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE));
320
321 oTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE, "o !"));
322
323 tTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
324
325 bTreeBuilder.finish();
326 oTreeBuilder.finish();
327 tTreeBuilder.finish();
328
329 ObjectInserter ow = db.newObjectInserter();
330 ObjectId b = commit(ow, treeB, new ObjectId[] {});
331 ObjectId o = commit(ow, treeO, new ObjectId[] { b });
332 ObjectId t = commit(ow, treeT, new ObjectId[] { b });
333
334 Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
335 boolean merge = ourMerger.merge(new ObjectId[] { o, t });
336 assertFalse(merge);
337 }
338
339 @Test
340 public void testTrivialTwoWay_rightDFconflict2() throws Exception {
341 DirCache treeB = db.readDirCache();
342 DirCache treeO = db.readDirCache();
343 DirCache treeT = db.readDirCache();
344
345 DirCacheBuilder bTreeBuilder = treeB.builder();
346 DirCacheBuilder oTreeBuilder = treeO.builder();
347 DirCacheBuilder tTreeBuilder = treeT.builder();
348
349 bTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE));
350
351 oTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
352
353 tTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE, "t !"));
354
355 bTreeBuilder.finish();
356 oTreeBuilder.finish();
357 tTreeBuilder.finish();
358
359 ObjectInserter ow = db.newObjectInserter();
360 ObjectId b = commit(ow, treeB, new ObjectId[] {});
361 ObjectId o = commit(ow, treeO, new ObjectId[] { b });
362 ObjectId t = commit(ow, treeT, new ObjectId[] { b });
363
364 Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
365 boolean merge = ourMerger.merge(new ObjectId[] { o, t });
366 assertFalse(merge);
367 }
368
369 private static void assertCorrectId(DirCache treeT, TreeWalk tw) {
370 assertEquals(treeT.getEntry(tw.getPathString()).getObjectId(), tw
371 .getObjectId(0));
372 }
373
374 private static ObjectId commit(ObjectInserter odi, DirCache treeB,
375 ObjectId[] parentIds) throws Exception {
376 CommitBuilder c = new CommitBuilder();
377 c.setTreeId(treeB.writeTree(odi));
378 c.setAuthor(new PersonIdent("A U Thor", "a.u.thor", 1L, 0));
379 c.setCommitter(c.getAuthor());
380 c.setParentIds(parentIds);
381 c.setMessage("Tree " + c.getTreeId().name());
382 ObjectId id = odi.insert(c);
383 odi.flush();
384 return id;
385 }
386 }