/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_transform.py

  • Committer: Jelmer Vernooij
  • Date: 2019-05-29 03:22:34 UTC
  • mfrom: (7303 work)
  • mto: This revision was merged to the branch mainline in revision 7306.
  • Revision ID: jelmer@jelmer.uk-20190529032234-mt3fuws8gq03tapi
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
    bencode,
25
25
    errors,
26
26
    filters,
27
 
    generate_ids,
28
27
    osutils,
29
28
    revision as _mod_revision,
30
29
    rules,
33
32
    transform,
34
33
    urlutils,
35
34
    )
 
35
from ..bzr import (
 
36
    generate_ids,
 
37
    )
36
38
from ..conflicts import (
37
39
    DeletingParent,
38
40
    DuplicateEntry,
185
187
                                  sha1=sha1)
186
188
        calls = []
187
189
        orig = self.wt._observed_sha1
 
190
 
188
191
        def _observed_sha1(*args):
189
192
            calls.append(args)
190
193
            orig(*args)
191
194
        self.wt._observed_sha1 = _observed_sha1
192
195
        trans.apply()
193
 
        self.assertEqual([(None, 'file1', trans._observed_sha1s[trans_id])],
 
196
        self.assertEqual([('file1', trans._observed_sha1s[trans_id])],
194
197
                         calls)
195
198
 
196
199
    def test_create_file_caches_sha1(self):
249
252
        transform._creation_mtime = creation_mtime = time.time() - 20.0
250
253
        transform.create_file([b'content-one'],
251
254
                              transform.create_path('one', root))
252
 
        time.sleep(1) # *ugly*
 
255
        time.sleep(1)  # *ugly*
253
256
        transform.create_file([b'content-two'],
254
257
                              transform.create_path('two', root))
255
258
        transform.apply()
258
261
        fo, st2 = self.wt.get_file_with_stat('two', filtered=False)
259
262
        fo.close()
260
263
        # We only guarantee 2s resolution
261
 
        self.assertTrue(abs(creation_mtime - st1.st_mtime) < 2.0,
 
264
        self.assertTrue(
 
265
            abs(creation_mtime - st1.st_mtime) < 2.0,
262
266
            "%s != %s within 2 seconds" % (creation_mtime, st1.st_mtime))
263
267
        # But if we have more than that, all files should get the same result
264
268
        self.assertEqual(st1.st_mtime, st2.st_mtime)
289
293
 
290
294
    def test_add_two_roots(self):
291
295
        transform, root = self.get_transform()
292
 
        new_trans_id = transform.new_directory('', ROOT_PARENT, b'new-root-id')
293
 
        new_trans_id = transform.new_directory('', ROOT_PARENT, b'alt-root-id')
 
296
        transform.new_directory('', ROOT_PARENT, b'new-root-id')
 
297
        transform.new_directory('', ROOT_PARENT, b'alt-root-id')
294
298
        self.assertRaises(ValueError, transform.fixup_new_roots)
295
299
 
296
300
    def test_retain_existing_root(self):
309
313
 
310
314
    def test_add_unversioned_root(self):
311
315
        transform, root = self.get_transform()
312
 
        new_trans_id = transform.new_directory('', ROOT_PARENT, None)
 
316
        transform.new_directory('', ROOT_PARENT, None)
313
317
        transform.delete_contents(transform.root)
314
318
        transform.fixup_new_roots()
315
319
        self.assertNotIn(transform.root, transform._new_id)
325
329
        self.assertEqual(old_root_id, self.wt.get_root_id())
326
330
 
327
331
        transform, root = self.get_transform()
328
 
        new_trans_id = transform.new_directory('', ROOT_PARENT, b'new-root-id')
329
 
        new_trans_id = transform.new_directory('', ROOT_PARENT, b'alt-root-id')
 
332
        transform.new_directory('', ROOT_PARENT, b'new-root-id')
 
333
        transform.new_directory('', ROOT_PARENT, b'alt-root-id')
330
334
        self.assertRaises(ValueError, transform.fixup_new_roots)
331
335
 
332
336
    def test_fixup_new_roots_permits_empty_tree(self):
374
378
        transform, root = self.get_transform()
375
379
        self.wt.lock_tree_write()
376
380
        self.addCleanup(self.wt.unlock)
377
 
        trans_id = transform.new_file('name', root, [b'contents'],
378
 
                                      b'my_pretties', True)
 
381
        transform.new_file('name', root, [b'contents'], b'my_pretties', True)
379
382
        oz = transform.new_directory('oz', root, b'oz-id')
380
383
        dorothy = transform.new_directory('dorothy', oz, b'dorothy-id')
381
 
        toto = transform.new_file('toto', dorothy, [b'toto-contents'],
382
 
                                  b'toto-id', False)
 
384
        transform.new_file('toto', dorothy, [b'toto-contents'], b'toto-id',
 
385
                           False)
383
386
 
384
387
        self.assertEqual(len(transform.find_conflicts()), 0)
385
388
        transform.apply()
404
407
        transform.apply()
405
408
        tree.lock_read()
406
409
        self.addCleanup(tree.unlock)
407
 
        self.assertEqual(b'subtree-revision',
408
 
                         tree.root_inventory.get_entry(b'subtree-id').reference_revision)
 
410
        self.assertEqual(
 
411
            b'subtree-revision',
 
412
            tree.root_inventory.get_entry(b'subtree-id').reference_revision)
409
413
 
410
414
    def test_conflicts(self):
411
415
        transform, root = self.get_transform()
640
644
 
641
645
        mangle_tree, root = self.get_transform()
642
646
        root = mangle_tree.root
643
 
        #swap names
 
647
        # swap names
644
648
        name1 = mangle_tree.trans_id_tree_path('name1')
645
649
        name2 = mangle_tree.trans_id_tree_path('name2')
646
650
        mangle_tree.adjust_path('name2', root, name1)
647
651
        mangle_tree.adjust_path('name1', root, name2)
648
652
 
649
 
        #tests for deleting parent directories
 
653
        # tests for deleting parent directories
650
654
        ddir = mangle_tree.trans_id_tree_path('dying_directory')
651
655
        mangle_tree.delete_contents(ddir)
652
656
        dfile = mangle_tree.trans_id_tree_path('dying_directory/dying_file')
655
659
        mfile = mangle_tree.trans_id_tree_path('dying_directory/moving_file')
656
660
        mangle_tree.adjust_path('mfile', root, mfile)
657
661
 
658
 
        #tests for adding parent directories
 
662
        # tests for adding parent directories
659
663
        newdir = mangle_tree.new_directory('new_directory', root, b'newdir')
660
664
        mfile2 = mangle_tree.trans_id_tree_path('moving_file2')
661
665
        mangle_tree.adjust_path('mfile2', newdir, mfile2)
684
688
    def test_both_rename(self):
685
689
        create_tree, root = self.get_transform()
686
690
        newdir = create_tree.new_directory('selftest', root, b'selftest-id')
687
 
        create_tree.new_file('blackbox.py', newdir, [b'hello1'], b'blackbox-id')
 
691
        create_tree.new_file('blackbox.py', newdir, [
 
692
                             b'hello1'], b'blackbox-id')
688
693
        create_tree.apply()
689
694
        mangle_tree, root = self.get_transform()
690
695
        selftest = mangle_tree.trans_id_tree_path('selftest')
705
710
        mangle_tree, root = self.get_transform()
706
711
        breezy = mangle_tree.trans_id_tree_path('breezy')
707
712
        tests = mangle_tree.trans_id_tree_path('breezy/tests')
708
 
        test_too_much = mangle_tree.trans_id_tree_path('breezy/tests/blackbox/test_too_much.py')
 
713
        test_too_much = mangle_tree.trans_id_tree_path(
 
714
            'breezy/tests/blackbox/test_too_much.py')
709
715
        mangle_tree.adjust_path('selftest', breezy, tests)
710
716
        mangle_tree.adjust_path('blackbox.py', tests, test_too_much)
711
717
        mangle_tree.set_executability(True, test_too_much)
719
725
        create_tree.apply()
720
726
        mangle_tree, root = self.get_transform()
721
727
        tests = mangle_tree.trans_id_tree_path('tests')
722
 
        test_too_much = mangle_tree.trans_id_tree_path('tests/test_too_much.py')
 
728
        test_too_much = mangle_tree.trans_id_tree_path(
 
729
            'tests/test_too_much.py')
723
730
        mangle_tree.adjust_path('selftest', root, tests)
724
731
        mangle_tree.adjust_path('blackbox.py', tests, test_too_much)
725
732
        mangle_tree.set_executability(True, test_too_much)
765
772
    def _test_symlinks(self, link_name1, link_target1,
766
773
                       link_name2, link_target2):
767
774
 
768
 
        def ozpath(p): return 'oz/' + p
 
775
        def ozpath(p):
 
776
            return 'oz/' + p
769
777
 
770
778
        self.requireFeature(SymlinkFeature)
771
779
        transform, root = self.get_transform()
772
780
        oz_id = transform.new_directory('oz', root, b'oz-id')
773
 
        wizard = transform.new_symlink(link_name1, oz_id, link_target1,
774
 
                                       b'wizard-id')
 
781
        transform.new_symlink(link_name1, oz_id, link_target1, b'wizard-id')
775
782
        wiz_id = transform.create_path(link_name2, oz_id)
776
783
        transform.create_symlink(link_target2, wiz_id)
777
784
        transform.version_file(b'wiz-id2', wiz_id)
872
879
                                               'munchkincity',
873
880
                                               b'munchkincity-id')
874
881
        unversioned_parent2 = UnversionedParent('Versioned directory', 'oz',
875
 
                                               b'oz-id')
 
882
                                                b'oz-id')
