~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-10-06 07:13:51 UTC
  • mto: This revision was merged to the branch mainline in revision 2071.
  • Revision ID: john@arbash-meinel.com-20061006071351-e3fdd47eed1c3e7e
lazy import revisionspec and errors for bzrlib.options

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
import sys
20
20
 
21
21
from bzrlib import (
22
 
    errors,
23
 
    generate_ids,
24
 
    symbol_versioning,
25
22
    tests,
26
23
    urlutils,
27
24
    )
40
37
                              find_interesting, build_tree, get_backup_name)
41
38
 
42
39
 
43
 
class TestTreeTransform(tests.TestCaseWithTransport):
 
40
class TestTreeTransform(TestCaseInTempDir):
44
41
 
45
42
    def setUp(self):
46
43
        super(TestTreeTransform, self).setUp()
47
 
        self.wt = self.make_branch_and_tree('.', format='dirstate-with-subtree')
 
44
        self.wt = BzrDir.create_standalone_workingtree('.')
48
45
        os.chdir('..')
49
46
 
50
47
    def get_transform(self):
51
48
        transform = TreeTransform(self.wt)
52
49
        #self.addCleanup(transform.finalize)
53
 
        return transform, transform.root
 
50
        return transform, transform.trans_id_tree_file_id(self.wt.get_root_id())
54
51
 
55
52
    def test_existing_limbo(self):
