1410
1409
# B C B nothing, C deletes foo
1412
1411
# D E D restores foo (same as B), E leaves it deleted
1413
# We should emit an entry for this
1413
# A => B, no changes
1414
# A => C, delete foo (C should supersede B)
1415
# C => D, restore foo
1416
# C => E, no changes
1417
# D would then win 'cleanly' and no record would be given
1414
1418
builder = self.get_builder()
1415
1419
builder.build_snapshot('A-id', None,
1416
1420
[('add', (u'', 'a-root-id', 'directory', None)),
1423
1427
merge_obj = self.make_merge_obj(builder, 'E-id')
1425
1429
entries = list(merge_obj._entries_lca())
1430
self.assertEqual([], entries)
1432
def test_not_in_other_mod_in_lca1_not_in_lca2(self):
1433
# A base, introduces 'foo'
1435
# B C B changes 'foo', C deletes foo
1437
# D E D restores foo (same as B), E leaves it deleted (as C)
1439
# A => B, modified foo
1440
# A => C, delete foo, C does not supersede B
1441
# B => D, no changes
1442
# C => D, resolve in favor of B
1443
# B => E, resolve in favor of E
1444
# C => E, no changes
1445
# In this case, we have a conflict of how the changes were resolved. E
1446
# picked C and D picked B, so we should issue a conflict
1447
builder = self.get_builder()
1448
builder.build_snapshot('A-id', None,
1449
[('add', (u'', 'a-root-id', 'directory', None)),
1450
('add', (u'foo', 'foo-id', 'file', 'content\n'))])
1451
builder.build_snapshot('B-id', ['A-id'], [
1452
('modify', ('foo-id', 'new-content\n'))])
1453
builder.build_snapshot('C-id', ['A-id'],
1454
[('unversion', 'foo-id')])
1455
builder.build_snapshot('E-id', ['C-id', 'B-id'], [])
1456
builder.build_snapshot('D-id', ['B-id', 'C-id'], [])
1457
merge_obj = self.make_merge_obj(builder, 'E-id')
1459
entries = list(merge_obj._entries_lca())
1426
1460
root_id = 'a-root-id'
1427
1461
self.assertEqual([('foo-id', True,
1428
1462
((root_id, [root_id, None]), None, root_id),
1433
1467
def test_only_in_one_lca(self):
1470
# B C B nothing, C add file
1472
# D E D still has nothing, E removes file
1475
# C => D, removed the file
1477
# C => E, removed the file
1478
# Thus D & E have identical changes, and this is a no-op
1481
# A => C, add file, thus C supersedes B
1482
# w/ C=BASE, D=THIS, E=OTHER we have 'happy convergence'
1434
1483
builder = self.get_builder()
1435
1484
builder.build_snapshot('A-id', None,
1436
1485
[('add', (u'', 'a-root-id', 'directory', None))])
1443
1492
merge_obj = self.make_merge_obj(builder, 'E-id')
1445
1494
entries = list(merge_obj._entries_lca())
1446
root_id = 'a-root-id'
1447
self.assertEqual([('a-id', True,
1448
((None, [None, root_id]), None, None),
1449
((None, [None, u'a']), None, None),
1450
((None, [None, False]), None, None)),
1495
self.assertEqual([], entries)
1453
1497
def test_only_in_other(self):
1454
1498
builder = self.get_builder()
1739
1782
('add', (u'a', 'a-id', 'directory', None))])
1740
1783
merge_obj = self.make_merge_obj(builder, 'E-id')
1741
1784
entries = list(merge_obj._entries_lca())
1742
root_id = 'a-root-id'
1743
1785
# Only the kind was changed (content)
1744
1786
self.assertEqual([], entries)