876
883
        self.assertEqual(cooked_conflicts[3], unversioned_parent)
877
 
        parent_loop = ParentLoop('Cancelled move', 'oz/emeraldcity',
878
 
                                 'oz/emeraldcity', b'emerald-id', b'emerald-id')
 
884
        parent_loop = ParentLoop(
 
885
            'Cancelled move', 'oz/emeraldcity',
 
886
            'oz/emeraldcity', b'emerald-id', b'emerald-id')
879
887
        self.assertEqual(cooked_conflicts[4], deleted_parent)
880
888
        self.assertEqual(cooked_conflicts[5], unversioned_parent2)
881
889
        self.assertEqual(cooked_conflicts[6], parent_loop)
900
908
        self.assertEqual(conflicts_s[3], 'Conflict because munchkincity is not'
901
909
                                         ' versioned, but has versioned'
902
910
                                         ' children.  Versioned directory.')
903
 
        self.assertEqualDiff(conflicts_s[4], "Conflict: can't delete oz because it"
904
 
                                         " is not empty.  Not deleting.")
 
911
        self.assertEqualDiff(
 
912
            conflicts_s[4], "Conflict: can't delete oz because it"
 
913
                            " is not empty.  Not deleting.")
905
914
        self.assertEqual(conflicts_s[5], 'Conflict because oz is not'
906
915
                                         ' versioned, but has versioned'
907
916
                                         ' children.  Versioned directory.')
925
934
        tt = self.prepare_wrong_parent_kind()
926
935
        raw_conflicts = resolve_conflicts(tt)
927
936
        self.assertEqual({('non-directory parent', 'Created directory',
928
 
                         'new-3')}, raw_conflicts)
 
937
                           'new-3')}, raw_conflicts)
929
938
        cooked_conflicts = cook_conflicts(raw_conflicts, tt)
930
939
        self.assertEqual([NonDirectoryParent('Created directory', 'parent.new',
931
 
        b'parent-id')], cooked_conflicts)
 
940
                                             b'parent-id')], cooked_conflicts)
932
941
        tt.apply()
933
942
        self.assertFalse(self.wt.is_versioned('parent'))
934
943
        self.assertEqual(b'parent-id', self.wt.path2id('parent.new'))
944
953
        tt.create_file([b'contents'], parent_id)
945
954
        raw_conflicts = resolve_conflicts(tt)
946
955
        self.assertEqual({('non-directory parent', 'Created directory',
947
 
                         'new-3')}, raw_conflicts)
 
956
                           'new-3')}, raw_conflicts)
948
957
        tt.apply()
949
958
        self.assertFalse(self.wt.is_versioned('parent'))
950
959
        self.assertEqual(b'parent-id', self.wt.path2id('parent.new'))
1020
1029
        self.requireFeature(features.not_running_as_root)
1021
1030
        # see https://bugs.launchpad.net/bzr/+bug/491763
1022
1031
        create, root_id = self.get_transform()
1023
 
        first_dir = create.new_directory('first-dir', root_id, b'first-id')
1024
 
        myfile = create.new_file('myfile', root_id, [b'myfile-text'],
1025
 
                                 b'myfile-id')
 
1032
        create.new_directory('first-dir', root_id, b'first-id')
 
1033
        create.new_file('myfile', root_id, [b'myfile-text'], b'myfile-id')
1026
1034
        create.apply()
1027
1035
        if os.name == "posix" and sys.platform != "cygwin":
1028
1036
            # posix filesystems fail on renaming if the readonly bit is set
1038
1046
        dir_id = rename_transform.trans_id_file_id(b'first-id')
1039
1047
        rename_transform.adjust_path('newname', dir_id, file_trans_id)
1040
1048
        e = self.assertRaises(errors.TransformRenameFailed,
1041
 
            rename_transform.apply)
1042
 
        # On nix looks like: 
 
1049
                              rename_transform.apply)
 
1050
        # On nix looks like:
1043
1051
        # "Failed to rename .../work/.bzr/checkout/limbo/new-1
1044
1052
        # to .../first-dir/newname: [Errno 13] Permission denied"
1045
1053
        # On windows looks like:
1046
 
        # "Failed to rename .../work/myfile to 
 
1054
        # "Failed to rename .../work/myfile to
1047
1055
        # .../work/.bzr/checkout/limbo/new-1: [Errno 13] Permission denied"
1048
1056
        # This test isn't concerned with exactly what the error looks like,
1049
1057
        # and the strerror will vary across OS and locales, but the assert
1059
1067
 
1060
1068
        - create file and set executability simultaneously
1061
1069
        - create file and set executability afterward
1062
 
        - unsetting the executability of a file whose executability has not been
 
1070
        - unsetting the executability of a file whose executability has not
 
1071
          been
1063
1072
        declared should throw an exception (this may happen when a
1064
1073
        merge attempts to create a file with a duplicate ID)
