215
215
tree_z.commit('removed b')
216
216
merge_inner(tree_z.branch, tree_a, base_tree, this_tree=tree_z)
217
217
self.assertEqual([
218
conflicts.MissingParent('Created directory', 'b', 'b-id'),
219
conflicts.UnversionedParent('Versioned directory', 'b', 'b-id')],
218
conflicts.MissingParent('Created directory', 'b', b'b-id'),
219
conflicts.UnversionedParent('Versioned directory', 'b', b'b-id')],
220
220
tree_z.conflicts())
221
221
merge_inner(tree_a.branch, tree_z.basis_tree(), base_tree,
222
222
this_tree=tree_a)
223
223
self.assertEqual([
224
conflicts.DeletingParent('Not deleting', 'b', 'b-id'),
225
conflicts.UnversionedParent('Versioned directory', 'b', 'b-id')],
224
conflicts.DeletingParent('Not deleting', 'b', b'b-id'),
225
conflicts.UnversionedParent('Versioned directory', 'b', b'b-id')],
226
226
tree_a.conflicts())
228
228
def test_nested_merge(self):
458
458
def test_make_preview_transform(self):
459
459
this_tree = self.make_branch_and_tree('this')
460
self.build_tree_contents([('this/file', '1\n')])
461
this_tree.add('file', 'file-id')
462
this_tree.commit('rev1', rev_id='rev1')
460
self.build_tree_contents([('this/file', b'1\n')])
461
this_tree.add('file', b'file-id')
462
this_tree.commit('rev1', rev_id=b'rev1')
463
463
other_tree = this_tree.controldir.sprout('other').open_workingtree()
464
self.build_tree_contents([('this/file', '1\n2a\n')])
465
this_tree.commit('rev2', rev_id='rev2a')
466
self.build_tree_contents([('other/file', '2b\n1\n')])
467
other_tree.commit('rev2', rev_id='rev2b')
464
self.build_tree_contents([('this/file', b'1\n2a\n')])
465
this_tree.commit('rev2', rev_id=b'rev2a')
466
self.build_tree_contents([('other/file', b'2b\n1\n')])
467
other_tree.commit('rev2', rev_id=b'rev2b')
468
468
this_tree.lock_write()
469
469
self.addCleanup(this_tree.unlock)
470
470
merger = _mod_merge.Merger.from_revision_ids(
471
this_tree, 'rev2b', other_branch=other_tree.branch)
471
this_tree, b'rev2b', other_branch=other_tree.branch)
472
472
merger.merge_type = _mod_merge.Merge3Merger
473
473
tree_merger = merger.make_merger()
474
474
tt = tree_merger.make_preview_transform()
488
488
def test_do_merge(self):
489
489
this_tree = self.make_branch_and_tree('this')
490
self.build_tree_contents([('this/file', '1\n')])
491
this_tree.add('file', 'file-id')
492
this_tree.commit('rev1', rev_id='rev1')
490
self.build_tree_contents([('this/file', b'1\n')])
491
this_tree.add('file', b'file-id')
492
this_tree.commit('rev1', rev_id=b'rev1')
493
493
other_tree = this_tree.controldir.sprout('other').open_workingtree()
494
self.build_tree_contents([('this/file', '1\n2a\n')])
495
this_tree.commit('rev2', rev_id='rev2a')
496
self.build_tree_contents([('other/file', '2b\n1\n')])
497
other_tree.commit('rev2', rev_id='rev2b')
494
self.build_tree_contents([('this/file', b'1\n2a\n')])
495
this_tree.commit('rev2', rev_id=b'rev2a')
496
self.build_tree_contents([('other/file', b'2b\n1\n')])
497
other_tree.commit('rev2', rev_id=b'rev2b')
498
498
this_tree.lock_write()
499
499
self.addCleanup(this_tree.unlock)
500
500
merger = _mod_merge.Merger.from_revision_ids(
501
this_tree, 'rev2b', other_branch=other_tree.branch)
501
this_tree, b'rev2b', other_branch=other_tree.branch)
502
502
merger.merge_type = _mod_merge.Merge3Merger
503
503
tree_merger = merger.make_merger()
504
504
tt = tree_merger.do_merge()
2304
2304
# Have to use a real WT, because BranchBuilder doesn't support exec bit
2305
2305
wt = self.get_wt_from_builder(builder)
2306
2306
os.symlink('bar', 'path/foo')
2307
wt.add(['foo'], ['foo-id'])
2307
wt.add(['foo'], [b'foo-id'])
2308
2308
self.assertEqual('bar', wt.get_symlink_target('foo'))
2309
wt.commit('add symlink', rev_id='F-id')
2309
wt.commit('add symlink', rev_id=b'F-id')
2310
2310
# Reset to D, so that we can merge F
2311
wt.set_parent_ids(['D-id'])
2312
wt.branch.set_last_revision_info(3, 'D-id')
2311
wt.set_parent_ids([b'D-id'])
2312
wt.branch.set_last_revision_info(3, b'D-id')
2314
2314
self.assertFalse(wt.is_versioned('foo'))
2315
conflicts = wt.merge_from_branch(wt.branch, to_revision='F-id')
2315
conflicts = wt.merge_from_branch(wt.branch, to_revision=b'F-id')
2316
2316
self.assertEqual(0, conflicts)
2317
self.assertEqual('foo-id', wt.path2id('foo'))
2317
self.assertEqual(b'foo-id', wt.path2id('foo'))
2318
2318
self.assertEqual('bar', wt.get_symlink_target('foo'))
2320
2320
def test_both_sides_revert(self):
2372
2372
wt.lock_write()
2373
2373
self.addCleanup(wt.unlock)
2374
2374
os.symlink('bar', 'path/foo')
2375
wt.add(['foo'], ['foo-id'])
2376
wt.commit('add symlink', rev_id='A-id')
2375
wt.add(['foo'], [b'foo-id'])
2376
wt.commit('add symlink', rev_id=b'A-id')
2377
2377
os.remove('path/foo')
2378
2378
os.symlink('baz', 'path/foo')
2379
wt.commit('foo => baz', rev_id='B-id')
2380
wt.set_last_revision('A-id')
2379
wt.commit('foo => baz', rev_id=b'B-id')
2380
wt.set_last_revision(b'A-id')
2381
2381
wt.branch.set_last_revision_info(1, 'A-id')
2383
wt.commit('C', rev_id='C-id')
2384
wt.merge_from_branch(wt.branch, 'B-id')
2383
wt.commit('C', rev_id=b'C-id')
2384
wt.merge_from_branch(wt.branch, b'B-id')
2385
2385
self.assertEqual('baz', wt.get_symlink_target('foo'))
2386
wt.commit('E merges C & B', rev_id='E-id')
2386
wt.commit('E merges C & B', rev_id=b'E-id')
2387
2387
os.remove('path/foo')
2388
2388
os.symlink('bing', 'path/foo')
2389
wt.commit('F foo => bing', rev_id='F-id')
2389
wt.commit('F foo => bing', rev_id=b'F-id')
2390
2390
wt.set_last_revision('B-id')
2391
wt.branch.set_last_revision_info(2, 'B-id')
2391
wt.branch.set_last_revision_info(2, b'B-id')
2393
wt.merge_from_branch(wt.branch, 'C-id')
2394
wt.commit('D merges B & C', rev_id='D-id')
2395
conflicts = wt.merge_from_branch(wt.branch, to_revision='F-id')
2393
wt.merge_from_branch(wt.branch, b'C-id')
2394
wt.commit('D merges B & C', rev_id=b'D-id')
2395
conflicts = wt.merge_from_branch(wt.branch, to_revision=b'F-id')
2396
2396
self.assertEqual(0, conflicts)
2397
2397
self.assertEqual('bing', wt.get_symlink_target('foo'))
2415
2415
wt.lock_write()
2416
2416
self.addCleanup(wt.unlock)
2417
2417
os.symlink('bar', 'path/foo')
2418
wt.add(['foo'], ['foo-id'])
2419
wt.commit('A add symlink', rev_id='A-id')
2418
wt.add(['foo'], [b'foo-id'])
2419
wt.commit('A add symlink', rev_id=b'A-id')
2420
2420
wt.rename_one('foo', 'barry')
2421
wt.commit('B foo => barry', rev_id='B-id')
2421
wt.commit('B foo => barry', rev_id=b'B-id')
2422
2422
wt.set_last_revision('A-id')
2423
wt.branch.set_last_revision_info(1, 'A-id')
2423
wt.branch.set_last_revision_info(1, b'A-id')
2425
wt.commit('C', rev_id='C-id')
2426
wt.merge_from_branch(wt.branch, 'B-id')
2427
self.assertEqual('barry', wt.id2path('foo-id'))
2425
wt.commit('C', rev_id=b'C-id')
2426
wt.merge_from_branch(wt.branch, b'B-id')
2427
self.assertEqual('barry', wt.id2path(b'foo-id'))
2428
2428
self.assertEqual('bar', wt.get_symlink_target('barry'))
2429
wt.commit('E merges C & B', rev_id='E-id')
2429
wt.commit('E merges C & B', rev_id=b'E-id')
2430
2430
wt.rename_one('barry', 'blah')
2431
wt.commit('F barry => blah', rev_id='F-id')
2432
wt.set_last_revision('B-id')
2433
wt.branch.set_last_revision_info(2, 'B-id')
2431
wt.commit('F barry => blah', rev_id=b'F-id')
2432
wt.set_last_revision(b'B-id')
2433
wt.branch.set_last_revision_info(2, b'B-id')
2435
wt.merge_from_branch(wt.branch, 'C-id')
2436
wt.commit('D merges B & C', rev_id='D-id')
2437
self.assertEqual('barry', wt.id2path('foo-id'))
2435
wt.merge_from_branch(wt.branch, b'C-id')
2436
wt.commit('D merges B & C', rev_id=b'D-id')
2437
self.assertEqual('barry', wt.id2path(b'foo-id'))
2438
2438
# Check the output of the Merger object directly
2439
merger = _mod_merge.Merger.from_revision_ids(wt, 'F-id')
2439
merger = _mod_merge.Merger.from_revision_ids(wt, b'F-id')
2440
2440
merger.merge_type = _mod_merge.Merge3Merger
2441
2441
merge_obj = merger.make_merger()
2442
2442
root_id = wt.path2id('')
2443
2443
entries = list(merge_obj._entries_lca())
2444
2444
# No content change, just a path change
2445
self.assertEqual([('foo-id', False,
2445
self.assertEqual([(b'foo-id', False,
2446
2446
((u'foo', [u'blah', u'blah']), u'blah', u'barry'),
2447
2447
((root_id, [root_id, root_id]), root_id, root_id),
2448
2448
((u'foo', [u'barry', u'foo']), u'blah', u'barry'),
2449
2449
((False, [False, False]), False, False)),
2451
conflicts = wt.merge_from_branch(wt.branch, to_revision='F-id')
2451
conflicts = wt.merge_from_branch(wt.branch, to_revision=b'F-id')
2452
2452
self.assertEqual(0, conflicts)
2453
self.assertEqual('blah', wt.id2path('foo-id'))
2453
self.assertEqual('blah', wt.id2path(b'foo-id'))
2455
2455
def test_symlink_no_content_change(self):
2456
2456
self.requireFeature(features.SymlinkFeature)
2470
2470
wt.lock_write()
2471
2471
self.addCleanup(wt.unlock)
2472
2472
os.symlink('bar', 'path/foo')
2473
wt.add(['foo'], ['foo-id'])
2474
wt.commit('add symlink', rev_id='A-id')
2473
wt.add(['foo'], [b'foo-id'])
2474
wt.commit('add symlink', rev_id=b'A-id')
2475
2475
os.remove('path/foo')
2476
2476
os.symlink('baz', 'path/foo')
2477
wt.commit('foo => baz', rev_id='B-id')
2478
wt.set_last_revision('A-id')
2479
wt.branch.set_last_revision_info(1, 'A-id')
2477
wt.commit('foo => baz', rev_id=b'B-id')
2478
wt.set_last_revision(b'A-id')
2479
wt.branch.set_last_revision_info(1, b'A-id')
2481
wt.commit('C', rev_id='C-id')
2482
wt.merge_from_branch(wt.branch, 'B-id')
2481
wt.commit('C', rev_id=b'C-id')
2482
wt.merge_from_branch(wt.branch, b'B-id')
2483
2483
self.assertEqual('baz', wt.get_symlink_target('foo'))
2484
wt.commit('E merges C & B', rev_id='E-id')
2485
wt.set_last_revision('B-id')
2486
wt.branch.set_last_revision_info(2, 'B-id')
2484
wt.commit('E merges C & B', rev_id=b'E-id')
2485
wt.set_last_revision(b'B-id')
2486
wt.branch.set_last_revision_info(2, b'B-id')
2488
wt.merge_from_branch(wt.branch, 'C-id')
2489
wt.commit('D merges B & C', rev_id='D-id')
2488
wt.merge_from_branch(wt.branch, b'C-id')
2489
wt.commit('D merges B & C', rev_id=b'D-id')
2490
2490
os.remove('path/foo')
2491
2491
os.symlink('bing', 'path/foo')
2492
wt.commit('F foo => bing', rev_id='F-id')
2492
wt.commit('F foo => bing', rev_id=b'F-id')
2494
2494
# Check the output of the Merger object directly
2495
merger = _mod_merge.Merger.from_revision_ids(wt, 'E-id')
2495
merger = _mod_merge.Merger.from_revision_ids(wt, b'E-id')
2496
2496
merger.merge_type = _mod_merge.Merge3Merger
2497
2497
merge_obj = merger.make_merger()
2498
2498
# Nothing interesting happened in OTHER relative to BASE
2499
2499
self.assertEqual([], list(merge_obj._entries_lca()))
2500
2500
# Now do a real merge, just to test the rest of the stack
2501
conflicts = wt.merge_from_branch(wt.branch, to_revision='E-id')
2501
conflicts = wt.merge_from_branch(wt.branch, to_revision=b'E-id')
2502
2502
self.assertEqual(0, conflicts)
2503
2503
self.assertEqual('bing', wt.get_symlink_target('foo'))
2517
2517
wt = self.make_branch_and_tree('path')
2518
2518
wt.lock_write()
2519
2519
self.addCleanup(wt.unlock)
2520
wt.commit('base', rev_id='A-id')
2520
wt.commit('base', rev_id=b'A-id')
2521
2521
os.symlink('bar', 'path/foo')
2522
wt.add(['foo'], ['foo-id'])
2523
wt.commit('add symlink foo => bar', rev_id='B-id')
2524
wt.set_last_revision('A-id')
2525
wt.branch.set_last_revision_info(1, 'A-id')
2522
wt.add(['foo'], [b'foo-id'])
2523
wt.commit('add symlink foo => bar', rev_id=b'B-id')
2524
wt.set_last_revision(b'A-id')
2525
wt.branch.set_last_revision_info(1, b'A-id')
2527
wt.commit('C', rev_id='C-id')
2528
wt.merge_from_branch(wt.branch, 'B-id')
2527
wt.commit('C', rev_id=b'C-id')
2528
wt.merge_from_branch(wt.branch, b'B-id')
2529
2529
self.assertEqual('bar', wt.get_symlink_target('foo'))
2530
2530
os.remove('path/foo')
2531
2531
# We have to change the link in E, or it won't try to do a comparison
2532
2532
os.symlink('bing', 'path/foo')
2533
wt.commit('E merges C & B, overrides to bing', rev_id='E-id')
2533
wt.commit('E merges C & B, overrides to bing', rev_id=b'E-id')
2534
2534
wt.set_last_revision('B-id')
2535
wt.branch.set_last_revision_info(2, 'B-id')
2535
wt.branch.set_last_revision_info(2, b'B-id')
2537
wt.merge_from_branch(wt.branch, 'C-id')
2537
wt.merge_from_branch(wt.branch, b'C-id')
2538
2538
os.remove('path/foo')
2539
self.build_tree_contents([('path/foo', 'file content\n')])
2539
self.build_tree_contents([('path/foo', b'file content\n')])
2540
2540
# XXX: workaround, WT doesn't detect kind changes unless you do
2541
2541
# iter_changes()
2542
2542
list(wt.iter_changes(wt.basis_tree()))
2543
wt.commit('D merges B & C, makes it a file', rev_id='D-id')
2543
wt.commit('D merges B & C, makes it a file', rev_id=b'D-id')
2545
merger = _mod_merge.Merger.from_revision_ids(wt, 'E-id')
2545
merger = _mod_merge.Merger.from_revision_ids(wt, b'E-id')
2546
2546
merger.merge_type = _mod_merge.Merge3Merger
2547
2547
merge_obj = merger.make_merger()
2548
2548
entries = list(merge_obj._entries_lca())
2549
2549
root_id = wt.path2id('')
2550
self.assertEqual([('foo-id', True,
2550
self.assertEqual([(b'foo-id', True,
2551
2551
((None, [u'foo', None]), u'foo', u'foo'),
2552
2552
((None, [root_id, None]), root_id, root_id),
2553
2553
((None, [u'foo', None]), u'foo', u'foo'),
2573
2573
wt.lock_write()
2574
2574
self.addCleanup(wt.unlock)
2575
2575
os.symlink('bar', 'path/foo')
2576
wt.add(['foo'], ['foo-id'])
2577
wt.commit('add symlink', rev_id='A-id')
2576
wt.add(['foo'], [b'foo-id'])
2577
wt.commit('add symlink', rev_id=b'A-id')
2578
2578
os.remove('path/foo')
2579
2579
os.symlink('baz', 'path/foo')
2580
wt.commit('foo => baz', rev_id='B-id')
2581
wt.set_last_revision('A-id')
2582
wt.branch.set_last_revision_info(1, 'A-id')
2580
wt.commit('foo => baz', rev_id=b'B-id')
2581
wt.set_last_revision(b'A-id')
2582
wt.branch.set_last_revision_info(1, b'A-id')
2584
wt.commit('C', rev_id='C-id')
2585
wt.merge_from_branch(wt.branch, 'B-id')
2584
wt.commit('C', rev_id=b'C-id')
2585
wt.merge_from_branch(wt.branch, b'B-id')
2586
2586
self.assertEqual('baz', wt.get_symlink_target('foo'))
2587
wt.commit('E merges C & B', rev_id='E-id')
2587
wt.commit('E merges C & B', rev_id=b'E-id')
2588
2588
os.remove('path/foo')
2589
2589
os.symlink('bing', 'path/foo')
2590
wt.commit('F foo => bing', rev_id='F-id')
2590
wt.commit('F foo => bing', rev_id=b'F-id')
2591
2591
wt.set_last_revision('B-id')
2592
wt.branch.set_last_revision_info(2, 'B-id')
2592
wt.branch.set_last_revision_info(2, b'B-id')
2594
wt.merge_from_branch(wt.branch, 'C-id')
2595
wt.commit('D merges B & C', rev_id='D-id')
2596
wt_base = wt.controldir.sprout('base', 'A-id').open_workingtree()
2594
wt.merge_from_branch(wt.branch, b'C-id')
2595
wt.commit('D merges B & C', rev_id=b'D-id')
2596
wt_base = wt.controldir.sprout('base', b'A-id').open_workingtree()
2597
2597
wt_base.lock_read()
2598
2598
self.addCleanup(wt_base.unlock)
2599
wt_lca1 = wt.controldir.sprout('b-tree', 'B-id').open_workingtree()
2599
wt_lca1 = wt.controldir.sprout('b-tree', b'B-id').open_workingtree()
2600
2600
wt_lca1.lock_read()
2601
2601
self.addCleanup(wt_lca1.unlock)
2602
wt_lca2 = wt.controldir.sprout('c-tree', 'C-id').open_workingtree()
2602
wt_lca2 = wt.controldir.sprout('c-tree', b'C-id').open_workingtree()
2603
2603
wt_lca2.lock_read()
2604
2604
self.addCleanup(wt_lca2.unlock)
2605
wt_other = wt.controldir.sprout('other', 'F-id').open_workingtree()
2605
wt_other = wt.controldir.sprout('other', b'F-id').open_workingtree()
2606
2606
wt_other.lock_read()
2607
2607
self.addCleanup(wt_other.unlock)
2608
2608
merge_obj = _mod_merge.Merge3Merger(wt, wt, wt_base,
2609
2609
wt_other, lca_trees=[wt_lca1, wt_lca2], do_merge=False)
2610
2610
entries = list(merge_obj._entries_lca())
2611
2611
root_id = wt.path2id('')
2612
self.assertEqual([('foo-id', True,
2612
self.assertEqual([(b'foo-id', True,
2613
2613
((u'foo', [u'foo', u'foo']), u'foo', u'foo'),
2614
2614
((root_id, [root_id, root_id]), root_id, root_id),
2615
2615
((u'foo', [u'foo', u'foo']), u'foo', u'foo'),
2628
2628
# F Path at 'foo'
2629
2629
builder = self.get_builder()
2630
2630
builder.build_snapshot(None,
2631
[('add', (u'', 'a-root-id', 'directory', None)),
2632
('add', (u'foo', 'foo-id', 'file', 'a\nb\nc\n'))],
2634
builder.build_snapshot(['A-id'], [], revision_id='C-id')
2635
builder.build_snapshot(['A-id'],
2636
[('rename', ('foo', 'bar'))], revision_id='B-id')
2637
builder.build_snapshot(['C-id', 'B-id'],
2638
[('rename', ('foo', 'bar'))], revision_id='E-id') # merge the rename
2639
builder.build_snapshot(['E-id'],
2640
[('rename', ('bar', 'foo'))], revision_id='F-id') # Rename back to BASE
2641
builder.build_snapshot(['B-id', 'C-id'], [], revision_id='D-id')
2642
wt, conflicts = self.do_merge(builder, 'F-id')
2631
[('add', (u'', b'a-root-id', 'directory', None)),
2632
('add', (u'foo', b'foo-id', 'file', 'a\nb\nc\n'))],
2633
revision_id=b'A-id')
2634
builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2635
builder.build_snapshot([b'A-id'],
2636
[('rename', ('foo', 'bar'))], revision_id=b'B-id')
2637
builder.build_snapshot([b'C-id', b'B-id'],
2638
[('rename', ('foo', 'bar'))], revision_id=b'E-id') # merge the rename
2639
builder.build_snapshot([b'E-id'],
2640
[('rename', ('bar', 'foo'))], revision_id=b'F-id') # Rename back to BASE
2641
builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2642
wt, conflicts = self.do_merge(builder, b'F-id')
2643
2643
self.assertEqual(0, conflicts)
2644
self.assertEqual('foo', wt.id2path('foo-id'))
2644
self.assertEqual('foo', wt.id2path(b'foo-id'))
2646
2646
def test_other_reverted_content_to_base(self):
2647
2647
builder = self.get_builder()
2648
2648
builder.build_snapshot(None,
2649
[('add', (u'', 'a-root-id', 'directory', None)),
2650
('add', (u'foo', 'foo-id', 'file', 'base content\n'))],
2649
[('add', (u'', b'a-root-id', 'directory', None)),
2650
('add', (u'foo', b'foo-id', 'file', 'base content\n'))],
2651
2651
revision_id='A-id')
2652
builder.build_snapshot(['A-id'], [], revision_id='C-id')
2653
builder.build_snapshot(['A-id'],
2654
[('modify', ('foo-id', 'B content\n'))],
2656
builder.build_snapshot(['C-id', 'B-id'],
2657
[('modify', ('foo-id', 'B content\n'))],
2658
revision_id='E-id') # merge the content
2659
builder.build_snapshot(['E-id'],
2660
[('modify', ('foo-id', 'base content\n'))],
2661
revision_id='F-id') # Revert back to BASE
2662
builder.build_snapshot(['B-id', 'C-id'], [], revision_id='D-id')
2663
wt, conflicts = self.do_merge(builder, 'F-id')
2652
builder.build_snapshot([b'A-id'], [], revision_id='C-id')
2653
builder.build_snapshot([b'A-id'],
2654
[('modify', (b'foo-id', 'B content\n'))],
2655
revision_id=b'B-id')
2656
builder.build_snapshot([b'C-id', b'B-id'],
2657
[('modify', (b'foo-id', 'B content\n'))],
2658
revision_id=b'E-id') # merge the content
2659
builder.build_snapshot([b'E-id'],
2660
[('modify', (b'foo-id', 'base content\n'))],
2661
revision_id=b'F-id') # Revert back to BASE
2662
builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2663
wt, conflicts = self.do_merge(builder, b'F-id')
2664
2664
self.assertEqual(0, conflicts)
2665
2665
# TODO: We need to use the per-file graph to properly select a BASE
2666
2666
# before this will work. Or at least use the LCA trees to find
2670
2670
def test_other_modified_content(self):
2671
2671
builder = self.get_builder()
2672
2672
builder.build_snapshot(None,
2673
[('add', (u'', 'a-root-id', 'directory', None)),
2674
('add', (u'foo', 'foo-id', 'file', 'base content\n'))],
2676
builder.build_snapshot(['A-id'], [], revision_id='C-id')
2677
builder.build_snapshot(['A-id'],
2678
[('modify', ('foo-id', 'B content\n'))],
2680
builder.build_snapshot(['C-id', 'B-id'],
2681
[('modify', ('foo-id', 'B content\n'))],
2682
revision_id='E-id') # merge the content
2683
builder.build_snapshot(['E-id'],
2684
[('modify', ('foo-id', 'F content\n'))],
2685
revision_id='F-id') # Override B content
2686
builder.build_snapshot(['B-id', 'C-id'], [], revision_id='D-id')
2687
wt, conflicts = self.do_merge(builder, 'F-id')
2673
[('add', (u'', b'a-root-id', 'directory', None)),
2674
('add', (u'foo', b'foo-id', 'file', 'base content\n'))],
2675
revision_id=b'A-id')
2676
builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2677
builder.build_snapshot([b'A-id'],
2678
[('modify', (b'foo-id', 'B content\n'))],
2679
revision_id=b'B-id')
2680
builder.build_snapshot([b'C-id', b'B-id'],
2681
[('modify', (b'foo-id', 'B content\n'))],
2682
revision_id=b'E-id') # merge the content
2683
builder.build_snapshot([b'E-id'],
2684
[('modify', (b'foo-id', 'F content\n'))],
2685
revision_id=b'F-id') # Override B content
2686
builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2687
wt, conflicts = self.do_merge(builder, b'F-id')
2688
2688
self.assertEqual(0, conflicts)
2689
2689
self.assertEqual('F content\n', wt.get_file_text('foo'))
2754
2754
self.addCleanup(wt.unlock)
2755
2755
sub_tree = self.make_branch_and_tree('tree/sub-tree',
2756
2756
format='development-subtree')
2757
wt.set_root_id('a-root-id')
2758
sub_tree.set_root_id('sub-tree-root')
2759
self.build_tree_contents([('tree/sub-tree/file', 'text1')])
2757
wt.set_root_id(b'a-root-id')
2758
sub_tree.set_root_id(b'sub-tree-root')
2759
self.build_tree_contents([('tree/sub-tree/file', b'text1')])
2760
2760
sub_tree.add('file')
2761
sub_tree.commit('foo', rev_id='sub-A-id')
2761
sub_tree.commit('foo', rev_id=b'sub-A-id')
2762
2762
wt.add_reference(sub_tree)
2763
wt.commit('set text to 1', rev_id='A-id', recursive=None)
2763
wt.commit('set text to 1', rev_id=b'A-id', recursive=None)
2764
2764
# Now create a criss-cross merge in the parent, without modifying the
2766
wt.commit('B', rev_id='B-id', recursive=None)
2766
wt.commit('B', rev_id=b'B-id', recursive=None)
2767
2767
wt.set_last_revision('A-id')
2768
2768
wt.branch.set_last_revision_info(1, 'A-id')
2769
wt.commit('C', rev_id='C-id', recursive=None)
2769
wt.commit('C', rev_id=b'C-id', recursive=None)
2770
2770
wt.merge_from_branch(wt.branch, to_revision='B-id')
2771
wt.commit('E', rev_id='E-id', recursive=None)
2771
wt.commit('E', rev_id=b'E-id', recursive=None)
2772
2772
wt.set_parent_ids(['B-id', 'C-id'])
2773
2773
wt.branch.set_last_revision_info(2, 'B-id')
2774
wt.commit('D', rev_id='D-id', recursive=None)
2774
wt.commit('D', rev_id=b'D-id', recursive=None)
2776
2776
merger = _mod_merge.Merger.from_revision_ids(wt, 'E-id')
2777
2777
merger.merge_type = _mod_merge.Merge3Merger
2788
2788
self.addCleanup(wt.unlock)
2789
2789
sub_tree = self.make_branch_and_tree('tree/sub',
2790
2790
format='development-subtree')
2791
wt.set_root_id('a-root-id')
2792
sub_tree.set_root_id('sub-tree-root')
2793
self.build_tree_contents([('tree/sub/file', 'text1')])
2791
wt.set_root_id(b'a-root-id')
2792
sub_tree.set_root_id(b'sub-tree-root')
2793
self.build_tree_contents([('tree/sub/file', b'text1')])
2794
2794
sub_tree.add('file')
2795
sub_tree.commit('foo', rev_id='sub-A-id')
2795
sub_tree.commit('foo', rev_id=b'sub-A-id')
2796
2796
wt.add_reference(sub_tree)
2797
wt.commit('set text to 1', rev_id='A-id', recursive=None)
2797
wt.commit('set text to 1', rev_id=b'A-id', recursive=None)
2798
2798
# Now create a criss-cross merge in the parent, without modifying the
2800
wt.commit('B', rev_id='B-id', recursive=None)
2800
wt.commit('B', rev_id=b'B-id', recursive=None)
2801
2801
wt.set_last_revision('A-id')
2802
2802
wt.branch.set_last_revision_info(1, 'A-id')
2803
wt.commit('C', rev_id='C-id', recursive=None)
2803
wt.commit('C', rev_id=b'C-id', recursive=None)
2804
2804
wt.merge_from_branch(wt.branch, to_revision='B-id')
2805
self.build_tree_contents([('tree/sub/file', 'text2')])
2806
sub_tree.commit('modify contents', rev_id='sub-B-id')
2807
wt.commit('E', rev_id='E-id', recursive=None)
2805
self.build_tree_contents([('tree/sub/file', b'text2')])
2806
sub_tree.commit('modify contents', rev_id=b'sub-B-id')
2807
wt.commit('E', rev_id=b'E-id', recursive=None)
2808
2808
wt.set_parent_ids(['B-id', 'C-id'])
2809
2809
wt.branch.set_last_revision_info(2, 'B-id')
2810
wt.commit('D', rev_id='D-id', recursive=None)
2810
wt.commit('D', rev_id=b'D-id', recursive=None)
2812
2812
merger = _mod_merge.Merger.from_revision_ids(wt, 'E-id')
2813
2813
merger.merge_type = _mod_merge.Merge3Merger
2826
2826
self.addCleanup(wt.unlock)
2827
2827
sub_tree = self.make_branch_and_tree('tree/sub',
2828
2828
format='development-subtree')
2829
wt.set_root_id('a-root-id')
2830
sub_tree.set_root_id('sub-tree-root')
2831
self.build_tree_contents([('tree/sub/file', 'text1')])
2829
wt.set_root_id(b'a-root-id')
2830
sub_tree.set_root_id(b'sub-tree-root')
2831
self.build_tree_contents([('tree/sub/file', b'text1')])
2832
2832
sub_tree.add('file')
2833
sub_tree.commit('foo', rev_id='sub-A-id')
2833
sub_tree.commit('foo', rev_id=b'sub-A-id')
2834
2834
wt.add_reference(sub_tree)
2835
wt.commit('set text to 1', rev_id='A-id', recursive=None)
2835
wt.commit('set text to 1', rev_id=b'A-id', recursive=None)
2836
2836
# Now create a criss-cross merge in the parent, without modifying the
2838
wt.commit('B', rev_id='B-id', recursive=None)
2838
wt.commit('B', rev_id=b'B-id', recursive=None)
2839
2839
wt.set_last_revision('A-id')
2840
2840
wt.branch.set_last_revision_info(1, 'A-id')
2841
wt.commit('C', rev_id='C-id', recursive=None)
2841
wt.commit('C', rev_id=b'C-id', recursive=None)
2842
2842
wt.merge_from_branch(wt.branch, to_revision='B-id')
2843
2843
wt.rename_one('sub', 'alt_sub')
2844
wt.commit('E', rev_id='E-id', recursive=None)
2844
wt.commit('E', rev_id=b'E-id', recursive=None)
2845
2845
wt.set_last_revision('B-id')
2847
2847
wt.set_parent_ids(['B-id', 'C-id'])
2848
2848
wt.branch.set_last_revision_info(2, 'B-id')
2849
wt.commit('D', rev_id='D-id', recursive=None)
2849
wt.commit('D', rev_id=b'D-id', recursive=None)
2851
2851
merger = _mod_merge.Merger.from_revision_ids(wt, 'E-id')
2852
2852
merger.merge_type = _mod_merge.Merge3Merger
2869
2869
self.addCleanup(wt.unlock)
2870
2870
sub_tree = self.make_branch_and_tree('tree/sub',
2871
2871
format='development-subtree')
2872
wt.set_root_id('a-root-id')
2873
sub_tree.set_root_id('sub-tree-root')
2874
self.build_tree_contents([('tree/sub/file', 'text1')])
2872
wt.set_root_id(b'a-root-id')
2873
sub_tree.set_root_id(b'sub-tree-root')
2874
self.build_tree_contents([('tree/sub/file', b'text1')])
2875
2875
sub_tree.add('file')
2876
sub_tree.commit('foo', rev_id='sub-A-id')
2876
sub_tree.commit('foo', rev_id=b'sub-A-id')
2877
2877
wt.add_reference(sub_tree)
2878
wt.commit('set text to 1', rev_id='A-id', recursive=None)
2878
wt.commit('set text to 1', rev_id=b'A-id', recursive=None)
2879
2879
# Now create a criss-cross merge in the parent, without modifying the
2881
wt.commit('B', rev_id='B-id', recursive=None)
2881
wt.commit('B', rev_id=b'B-id', recursive=None)
2882
2882
wt.set_last_revision('A-id')
2883
2883
wt.branch.set_last_revision_info(1, 'A-id')
2884
wt.commit('C', rev_id='C-id', recursive=None)
2884
wt.commit('C', rev_id=b'C-id', recursive=None)
2885
2885
wt.merge_from_branch(wt.branch, to_revision='B-id')
2886
self.build_tree_contents([('tree/sub/file', 'text2')])
2887
sub_tree.commit('modify contents', rev_id='sub-B-id')
2886
self.build_tree_contents([('tree/sub/file', b'text2')])
2887
sub_tree.commit('modify contents', rev_id=b'sub-B-id')
2888
2888
wt.rename_one('sub', 'alt_sub')
2889
wt.commit('E', rev_id='E-id', recursive=None)
2889
wt.commit('E', rev_id=b'E-id', recursive=None)
2890
2890
wt.set_last_revision('B-id')
2892
2892
wt.set_parent_ids(['B-id', 'C-id'])
2893
2893
wt.branch.set_last_revision_info(2, 'B-id')
2894
wt.commit('D', rev_id='D-id', recursive=None)
2894
wt.commit('D', rev_id=b'D-id', recursive=None)
2896
2896
merger = _mod_merge.Merger.from_revision_ids(wt, 'E-id')
2897
2897
merger.merge_type = _mod_merge.Merge3Merger
3366
3366
def setUp(self):
3367
3367
super(TestMergeHooks, self).setUp()
3368
3368
self.tree_a = self.make_branch_and_tree('tree_a')
3369
self.build_tree_contents([('tree_a/file', 'content_1')])
3370
self.tree_a.add('file', 'file-id')
3369
self.build_tree_contents([('tree_a/file', b'content_1')])
3370
self.tree_a.add('file', b'file-id')
3371
3371
self.tree_a.commit('added file')
3373
3373
self.tree_b = self.tree_a.controldir.sprout('tree_b').open_workingtree()
3374
self.build_tree_contents([('tree_b/file', 'content_2')])
3374
self.build_tree_contents([('tree_b/file', b'content_2')])
3375
3375
self.tree_b.commit('modify file')
3377
3377
def test_pre_merge_hook_inject_different_tree(self):
3378
3378
tree_c = self.tree_b.controldir.sprout('tree_c').open_workingtree()
3379
self.build_tree_contents([('tree_c/file', 'content_3')])
3379
self.build_tree_contents([('tree_c/file', b'content_3')])
3380
3380
tree_c.commit("more content")
3382
3382
def factory(merger):