~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_transform.py

  • Committer: John Arbash Meinel
  • Date: 2006-11-10 15:38:16 UTC
  • mto: This revision was merged to the branch mainline in revision 2129.
  • Revision ID: john@arbash-meinel.com-20061110153816-46acf76fc86a512b
use try/finally to clean up a nested progress bar during weave fetching

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
from bzrlib import (
22
22
    errors,
23
 
    generate_ids,
24
 
    symbol_versioning,
25
23
    tests,
26
24
    urlutils,
27
25
    )
38
36
from bzrlib.transform import (TreeTransform, ROOT_PARENT, FinalPaths, 
39
37
                              resolve_conflicts, cook_conflicts, 
40
38
                              find_interesting, build_tree, get_backup_name)
41
 
 
42
 
 
43
 
class TestTreeTransform(tests.TestCaseWithTransport):
 
39
from bzrlib.workingtree import gen_root_id
 
40
 
 
41
 
 
42
class TestTreeTransform(TestCaseInTempDir):
44
43
 
45
44
    def setUp(self):
46
45
        super(TestTreeTransform, self).setUp()
47
 
        self.wt = self.make_branch_and_tree('.', format='dirstate-with-subtree')
 
46
        self.wt = BzrDir.create_standalone_workingtree('.')
48
47
        os.chdir('..')
49
48
 
50
49
    def get_transform(self):
127
126
        self.assertEqual(self.wt.path2id('oz/dorothy'), 'dorothy-id')
128
127
        self.assertEqual(self.wt.path2id('oz/dorothy/toto'), 'toto-id')
129
128
 