1065
1074
        """
1067
1076
        wt = transform._tree
1068
1077
        wt.lock_read()
1069
1078
        self.addCleanup(wt.unlock)
1070
 
        transform.new_file('set_on_creation', root, [b'Set on creation'], b'soc',
1071
 
                           True)
 
1079
        transform.new_file('set_on_creation', root, [b'Set on creation'],
 
1080
                           b'soc', True)
1072
1081
        sac = transform.new_file('set_after_creation', root,
1073
1082
                                 [b'Set after creation'], b'sac')
1074
1083
        transform.set_executability(True, sac)
1103
1112
 
1104
1113
        stat_paths = []
1105
1114
        real_stat = os.stat
 
1115
 
1106
1116
        def instrumented_stat(path):
1107
1117
            stat_paths.append(path)
1108
1118
            return real_stat(path)
1118
1128
        bar2_id = transform.trans_id_tree_path('bar2')
1119
1129
        try:
1120
1130
            os.stat = instrumented_stat
1121
 
            transform.create_file([b'bar2 contents\n'], bar2_id, mode_id=bar1_id)
 
1131
            transform.create_file([b'bar2 contents\n'],
 
1132
                                  bar2_id, mode_id=bar1_id)
1122
1133
        finally:
1123
1134
            os.stat = real_stat
1124
1135
            transform.finalize()
1137
1148
            old = transform.trans_id_tree_path('old')
1138
1149
            transform.unversion_file(old)
1139
1150
            self.assertEqual([(b'id-1', ('old', None), False, (True, False),
1140
 
                (b'eert_toor', b'eert_toor'), ('old', 'old'), ('file', 'file'),
1141
 
                (True, True))], list(transform.iter_changes()))
 
1151
                               (b'eert_toor', b'eert_toor'),
 
1152
                               ('old', 'old'), ('file', 'file'),
 
1153
                               (True, True))], list(transform.iter_changes()))
1142
1154
            transform.new_directory('new', root, b'id-1')
1143
1155
            self.assertEqual([(b'id-1', ('old', 'new'), True, (True, True),
1144
 
                (b'eert_toor', b'eert_toor'), ('old', 'new'),
1145
 
                ('file', 'directory'),
1146
 
                (True, False))], list(transform.iter_changes()))
 
1156
                               (b'eert_toor', b'eert_toor'), ('old', 'new'),
 
1157
                               ('file', 'directory'),
 
1158
                               (True, False))], list(transform.iter_changes()))
1147
1159
        finally:
1148
1160
            transform.finalize()
1149
1161
 
1157
1169
            old = transform.trans_id_tree_path('old')
1158
1170
            transform.version_file(b'id-1', old)
1159
1171
            self.assertEqual([(b'id-1', (None, 'old'), False, (False, True),
1160
 
                (b'eert_toor', b'eert_toor'), ('old', 'old'), ('file', 'file'),
1161
 
                (False, False))], list(transform.iter_changes()))
 
1172
                               (b'eert_toor', b'eert_toor'),
 
1173
                               ('old', 'old'), ('file', 'file'),
 
1174
                               (False, False))],
 
1175
                             list(transform.iter_changes()))
1162
1176
        finally:
1163
1177
            transform.finalize()
1164
1178
 
1176
1190
            new = transform.trans_id_tree_path('new')
1177
1191
            self.assertEqual([], list(transform.iter_changes()))
1178
1192
 
1179
 
            #content deletion
 
1193
            # content deletion
1180
1194
            transform.delete_contents(old)
1181
1195
            self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
1182
 
                (b'eert_toor', b'eert_toor'), ('old', 'old'), ('file', None),
1183
 
                (False, False))], list(transform.iter_changes()))
 
1196
                               (b'eert_toor', b'eert_toor'),
 
1197
                               ('old', 'old'), ('file', None),
 
1198
                               (False, False))],
 
1199
                             list(transform.iter_changes()))
1184
1200
 
1185
 
            #content change
 
1201
            # content change
1186
1202
            transform.create_file([b'blah'], old)
1187
1203
            self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
1188
 
                (b'eert_toor', b'eert_toor'), ('old', 'old'), ('file', 'file'),
1189
 
                (False, False))], list(transform.iter_changes()))
 
1204
                               (b'eert_toor', b'eert_toor'),
 
1205
                               ('old', 'old'), ('file', 'file'),
 
1206
                               (False, False))],
 
1207
                             list(transform.iter_changes()))
1190
1208
            transform.cancel_deletion(old)
1191
1209
            self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
1192
 
                (b'eert_toor', b'eert_toor'), ('old', 'old'), ('file', 'file'),
1193
 
                (False, False))], list(transform.iter_changes()))
 
1210
                               (b'eert_toor', b'eert_toor'),
 
1211
                               ('old', 'old'), ('file', 'file'),
 
1212
                               (False, False))],
 
1213
                             list(transform.iter_changes()))
1194
1214
            transform.cancel_creation(old)
1195
1215
 
1196
1216
            # move file_id to a different file
1199
1219
            transform.version_file(b'id-1', new)
1200
1220
            transform.adjust_path('old', root, new)
1201
1221
            self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
1202
 
                (b'eert_toor', b'eert_toor'), ('old', 'old'), ('file', 'file'),
1203
 
                (False, False))], list(transform.iter_changes()))
 
1222
                               (b'eert_toor', b'eert_toor'),
 
1223
                               ('old', 'old'), ('file', 'file'),
 
1224
                               (False, False))],
 
1225
                             list(transform.iter_changes()))
1204
1226
            transform.cancel_versioning(new)
1205
1227
            transform._removed_id = set()
1206
1228
 
1207
 
            #execute bit
 
1229
            # execute bit
1208
1230
            self.assertEqual([], list(transform.iter_changes()))
1209
1231
            transform.set_executability(True, old)
1210
1232
            self.assertEqual([(b'id-1', ('old', 'old'), False, (True, True),
1211
 
                (b'eert_toor', b'eert_toor'), ('old', 'old'), ('file', 'file'),
1212
 
                (False, True))], list(transform.iter_changes()))
 
1233
                               (b'eert_toor', b'eert_toor'),
 
1234
                               ('old', 'old'), ('file', 'file'),
 
1235
                               (False, True))],
 
1236
                             list(transform.iter_changes()))
1213
1237
            transform.set_executability(None, old)
1214
1238
 
1215
1239
            # filename
1217
1241
            transform.adjust_path('new', root, old)
1218
1242
            transform._new_parent = {}
1219
1243
            self.assertEqual([(b'id-1', ('old', 'new'), False, (True, True),
1220
 
                (b'eert_toor', b'eert_toor'), ('old', 'new'), ('file', 'file'),
1221
 
                (False, False))], list(transform.iter_changes()))
 
1244
                               (b'eert_toor', b'eert_toor'),
 
1245
                               ('old', 'new'), ('file', 'file'),
 
1246
                               (False, False))],
 
1247
                             list(transform.iter_changes()))
1222
1248
            transform._new_name = {}
1223
1249
 
1224
1250
            # parent directory
1226
1252
            transform.adjust_path('new', subdir, old)
1227
1253
            transform._new_name = {}
1228
1254
            self.assertEqual([(b'id-1', ('old', 'subdir/old'), False,
1229
 
                (True, True), (b'eert_toor', b'subdir-id'), ('old', 'old'),
1230
 
                ('file', 'file'), (False, False))],
1231
 
                list(transform.iter_changes()))
 
1255
                               (True, True), (b'eert_toor',
 
1256
                                              b'subdir-id'), ('old', 'old'),
 
1257
                               ('file', 'file'), (False, False))],
 
1258
                             list(transform.iter_changes()))
1232
1259
            transform._new_path = {}
1233
1260
 
1234
1261
        finally:
1249
1276
        try:
1250
1277
            transform.delete_contents(transform.trans_id_file_id(b'id-1'))
1251
1278
            transform.set_executability(True,
1252
 
            transform.trans_id_file_id(b'id-2'))
1253
 
            self.assertEqual([(b'id-1', (u'file1', u'file1'), True, (True, True),
1254
 
                (b'eert_toor', b'eert_toor'), ('file1', u'file1'),
1255
 
                ('file', None), (False, False)),
1256
 
                (b'id-2', (u'file2', u'file2'), False, (True, True),
1257
 
                (b'eert_toor', b'eert_toor'), ('file2', u'file2'),
1258
 
                ('file', 'file'), (False, True))],
 
1279
                                        transform.trans_id_file_id(b'id-2'))
 
1280
            self.assertEqual(
 
1281
                [(b'id-1', (u'file1', u'file1'), True, (True, True),
 
1282
                 (b'eert_toor', b'eert_toor'), ('file1', u'file1'),
 
1283
                 ('file', None), (False, False)),
 
1284
                 (b'id-2', (u'file2', u'file2'), False, (True, True),
 
1285
                 (b'eert_toor', b'eert_toor'), ('file2', u'file2'),
 
1286
                 ('file', 'file'), (False, True))],
1259
1287
                list(transform.iter_changes()))
1260
1288
        finally:
1261
1289
            transform.finalize()
1275
1303
        try:
1276
1304
            transform.adjust_path('flitter', root, floater)
1277
1305
            self.assertEqual([(b'floater-id', ('floater', 'flitter'), False,
1278
 
            (True, True), (b'toor_eert', b'toor_eert'), ('floater', 'flitter'),
1279
 
            (None, None), (False, False))], list(transform.iter_changes()))
 
1306
                               (True, True),
 
1307
                               (b'toor_eert', b'toor_eert'),
 
1308
                               ('floater', 'flitter'),
 
1309
                               (None, None), (False, False))],
 
1310
                             list(transform.iter_changes()))
1280
1311
        finally:
1281
1312
            transform.finalize()
1282
1313
 
1403
1434
            transform.create_directory(parent)
1404
1435
        except KeyError:
1405
1436
            self.fail("Can't handle contents with no name")
1406
 
        child = transform.new_directory('child', parent)
 
1437
        transform.new_directory('child', parent)
1407
1438
        transform.adjust_path('parent', root, parent)
1408
1439
        transform.apply()
1409
1440
        self.assertPathExists(self.wt.abspath('parent/child'))
1413
1444
        """Avoid reusing the same limbo name for different files"""
1414
1445
        transform, root = self.get_transform()
1415
1446
        parent = transform.new_directory('parent', root)
1416
 
        child1 = transform.new_directory('child', parent)
 
1447
        transform.new_directory('child', parent)
1417
1448
        try:
1418
1449
            child2 = transform.new_directory('child', parent)
1419
1450
        except OSError:
1433
1464
        parent = transform.new_directory('parent', root)
1434
1465
        child1 = transform.new_directory('child', parent)
1435
1466
        transform.adjust_path('child1', parent, child1)
1436
 
        child2 = transform.new_directory('child', parent)
 
1467
        transform.new_directory('child', parent)
1437
1468
        transform.apply()
1438
1469
        # limbo/new-1 => parent
1439
1470
        self.assertEqual(1, transform.rename_count)
1445
1476
        child1 = transform.new_directory('child1', parent2)
1446
1477
        transform.cancel_creation(parent2)
1447
1478
        transform.create_directory(parent2)
1448
 
        child2 = transform.new_directory('child1', parent2)
 
1479
        transform.new_directory('child1', parent2)
1449
1480
        transform.adjust_path('child2', parent2, child1)
1450
1481
        transform.apply()
1451
1482
        # limbo/new-1 => parent2, limbo/new-2 => parent2/child1
1455
1486
        """Finalize must be done in child-to-parent order"""
1456
1487
        transform, root = self.get_transform()
1457
1488
        parent = transform.new_directory('parent', root)
1458
 
        child = transform.new_directory('child', parent)
 
1489
        transform.new_directory('child', parent)
1459
1490
        try:
1460
1491
            transform.finalize()
1461
1492
        except OSError:
1482
1513
                tt.adjust_path('baz', tt.root, foo)
1483
1514
                # Lie to tt that we've already resolved all conflicts.
1484
1515
                tt.apply(no_conflicts=True)
1485
 
            except:
 
1516
            except BaseException:
1486
1517
                wt.unlock()
1487
1518
                raise
1488
1519
        # The rename will fail because the target directory is not empty (but
1502
1533
                tt.new_directory('baz', foo_2)
1503
1534
                # Lie to tt that we've already resolved all conflicts.
1504
1535
                tt.apply(no_conflicts=True)
1505
 
            except:
 
1536
            except BaseException:
1506
1537
                wt.unlock()
1507
1538
                raise
1508
1539
        err = self.assertRaises(errors.FileExists, tt_helper)
1520
1551
                tt.new_directory('baz', foo_2)
1521
1552
                # Lie to tt that we've already resolved all conflicts.
1522
1553
                tt.apply(no_conflicts=True)
1523
 
            except:
 
1554
            except BaseException:
1524
1555
                tt.finalize()
1525
1556
                raise
1526
1557
        err = self.assertRaises(errors.FileExists, tt_helper)
1630
1661
    def test_create_from_tree_bytes(self):
1631
1662
        """Provided lines are used instead of tree content."""
1632
1663
        tree1 = self.make_branch_and_tree('tree1')
1633
 
        self.build_tree_contents([('tree1/foo', b'bar'),])
 
1664
        self.build_tree_contents([('tree1/foo', b'bar'), ])
1634
1665
        tree1.add('foo', b'foo-id')
1635
1666
        tree2 = self.make_branch_and_tree('tree2')
1636
1667
        tt = TreeTransform(tree2)
1697
1728
        with TransformPreview(tree) as tt:
1698
1729
            tt.unversion_file(tt.root)
1699
1730
            tt.version_file(tree.get_root_id(), tt.root)
1700
 
            foo_trans_id = tt.trans_id_tree_path('foo')
 
1731
            tt.trans_id_tree_path('foo')
1701
1732
            self.assertEqual([], tt._inventory_altered())
1702
1733
 
1703
1734
 
1774
1805
        merge_modified = this.wt.merge_modified()
1775
1806
        self.assertSubset(merge_modified, modified)
1776
1807
        self.assertEqual(len(merge_modified), len(modified))
1777
 
        with open(this.wt.abspath(this.wt.id2path(b'a')), 'wb') as f: f.write(b'booga')
 
1808
        with open(this.wt.abspath(this.wt.id2path(b'a')), 'wb') as f:
 
1809
            f.write(b'booga')
1778
1810
        modified.pop(0)
1779
1811
        merge_modified = this.wt.merge_modified()
1780
1812
        self.assertSubset(merge_modified, modified)
1800
1832
            for link, target in (('e', e_target), ('f', f_target),
1801
1833
                                 ('g', g_target), ('h', h_target)):
1802
1834
                if target is not None:
1803
 
                    tg.tt.new_symlink(link, tg.root, target, link.encode('ascii'))
 
1835
                    tg.tt.new_symlink(link, tg.root, target,
 
1836
                                      link.encode('ascii'))
1804
1837
 
1805
1838
        for tg in this, base, other:
1806
1839
            tg.tt.apply()
1809
1842
        self.assertIs(os.path.islink(this.wt.abspath('b')), True)
1810
1843
        self.assertIs(os.path.isfile(this.wt.abspath('c')), True)
1811
1844
        for suffix in ('THIS', 'BASE', 'OTHER'):
1812
 
            self.assertEqual(os.readlink(this.wt.abspath('d.'+suffix)), suffix)
 
1845
            self.assertEqual(os.readlink(
 
1846
                this.wt.abspath('d.' + suffix)), suffix)
1813
1847
        self.assertIs(os.path.lexists(this.wt.abspath('d')), False)
1814
1848
        self.assertEqual(this.wt.id2path(b'd'), 'd.OTHER')
1815
1849
        self.assertEqual(this.wt.id2path(b'f'), 'f.THIS')
1896
1930
        os.mkdir('a')
1897
1931
        a = ControlDir.create_standalone_workingtree('a')
1898
1932
        os.mkdir('a/foo')
1899
 
        with open('a/foo/bar', 'wb') as f: f.write(b'contents')
 
1933
        with open('a/foo/bar', 'wb') as f:
 
1934
            f.write(b'contents')
1900
1935
        os.symlink('a/foo/bar', 'a/foo/baz')
1901
1936
        a.add(['foo', 'foo/bar', 'foo/baz'])
1902
1937
        a.commit('initial commit')
1912
1947
 
1913
1948
    def test_build_with_references(self):
1914
1949
        tree = self.make_branch_and_tree('source',
1915
 
            format='development-subtree')
 
1950
                                         format='development-subtree')
1916
1951
        subtree = self.make_branch_and_tree('source/subtree',
1917
 
            format='development-subtree')
 
1952
                                            format='development-subtree')
1918
1953
        tree.add_reference(subtree)
1919
1954
        tree.commit('a revision')
1920
1955
        tree.branch.create_checkout('target')
1929
1964
        source.add('file', b'new-file')
1930
1965
        source.commit('added file')
1931
1966
        build_tree(source.basis_tree(), target)
1932
 
        self.assertEqual([DuplicateEntry('Moved existing file to',
1933
 
                          'file.moved', 'file', None, 'new-file')],
1934
 
                         target.conflicts())
 
1967
        self.assertEqual(
 
1968
            [DuplicateEntry('Moved existing file to', 'file.moved',
 
1969
                            'file', None, 'new-file')],
 
1970
            target.conflicts())
1935
1971
        target2 = self.make_branch_and_tree('target2')
1936
1972
        with open('target2/file', 'wb') as target_file, \
1937
1973
                open('source/file', 'rb') as source_file:
1949
1985
        target = self.make_branch_and_tree('target')
1950
1986
        os.symlink('bar', 'target/symlink')
1951
1987
        build_tree(source.basis_tree(), target)
1952
 
        self.assertEqual([DuplicateEntry('Moved existing file to',
1953
 
            'symlink.moved', 'symlink', None, 'new-symlink')],
 
1988
        self.assertEqual(
 
1989
            [DuplicateEntry('Moved existing file to', 'symlink.moved',
 
1990
                            'symlink', None, 'new-symlink')],
1954
1991
            target.conflicts())
1955
1992
        target = self.make_branch_and_tree('target2')
1956
1993
        os.symlink('foo', 'target2/symlink')
1984
2021
        self.assertPathDoesNotExist('target3/dir1/file')
1985
2022
        self.assertPathExists('target3/dir1/file2')
1986
2023
        self.assertPathExists('target3/dir1.diverted/file')
1987
 
        self.assertEqual([DuplicateEntry('Diverted to',
1988
 
            'dir1.diverted', 'dir1', 'new-dir1', None)],
 
2024
        self.assertEqual(
 
2025
            [DuplicateEntry('Diverted to', 'dir1.diverted',
 
2026
                            'dir1', 'new-dir1', None)],
1989
2027
            target.conflicts())
1990
2028
 
1991
2029
        target = self.make_branch_and_tree('target4')
1995
2033
        self.assertPathExists('target4/dir1/file')
1996
2034
        self.assertEqual('directory', file_kind('target4/dir1/file'))
1997
2035
        self.assertPathExists('target4/dir1/file.diverted')
1998
 
        self.assertEqual([DuplicateEntry('Diverted to',
1999
 
            'dir1/file.diverted', 'dir1/file', 'new-file', None)],
 
2036
        self.assertEqual(
 
2037
            [DuplicateEntry('Diverted to', 'dir1/file.diverted',
 
2038
                            'dir1/file', 'new-file', None)],
2000
2039
            target.conflicts())
2001
2040
 
2002
2041
    def test_mixed_conflict_handling(self):
2007
2046
        source.add('name', b'new-name')
2008
2047
        source.commit('added file')
2009
2048
        build_tree(source.basis_tree(), target)
2010
 
        self.assertEqual([DuplicateEntry('Moved existing file to',
2011
 
            'name.moved', 'name', None, 'new-name')], target.conflicts())
 
2049
        self.assertEqual(
 
2050
            [DuplicateEntry('Moved existing file to',
 
2051
                            'name.moved', 'name', None, 'new-name')],
 
2052
            target.conflicts())
2012
2053
 
2013
2054
    def test_raises_in_populated(self):
2014
2055
        source = self.make_branch_and_tree('source')
2019
2060
        self.build_tree(['target/name'])
2020
2061
        target.add('name')
2021
2062
        self.assertRaises(errors.WorkingTreeAlreadyPopulated,
2022
 
            build_tree, source.basis_tree(), target)
 
2063
                          build_tree, source.basis_tree(), target)
2023
2064
 
2024
2065
    def test_build_tree_rename_count(self):
2025
2066
        source = self.make_branch_and_tree('source')
2054
2095
        self.build_tree_contents([('source/file2', b'C')])
2055
2096
        calls = []
2056
2097
        real_source_get_file = source.get_file
2057
 
        def get_file(path, file_id=None):
2058
 
            calls.append(file_id)
2059
 
            return real_source_get_file(path, file_id)
 
2098
 
 
2099
        def get_file(path):
 
2100
            calls.append(path)
 
2101
            return real_source_get_file(path)
2060
2102
        source.get_file = get_file
2061
2103
        target = self.make_branch_and_tree('target')
2062
2104
        revision_tree = source.basis_tree()
2063
2105
        revision_tree.lock_read()
2064
2106
        self.addCleanup(revision_tree.unlock)
2065
2107
        build_tree(revision_tree, target, source)
2066
 
        self.assertEqual([b'file1-id'], calls)
 
2108
        self.assertEqual(['file1'], calls)
2067
2109
        target.lock_read()
2068
2110
        self.addCleanup(target.unlock)
2069
2111
        self.assertEqual([], list(target.iter_changes(revision_tree)))
2106
2148
        os.symlink('file2', 'source/file1')
2107
2149
        calls = []
2108
2150
        real_source_get_file = source.get_file
2109
 
        def get_file(path, file_id=None):
2110
 
            calls.append(file_id)
2111
 
            return real_source_get_file(path, file_id)
 
2151
 
 
2152
        def get_file(path):
 
2153
            calls.append(path)
 
2154
            return real_source_get_file(path)
2112
2155
        source.get_file = get_file
2113
2156
        target = self.make_branch_and_tree('target')
2114
2157
        revision_tree = source.basis_tree()
2186
2229
        # below, but that looks a bit... hard to read even if it's exactly
2187
2230
        # the same thing.
2188
2231
        original_registry = filters._reset_registry()
 
2232
 
2189
2233
        def restore_registry():
2190
2234
            filters._reset_registry(original_registry)
2191
2235
        self.addCleanup(restore_registry)
 
2236
 
2192
2237
        def rot13(chunks, context=None):
2193
 
            return [codecs.encode(chunk.decode('ascii'), 'rot13').encode('ascii')
2194
 
                    for chunk in chunks]
 
2238
            return [
 
2239
                codecs.encode(chunk.decode('ascii'), 'rot13').encode('ascii')
 
2240
                for chunk in chunks]
2195
2241
        rot13filter = filters.ContentFilter(rot13, rot13)
2196
2242
        filters.filter_stacks_registry.register(
2197
2243
            'rot13', {'yes': [rot13filter]}.get)
2199
2245
        rules_filename = self.test_home_dir + '/.bazaar/rules'
2200
2246
        with open(rules_filename, 'wb') as f:
2201
2247
            f.write(b'[name %s]\nrot13=yes\n' % (pattern,))
 
2248
 
2202
2249
        def uninstall_rules():
2203
2250
            os.remove(rules_filename)
2204
2251
            rules.reset_rules()
2230
2277
 
2231
2278
    def test_case_insensitive_build_tree_inventory(self):
2232
2279
        if (features.CaseInsensitiveFilesystemFeature.available()
2233
 
            or features.CaseInsCasePresFilenameFeature.available()):
 
2280
                or features.CaseInsCasePresFilenameFeature.available()):
2234
2281
            raise tests.UnavailableFeature('Fully case sensitive filesystem')
2235
2282
        source = self.make_branch_and_tree('source')
2236
2283
        self.build_tree(['source/file', 'source/FILE'])
2274
2321
        entry2_state = entry2[1][0]
2275
2322
        # Now, make sure that we don't have to re-read the content. The
2276
2323
        # packed_stat should match exactly.
2277
 
        self.assertEqual(entry1_sha, target.get_file_sha1('file1', b'file1-id'))
2278
 
        self.assertEqual(entry2_sha,
2279
 
                         target.get_file_sha1('dir/file2', b'file2-id'))
 
2324
        self.assertEqual(entry1_sha, target.get_file_sha1('file1'))
 
2325
        self.assertEqual(entry2_sha, target.get_file_sha1('dir/file2'))
2280
2326
        self.assertEqual(entry1_state, entry1[1][0])
2281
2327
        self.assertEqual(entry2_state, entry2[1][0])
2282
2328
 
2315
2361
 
2316
2362
    def test_merge_parents(self):
2317
2363
        branch, tt = self.get_branch_and_transform()
2318
 
        rev = tt.commit(branch, 'my message', [b'rev1b', b'rev1c'])
 
2364
        tt.commit(branch, 'my message', [b'rev1b', b'rev1c'])
2319
2365
        self.assertEqual([b'rev1b', b'rev1c'],
2320
2366
                         branch.basis_tree().get_parent_ids()[1:])
2321
2367
 
2326
2372
        tt = TransformPreview(branch.basis_tree())
2327
2373
        self.addCleanup(tt.finalize)
2328
2374
        tt.new_directory('', ROOT_PARENT, b'TREE_ROOT')
2329
 
        rev = tt.commit(branch, 'my message')
 
2375
        tt.commit(branch, 'my message')
2330
2376
        self.assertEqual([], branch.basis_tree().get_parent_ids())
2331
2377
        self.assertNotEqual(_mod_revision.NULL_REVISION,
2332
2378
                            branch.last_revision())
2338
2384
        tt = TransformPreview(branch.basis_tree())
2339
2385
        self.addCleanup(tt.finalize)
2340
2386
        e = self.assertRaises(ValueError, tt.commit, branch,
2341
 
                          'my message', [b'rev1b-id'])
 
2387
                              'my message', [b'rev1b-id'])
2342
2388
        self.assertEqual('Cannot supply merge parents for first commit.',
2343
2389
                         str(e))
2344
2390
        self.assertEqual(_mod_revision.NULL_REVISION, branch.last_revision())
2349
2395
        trans_id = tt.new_directory('dir', tt.root, b'dir-id')
2350
2396
        if SymlinkFeature.available():
2351
2397
            tt.new_symlink('symlink', trans_id, 'target', b'symlink-id')
2352
 
        rev = tt.commit(branch, 'message')
 
2398
        tt.commit(branch, 'message')
2353
2399
        tree = branch.basis_tree()
2354
2400
        self.assertEqual('file', tree.id2path(b'file-id'))
2355
 
        self.assertEqual(b'contents', tree.get_file_text('file', b'file-id'))
 
2401
        self.assertEqual(b'contents', tree.get_file_text('file'))
2356
2402
        self.assertEqual('dir', tree.id2path(b'dir-id'))
2357
2403
        if SymlinkFeature.available():
2358
2404
            self.assertEqual('dir/symlink', tree.id2path(b'symlink-id'))
2392
2438
                           committer='me <me@example.com>',
2393
2439
                           revprops={u'foo': 'bar'}, revision_id=b'revid-1',
2394
2440
                           authors=['Author1 <author1@example.com>',
2395
 
                              'Author2 <author2@example.com>',
2396
 
                               ])
 
2441
                                    'Author2 <author2@example.com>',
 
2442
                                    ])
2397
2443
        self.assertEqual(b'revid-1', rev_id)
2398
2444
        revision = branch.repository.get_revision(rev_id)
2399
2445
        self.assertEqual(1, revision.timestamp)
2463
2509
        mover.rename('c/e', 'c/d')
2464
2510
        try:
2465
2511
            mover.rename('a', 'c')
2466
 
        except errors.FileExists as e:
 
2512
        except errors.FileExists:
2467
2513
            mover.rollback()
2468
2514
        self.assertPathExists('a')
2469
2515
        self.assertPathExists('c/d')
2484
2530
 
2485
2531
        def rename(self, source, target):
2486
2532
            if (self.bad_source is not None and
2487
 
                source.endswith(self.bad_source)):
 
2533
                    source.endswith(self.bad_source)):
2488
2534
                raise Bogus
2489
2535
            elif (self.bad_target is not None and
2490
 
                target.endswith(self.bad_target)):
 
2536
                  target.endswith(self.bad_target)):
2491
2537
                raise Bogus
2492
2538
            else:
2493
2539
                _FileMover.rename(self, source, target)
2548
2594
        new_globals = dict(func.__globals__)
2549
2595
        new_globals.update(globals)
2550
2596
        new_func = types.FunctionType(func.__code__, new_globals,
2551
 
            func.__name__, func.__defaults__)
 
2597
                                      func.__name__, func.__defaults__)
2552
2598
        if PY3:
2553
2599
            setattr(instance, method_name,
2554
 
                types.MethodType(new_func, instance))
 
2600
                    types.MethodType(new_func, instance))
2555
2601
        else:
2556
2602
            setattr(instance, method_name,
2557
 
                types.MethodType(new_func, instance, instance.__class__))
 
2603
                    types.MethodType(new_func, instance, instance.__class__))
2558
2604
        self.addCleanup(delattr, instance, method_name)
2559
2605
 
2560
2606
    @staticmethod
2586
2632
 
2587
2633
    def test_root_create_file_open_raises_before_creation(self):
2588
2634
        tt, trans_id = self.create_transform_and_root_trans_id()
2589
 
        self._override_globals_in_method(tt, "create_file",
2590
 
            {"open": self._fake_open_raises_before})
2591
 
        self.assertRaises(RuntimeError, tt.create_file, [b"contents"], trans_id)
 
2635
        self._override_globals_in_method(
 
2636
            tt, "create_file", {"open": self._fake_open_raises_before})
 
2637
        self.assertRaises(RuntimeError, tt.create_file,
 
2638
                          [b"contents"], trans_id)
2592
2639
        path = tt._limbo_name(trans_id)
2593
2640
        self.assertPathDoesNotExist(path)
2594
2641
        tt.finalize()
2596
2643
 
2597
2644
    def test_root_create_file_open_raises_after_creation(self):
2598
2645
        tt, trans_id = self.create_transform_and_root_trans_id()
2599
 
        self._override_globals_in_method(tt, "create_file",
2600
 
            {"open": self._fake_open_raises_after})
2601
 
        self.assertRaises(RuntimeError, tt.create_file, [b"contents"], trans_id)
 
2646
        self._override_globals_in_method(
 
2647
            tt, "create_file", {"open": self._fake_open_raises_after})
 
2648
        self.assertRaises(RuntimeError, tt.create_file,
 
2649
                          [b"contents"], trans_id)
2602
2650
        path = tt._limbo_name(trans_id)
2603
2651
        self.assertPathExists(path)
2604
2652
        tt.finalize()
2607
2655
 
2608
2656
    def test_subdir_create_file_open_raises_before_creation(self):
2609
2657
        tt, trans_id = self.create_transform_and_subdir_trans_id()
2610
 
        self._override_globals_in_method(tt, "create_file",
2611
 
            {"open": self._fake_open_raises_before})
2612
 
        self.assertRaises(RuntimeError, tt.create_file, [b"contents"], trans_id)
 
2658
        self._override_globals_in_method(
 
2659
            tt, "create_file", {"open": self._fake_open_raises_before})
 
2660
        self.assertRaises(RuntimeError, tt.create_file,
 
2661
                          [b"contents"], trans_id)
2613
2662
        path = tt._limbo_name(trans_id)
2614
2663
        self.assertPathDoesNotExist(path)
2615
2664
        tt.finalize()
2617
2666
 
2618
2667
    def test_subdir_create_file_open_raises_after_creation(self):
2619
2668
        tt, trans_id = self.create_transform_and_subdir_trans_id()
2620
 
        self._override_globals_in_method(tt, "create_file",
2621
 
            {"open": self._fake_open_raises_after})
2622
 
        self.assertRaises(RuntimeError, tt.create_file, [b"contents"], trans_id)
 
2669
        self._override_globals_in_method(
 
2670
            tt, "create_file", {"open": self._fake_open_raises_after})
 
2671
        self.assertRaises(RuntimeError, tt.create_file,
 
2672
                          [b"contents"], trans_id)
2623
2673
        path = tt._limbo_name(trans_id)
2624
2674
        self.assertPathExists(path)
2625
2675
        tt.finalize()
2637
2687
                os.rename(old, new)
2638
2688
                raise RuntimeError
2639
2689
        self._override_globals_in_method(tt, "_rename_in_limbo",
2640
 
            {"os": FakeOSModule()})
 
2690
                                         {"os": FakeOSModule()})
2641
2691
        self.assertRaises(
2642
2692
            RuntimeError, tt.adjust_path, "child1", parent2, child1)
2643
2693
        path = osutils.pathjoin(tt._limbo_name(parent2), "child1")
2656
2706
            def rename(self, old, new):
2657
2707
                raise RuntimeError
2658
2708
        self._override_globals_in_method(tt, "_rename_in_limbo",
2659
 
            {"os": FakeOSModule()})
 
2709
                                         {"os": FakeOSModule()})
2660
2710
        self.assertRaises(
2661
2711
            RuntimeError, tt.adjust_path, "child1", parent2, child1)
2662
2712
        path = osutils.pathjoin(tt._limbo_name(parent1), "child1")
2670
2720
 
2671
2721
    def make_tt_with_versioned_dir(self):
2672
2722
        wt = self.make_branch_and_tree('.')
2673
 
        self.build_tree(['dir/',])
 
2723
        self.build_tree(['dir/', ])
2674
2724
        wt.add(['dir'], [b'dir-id'])
2675
2725
        wt.commit('Create dir')
2676
2726
        tt = TreeTransform(wt)
2680
2730
    def test_resolve_create_parent_for_versioned_file(self):
2681
2731
        wt, tt = self.make_tt_with_versioned_dir()
2682
2732
        dir_tid = tt.trans_id_tree_path('dir')
2683
 
        file_tid = tt.new_file('file', dir_tid, [b'Contents'], file_id=b'file-id')
 
2733
        tt.new_file('file', dir_tid, [b'Contents'], file_id=b'file-id')
2684
2734
        tt.delete_contents(dir_tid)
2685
2735
        tt.unversion_file(dir_tid)
2686
2736
        conflicts = resolve_conflicts(tt)
2702
2752
 
2703
2753
 
2704
2754
A_ENTRY = (b'a-id', ('a', 'a'), True, (True, True),
2705
 
                  (b'TREE_ROOT', b'TREE_ROOT'), ('a', 'a'), ('file', 'file'),
2706
 
                  (False, False))
 
2755
           (b'TREE_ROOT', b'TREE_ROOT'), ('a', 'a'), ('file', 'file'),
 
2756
           (False, False))
2707
2757
ROOT_ENTRY = (b'TREE_ROOT', ('', ''), False, (True, True), (None, None),
2708
2758
              ('', ''), ('directory', 'directory'), (False, False))
2709
2759
 
2743
2793
        preview.new_file('file2', preview.root, [b'content B\n'], b'file2-id')
2744
2794
        preview_tree = preview.get_preview_tree()
2745
2795
        self.assertEqual(preview_tree.kind('file2'), 'file')
2746
 
        with preview_tree.get_file('file2', b'file2-id') as f:
 
2796
        with preview_tree.get_file('file2') as f:
2747
2797
            self.assertEqual(f.read(), b'content B\n')
2748
2798
 
2749
2799
    def test_diff_preview_tree(self):
2782
2832
        revision_tree, preview_tree = self.get_tree_and_preview_tree()
2783
2833
        root = revision_tree.get_root_id()
2784
2834
        self.assertEqual([(b'a-id', ('a', 'a'), True, (True, True),
2785
 
                          (root, root), ('a', 'a'), ('file', 'file'),
2786
 
                          (False, False))],
2787
 
                          list(preview_tree.iter_changes(revision_tree)))
 
2835
                           (root, root), ('a', 'a'), ('file', 'file'),
 
2836
                           (False, False))],
 
2837
                         list(preview_tree.iter_changes(revision_tree)))
2788
2838
 
2789
2839
    def test_include_unchanged_succeeds(self):
2790
2840
        revision_tree, preview_tree = self.get_tree_and_preview_tree()
2791
2841
        changes = preview_tree.iter_changes(revision_tree,
2792
2842
                                            include_unchanged=True)
2793
 
        root = revision_tree.get_root_id()
2794
 
 
2795
2843
        self.assertEqual([ROOT_ENTRY, A_ENTRY], list(changes))
2796
2844
 
2797
2845
    def test_specific_files(self):
2839
2887
        limbo_path = preview._limbo_name(file_trans_id)
2840
2888
        preview_tree = preview.get_preview_tree()
2841
2889
        self.assertEqual(os.stat(limbo_path).st_mtime,
2842
 
                         preview_tree.get_file_mtime('file', b'file-id'))
 
2890
                         preview_tree.get_file_mtime('file'))
2843
2891
 
2844
2892
    def test_get_file_mtime_renamed(self):
2845
2893
        work_tree = self.make_branch_and_tree('tree')
2850
2898
        file_trans_id = preview.trans_id_tree_path('file')
2851
2899
        preview.adjust_path('renamed', preview.root, file_trans_id)
2852
2900
        preview_tree = preview.get_preview_tree()
2853
 
        preview_mtime = preview_tree.get_file_mtime('renamed', b'file-id')
2854
 
        work_mtime = work_tree.get_file_mtime('file', b'file-id')
 
2901
        preview_mtime = preview_tree.get_file_mtime('renamed')
 
2902
        work_mtime = work_tree.get_file_mtime('file')
2855
2903
 
2856
2904
    def test_get_file_size(self):
2857
2905
        work_tree = self.make_branch_and_tree('tree')
2859
2907
        work_tree.add('old', b'old-id')
2860
2908
        preview = TransformPreview(work_tree)
2861
2909
        self.addCleanup(preview.finalize)
2862
 
        new_id = preview.new_file('name', preview.root, [b'contents'], b'new-id',
2863
 
                                  'executable')
 
2910
        preview.new_file('name', preview.root, [b'contents'], b'new-id',
 
2911
                         'executable')
2864
2912
        tree = preview.get_preview_tree()
2865
2913
        self.assertEqual(len('old'), tree.get_file_size('old'))
2866
2914
        self.assertEqual(len('contents'), tree.get_file_size('name'))
2912
2960
        preview = TransformPreview(tree)
2913
2961
        self.addCleanup(preview.finalize)
2914
2962
        preview.new_file('new', preview.trans_id_file_id(b'unchanged-id'),
2915
 
            [b'contents'], b'new-id')
 
2963
                         [b'contents'], b'new-id')
2916
2964
        preview_tree = preview.get_preview_tree()
2917
2965
        self.assertEqual(b'new-id', preview_tree.path2id('unchanged/new'))
2918
2966
 
3017
3065
 
3018
3066
    def test_file_content_summary_executable(self):
3019
3067
        preview = self.get_empty_preview()
3020
 
        path_id = preview.new_file('path', preview.root, [b'contents'], b'path-id')
 
3068
        path_id = preview.new_file('path', preview.root, [
 
3069
                                   b'contents'], b'path-id')
3021
3070
        preview.set_executability(True, path_id)
3022
3071
        summary = preview.get_preview_tree().path_content_summary('path')
3023
3072
        self.assertEqual(4, len(summary))
3084
3133
            (b'me:', b'b\n'),
3085
3134
            (b'me:', b'c\n'),
3086
3135
        ]
3087
 
        annotation = preview_tree.annotate_iter('file', default_revision=b'me:')
 
3136
        annotation = preview_tree.annotate_iter(
 
3137
            'file', default_revision=b'me:')
3088
3138
        self.assertEqual(expected, annotation)
3089
3139
 
3090
3140
    def test_annotate_missing(self):
3095
3145
            (b'me:', b'a\n'),
3096
3146
            (b'me:', b'b\n'),
3097
3147
            (b'me:', b'c\n'),
3098
 
         ]
3099
 
        annotation = preview_tree.annotate_iter('file', default_revision=b'me:')
 
3148
            ]
 
3149
        annotation = preview_tree.annotate_iter(
 
3150
            'file', default_revision=b'me:')
3100
3151
        self.assertEqual(expected, annotation)
3101
3152
 
3102
3153
    def test_annotate_rename(self):
3112
3163
        expected = [
3113
3164
            (b'one', b'a\n'),
3114
3165
        ]
3115
 
        annotation = preview_tree.annotate_iter('file', default_revision=b'me:')
 
3166
        annotation = preview_tree.annotate_iter(
 
3167
            'file', default_revision=b'me:')
3116
3168
        self.assertEqual(expected, annotation)
3117
3169
 
3118
3170
    def test_annotate_deleted(self):
3126
3178
        file_trans_id = preview.trans_id_file_id(b'file-id')
3127
3179
        preview.delete_contents(file_trans_id)
3128
3180
        preview_tree = preview.get_preview_tree()
3129
 
        annotation = preview_tree.annotate_iter('file', default_revision=b'me:')
 
3181
        annotation = preview_tree.annotate_iter(
 
3182
            'file', default_revision=b'me:')
3130
3183
        self.assertIs(None, annotation)
3131
3184
 
3132
3185
    def test_stored_kind(self):
3196
3249
 
3197
3250
    def test_walkdirs(self):
3198
3251
        preview = self.get_empty_preview()
3199
 
        root = preview.new_directory('', ROOT_PARENT, b'tree-root')
 
3252
        preview.new_directory('', ROOT_PARENT, b'tree-root')
3200
3253
        # FIXME: new_directory should mark root.
3201
3254
        preview.fixup_new_roots()
3202
3255
        preview_tree = preview.get_preview_tree()
3203
 
        file_trans_id = preview.new_file('a', preview.root, [b'contents'],
3204
 
                                         b'a-id')
 
3256
        preview.new_file('a', preview.root, [b'contents'], b'a-id')
3205
3257
        expected = [(('', b'tree-root'),
3206
 
                    [('a', 'a', 'file', None, b'a-id', 'file')])]
 
3258
                     [('a', 'a', 'file', None, b'a-id', 'file')])]
3207
3259
        self.assertEqual(expected, list(preview_tree.walkdirs()))
3208
3260
 
3209
3261
    def test_extras(self):
3248
3300
        self.addCleanup(tt.finalize)
3249
3301
        final_tree = tt.get_preview_tree()
3250
3302
        self.assertEqual(
3251
 
                b'a\nb\nc\n',
3252
 
                final_tree.get_file_text(final_tree.id2path(b'file-id')))
 
3303
            b'a\nb\nc\n',
 
3304
            final_tree.get_file_text(final_tree.id2path(b'file-id')))
3253
3305
 
3254
3306
    def test_merge_preview_into_workingtree(self):
3255
3307
        tree = self.make_branch_and_tree('tree')
3305
3357
        self.addCleanup(preview.finalize)
3306
3358
        preview.new_file('foo', preview.root, [b'bar'], b'baz-id')
3307
3359
        preview_tree = preview.get_preview_tree()
3308
 
        self.assertEqual(False, preview_tree.is_executable('tree/foo', b'baz-id'))
3309
3360
        self.assertEqual(False, preview_tree.is_executable('tree/foo'))
3310
3361
 
3311
3362
    def test_commit_preview_tree(self):
3485
3536
        attribs = self.default_attribs()
3486
3537
        attribs[b'_id_number'] = 2
3487
3538
        attribs[b'_non_present_ids'] = {
3488
 
            b'boo': b'new-1',}
 
3539
            b'boo': b'new-1', }
3489
3540
        return self.make_records(attribs, [])
3490
3541
 
3491
3542
    def test_serialize_missing(self):
3492
3543
        tt = self.get_preview()
3493
 
        boo_trans_id = tt.trans_id_file_id(b'boo')
 
3544
        tt.trans_id_file_id(b'boo')
3494
3545
        self.assertSerializesTo(self.missing_records(), tt)
3495
3546
 
3496
3547
    def test_deserialize_missing(self):
3511
3562
        attribs[b'_id_number'] = 2
3512
3563
        attribs[b'_tree_path_ids'] = {
3513
3564
            b'file': b'new-1',
3514
 
            b'': b'new-0',}
 
3565
            b'': b'new-0', }
3515
3566
        attribs[b'_removed_contents'] = [b'new-1']
3516
3567
        contents = [(b'new-1', b'file',
3517
3568
                     b'i 1\nz\n\nc 0 1 1 1\ni 1\nx\n\nc 0 3 3 1\n')]
3541
3592
        attribs[b'_id_number'] = 2
3542
3593
        attribs[b'_tree_path_ids'] = {
3543
3594
            b'foo': b'new-1',
3544
 
            b'': b'new-0',}
 
3595
            b'': b'new-0', }
3545
3596
        attribs[b'_removed_contents'] = [b'new-1']
3546
3597
        contents = [(b'new-1', b'file',
3547
3598
                     b'i 4\na\nb\nc\nd\n\n')]
3572
3623
        attribs[b'_id_number'] = 2
3573
3624
        attribs[b'_tree_path_ids'] = {
3574
3625
            b'foo': b'new-1',
3575
 
            b'': b'new-0',}
 
3626
            b'': b'new-0', }
3576
3627
        contents = [(b'new-1', b'file',
3577
3628
                     b'i 4\na\nb\nc\nd\n\n')]
3578
3629
        return self.make_records(attribs, contents)
3590
3641
 
3591
3642
    def test_get_parents_lines(self):
3592
3643
        LINES_ONE = b'aa\nbb\ncc\ndd\n'
3593
 
        LINES_TWO = b'z\nbb\nx\ndd\n'
3594
3644
        tree = self.make_branch_and_tree('tree')
3595
3645
        self.build_tree_contents([('tree/file', LINES_ONE)])
3596
3646
        tree.add('file', b'file-id')
3597
3647
        tt = self.get_preview(tree)
3598
3648
        trans_id = tt.trans_id_tree_path('file')
3599
3649
        self.assertEqual(([b'aa\n', b'bb\n', b'cc\n', b'dd\n'],),
3600
 
            tt._get_parents_lines(trans_id))
 
3650
                         tt._get_parents_lines(trans_id))
3601
3651
 
3602
3652
    def test_get_parents_texts(self):
3603
3653
        LINES_ONE = b'aa\nbb\ncc\ndd\n'
3604
 
        LINES_TWO = b'z\nbb\nx\ndd\n'
3605
3654
        tree = self.make_branch_and_tree('tree')
3606
3655
        self.build_tree_contents([('tree/file', LINES_ONE)])
3607
3656
        tree.add('file', b'file-id')
3608
3657
        tt = self.get_preview(tree)
3609
3658
        trans_id = tt.trans_id_tree_path('file')
3610
3659
        self.assertEqual((LINES_ONE,),
3611
 
            tt._get_parents_texts(trans_id))
 
3660
                         tt._get_parents_texts(trans_id))
3612
3661
 
3613
3662
 
3614
3663
class TestOrphan(tests.TestCaseWithTransport):
3621
3670
 
3622
3671
    def _set_orphan_policy(self, wt, policy):
3623
3672
        wt.branch.get_config_stack().set('transform.orphan_policy',
3624
 
                                               policy)
 
3673
                                         policy)
3625
3674
 
3626
3675
    def _prepare_orphan(self, wt):
3627
3676
        self.build_tree(['dir/', 'dir/file', 'dir/foo'])
3648
3697
        self._set_orphan_policy(wt, 'move')
3649
3698
        tt, orphan_tid = self._prepare_orphan(wt)
3650
3699
        warnings = []
 
3700
 
3651
3701
        def warning(*args):
3652
3702
            warnings.append(args[0] % args[1:])
3653
3703
        self.overrideAttr(trace, 'warning', warning)
3654
3704
        remaining_conflicts = resolve_conflicts(tt)
3655
3705
        self.assertEqual(['dir/foo has been orphaned in brz-orphans'],
3656
 
                          warnings)
 
3706
                         warnings)
3657
3707
        # Yeah for resolved conflicts !
3658
3708
        self.assertLength(0, remaining_conflicts)
3659
3709
        # We have a new orphan
3660
3710
        self.assertEqual('foo.~1~', tt.final_name(orphan_tid))
3661
3711
        self.assertEqual('brz-orphans',
3662
 
                          tt.final_name(tt.final_parent(orphan_tid)))
 
3712
                         tt.final_name(tt.final_parent(orphan_tid)))
3663
3713
 
3664
3714
    def test_never_orphan(self):
3665
3715
        wt = self.make_branch_and_tree('.')
3690
3740
        self._set_orphan_policy(wt, 'donttouchmypreciouuus')
3691
3741
        tt, orphan_tid = self._prepare_orphan(wt)
3692
3742
        warnings = []
 
3743
 
3693
3744
        def warning(*args):
3694
3745
            warnings.append(args[0] % args[1:])
3695
3746
        self.overrideAttr(trace, 'warning', warning)
3716
3767
 
3717
3768
    def test_pre_commit_hooks(self):
3718
3769
        calls = []
 
3770
 
3719
3771
        def record_pre_transform(tree, tt):
3720
3772
            calls.append((tree, tt))
3721
 
        MutableTree.hooks.install_named_hook('pre_transform',
3722
 
            record_pre_transform, "Pre transform")
 
3773
        MutableTree.hooks.install_named_hook(
 
3774
            'pre_transform', record_pre_transform, "Pre transform")
3723
3775
        transform, root = self.get_transform()
3724
3776
        old_root_id = transform.tree_file_id(root)
3725
3777
        transform.apply()
3728
3780
 
3729
3781
    def test_post_commit_hooks(self):
3730
3782
        calls = []
 
3783
 
3731
3784
        def record_post_transform(tree, tt):
3732
3785
            calls.append((tree, tt))
3733
 
        MutableTree.hooks.install_named_hook('post_transform',
3734
 
            record_post_transform, "Post transform")
 
3786
        MutableTree.hooks.install_named_hook(
 
3787
            'post_transform', record_post_transform, "Post transform")
3735
3788
        transform, root = self.get_transform()
3736
3789
        old_root_id = transform.tree_file_id(root)
3737
3790
        transform.apply()