259
259
fo, st2 = self.wt.get_file_with_stat('two', filtered=False)
261
261
# We only guarantee 2s resolution
262
self.assertTrue(abs(creation_mtime - st1.st_mtime) < 2.0,
263
"%s != %s within 2 seconds" % (creation_mtime, st1.st_mtime))
263
abs(creation_mtime - st1.st_mtime) < 2.0,
264
"%s != %s within 2 seconds" % (creation_mtime, st1.st_mtime))
264
265
# But if we have more than that, all files should get the same result
265
266
self.assertEqual(st1.st_mtime, st2.st_mtime)
291
292
def test_add_two_roots(self):
292
293
transform, root = self.get_transform()
293
new_trans_id = transform.new_directory('', ROOT_PARENT, b'new-root-id')
294
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')
295
296
self.assertRaises(ValueError, transform.fixup_new_roots)
297
298
def test_retain_existing_root(self):
311
312
def test_add_unversioned_root(self):
312
313
transform, root = self.get_transform()
313
new_trans_id = transform.new_directory('', ROOT_PARENT, None)
314
transform.new_directory('', ROOT_PARENT, None)
314
315
transform.delete_contents(transform.root)
315
316
transform.fixup_new_roots()
316
317
self.assertNotIn(transform.root, transform._new_id)
326
327
self.assertEqual(old_root_id, self.wt.get_root_id())
328
329
transform, root = self.get_transform()
329
new_trans_id = transform.new_directory('', ROOT_PARENT, b'new-root-id')
330
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')
331
332
self.assertRaises(ValueError, transform.fixup_new_roots)
333
334
def test_fixup_new_roots_permits_empty_tree(self):
375
376
transform, root = self.get_transform()
376
377
self.wt.lock_tree_write()
377
378
self.addCleanup(self.wt.unlock)
378
trans_id = transform.new_file('name', root, [b'contents'],
379
b'my_pretties', True)
379
transform.new_file('name', root, [b'contents'], b'my_pretties', True)
380
380
oz = transform.new_directory('oz', root, b'oz-id')
381
381
dorothy = transform.new_directory('dorothy', oz, b'dorothy-id')
382
toto = transform.new_file('toto', dorothy, [b'toto-contents'],
382
transform.new_file('toto', dorothy, [b'toto-contents'], b'toto-id',
385
385
self.assertEqual(len(transform.find_conflicts()), 0)
386
386
transform.apply()
405
405
transform.apply()
407
407
self.addCleanup(tree.unlock)
408
self.assertEqual(b'subtree-revision',
409
tree.root_inventory.get_entry(b'subtree-id').reference_revision)
410
tree.root_inventory.get_entry(b'subtree-id').reference_revision)
411
412
def test_conflicts(self):
412
413
transform, root = self.get_transform()
769
770
def _test_symlinks(self, link_name1, link_target1,
770
771
link_name2, link_target2):
772
def ozpath(p): return 'oz/' + p
774
776
self.requireFeature(SymlinkFeature)
775
777
transform, root = self.get_transform()
776
778
oz_id = transform.new_directory('oz', root, b'oz-id')
777
wizard = transform.new_symlink(link_name1, oz_id, link_target1,
779
transform.new_symlink(link_name1, oz_id, link_target1, b'wizard-id')
779
780
wiz_id = transform.create_path(link_name2, oz_id)
780
781
transform.create_symlink(link_target2, wiz_id)
781
782
transform.version_file(b'wiz-id2', wiz_id)
878
879
unversioned_parent2 = UnversionedParent('Versioned directory', 'oz',
880
881
self.assertEqual(cooked_conflicts[3], unversioned_parent)
881
parent_loop = ParentLoop('Cancelled move', 'oz/emeraldcity',
882
'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')
883
885
self.assertEqual(cooked_conflicts[4], deleted_parent)
884
886
self.assertEqual(cooked_conflicts[5], unversioned_parent2)
885
887
self.assertEqual(cooked_conflicts[6], parent_loop)
904
906
self.assertEqual(conflicts_s[3], 'Conflict because munchkincity is not'
905
907
' versioned, but has versioned'
906
908
' children. Versioned directory.')
907
self.assertEqualDiff(conflicts_s[4], "Conflict: can't delete oz because it"
908
" 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.")
909
912
self.assertEqual(conflicts_s[5], 'Conflict because oz is not'
910
913
' versioned, but has versioned'
911
914
' children. Versioned directory.')
1024
1027
self.requireFeature(features.not_running_as_root)
1025
1028
# see https://bugs.launchpad.net/bzr/+bug/491763
1026
1029
create, root_id = self.get_transform()
1027
first_dir = create.new_directory('first-dir', root_id, b'first-id')
1028
myfile = create.new_file('myfile', root_id, [b'myfile-text'],
1030
create.new_directory('first-dir', root_id, b'first-id')
1031
create.new_file('myfile', root_id, [b'myfile-text'], b'myfile-id')
1031
1033
if os.name == "posix" and sys.platform != "cygwin":
1032
1034
# posix filesystems fail on renaming if the readonly bit is set
1071
1074
wt = transform._tree
1073
1076
self.addCleanup(wt.unlock)
1074
transform.new_file('set_on_creation', root, [b'Set on creation'], b'soc',
1077
transform.new_file('set_on_creation', root, [b'Set on creation'],
1076
1079
sac = transform.new_file('set_after_creation', root,
1077
1080
[b'Set after creation'], b'sac')
1078
1081
transform.set_executability(True, sac)
1143
1146
old = transform.trans_id_tree_path('old')
1144
1147
transform.unversion_file(old)
1145
1148
self.assertEqual([(b'id-1', ('old', None), False, (True, False),
1146
(b'eert_toor', b'eert_toor'), ('old',
1147
'old'), ('file', 'file'),
1149
(b'eert_toor', b'eert_toor'),
1150
('old', 'old'), ('file', 'file'),
1148
1151
(True, True))], list(transform.iter_changes()))
1149
1152
transform.new_directory('new', root, b'id-1')
1150
1153
self.assertEqual([(b'id-1', ('old', 'new'), True, (True, True),
1164
1167
old = transform.trans_id_tree_path('old')
1165
1168
transform.version_file(b'id-1', old)
1166
1169
self.assertEqual([(b'id-1', (None, 'old'), False, (False, True),
1167
(b'eert_toor', b'eert_toor'), ('old',
1168
'old'), ('file', 'file'),
1169
(False, False))], list(transform.iter_changes()))
1170
(b'eert_toor', b'eert_toor'),
1171
('old', 'old'), ('file', 'file'),
1173
list(transform.iter_changes()))
1171
1175
transform.finalize()
1187
1191
# content deletion
1188
1192
transform.delete_contents(old)
1189
1193
self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
1190
(b'eert_toor', b'eert_toor'), ('old',
1191
'old'), ('file', None),
1192
(False, False))], list(transform.iter_changes()))
1194
(b'eert_toor', b'eert_toor'),
1195
('old', 'old'), ('file', None),
1197
list(transform.iter_changes()))
1194
1199
# content change
1195
1200
transform.create_file([b'blah'], old)
1196
1201
self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
1197
(b'eert_toor', b'eert_toor'), ('old',
1198
'old'), ('file', 'file'),
1199
(False, False))], list(transform.iter_changes()))
1202
(b'eert_toor', b'eert_toor'),
1203
('old', 'old'), ('file', 'file'),
1205
list(transform.iter_changes()))
1200
1206
transform.cancel_deletion(old)
1201
1207
self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
1202
(b'eert_toor', b'eert_toor'), ('old',
1203
'old'), ('file', 'file'),
1204
(False, False))], list(transform.iter_changes()))
1208
(b'eert_toor', b'eert_toor'),
1209
('old', 'old'), ('file', 'file'),
1211
list(transform.iter_changes()))
1205
1212
transform.cancel_creation(old)
1207
1214
# move file_id to a different file
1210
1217
transform.version_file(b'id-1', new)
1211
1218
transform.adjust_path('old', root, new)
1212
1219
self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
1213
(b'eert_toor', b'eert_toor'), ('old',
1214
'old'), ('file', 'file'),
1215
(False, False))], list(transform.iter_changes()))
1220
(b'eert_toor', b'eert_toor'),
1221
('old', 'old'), ('file', 'file'),
1223
list(transform.iter_changes()))
1216
1224
transform.cancel_versioning(new)
1217
1225
transform._removed_id = set()
1220
1228
self.assertEqual([], list(transform.iter_changes()))
1221
1229
transform.set_executability(True, old)
1222
1230
self.assertEqual([(b'id-1', ('old', 'old'), False, (True, True),
1223
(b'eert_toor', b'eert_toor'), ('old',
1224
'old'), ('file', 'file'),
1225
(False, True))], list(transform.iter_changes()))
1231
(b'eert_toor', b'eert_toor'),
1232
('old', 'old'), ('file', 'file'),
1234
list(transform.iter_changes()))
1226
1235
transform.set_executability(None, old)
1230
1239
transform.adjust_path('new', root, old)
1231
1240
transform._new_parent = {}
1232
1241
self.assertEqual([(b'id-1', ('old', 'new'), False, (True, True),
1233
(b'eert_toor', b'eert_toor'), ('old',
1234
'new'), ('file', 'file'),
1235
(False, False))], list(transform.iter_changes()))
1242
(b'eert_toor', b'eert_toor'),
1243
('old', 'new'), ('file', 'file'),
1245
list(transform.iter_changes()))
1236
1246
transform._new_name = {}
1238
1248
# parent directory
1265
1275
transform.delete_contents(transform.trans_id_file_id(b'id-1'))
1266
1276
transform.set_executability(True,
1267
1277
transform.trans_id_file_id(b'id-2'))
1268
self.assertEqual([(b'id-1', (u'file1', u'file1'), True, (True, True),
1269
(b'eert_toor', b'eert_toor'), ('file1', u'file1'),
1270
('file', None), (False, False)),
1271
(b'id-2', (u'file2', u'file2'), False, (True, True),
1272
(b'eert_toor', b'eert_toor'), ('file2', u'file2'),
1273
('file', 'file'), (False, True))],
1274
list(transform.iter_changes()))
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))],
1285
list(transform.iter_changes()))
1276
1287
transform.finalize()
1291
1302
transform.adjust_path('flitter', root, floater)
1292
1303
self.assertEqual([(b'floater-id', ('floater', 'flitter'), False,
1293
(True, True), (b'toor_eert',
1294
b'toor_eert'), ('floater', 'flitter'),
1295
(None, None), (False, False))], list(transform.iter_changes()))
1305
(b'toor_eert', b'toor_eert'),
1306
('floater', 'flitter'),
1307
(None, None), (False, False))],
1308
list(transform.iter_changes()))
1297
1310
transform.finalize()
1419
1432
transform.create_directory(parent)
1420
1433
except KeyError:
1421
1434
self.fail("Can't handle contents with no name")
1422
child = transform.new_directory('child', parent)
1435
transform.new_directory('child', parent)
1423
1436
transform.adjust_path('parent', root, parent)
1424
1437
transform.apply()
1425
1438
self.assertPathExists(self.wt.abspath('parent/child'))
1429
1442
"""Avoid reusing the same limbo name for different files"""
1430
1443
transform, root = self.get_transform()
1431
1444
parent = transform.new_directory('parent', root)
1432
child1 = transform.new_directory('child', parent)
1445
transform.new_directory('child', parent)
1434
1447
child2 = transform.new_directory('child', parent)
1435
1448
except OSError:
1449
1462
parent = transform.new_directory('parent', root)
1450
1463
child1 = transform.new_directory('child', parent)
1451
1464
transform.adjust_path('child1', parent, child1)
1452
child2 = transform.new_directory('child', parent)
1465
transform.new_directory('child', parent)
1453
1466
transform.apply()
1454
1467
# limbo/new-1 => parent
1455
1468
self.assertEqual(1, transform.rename_count)
1461
1474
child1 = transform.new_directory('child1', parent2)
1462
1475
transform.cancel_creation(parent2)
1463
1476
transform.create_directory(parent2)
1464
child2 = transform.new_directory('child1', parent2)
1477
transform.new_directory('child1', parent2)
1465
1478
transform.adjust_path('child2', parent2, child1)
1466
1479
transform.apply()
1467
1480
# limbo/new-1 => parent2, limbo/new-2 => parent2/child1
1471
1484
"""Finalize must be done in child-to-parent order"""
1472
1485
transform, root = self.get_transform()
1473
1486
parent = transform.new_directory('parent', root)
1474
child = transform.new_directory('child', parent)
1487
transform.new_directory('child', parent)
1476
1489
transform.finalize()
1477
1490
except OSError:
1713
1726
with TransformPreview(tree) as tt:
1714
1727
tt.unversion_file(tt.root)
1715
1728
tt.version_file(tree.get_root_id(), tt.root)
1716
foo_trans_id = tt.trans_id_tree_path('foo')
1729
tt.trans_id_tree_path('foo')
1717
1730
self.assertEqual([], tt._inventory_altered())
1949
1962
source.add('file', b'new-file')
1950
1963
source.commit('added file')
1951
1964
build_tree(source.basis_tree(), target)
1952
self.assertEqual([DuplicateEntry('Moved existing file to',
1953
'file.moved', 'file', None, 'new-file')],
1966
[DuplicateEntry('Moved existing file to', 'file.moved',
1967
'file', None, 'new-file')],
1955
1969
target2 = self.make_branch_and_tree('target2')
1956
1970
with open('target2/file', 'wb') as target_file, \
1957
1971
open('source/file', 'rb') as source_file:
1969
1983
target = self.make_branch_and_tree('target')
1970
1984
os.symlink('bar', 'target/symlink')
1971
1985
build_tree(source.basis_tree(), target)
1972
self.assertEqual([DuplicateEntry('Moved existing file to',
1973
'symlink.moved', 'symlink', None, 'new-symlink')],
1987
[DuplicateEntry('Moved existing file to', 'symlink.moved',
1988
'symlink', None, 'new-symlink')],
1975
1990
target = self.make_branch_and_tree('target2')
1976
1991
os.symlink('foo', 'target2/symlink')
1977
1992
build_tree(source.basis_tree(), target)
2004
2019
self.assertPathDoesNotExist('target3/dir1/file')
2005
2020
self.assertPathExists('target3/dir1/file2')
2006
2021
self.assertPathExists('target3/dir1.diverted/file')
2007
self.assertEqual([DuplicateEntry('Diverted to',
2008
'dir1.diverted', 'dir1', 'new-dir1', None)],
2023
[DuplicateEntry('Diverted to', 'dir1.diverted',
2024
'dir1', 'new-dir1', None)],
2011
2027
target = self.make_branch_and_tree('target4')
2012
2028
self.build_tree(['target4/dir1/'])
2015
2031
self.assertPathExists('target4/dir1/file')
2016
2032
self.assertEqual('directory', file_kind('target4/dir1/file'))
2017
2033
self.assertPathExists('target4/dir1/file.diverted')
2018
self.assertEqual([DuplicateEntry('Diverted to',
2019
'dir1/file.diverted', 'dir1/file', 'new-file', None)],
2035
[DuplicateEntry('Diverted to', 'dir1/file.diverted',
2036
'dir1/file', 'new-file', None)],
2022
2039
def test_mixed_conflict_handling(self):
2023
2040
"""Ensure that when building trees, conflict handling is done"""
2027
2044
source.add('name', b'new-name')
2028
2045
source.commit('added file')
2029
2046
build_tree(source.basis_tree(), target)
2030
self.assertEqual([DuplicateEntry('Moved existing file to',
2031
'name.moved', 'name', None, 'new-name')], target.conflicts())
2048
[DuplicateEntry('Moved existing file to',
2049
'name.moved', 'name', None, 'new-name')],
2033
2052
def test_raises_in_populated(self):
2034
2053
source = self.make_branch_and_tree('source')
2214
2233
self.addCleanup(restore_registry)
2216
2235
def rot13(chunks, context=None):
2217
return [codecs.encode(chunk.decode('ascii'), 'rot13').encode('ascii')
2218
for chunk in chunks]
2237
codecs.encode(chunk.decode('ascii'), 'rot13').encode('ascii')
2238
for chunk in chunks]
2219
2239
rot13filter = filters.ContentFilter(rot13, rot13)
2220
2240
filters.filter_stacks_registry.register(
2221
2241
'rot13', {'yes': [rot13filter]}.get)
2342
2362
def test_merge_parents(self):
2343
2363
branch, tt = self.get_branch_and_transform()
2344
rev = tt.commit(branch, 'my message', [b'rev1b', b'rev1c'])
2364
tt.commit(branch, 'my message', [b'rev1b', b'rev1c'])
2345
2365
self.assertEqual([b'rev1b', b'rev1c'],
2346
2366
branch.basis_tree().get_parent_ids()[1:])
2352
2372
tt = TransformPreview(branch.basis_tree())
2353
2373
self.addCleanup(tt.finalize)
2354
2374
tt.new_directory('', ROOT_PARENT, b'TREE_ROOT')
2355
rev = tt.commit(branch, 'my message')
2375
tt.commit(branch, 'my message')
2356
2376
self.assertEqual([], branch.basis_tree().get_parent_ids())
2357
2377
self.assertNotEqual(_mod_revision.NULL_REVISION,
2358
2378
branch.last_revision())
2375
2395
trans_id = tt.new_directory('dir', tt.root, b'dir-id')
2376
2396
if SymlinkFeature.available():
2377
2397
tt.new_symlink('symlink', trans_id, 'target', b'symlink-id')
2378
rev = tt.commit(branch, 'message')
2398
tt.commit(branch, 'message')
2379
2399
tree = branch.basis_tree()
2380
2400
self.assertEqual('file', tree.id2path(b'file-id'))
2381
2401
self.assertEqual(b'contents', tree.get_file_text('file', b'file-id'))
2613
2633
def test_root_create_file_open_raises_before_creation(self):
2614
2634
tt, trans_id = self.create_transform_and_root_trans_id()
2615
self._override_globals_in_method(tt, "create_file",
2616
{"open": self._fake_open_raises_before})
2635
self._override_globals_in_method(
2636
tt, "create_file", {"open": self._fake_open_raises_before})
2617
2637
self.assertRaises(RuntimeError, tt.create_file,
2618
2638
[b"contents"], trans_id)
2619
2639
path = tt._limbo_name(trans_id)
2624
2644
def test_root_create_file_open_raises_after_creation(self):
2625
2645
tt, trans_id = self.create_transform_and_root_trans_id()
2626
self._override_globals_in_method(tt, "create_file",
2627
{"open": self._fake_open_raises_after})
2646
self._override_globals_in_method(
2647
tt, "create_file", {"open": self._fake_open_raises_after})
2628
2648
self.assertRaises(RuntimeError, tt.create_file,
2629
2649
[b"contents"], trans_id)
2630
2650
path = tt._limbo_name(trans_id)
2636
2656
def test_subdir_create_file_open_raises_before_creation(self):
2637
2657
tt, trans_id = self.create_transform_and_subdir_trans_id()
2638
self._override_globals_in_method(tt, "create_file",
2639
{"open": self._fake_open_raises_before})
2658
self._override_globals_in_method(
2659
tt, "create_file", {"open": self._fake_open_raises_before})
2640
2660
self.assertRaises(RuntimeError, tt.create_file,
2641
2661
[b"contents"], trans_id)
2642
2662
path = tt._limbo_name(trans_id)
2647
2667
def test_subdir_create_file_open_raises_after_creation(self):
2648
2668
tt, trans_id = self.create_transform_and_subdir_trans_id()
2649
self._override_globals_in_method(tt, "create_file",
2650
{"open": self._fake_open_raises_after})
2669
self._override_globals_in_method(
2670
tt, "create_file", {"open": self._fake_open_raises_after})
2651
2671
self.assertRaises(RuntimeError, tt.create_file,
2652
2672
[b"contents"], trans_id)
2653
2673
path = tt._limbo_name(trans_id)
2710
2730
def test_resolve_create_parent_for_versioned_file(self):
2711
2731
wt, tt = self.make_tt_with_versioned_dir()
2712
2732
dir_tid = tt.trans_id_tree_path('dir')
2713
file_tid = tt.new_file(
2714
'file', dir_tid, [b'Contents'], file_id=b'file-id')
2733
tt.new_file('file', dir_tid, [b'Contents'], file_id=b'file-id')
2715
2734
tt.delete_contents(dir_tid)
2716
2735
tt.unversion_file(dir_tid)
2717
2736
conflicts = resolve_conflicts(tt)
2821
2840
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2822
2841
changes = preview_tree.iter_changes(revision_tree,
2823
2842
include_unchanged=True)
2824
root = revision_tree.get_root_id()
2826
2843
self.assertEqual([ROOT_ENTRY, A_ENTRY], list(changes))
2828
2845
def test_specific_files(self):
2881
2898
file_trans_id = preview.trans_id_tree_path('file')
2882
2899
preview.adjust_path('renamed', preview.root, file_trans_id)
2883
2900
preview_tree = preview.get_preview_tree()
2884
preview_mtime = preview_tree.get_file_mtime('renamed', b'file-id')
2885
work_mtime = work_tree.get_file_mtime('file', b'file-id')
2901
preview_tree.get_file_mtime('renamed', b'file-id')
2902
work_tree.get_file_mtime('file', b'file-id')
2887
2904
def test_get_file_size(self):
2888
2905
work_tree = self.make_branch_and_tree('tree')
2890
2907
work_tree.add('old', b'old-id')
2891
2908
preview = TransformPreview(work_tree)
2892
2909
self.addCleanup(preview.finalize)
2893
new_id = preview.new_file('name', preview.root, [b'contents'], b'new-id',
2910
preview.new_file('name', preview.root, [b'contents'], b'new-id',
2895
2912
tree = preview.get_preview_tree()
2896
2913
self.assertEqual(len('old'), tree.get_file_size('old'))
2897
2914
self.assertEqual(len('contents'), tree.get_file_size('name'))
3233
3250
def test_walkdirs(self):
3234
3251
preview = self.get_empty_preview()
3235
root = preview.new_directory('', ROOT_PARENT, b'tree-root')
3252
preview.new_directory('', ROOT_PARENT, b'tree-root')
3236
3253
# FIXME: new_directory should mark root.
3237
3254
preview.fixup_new_roots()
3238
3255
preview_tree = preview.get_preview_tree()
3239
file_trans_id = preview.new_file('a', preview.root, [b'contents'],
3256
preview.new_file('a', preview.root, [b'contents'], b'a-id')
3241
3257
expected = [(('', b'tree-root'),
3242
3258
[('a', 'a', 'file', None, b'a-id', 'file')])]
3243
3259
self.assertEqual(expected, list(preview_tree.walkdirs()))
3628
3644
def test_get_parents_lines(self):
3629
3645
LINES_ONE = b'aa\nbb\ncc\ndd\n'
3630
LINES_TWO = b'z\nbb\nx\ndd\n'
3631
3646
tree = self.make_branch_and_tree('tree')
3632
3647
self.build_tree_contents([('tree/file', LINES_ONE)])
3633
3648
tree.add('file', b'file-id')
3639
3654
def test_get_parents_texts(self):
3640
3655
LINES_ONE = b'aa\nbb\ncc\ndd\n'
3641
LINES_TWO = b'z\nbb\nx\ndd\n'
3642
3656
tree = self.make_branch_and_tree('tree')
3643
3657
self.build_tree_contents([('tree/file', LINES_ONE)])
3644
3658
tree.add('file', b'file-id')
3759
3773
def record_pre_transform(tree, tt):
3760
3774
calls.append((tree, tt))
3761
MutableTree.hooks.install_named_hook('pre_transform',
3762
record_pre_transform, "Pre transform")
3775
MutableTree.hooks.install_named_hook(
3776
'pre_transform', record_pre_transform, "Pre transform")
3763
3777
transform, root = self.get_transform()
3764
3778
old_root_id = transform.tree_file_id(root)
3765
3779
transform.apply()
3772
3786
def record_post_transform(tree, tt):
3773
3787
calls.append((tree, tt))
3774
MutableTree.hooks.install_named_hook('post_transform',
3775
record_post_transform, "Post transform")
3788
MutableTree.hooks.install_named_hook(
3789
'post_transform', record_post_transform, "Post transform")
3776
3790
transform, root = self.get_transform()
3777
3791
old_root_id = transform.tree_file_id(root)
3778
3792
transform.apply()