130
 
        self.assertEqual('toto-contents',
 
129
        self.assertEqual('toto-contents', 
131
130
                         self.wt.get_file_byname('oz/dorothy/toto').read())
132
131
        self.assertIs(self.wt.is_executable('toto-id'), False)
133
132
 
134
 
    def test_tree_reference(self):
135
 
        transform, root = self.get_transform()
136
 
        tree = transform._tree
137
 
        trans_id = transform.new_directory('reference', root, 'subtree-id')
138
 
        transform.set_tree_reference('subtree-revision', trans_id)
139
 
        transform.apply()
140
 
        tree.lock_read()
141
 
        self.addCleanup(tree.unlock)
142
 
        self.assertEqual('subtree-revision',
143
 
                         tree.inventory['subtree-id'].reference_revision)
144
 
 
145
133
    def test_conflicts(self):
146
134
        transform, root = self.get_transform()
147
135
        trans_id = transform.new_file('name', root, 'contents', 
394
382
        self.assertEqual(os.readlink(self.wt.abspath('oz/wizard')),
395
383
                         'wizard-target')
396
384
 
 
385
 
397
386
    def get_conflicted(self):
398
387
        create,root = self.get_transform()
399
388
        create.new_file('dorothy', root, 'dorothy', 'dorothy-id')
527
516
        create.new_file('vfile', root, 'myfile-text', 'myfile-id')
528
517
        create.new_file('uvfile', root, 'othertext')
529
518
        create.apply()
530
 
        result = self.applyDeprecated(symbol_versioning.zero_fifteen,
531
 
            find_interesting, wt, wt, ['vfile'])
532
 
        self.assertEqual(result, set(['myfile-id']))
 
519
        self.assertEqual(find_interesting(wt, wt, ['vfile']),
 
520
                         set(['myfile-id']))
 
521
        self.assertRaises(PathsNotVersionedError, find_interesting, wt, wt,
 
522
                          ['uvfile'])
533
523
 
534
524
    def test_set_executability_order(self):
535
525
        """Ensure that executability behaves the same, no matter what order.
544
534
        wt = transform._tree
545
535
        transform.new_file('set_on_creation', root, 'Set on creation', 'soc',
546
536
                           True)
547
 
        sac = transform.new_file('set_after_creation', root,
548
 
                                 'Set after creation', 'sac')
 
537
        sac = transform.new_file('set_after_creation', root, 'Set after creation', 'sac')
549
538
        transform.set_executability(True, sac)
550
 
        uws = transform.new_file('unset_without_set', root, 'Unset badly',
551
 
                                 'uws')
 
539
        uws = transform.new_file('unset_without_set', root, 'Unset badly', 'uws')
552
540
        self.assertRaises(KeyError, transform.set_executability, None, uws)
553
541
        transform.apply()
554
542
        self.assertTrue(wt.is_executable('soc'))
599
587
        bar1_abspath = self.wt.abspath('bar')
600
588
        self.assertEqual([bar1_abspath], stat_paths)
601
589
 
602
 
    def test_iter_changes(self):
603
 
        self.wt.set_root_id('eert_toor')
604
 
        transform, root = self.get_transform()
605
 
        transform.new_file('old', root, 'blah', 'id-1', True)
606
 
        transform.apply()
607
 
        transform, root = self.get_transform()
608
 
        try:
609
 
            self.assertEqual([], list(transform._iter_changes()))
610
 
            old = transform.trans_id_tree_file_id('id-1')
611
 
            transform.unversion_file(old)
612
 
            self.assertEqual([('id-1', ('old', None), False, (True, False),
613
 
                ('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
614
 
                (True, True))], list(transform._iter_changes()))
615
 
            transform.new_directory('new', root, 'id-1')
616
 
            self.assertEqual([('id-1', ('old', 'new'), True, (True, True),
617
 
                ('eert_toor', 'eert_toor'), ('old', 'new'),
618
 
                ('file', 'directory'),
619
 
                (True, False))], list(transform._iter_changes()))
620
 
        finally:
621
 
            transform.finalize()
622
 
 
623
 
    def test_iter_changes_new(self):
624
 
        self.wt.set_root_id('eert_toor')
625
 
        transform, root = self.get_transform()
626
 
        transform.new_file('old', root, 'blah')
627
 
        transform.apply()
628
 
        transform, root = self.get_transform()
629
 
        try:
630
 
            old = transform.trans_id_tree_path('old')
631
 
            transform.version_file('id-1', old)
632
 
            self.assertEqual([('id-1', (None, 'old'), False, (False, True),
633
 
                ('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
634
 
                (False, False))], list(transform._iter_changes()))
635
 
        finally:
636
 
            transform.finalize()
637
 
 
638
 
    def test_iter_changes_modifications(self):
639
 
        self.wt.set_root_id('eert_toor')
640
 
        transform, root = self.get_transform()
641
 
        transform.new_file('old', root, 'blah', 'id-1')
642
 
        transform.new_file('new', root, 'blah')
643
 
        transform.new_directory('subdir', root, 'subdir-id')
644
 
        transform.apply()
645
 
        transform, root = self.get_transform()
646
 
        try:
647
 
            old = transform.trans_id_tree_path('old')
648
 
            subdir = transform.trans_id_tree_file_id('subdir-id')
649
 
            new = transform.trans_id_tree_path('new')
650
 
            self.assertEqual([], list(transform._iter_changes()))
651
 
 
652
 
            #content deletion
653
 
            transform.delete_contents(old)
654
 
            self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
655
 
                ('eert_toor', 'eert_toor'), ('old', 'old'), ('file', None),
656
 
                (False, False))], list(transform._iter_changes()))
657
 
 
658
 
            #content change
659
 
            transform.create_file('blah', old)
660
 
            self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
661
 
                ('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
662
 
                (False, False))], list(transform._iter_changes()))
663
 
            transform.cancel_deletion(old)
664
 
            self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
665
 
                ('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
666
 
                (False, False))], list(transform._iter_changes()))
667
 
            transform.cancel_creation(old)
668
 
 
669
 
            # move file_id to a different file
670
 
            self.assertEqual([], list(transform._iter_changes()))
671
 
            transform.unversion_file(old)
672
 
            transform.version_file('id-1', new)
673
 
            transform.adjust_path('old', root, new)
674
 
            self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
675
 
                ('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
676
 
                (False, False))], list(transform._iter_changes()))
677
 
            transform.cancel_versioning(new)
678
 
            transform._removed_id = set()
679
 
 
680
 
            #execute bit
681
 
            self.assertEqual([], list(transform._iter_changes()))
682
 
            transform.set_executability(True, old)
683
 
            self.assertEqual([('id-1', ('old', 'old'), False, (True, True),
684
 
                ('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
685
 
                (False, True))], list(transform._iter_changes()))
686
 
            transform.set_executability(None, old)
687
 
 
688
 
            # filename
689
 
            self.assertEqual([], list(transform._iter_changes()))
690
 
            transform.adjust_path('new', root, old)
691
 
            transform._new_parent = {}
692
 
            self.assertEqual([('id-1', ('old', 'new'), False, (True, True),
693
 
                ('eert_toor', 'eert_toor'), ('old', 'new'), ('file', 'file'),
694
 
                (False, False))], list(transform._iter_changes()))
695
 
            transform._new_name = {}
696
 
 
697
 
            # parent directory
698
 
            self.assertEqual([], list(transform._iter_changes()))
699
 
            transform.adjust_path('new', subdir, old)
700
 
            transform._new_name = {}
701
 
            self.assertEqual([('id-1', ('old', 'subdir/old'), False,
702
 
                (True, True), ('eert_toor', 'subdir-id'), ('old', 'old'),
703
 
                ('file', 'file'), (False, False))],
704
 
                list(transform._iter_changes()))
705
 
            transform._new_path = {}
706
 
 
707
 
        finally:
708
 
            transform.finalize()
709
 
 
710
 
    def test_iter_changes_modified_bleed(self):
711
 
        self.wt.set_root_id('eert_toor')
712
 
        """Modified flag should not bleed from one change to another"""
713
 
        # unfortunately, we have no guarantee that file1 (which is modified)
714
 
        # will be applied before file2.  And if it's applied after file2, it
715
 
        # obviously can't bleed into file2's change output.  But for now, it
716
 
        # works.
717
 
        transform, root = self.get_transform()
718
 
        transform.new_file('file1', root, 'blah', 'id-1')
719
 
        transform.new_file('file2', root, 'blah', 'id-2')
720
 
        transform.apply()
721
 
        transform, root = self.get_transform()
722
 
        try:
723
 
            transform.delete_contents(transform.trans_id_file_id('id-1'))
724
 
            transform.set_executability(True,
725
 
            transform.trans_id_file_id('id-2'))
726
 
            self.assertEqual([('id-1', (u'file1', u'file1'), True, (True, True),
727
 
                ('eert_toor', 'eert_toor'), ('file1', u'file1'),
728
 
                ('file', None), (False, False)),
729
 
                ('id-2', (u'file2', u'file2'), False, (True, True),
730
 
                ('eert_toor', 'eert_toor'), ('file2', u'file2'),
731
 
                ('file', 'file'), (False, True))],
732
 
                list(transform._iter_changes()))
733
 
        finally:
734
 
            transform.finalize()
735
 
 
736
 
    def test_iter_changes_move_missing(self):
737
 
        """Test moving ids with no files around"""
738
 
        self.wt.set_root_id('toor_eert')
739
 
        # Need two steps because versioning a non-existant file is a conflict.
740
 
        transform, root = self.get_transform()
741
 
        transform.new_directory('floater', root, 'floater-id')
742
 
        transform.apply()
743
 
        transform, root = self.get_transform()
744
 
        transform.delete_contents(transform.trans_id_tree_path('floater'))
745
 
        transform.apply()
746
 
        transform, root = self.get_transform()
747
 
        floater = transform.trans_id_tree_path('floater')
748
 
        try:
749
 
            transform.adjust_path('flitter', root, floater)
750
 
            self.assertEqual([('floater-id', ('floater', 'flitter'), False,
751
 
            (True, True), ('toor_eert', 'toor_eert'), ('floater', 'flitter'),
752
 
            (None, None), (False, False))], list(transform._iter_changes()))
753
 
        finally:
754
 
            transform.finalize()
755
 
 
756
 
    def test_iter_changes_pointless(self):
757
 
        """Ensure that no-ops are not treated as modifications"""
758
 
        self.wt.set_root_id('eert_toor')
759
 
        transform, root = self.get_transform()
760
 
        transform.new_file('old', root, 'blah', 'id-1')
761
 
        transform.new_directory('subdir', root, 'subdir-id')
762
 
        transform.apply()
763
 
        transform, root = self.get_transform()
764
 
        try:
765
 
            old = transform.trans_id_tree_path('old')
766
 
            subdir = transform.trans_id_tree_file_id('subdir-id')
767
 
            self.assertEqual([], list(transform._iter_changes()))
768
 
            transform.delete_contents(subdir)
769
 
            transform.create_directory(subdir)
770
 
            transform.set_executability(False, old)
771
 
            transform.unversion_file(old)
772
 
            transform.version_file('id-1', old)
773
 
            transform.adjust_path('old', root, old)
774
 
            self.assertEqual([], list(transform._iter_changes()))
775
 
        finally:
776
 
            transform.finalize()
777
 
 
778
 
    def test_rename_count(self):
779
 
        transform, root = self.get_transform()
780
 
        transform.new_file('name1', root, 'contents')
781
 
        self.assertEqual(transform.rename_count, 0)
782
 
        transform.apply()
783
 
        self.assertEqual(transform.rename_count, 1)
784
 
        transform2, root = self.get_transform()
785
 
        transform2.adjust_path('name2', root,
786
 
                               transform2.trans_id_tree_path('name1'))
787
 
        self.assertEqual(transform2.rename_count, 0)
788
 
        transform2.apply()
789
 
        self.assertEqual(transform2.rename_count, 2)
790
 
 
791
 
    def test_change_parent(self):
792
 
        """Ensure that after we change a parent, the results are still right.
793
 
 
794
 
        Renames and parent changes on pending transforms can happen as part
795
 
        of conflict resolution, and are explicitly permitted by the
796
 
        TreeTransform API.
797
 
 
798
 
        This test ensures they work correctly with the rename-avoidance
799
 
        optimization.
800
 
        """
801
 
        transform, root = self.get_transform()
802
 
        parent1 = transform.new_directory('parent1', root)
803
 
        child1 = transform.new_file('child1', parent1, 'contents')
804
 
        parent2 = transform.new_directory('parent2', root)
805
 
        transform.adjust_path('child1', parent2, child1)
806
 
        transform.apply()
807
 
        self.failIfExists(self.wt.abspath('parent1/child1'))
808
 
        self.failUnlessExists(self.wt.abspath('parent2/child1'))
809
 
        # rename limbo/new-1 => parent1, rename limbo/new-3 => parent2
810
 
        # no rename for child1 (counting only renames during apply)
811
 
        self.failUnlessEqual(2, transform.rename_count)
812
 
 
813
 
    def test_cancel_parent(self):
814
 
        """Cancelling a parent doesn't cause deletion of a non-empty directory
815
 
 
816
 
        This is like the test_change_parent, except that we cancel the parent
817
 
        before adjusting the path.  The transform must detect that the
818
 
        directory is non-empty, and move children to safe locations.
819
 
        """
820
 
        transform, root = self.get_transform()
821
 
        parent1 = transform.new_directory('parent1', root)
822
 
        child1 = transform.new_file('child1', parent1, 'contents')
823
 
        child2 = transform.new_file('child2', parent1, 'contents')
824
 
        try:
825
 
            transform.cancel_creation(parent1)
826
 
        except OSError:
827
 
            self.fail('Failed to move child1 before deleting parent1')
828
 
        transform.cancel_creation(child2)
829
 
        transform.create_directory(parent1)
830
 
        try:
831
 
            transform.cancel_creation(parent1)
832
 
        # If the transform incorrectly believes that child2 is still in
833
 
        # parent1's limbo directory, it will try to rename it and fail
834
 
        # because was already moved by the first cancel_creation.
835
 
        except OSError:
836
 
            self.fail('Transform still thinks child2 is a child of parent1')
837
 
        parent2 = transform.new_directory('parent2', root)
838
 
        transform.adjust_path('child1', parent2, child1)
839
 
        transform.apply()
840
 
        self.failIfExists(self.wt.abspath('parent1'))
841
 
        self.failUnlessExists(self.wt.abspath('parent2/child1'))
842
 
        # rename limbo/new-3 => parent2, rename limbo/new-2 => child1
843
 
        self.failUnlessEqual(2, transform.rename_count)
844
 
 
845
 
    def test_adjust_and_cancel(self):
846
 
        """Make sure adjust_path keeps track of limbo children properly"""
847
 
        transform, root = self.get_transform()
848
 
        parent1 = transform.new_directory('parent1', root)
849
 
        child1 = transform.new_file('child1', parent1, 'contents')
850
 
        parent2 = transform.new_directory('parent2', root)
851
 
        transform.adjust_path('child1', parent2, child1)
852
 
        transform.cancel_creation(child1)
853
 
        try:
854
 
            transform.cancel_creation(parent1)
855
 
        # if the transform thinks child1 is still in parent1's limbo
856
 
        # directory, it will attempt to move it and fail.
857
 
        except OSError:
858
 
            self.fail('Transform still thinks child1 is a child of parent1')
859
 
        transform.finalize()
860
 
 
861
 
    def test_noname_contents(self):
862
 
        """TreeTransform should permit deferring naming files."""
863
 
        transform, root = self.get_transform()
864
 
        parent = transform.trans_id_file_id('parent-id')
865
 
        try:
866
 
            transform.create_directory(parent)
867
 
        except KeyError:
868
 
            self.fail("Can't handle contents with no name")
869
 
        transform.finalize()
870
 
 
871
 
    def test_noname_contents_nested(self):
872
 
        """TreeTransform should permit deferring naming files."""
873
 
        transform, root = self.get_transform()
874
 
        parent = transform.trans_id_file_id('parent-id')
875
 
        try:
876
 
            transform.create_directory(parent)
877
 
        except KeyError:
878
 
            self.fail("Can't handle contents with no name")
879
 
        child = transform.new_directory('child', parent)
880
 
        transform.adjust_path('parent', root, parent)
881
 
        transform.apply()
882
 
        self.failUnlessExists(self.wt.abspath('parent/child'))
883
 
        self.assertEqual(1, transform.rename_count)
884
 
 
885
 
    def test_reuse_name(self):
886
 
        """Avoid reusing the same limbo name for different files"""
887
 
        transform, root = self.get_transform()
888
 
        parent = transform.new_directory('parent', root)
889
 
        child1 = transform.new_directory('child', parent)
890
 
        try:
891
 
            child2 = transform.new_directory('child', parent)
892
 
        except OSError:
893
 
            self.fail('Tranform tried to use the same limbo name twice')
894
 
        transform.adjust_path('child2', parent, child2)
895
 
        transform.apply()
896
 
        # limbo/new-1 => parent, limbo/new-3 => parent/child2
897
 
        # child2 is put into top-level limbo because child1 has already
898
 
        # claimed the direct limbo path when child2 is created.  There is no
899
 
        # advantage in renaming files once they're in top-level limbo, except
900
 
        # as part of apply.
901
 
        self.assertEqual(2, transform.rename_count)
902
 
 
903
 
    def test_reuse_when_first_moved(self):
904
 
        """Don't avoid direct paths when it is safe to use them"""
905
 
        transform, root = self.get_transform()
906
 
        parent = transform.new_directory('parent', root)
907
 
        child1 = transform.new_directory('child', parent)
908
 
        transform.adjust_path('child1', parent, child1)
909
 
        child2 = transform.new_directory('child', parent)
910
 
        transform.apply()
911
 
        # limbo/new-1 => parent
912
 
        self.assertEqual(1, transform.rename_count)
913
 
 
914
 
    def test_reuse_after_cancel(self):
915
 
        """Don't avoid direct paths when it is safe to use them"""
916
 
        transform, root = self.get_transform()
917
 
        parent2 = transform.new_directory('parent2', root)
918
 
        child1 = transform.new_directory('child1', parent2)
919
 
        transform.cancel_creation(parent2)
920
 
        transform.create_directory(parent2)
921
 
        child2 = transform.new_directory('child1', parent2)
922
 
        transform.adjust_path('child2', parent2, child1)
923
 
        transform.apply()
924
 
        # limbo/new-1 => parent2, limbo/new-2 => parent2/child1
925
 
        self.assertEqual(2, transform.rename_count)
926
 
 
927
 
    def test_finalize_order(self):
928
 
        """Finalize must be done in child-to-parent order"""
929
 
        transform, root = self.get_transform()
930
 
        parent = transform.new_directory('parent', root)
931
 
        child = transform.new_directory('child', parent)
932
 
        try:
933
 
            transform.finalize()
934
 
        except OSError:
935
 
            self.fail('Tried to remove parent before child1')
936
 
 
937
 
    def test_cancel_with_cancelled_child_should_succeed(self):
938
 
        transform, root = self.get_transform()
939
 
        parent = transform.new_directory('parent', root)
940
 
        child = transform.new_directory('child', parent)
941
 
        transform.cancel_creation(child)
942
 
        transform.cancel_creation(parent)
943
 
        transform.finalize()
944
 
 
945
590
 
946
591
class TransformGroup(object):
947
592
    def __init__(self, dirname, root_id):
953
598
        self.tt = TreeTransform(self.wt)
954
599
        self.root = self.tt.trans_id_tree_file_id(self.wt.get_root_id())
955
600
 
956
 
 
957
601
def conflict_text(tree, merge):
958
602
    template = '%s TREE\n%s%s\n%s%s MERGE-SOURCE\n'
959
603
    return template % ('<' * 7, tree, '=' * 7, merge, '>' * 7)
961
605
 
962
606
class TestTransformMerge(TestCaseInTempDir):
963
607
    def test_text_merge(self):
964
 
        root_id = generate_ids.gen_root_id()
 
608
        root_id = gen_root_id()
965
609
        base = TransformGroup("base", root_id)
966
610
        base.tt.new_file('a', base.root, 'a\nb\nc\nd\be\n', 'a')
967
611
        base.tt.new_file('b', base.root, 'b1', 'b')
1040
684
    def test_file_merge(self):
1041
685
        if not has_symlinks():
1042
686
            raise TestSkipped('Symlinks are not supported on this platform')
1043
 
        root_id = generate_ids.gen_root_id()
 
687
        root_id = gen_root_id()
1044
688
        base = TransformGroup("BASE", root_id)
1045
689
        this = TransformGroup("THIS", root_id)
1046
690
        other = TransformGroup("OTHER", root_id)
1081
725
        self.assertIs(os.path.lexists(this.wt.abspath('h.OTHER')), True)
1082
726
 
1083
727
    def test_filename_merge(self):
1084
 
        root_id = generate_ids.gen_root_id()
 
728
        root_id = gen_root_id()
1085
729
        base = TransformGroup("BASE", root_id)
1086
730
        this = TransformGroup("THIS", root_id)
1087
731
        other = TransformGroup("OTHER", root_id)
1114
758
        self.assertEqual(this.wt.id2path('f'), pathjoin('b/f1'))
1115
759
 
1116
760
    def test_filename_merge_conflicts(self):
1117
 
        root_id = generate_ids.gen_root_id()
 
761
        root_id = gen_root_id()
1118
762
        base = TransformGroup("BASE", root_id)
1119
763
        this = TransformGroup("THIS", root_id)
1120
764
        other = TransformGroup("OTHER", root_id)
1158
802
        a.add(['foo', 'foo/bar', 'foo/baz'])
1159
803
        a.commit('initial commit')
1160
804
        b = BzrDir.create_standalone_workingtree('b')
1161
 
        basis = a.basis_tree()
1162
 
        basis.lock_read()
1163
 
        self.addCleanup(basis.unlock)
1164
 
        build_tree(basis, b)
 
805
        build_tree(a.basis_tree(), b)
1165
806
        self.assertIs(os.path.isdir('b/foo'), True)
1166
807
        self.assertEqual(file('b/foo/bar', 'rb').read(), "contents")
1167
808
        self.assertEqual(os.readlink('b/foo/baz'), 'a/foo/bar')
1168
809
 
1169
 
    def test_build_with_references(self):
1170
 
        tree = self.make_branch_and_tree('source',
1171
 
            format='dirstate-with-subtree')
1172
 
        subtree = self.make_branch_and_tree('source/subtree',
1173
 
            format='dirstate-with-subtree')
1174
 
        tree.add_reference(subtree)
1175
 
        tree.commit('a revision')
1176
 
        tree.branch.create_checkout('target')
1177
 
        self.failUnlessExists('target')
1178
 
        self.failUnlessExists('target/subtree')
1179
 
 
1180
810
    def test_file_conflict_handling(self):
1181
811
        """Ensure that when building trees, conflict handling is done"""
1182
812
        source = self.make_branch_and_tree('source')
1284
914
        self.assertRaises(errors.WorkingTreeAlreadyPopulated, 
1285
915
            build_tree, source.basis_tree(), target)
1286
916
 
1287
 
    def test_build_tree_rename_count(self):
1288
 
        source = self.make_branch_and_tree('source')
1289
 
        self.build_tree(['source/file1', 'source/dir1/'])
1290
 
        source.add(['file1', 'dir1'])
1291
 
        source.commit('add1')
1292
 
        target1 = self.make_branch_and_tree('target1')
1293
 
        transform_result = build_tree(source.basis_tree(), target1)
1294
 
        self.assertEqual(2, transform_result.rename_count)
1295
 
 
1296
 
        self.build_tree(['source/dir1/file2'])
1297
 
        source.add(['dir1/file2'])
1298
 
        source.commit('add3')
1299
 
        target2 = self.make_branch_and_tree('target2')
1300
 
        transform_result = build_tree(source.basis_tree(), target2)
1301
 
        # children of non-root directories should not be renamed
1302
 
        self.assertEqual(2, transform_result.rename_count)
1303
 
 
1304
917
 
1305
918
class MockTransform(object):
1306
919
 
1313
926
                return True
1314
927
        return False
1315
928
 
1316
 
 
1317
929
class MockEntry(object):
1318
930
    def __init__(self):
1319
931
        object.__init__(self)