290
293
('a', F, blob_a2.id))],
296
def test_tree_changes_rename_detector(self):
297
blob_a1 = make_object(Blob, data='a\nb\nc\nd\n')
298
blob_a2 = make_object(Blob, data='a\nb\nc\ne\n')
299
blob_b = make_object(Blob, data='b')
300
tree1 = self.commit_tree([('a', blob_a1), ('b', blob_b)])
301
tree2 = self.commit_tree([('c', blob_a2), ('b', blob_b)])
302
detector = RenameDetector(self.store)
304
self.assertChangesEqual(
305
[TreeChange.delete(('a', F, blob_a1.id)),
306
TreeChange.add(('c', F, blob_a2.id))],
308
self.assertChangesEqual(
309
[TreeChange.delete(('a', F, blob_a1.id)),
310
TreeChange(CHANGE_UNCHANGED, ('b', F, blob_b.id),
311
('b', F, blob_b.id)),
312
TreeChange.add(('c', F, blob_a2.id))],
313
tree1, tree2, want_unchanged=True)
314
self.assertChangesEqual(
315
[TreeChange(CHANGE_RENAME, ('a', F, blob_a1.id),
316
('c', F, blob_a2.id))],
317
tree1, tree2, rename_detector=detector)
318
self.assertChangesEqual(
319
[TreeChange(CHANGE_RENAME, ('a', F, blob_a1.id),
320
('c', F, blob_a2.id)),
321
TreeChange(CHANGE_UNCHANGED, ('b', F, blob_b.id),
322
('b', F, blob_b.id))],
323
tree1, tree2, rename_detector=detector, want_unchanged=True)
325
def assertChangesForMergeEqual(self, expected, parent_trees, merge_tree,
327
parent_tree_ids = [t.id for t in parent_trees]
328
actual = list(tree_changes_for_merge(
329
self.store, parent_tree_ids, merge_tree.id, **kwargs))
330
self.assertEqual(expected, actual)
332
parent_tree_ids.reverse()
333
expected = [list(reversed(cs)) for cs in expected]
334
actual = list(tree_changes_for_merge(
335
self.store, parent_tree_ids, merge_tree.id, **kwargs))
336
self.assertEqual(expected, actual)
338
def test_tree_changes_for_merge_add_no_conflict(self):
339
blob = make_object(Blob, data='blob')
340
parent1 = self.commit_tree([])
341
parent2 = merge = self.commit_tree([('a', blob)])
342
self.assertChangesForMergeEqual([], [parent1, parent2], merge)
343
self.assertChangesForMergeEqual([], [parent2, parent2], merge)
345
def test_tree_changes_for_merge_add_modify_conflict(self):
346
blob1 = make_object(Blob, data='1')
347
blob2 = make_object(Blob, data='2')
348
parent1 = self.commit_tree([])
349
parent2 = self.commit_tree([('a', blob1)])
350
merge = self.commit_tree([('a', blob2)])
351
self.assertChangesForMergeEqual(
352
[[TreeChange.add(('a', F, blob2.id)),
353
TreeChange(CHANGE_MODIFY, ('a', F, blob1.id), ('a', F, blob2.id))]],
354
[parent1, parent2], merge)
356
def test_tree_changes_for_merge_modify_modify_conflict(self):
357
blob1 = make_object(Blob, data='1')
358
blob2 = make_object(Blob, data='2')
359
blob3 = make_object(Blob, data='3')
360
parent1 = self.commit_tree([('a', blob1)])
361
parent2 = self.commit_tree([('a', blob2)])
362
merge = self.commit_tree([('a', blob3)])
363
self.assertChangesForMergeEqual(
364
[[TreeChange(CHANGE_MODIFY, ('a', F, blob1.id), ('a', F, blob3.id)),
365
TreeChange(CHANGE_MODIFY, ('a', F, blob2.id), ('a', F, blob3.id))]],
366
[parent1, parent2], merge)
368
def test_tree_changes_for_merge_modify_no_conflict(self):
369
blob1 = make_object(Blob, data='1')
370
blob2 = make_object(Blob, data='2')
371
parent1 = self.commit_tree([('a', blob1)])
372
parent2 = merge = self.commit_tree([('a', blob2)])
373
self.assertChangesForMergeEqual([], [parent1, parent2], merge)
375
def test_tree_changes_for_merge_delete_delete_conflict(self):
376
blob1 = make_object(Blob, data='1')
377
blob2 = make_object(Blob, data='2')
378
parent1 = self.commit_tree([('a', blob1)])
379
parent2 = self.commit_tree([('a', blob2)])
380
merge = self.commit_tree([])
381
self.assertChangesForMergeEqual(
382
[[TreeChange.delete(('a', F, blob1.id)),
383
TreeChange.delete(('a', F, blob2.id))]],
384
[parent1, parent2], merge)
386
def test_tree_changes_for_merge_delete_no_conflict(self):
387
blob = make_object(Blob, data='blob')
388
has = self.commit_tree([('a', blob)])
389
doesnt_have = self.commit_tree([])
390
self.assertChangesForMergeEqual([], [has, has], doesnt_have)
391
self.assertChangesForMergeEqual([], [has, doesnt_have], doesnt_have)
393
def test_tree_changes_for_merge_octopus_no_conflict(self):
395
blobs = [make_object(Blob, data=str(i)) for i in r]
396
parents = [self.commit_tree([('a', blobs[i])]) for i in r]
398
# Take the SHA from each of the parents.
399
self.assertChangesForMergeEqual([], parents, parents[i])
401
def test_tree_changes_for_merge_octopus_modify_conflict(self):
402
# Because the octopus merge strategy is limited, I doubt it's possible
403
# to create this with the git command line. But the output is well-
404
# defined, so test it anyway.
406
parent_blobs = [make_object(Blob, data=str(i)) for i in r]
407
merge_blob = make_object(Blob, data='merge')
408
parents = [self.commit_tree([('a', parent_blobs[i])]) for i in r]
409
merge = self.commit_tree([('a', merge_blob)])
410
expected = [[TreeChange(CHANGE_MODIFY, ('a', F, parent_blobs[i].id),
411
('a', F, merge_blob.id)) for i in r]]
412
self.assertChangesForMergeEqual(expected, parents, merge)
414
def test_tree_changes_for_merge_octopus_delete(self):
415
blob1 = make_object(Blob, data='1')
416
blob2 = make_object(Blob, data='3')
417
parent1 = self.commit_tree([('a', blob1)])
418
parent2 = self.commit_tree([('a', blob2)])
419
parent3 = merge = self.commit_tree([])
420
self.assertChangesForMergeEqual([], [parent1, parent1, parent1], merge)
421
self.assertChangesForMergeEqual([], [parent1, parent1, parent3], merge)
422
self.assertChangesForMergeEqual([], [parent1, parent3, parent3], merge)
423
self.assertChangesForMergeEqual(
424
[[TreeChange.delete(('a', F, blob1.id)),
425
TreeChange.delete(('a', F, blob2.id)),
427
[parent1, parent2, parent3], merge)
429
def test_tree_changes_for_merge_add_add_same_conflict(self):
430
blob = make_object(Blob, data='a\nb\nc\nd\n')
431
parent1 = self.commit_tree([('a', blob)])
432
parent2 = self.commit_tree([])
433
merge = self.commit_tree([('b', blob)])
434
add = TreeChange.add(('b', F, blob.id))
435
self.assertChangesForMergeEqual([[add, add]], [parent1, parent2], merge)
437
def test_tree_changes_for_merge_add_exact_rename_conflict(self):
438
blob = make_object(Blob, data='a\nb\nc\nd\n')
439
parent1 = self.commit_tree([('a', blob)])
440
parent2 = self.commit_tree([])
441
merge = self.commit_tree([('b', blob)])
442
self.assertChangesForMergeEqual(
443
[[TreeChange(CHANGE_RENAME, ('a', F, blob.id), ('b', F, blob.id)),
444
TreeChange.add(('b', F, blob.id))]],
445
[parent1, parent2], merge, rename_detector=self.detector)
447
def test_tree_changes_for_merge_add_content_rename_conflict(self):
448
blob1 = make_object(Blob, data='a\nb\nc\nd\n')
449
blob2 = make_object(Blob, data='a\nb\nc\ne\n')
450
parent1 = self.commit_tree([('a', blob1)])
451
parent2 = self.commit_tree([])
452
merge = self.commit_tree([('b', blob2)])
453
self.assertChangesForMergeEqual(
454
[[TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('b', F, blob2.id)),
455
TreeChange.add(('b', F, blob2.id))]],
456
[parent1, parent2], merge, rename_detector=self.detector)
458
def test_tree_changes_for_merge_modify_rename_conflict(self):
459
blob1 = make_object(Blob, data='a\nb\nc\nd\n')
460
blob2 = make_object(Blob, data='a\nb\nc\ne\n')
461
parent1 = self.commit_tree([('a', blob1)])
462
parent2 = self.commit_tree([('b', blob1)])
463
merge = self.commit_tree([('b', blob2)])
464
self.assertChangesForMergeEqual(
465
[[TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('b', F, blob2.id)),
466
TreeChange(CHANGE_MODIFY, ('b', F, blob1.id), ('b', F, blob2.id))]],
467
[parent1, parent2], merge, rename_detector=self.detector)
294
470
class RenameDetectionTest(DiffTestCase):