/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: 2018-11-16 23:19:12 UTC
  • mfrom: (7180 work)
  • mto: This revision was merged to the branch mainline in revision 7294.
  • Revision ID: jelmer@jelmer.uk-20181116231912-e043vpq22bdkxa6q
Merge trunk.

Show diffs side-by-side

added added

removed removed

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