6
from bzrlib.tests import TestCaseInTempDir, TestCase
6
from bzrlib.add import smart_add_tree
7
7
from bzrlib.branch import ScratchBranch, Branch
8
from bzrlib.builtins import merge
8
9
from bzrlib.errors import (NotBranchError, NotVersionedError,
9
10
WorkingTreeNotRevision, BzrCommandError)
10
11
from bzrlib.inventory import RootEntry
11
12
import bzrlib.inventory as inventory
12
13
from bzrlib.osutils import file_kind, rename, sha_file, pathjoin, mkdtemp
13
from bzrlib import changeset
14
from bzrlib.merge_core import (ApplyMerge3, make_merge_changeset,
14
from bzrlib import _changeset as changeset
15
from bzrlib._merge_core import (ApplyMerge3, make_merge_changeset,
15
16
BackupBeforeChange, ExecFlagMerge, WeaveMerge)
16
from bzrlib.changeset import Inventory, apply_changeset, invert_dict, \
17
get_contents, ReplaceContents, ChangeExecFlag
18
from bzrlib.clone import copy_branch
19
from bzrlib.merge import merge
17
from bzrlib._changeset import Inventory, apply_changeset, invert_dict, \
18
get_contents, ReplaceContents, ChangeExecFlag, Diff3Merge
19
from bzrlib.tests import TestCaseWithTransport, TestCase
20
20
from bzrlib.workingtree import WorkingTree
531
531
self.assert_(os.lstat(builder.this.full_path("3")).st_mode &0100 == 0000)
532
532
builder.cleanup();
535
class FunctionalMergeTest(TestCaseInTempDir):
534
def test_new_suffix(self):
535
for merge_type in ApplyMerge3, Diff3Merge:
536
builder = MergeBuilder()
537
builder.add_file("1", "0", "name1", "text1", 0755)
538
builder.change_contents("1", other="text3")
539
builder.add_file("2", "0", "name1.new", "text2", 0777)
540
cset = builder.merge_changeset(ApplyMerge3)
541
os.lstat(builder.this.full_path("2"))
542
builder.apply_changeset(cset)
543
os.lstat(builder.this.full_path("2"))
547
class FunctionalMergeTest(TestCaseWithTransport):
537
549
def test_trivial_star_merge(self):
538
550
"""Test that merges in a star shape Just Work."""
539
from bzrlib.add import smart_add_tree
540
from bzrlib.clone import copy_branch
541
from bzrlib.merge import merge
542
551
# John starts a branch
543
552
self.build_tree(("original/", "original/file1", "original/file2"))
544
branch = Branch.initialize("original")
545
tree = WorkingTree('original', branch)
553
tree = WorkingTree.create_standalone('original')
546
555
smart_add_tree(tree, ["original"])
547
556
tree.commit("start branch.", verbose=False)
548
557
# Mary branches it.
549
558
self.build_tree(("mary/",))
550
copy_branch(branch, "mary")
551
560
# Now John commits a change
552
561
file = open("original/file1", "wt")
553
562
file.write("John\n")
555
branch.working_tree().commit("change file1")
564
tree.commit("change file1")
557
566
mary_branch = Branch.open("mary")
558
567
file = open("mary/file2", "wt")
574
583
def test_conflicts(self):
576
a = Branch.initialize('a')
585
wta = WorkingTree.create_standalone('a')
577
587
file('a/file', 'wb').write('contents\n')
578
a.working_tree().add('file')
579
a.working_tree().commit('base revision', allow_pointless=False)
580
b = copy_branch(a, 'b')
589
wta.commit('base revision', allow_pointless=False)
581
591
file('a/file', 'wb').write('other contents\n')
582
a.working_tree().commit('other revision', allow_pointless=False)
592
wta.commit('other revision', allow_pointless=False)
583
593
file('b/file', 'wb').write('this contents contents\n')
584
594
b.working_tree().commit('this revision', allow_pointless=False)
585
595
self.assertEqual(merge(['a', -1], [None, None], this_dir='b'), 1)
603
613
def test_merge_unrelated(self):
604
614
"""Sucessfully merges unrelated branches with no common names"""
606
a = Branch.initialize('a')
615
wta = self.make_branch_and_tree('a')
607
617
file('a/a_file', 'wb').write('contents\n')
608
a.working_tree().add('a_file')
609
a.working_tree().commit('a_revision', allow_pointless=False)
611
b = Branch.initialize('b')
619
wta.commit('a_revision', allow_pointless=False)
620
wtb = self.make_branch_and_tree('b')
612
622
file('b/b_file', 'wb').write('contents\n')
613
b.working_tree().add('b_file')
614
b.working_tree().commit('b_revision', allow_pointless=False)
624
wtb.commit('b_revision', allow_pointless=False)
615
625
merge(['b', -1], ['b', 0], this_dir='a')
616
626
self.assert_(os.path.lexists('a/b_file'))
617
self.assertEqual(a.working_tree().pending_merges(),
627
self.assertEqual(wta.pending_merges(),
618
628
[b.last_revision()])
620
630
def test_merge_unrelated_conflicting(self):
621
631
"""Sucessfully merges unrelated branches with common names"""
623
a = Branch.initialize('a')
632
wta = self.make_branch_and_tree('a')
624
634
file('a/file', 'wb').write('contents\n')
625
a.working_tree().add('file')
626
a.working_tree().commit('a_revision', allow_pointless=False)
628
b = Branch.initialize('b')
636
wta.commit('a_revision', allow_pointless=False)
637
wtb = self.make_branch_and_tree('b')
629
639
file('b/file', 'wb').write('contents\n')
630
b.working_tree().add('file')
631
b.working_tree().commit('b_revision', allow_pointless=False)
641
wtb.commit('b_revision', allow_pointless=False)
632
642
merge(['b', -1], ['b', 0], this_dir='a')
633
643
self.assert_(os.path.lexists('a/file'))
634
644
self.assert_(os.path.lexists('a/file.moved'))
635
self.assertEqual(a.working_tree().pending_merges(), [b.last_revision()])
645
self.assertEqual(wta.pending_merges(), [b.last_revision()])
637
647
def test_merge_deleted_conflicts(self):
639
a = Branch.initialize('a')
648
wta = self.make_branch_and_tree('a')
640
649
file('a/file', 'wb').write('contents\n')
641
a.working_tree().add('file')
642
a.working_tree().commit('a_revision', allow_pointless=False)
651
wta.commit('a_revision', allow_pointless=False)
644
652
self.run_bzr('branch', 'a', 'b')
646
653
os.remove('a/file')
647
a.working_tree().commit('removed file', allow_pointless=False)
654
wta.commit('removed file', allow_pointless=False)
648
655
file('b/file', 'wb').write('changed contents\n')
650
b.working_tree().commit('changed file', allow_pointless=False)
656
wtb = WorkingTree('b')
657
wtb.commit('changed file', allow_pointless=False)
651
658
merge(['a', -1], ['a', 1], this_dir='b')
652
659
self.failIf(os.path.lexists('b/file'))
654
661
def test_merge_metadata_vs_deletion(self):
655
662
"""Conflict deletion vs metadata change"""
657
a = Branch.initialize('a')
663
a_wt = self.make_branch_and_tree('a')
658
664
file('a/file', 'wb').write('contents\n')
659
a_wt = a.working_tree()
661
666
a_wt.commit('r0')
664
b_wt = b.working_tree()
667
self.run_bzr('branch', 'a', 'b')
668
b_wt = WorkingTree('b')
665
669
os.chmod('b/file', 0755)
666
670
os.remove('a/file')
667
671
a_wt.commit('removed a')
668
self.assertEqual(a.revno(), 2)
672
self.assertEqual(a_wt.branch.revno(), 2)
669
673
self.assertFalse(os.path.exists('a/file'))
670
674
b_wt.commit('exec a')
671
675
merge(['b', -1], ['b', 0], this_dir='a')
672
676
self.assert_(os.path.exists('a/file'))
674
678
def test_merge_swapping_renames(self):
676
a = Branch.initialize('a')
679
a_wt = self.make_branch_and_tree('a')
677
680
file('a/un','wb').write('UN')
678
681
file('a/deux','wb').write('DEUX')
679
a_wt = a.working_tree()
682
684
a_wt.commit('r0')
685
b_wt = b.working_tree()
685
self.run_bzr('branch', 'a', 'b')
686
b_wt = WorkingTree('b')
686
687
b_wt.rename_one('un','tmp')
687
688
b_wt.rename_one('deux','un')
688
689
b_wt.rename_one('tmp','deux')