34
39
from bzrlib.osutils import getcwd, pathjoin
35
from bzrlib import progress
36
40
from bzrlib.transform import TreeTransform
37
41
from bzrlib.tests import TestCaseWithTransport, TestSkipped
38
42
from bzrlib.workingtree import WorkingTree
41
45
class MergeBuilder(object):
42
47
def __init__(self, dir=None):
43
48
self.dir = osutils.mkdtemp(prefix="merge-test", dir=dir)
44
49
self.tree_root = generate_ids.gen_root_id()
46
51
path = pathjoin(self.dir, name)
48
wt = bzrlib.bzrdir.BzrDir.create_standalone_workingtree(path)
53
wt = controldir.ControlDir.create_standalone_workingtree(path)
49
54
# the tests perform pulls, so need a branch that is writeable.
51
56
wt.set_root_id(self.tree_root)
490
495
wtb = d_b.open_workingtree()
491
496
wtb.commit('this revision', allow_pointless=False)
492
497
self.assertEqual(1, wtb.merge_from_branch(wta.branch))
493
self.failUnlessExists('b/file.THIS')
494
self.failUnlessExists('b/file.BASE')
495
self.failUnlessExists('b/file.OTHER')
498
self.assertPathExists('b/file.THIS')
499
self.assertPathExists('b/file.BASE')
500
self.assertPathExists('b/file.OTHER')
497
502
self.assertEqual(1, wtb.merge_from_branch(wta.branch,
498
503
merge_type=WeaveMerger))
499
self.failUnlessExists('b/file')
500
self.failUnlessExists('b/file.THIS')
501
self.failUnlessExists('b/file.BASE')
502
self.failUnlessExists('b/file.OTHER')
504
self.assertPathExists('b/file')
505
self.assertPathExists('b/file.THIS')
506
self.assertPathExists('b/file.BASE')
507
self.assertPathExists('b/file.OTHER')
504
509
def test_weave_conflicts_not_in_base(self):
505
510
builder = self.make_branch_builder('source')
529
534
self.assertEqual(1, tree.merge_from_branch(tree.branch,
530
535
to_revision='D-id',
531
536
merge_type=WeaveMerger))
532
self.failUnlessExists('tree/foo.THIS')
533
self.failUnlessExists('tree/foo.OTHER')
537
self.assertPathExists('tree/foo.THIS')
538
self.assertPathExists('tree/foo.OTHER')
534
539
self.expectFailure('fail to create .BASE in some criss-cross merges',
535
self.failUnlessExists, 'tree/foo.BASE')
536
self.failUnlessExists('tree/foo.BASE')
540
self.assertPathExists, 'tree/foo.BASE')
541
self.assertPathExists('tree/foo.BASE')
538
543
def test_merge_unrelated(self):
539
544
"""Sucessfully merges unrelated branches with no common names"""
540
545
wta = self.make_branch_and_tree('a')
542
file('a/a_file', 'wb').write('contents\n')
547
with file('a/a_file', 'wb') as f: f.write('contents\n')
543
548
wta.add('a_file')
544
549
wta.commit('a_revision', allow_pointless=False)
545
550
wtb = self.make_branch_and_tree('b')
547
file('b/b_file', 'wb').write('contents\n')
552
with file('b/b_file', 'wb') as f: f.write('contents\n')
548
553
wtb.add('b_file')
549
554
b_rev = wtb.commit('b_revision', allow_pointless=False)
550
555
wta.merge_from_branch(wtb.branch, b_rev, 'null:')
551
self.assert_(os.path.lexists('a/b_file'))
556
self.assertTrue(os.path.lexists('a/b_file'))
552
557
self.assertEqual([b_rev], wta.get_parent_ids()[1:])
554
559
def test_merge_unrelated_conflicting(self):
555
560
"""Sucessfully merges unrelated branches with common names"""
556
561
wta = self.make_branch_and_tree('a')
558
file('a/file', 'wb').write('contents\n')
563
with file('a/file', 'wb') as f: f.write('contents\n')
560
565
wta.commit('a_revision', allow_pointless=False)
561
566
wtb = self.make_branch_and_tree('b')
563
file('b/file', 'wb').write('contents\n')
568
with file('b/file', 'wb') as f: f.write('contents\n')
565
570
b_rev = wtb.commit('b_revision', allow_pointless=False)
566
571
wta.merge_from_branch(wtb.branch, b_rev, 'null:')
567
self.assert_(os.path.lexists('a/file'))
568
self.assert_(os.path.lexists('a/file.moved'))
572
self.assertTrue(os.path.lexists('a/file'))
573
self.assertTrue(os.path.lexists('a/file.moved'))
569
574
self.assertEqual([b_rev], wta.get_parent_ids()[1:])
571
576
def test_merge_deleted_conflicts(self):
572
577
wta = self.make_branch_and_tree('a')
573
file('a/file', 'wb').write('contents\n')
578
with file('a/file', 'wb') as f: f.write('contents\n')
575
580
wta.commit('a_revision', allow_pointless=False)
576
581
self.run_bzr('branch a b')
577
582
os.remove('a/file')
578
583
wta.commit('removed file', allow_pointless=False)
579
file('b/file', 'wb').write('changed contents\n')
584
with file('b/file', 'wb') as f: f.write('changed contents\n')
580
585
wtb = WorkingTree.open('b')
581
586
wtb.commit('changed file', allow_pointless=False)
582
587
wtb.merge_from_branch(wta.branch, wta.branch.last_revision(),
583
588
wta.branch.get_rev_id(1))
584
self.failIf(os.path.lexists('b/file'))
589
self.assertFalse(os.path.lexists('b/file'))
586
591
def test_merge_metadata_vs_deletion(self):
587
592
"""Conflict deletion vs metadata change"""
588
593
a_wt = self.make_branch_and_tree('a')
589
file('a/file', 'wb').write('contents\n')
594
with file('a/file', 'wb') as f: f.write('contents\n')
591
596
a_wt.commit('r0')
592
597
self.run_bzr('branch a b')
598
603
self.assertFalse(os.path.exists('a/file'))
599
604
b_wt.commit('exec a')
600
605
a_wt.merge_from_branch(b_wt.branch, b_wt.last_revision(), 'null:')
601
self.assert_(os.path.exists('a/file'))
606
self.assertTrue(os.path.exists('a/file'))
603
608
def test_merge_swapping_renames(self):
604
609
a_wt = self.make_branch_and_tree('a')
605
file('a/un','wb').write('UN')
606
file('a/deux','wb').write('DEUX')
610
with file('a/un','wb') as f: f.write('UN')
611
with file('a/deux','wb') as f: f.write('DEUX')
607
612
a_wt.add('un', 'un-id')
608
613
a_wt.add('deux', 'deux-id')
609
614
a_wt.commit('r0', rev_id='r0')
615
620
b_wt.commit('r1', rev_id='r1')
616
621
self.assertEqual(0, a_wt.merge_from_branch(b_wt.branch,
617
622
b_wt.branch.last_revision(), b_wt.branch.get_rev_id(1)))
618
self.failUnlessExists('a/un')
619
self.failUnless('a/deux')
623
self.assertPathExists('a/un')
624
self.assertTrue('a/deux')
620
625
self.assertFalse(os.path.exists('a/tmp'))
621
626
self.assertEqual(file('a/un').read(),'DEUX')
622
627
self.assertEqual(file('a/deux').read(),'UN')
624
629
def test_merge_delete_and_add_same(self):
625
630
a_wt = self.make_branch_and_tree('a')
626
file('a/file', 'wb').write('THIS')
631
with file('a/file', 'wb') as f: f.write('THIS')
628
633
a_wt.commit('r0')
629
634
self.run_bzr('branch a b')
630
635
b_wt = WorkingTree.open('b')
631
636
os.remove('b/file')
632
637
b_wt.commit('r1')
633
file('b/file', 'wb').write('THAT')
638
with file('b/file', 'wb') as f: f.write('THAT')
635
640
b_wt.commit('r2')
636
641
a_wt.merge_from_branch(b_wt.branch, b_wt.branch.last_revision(),
637
642
b_wt.branch.get_rev_id(1))
638
self.assert_(os.path.exists('a/file'))
643
self.assertTrue(os.path.exists('a/file'))
639
644
self.assertEqual(file('a/file').read(),'THAT')
641
646
def test_merge_rename_before_create(self):
655
660
a_wt = self.make_branch_and_tree('a')
656
file('a/foo', 'wb').write('A/FOO')
661
with file('a/foo', 'wb') as f: f.write('A/FOO')
658
663
a_wt.commit('added foo')
659
664
self.run_bzr('branch a b')
660
665
b_wt = WorkingTree.open('b')
661
666
b_wt.rename_one('foo', 'bar')
662
file('b/foo', 'wb').write('B/FOO')
667
with file('b/foo', 'wb') as f: f.write('B/FOO')
664
669
b_wt.commit('moved foo to bar, added new foo')
665
670
a_wt.merge_from_branch(b_wt.branch, b_wt.branch.last_revision(),