56
53
        limbo_name = urlutils.local_path_from_url(
127
124
        self.assertEqual(self.wt.path2id('oz/dorothy'), 'dorothy-id')
128
125
        self.assertEqual(self.wt.path2id('oz/dorothy/toto'), 'toto-id')
129
126
 
130
 
        self.assertEqual('toto-contents',
 
127
        self.assertEqual('toto-contents', 
131
128
                         self.wt.get_file_byname('oz/dorothy/toto').read())
132
129
        self.assertIs(self.wt.is_executable('toto-id'), False)
133
130
 
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
131
    def test_conflicts(self):
146
132
        transform, root = self.get_transform()
147
133
        trans_id = transform.new_file('name', root, 'contents', 
211
197
        transform3.delete_contents(oz_id)
212
198
        self.assertEqual(transform3.find_conflicts(), 
213
199
                         [('missing parent', oz_id)])
214
 
        root_id = transform3.root
 
200
        root_id = transform3.trans_id_tree_file_id('TREE_ROOT')
215
201
        tip_id = transform3.trans_id_tree_file_id('tip-id')
216
202
        transform3.adjust_path('tip', root_id, tip_id)
217
203
        transform3.apply()
243
229
    def test_name_invariants(self):
244
230
        create_tree, root = self.get_transform()
245
231
        # prepare tree
246
 
        root = create_tree.root
 
232
        root = create_tree.trans_id_tree_file_id('TREE_ROOT')
247
233
        create_tree.new_file('name1', root, 'hello1', 'name1')
248
234
        create_tree.new_file('name2', root, 'hello2', 'name2')
249
235
        ddir = create_tree.new_directory('dying_directory', root, 'ddir')
253
239
        create_tree.apply()
254
240
 
255
241
        mangle_tree,root = self.get_transform()
256
 
        root = mangle_tree.root
 
242
        root = mangle_tree.trans_id_tree_file_id('TREE_ROOT')
257
243
        #swap names
258
244
        name1 = mangle_tree.trans_id_tree_file_id('name1')
259
245
        name2 = mangle_tree.trans_id_tree_file_id('name2')
338
324
    def test_move_dangling_ie(self):
339
325
        create_tree, root = self.get_transform()
340
326
        # prepare tree
341
 
        root = create_tree.root
 
327
        root = create_tree.trans_id_tree_file_id('TREE_ROOT')
342
328
        create_tree.new_file('name1', root, 'hello1', 'name1')
343
329
        create_tree.apply()
344
330
        delete_contents, root = self.get_transform()
354
340
    def test_replace_dangling_ie(self):
355
341
        create_tree, root = self.get_transform()
356
342
        # prepare tree
357
 
        root = create_tree.root
 
343
        root = create_tree.trans_id_tree_file_id('TREE_ROOT')
358
344
        create_tree.new_file('name1', root, 'hello1', 'name1')
359
345
        create_tree.apply()
360
346
        delete_contents = TreeTransform(self.wt)
394
380
        self.assertEqual(os.readlink(self.wt.abspath('oz/wizard')),
395
381
                         'wizard-target')
396
382
 
 
383
 
397
384
    def get_conflicted(self):
398
385
        create,root = self.get_transform()
399
386
        create.new_file('dorothy', root, 'dorothy', 'dorothy-id')
527
514
        create.new_file('vfile', root, 'myfile-text', 'myfile-id')
528
515
        create.new_file('uvfile', root, 'othertext')
529
516
        create.apply()
530
 
        result = self.applyDeprecated(symbol_versioning.zero_fifteen,
531
 
            find_interesting, wt, wt, ['vfile'])
532
 
        self.assertEqual(result, set(['myfile-id']))
 
517
        self.assertEqual(find_interesting(wt, wt, ['vfile']),
 
518
                         set(['myfile-id']))
 
519
        self.assertRaises(PathsNotVersionedError, find_interesting, wt, wt,
 
520
                          ['uvfile'])
533
521
 
534
522
    def test_set_executability_order(self):
535
523
        """Ensure that executability behaves the same, no matter what order.
544
532
        wt = transform._tree
545
533
        transform.new_file('set_on_creation', root, 'Set on creation', 'soc',
546
534
                           True)
547
 
        sac = transform.new_file('set_after_creation', root,
548
 
                                 'Set after creation', 'sac')
 
535
        sac = transform.new_file('set_after_creation', root, 'Set after creation', 'sac')
549
536
        transform.set_executability(True, sac)
550
 
        uws = transform.new_file('unset_without_set', root, 'Unset badly',
551
 
                                 'uws')
 
537
        uws = transform.new_file('unset_without_set', root, 'Unset badly', 'uws')
552
538
        self.assertRaises(KeyError, transform.set_executability, None, uws)
553
539
        transform.apply()
554
540
        self.assertTrue(wt.is_executable('soc'))
599
585
        bar1_abspath = self.wt.abspath('bar')
600
586
        self.assertEqual([bar1_abspath], stat_paths)
601
587
 
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
588
 
946
589
class TransformGroup(object):
947
 
    def __init__(self, dirname, root_id):
 
590
    def __init__(self, dirname):
948
591
        self.name = dirname
949
592
        os.mkdir(dirname)
950
593
        self.wt = BzrDir.create_standalone_workingtree(dirname)
951
 
        self.wt.set_root_id(root_id)
952
594
        self.b = self.wt.branch
953
595
        self.tt = TreeTransform(self.wt)
954
596
        self.root = self.tt.trans_id_tree_file_id(self.wt.get_root_id())
955
597
 
956
 
 
957
598
def conflict_text(tree, merge):
958
599
    template = '%s TREE\n%s%s\n%s%s MERGE-SOURCE\n'
959
600
    return template % ('<' * 7, tree, '=' * 7, merge, '>' * 7)
961
602
 
962
603
class TestTransformMerge(TestCaseInTempDir):
963
604
    def test_text_merge(self):
964
 
        root_id = generate_ids.gen_root_id()
965
 
        base = TransformGroup("base", root_id)
 
605
        base = TransformGroup("base")
966
606
        base.tt.new_file('a', base.root, 'a\nb\nc\nd\be\n', 'a')
967
607
        base.tt.new_file('b', base.root, 'b1', 'b')
968
608
        base.tt.new_file('c', base.root, 'c', 'c')
972
612
        base.tt.new_directory('g', base.root, 'g')
973
613
        base.tt.new_directory('h', base.root, 'h')
974
614
        base.tt.apply()
975
 
        other = TransformGroup("other", root_id)
 
615
        other = TransformGroup("other")
976
616
        other.tt.new_file('a', other.root, 'y\nb\nc\nd\be\n', 'a')
977
617
        other.tt.new_file('b', other.root, 'b2', 'b')
978
618
        other.tt.new_file('c', other.root, 'c2', 'c')
983
623
        other.tt.new_file('h', other.root, 'h\ni\nj\nk\n', 'h')
984
624
        other.tt.new_file('i', other.root, 'h\ni\nj\nk\n', 'i')
985
625
        other.tt.apply()
986
 
        this = TransformGroup("this", root_id)
 
626
        this = TransformGroup("this")
987
627
        this.tt.new_file('a', this.root, 'a\nb\nc\nd\bz\n', 'a')
988
628
        this.tt.new_file('b', this.root, 'b', 'b')
989
629
        this.tt.new_file('c', this.root, 'c', 'c')
1040
680
    def test_file_merge(self):
1041
681
        if not has_symlinks():
1042
682
            raise TestSkipped('Symlinks are not supported on this platform')
1043
 
        root_id = generate_ids.gen_root_id()
1044
 
        base = TransformGroup("BASE", root_id)
1045
 
        this = TransformGroup("THIS", root_id)
1046
 
        other = TransformGroup("OTHER", root_id)
 
683
        base = TransformGroup("BASE")
 
684
        this = TransformGroup("THIS")
 
685
        other = TransformGroup("OTHER")
1047
686
        for tg in this, base, other:
1048
687
            tg.tt.new_directory('a', tg.root, 'a')
1049
688
            tg.tt.new_symlink('b', tg.root, 'b', 'b')
1081
720
        self.assertIs(os.path.lexists(this.wt.abspath('h.OTHER')), True)
1082
721
 
1083
722
    def test_filename_merge(self):
1084
 
        root_id = generate_ids.gen_root_id()
1085
 
        base = TransformGroup("BASE", root_id)
1086
 
        this = TransformGroup("THIS", root_id)
1087
 
        other = TransformGroup("OTHER", root_id)
 
723
        base = TransformGroup("BASE")
 
724
        this = TransformGroup("THIS")
 
725
        other = TransformGroup("OTHER")
1088
726
        base_a, this_a, other_a = [t.tt.new_directory('a', t.root, 'a') 
1089
727
                                   for t in [base, this, other]]
1090
728
        base_b, this_b, other_b = [t.tt.new_directory('b', t.root, 'b') 
1114
752
        self.assertEqual(this.wt.id2path('f'), pathjoin('b/f1'))
1115
753
 
1116
754
    def test_filename_merge_conflicts(self):
1117
 
        root_id = generate_ids.gen_root_id()
1118
 
        base = TransformGroup("BASE", root_id)
1119
 
        this = TransformGroup("THIS", root_id)
1120
 
        other = TransformGroup("OTHER", root_id)
 
755
        base = TransformGroup("BASE")
 
756
        this = TransformGroup("THIS")
 
757
        other = TransformGroup("OTHER")
1121
758
        base_a, this_a, other_a = [t.tt.new_directory('a', t.root, 'a') 
1122
759
                                   for t in [base, this, other]]
1123
760
        base_b, this_b, other_b = [t.tt.new_directory('b', t.root, 'b') 
1158
795
        a.add(['foo', 'foo/bar', 'foo/baz'])
1159
796
        a.commit('initial commit')
1160
797
        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)
 
798
        build_tree(a.basis_tree(), b)
1165
799
        self.assertIs(os.path.isdir('b/foo'), True)
1166
800
        self.assertEqual(file('b/foo/bar', 'rb').read(), "contents")
1167
801
        self.assertEqual(os.readlink('b/foo/baz'), 'a/foo/bar')
1168
802
 
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
803
    def test_file_conflict_handling(self):
1181
804
        """Ensure that when building trees, conflict handling is done"""
1182
805
        source = self.make_branch_and_tree('source')
1281
904
        target = self.make_branch_and_tree('target')
1282
905
        self.build_tree(['target/name'])
1283
906
        target.add('name')
1284
 
        self.assertRaises(errors.WorkingTreeAlreadyPopulated, 
1285
 
            build_tree, source.basis_tree(), target)
1286
 
 
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)
 
907
        self.assertRaises(AssertionError, build_tree, source.basis_tree(),
 
908
                          target)
1303
909
 
1304
910
 
1305
911
class MockTransform(object):
1313
919
                return True
1314
920
        return False
1315
921
 
1316
 
 
1317
922
class MockEntry(object):
1318
923
    def __init__(self):
1319
924
        object.__init__(self)