62
62
from bzrlib.merge import Merge3Merger, Merger
63
from bzrlib.mutabletree import MutableTree
63
64
from bzrlib.tests import (
69
from bzrlib.tests.features import (
70
73
from bzrlib.transform import (
87
90
super(TestTreeTransform, self).setUp()
88
self.wt = self.make_branch_and_tree('.', format='dirstate-with-subtree')
91
self.wt = self.make_branch_and_tree('.', format='development-subtree')
91
94
def get_transform(self):
285
288
new_trans_id = transform.new_directory('', ROOT_PARENT, 'alt-root-id')
286
289
self.assertRaises(ValueError, transform.fixup_new_roots)
291
def test_retain_existing_root(self):
292
tt, root = self.get_transform()
294
tt.new_directory('', ROOT_PARENT, 'new-root-id')
296
self.assertNotEqual('new-root-id', tt.final_file_id(tt.root))
298
def test_retain_existing_root_added_file(self):
299
tt, root = self.get_transform()
300
new_trans_id = tt.new_directory('', ROOT_PARENT, 'new-root-id')
301
child = tt.new_directory('child', new_trans_id, 'child-id')
303
self.assertEqual(tt.root, tt.final_parent(child))
288
305
def test_add_unversioned_root(self):
289
306
transform, root = self.get_transform()
290
307
new_trans_id = transform.new_directory('', ROOT_PARENT, None)
308
transform.delete_contents(transform.root)
291
309
transform.fixup_new_roots()
292
310
self.assertNotIn(transform.root, transform._new_id)
306
324
new_trans_id = transform.new_directory('', ROOT_PARENT, 'alt-root-id')
307
325
self.assertRaises(ValueError, transform.fixup_new_roots)
327
def test_fixup_new_roots_permits_empty_tree(self):
328
transform, root = self.get_transform()
329
transform.delete_contents(root)
330
transform.unversion_file(root)
331
transform.fixup_new_roots()
332
self.assertIs(None, transform.final_kind(root))
333
self.assertIs(None, transform.final_file_id(root))
309
335
def test_apply_retains_root_directory(self):
310
336
# Do not attempt to delete the physical root directory, because that
318
344
self.assertContainsRe('TransformRenameFailed not raised', str(e))
346
def test_apply_retains_file_id(self):
347
transform, root = self.get_transform()
348
old_root_id = transform.tree_file_id(root)
349
transform.unversion_file(root)
351
self.assertEqual(old_root_id, self.wt.get_root_id())
320
353
def test_hardlink(self):
321
354
self.requireFeature(HardlinkFeature)
322
355
transform, root = self.get_transform()
367
400
self.addCleanup(tree.unlock)
368
401
self.assertEqual('subtree-revision',
369
tree.inventory['subtree-id'].reference_revision)
402
tree.root_inventory['subtree-id'].reference_revision)
371
404
def test_conflicts(self):
372
405
transform, root = self.get_transform()
749
782
'wizard2', 'behind_curtain')
751
784
def test_symlinks_unicode(self):
752
self.requireFeature(tests.UnicodeFilenameFeature)
785
self.requireFeature(features.UnicodeFilenameFeature)
753
786
self._test_symlinks(u'\N{Euro Sign}wizard',
754
787
u'wizard-targ\N{Euro Sign}t',
755
788
u'\N{Euro Sign}wizard2',
1444
1477
# The rename will fail because the target directory is not empty (but
1445
1478
# raises FileExists anyway).
1446
1479
err = self.assertRaises(errors.FileExists, tt_helper)
1447
self.assertContainsRe(str(err),
1448
"^File exists: .+/baz")
1480
self.assertEndsWith(err.path, "/baz")
1450
1482
def test_two_directories_clash(self):
1451
1483
def tt_helper():
1465
1497
err = self.assertRaises(errors.FileExists, tt_helper)
1466
self.assertContainsRe(str(err),
1467
"^File exists: .+/foo")
1498
self.assertEndsWith(err.path, "/foo")
1469
1500
def test_two_directories_clash_finalize(self):
1470
1501
def tt_helper():
1484
1515
err = self.assertRaises(errors.FileExists, tt_helper)
1485
self.assertContainsRe(str(err),
1486
"^File exists: .+/foo")
1516
self.assertEndsWith(err.path, "/foo")
1488
1518
def test_file_to_directory(self):
1489
1519
wt = self.make_branch_and_tree('.')
1525
1554
self.assertPathExists("foo")
1527
1556
self.addCleanup(wt.unlock)
1528
self.assertEqual(wt.inventory.get_file_kind(wt.path2id("foo")),
1557
self.assertEqual(wt.kind(wt.path2id("foo")), "symlink")
1531
1559
def test_dir_to_file(self):
1532
1560
wt = self.make_branch_and_tree('.')
1544
1572
self.assertPathExists("foo")
1546
1574
self.addCleanup(wt.unlock)
1547
self.assertEqual(wt.inventory.get_file_kind(wt.path2id("foo")),
1575
self.assertEqual(wt.kind(wt.path2id("foo")), "file")
1550
1577
def test_dir_to_hardlink(self):
1551
1578
self.requireFeature(HardlinkFeature)
1566
1593
self.assertPathExists("baz")
1568
1595
self.addCleanup(wt.unlock)
1569
self.assertEqual(wt.inventory.get_file_kind(wt.path2id("foo")),
1596
self.assertEqual(wt.kind(wt.path2id("foo")), "file")
1572
1598
def test_no_final_path(self):
1573
1599
transform, root = self.get_transform()
1619
1645
def __init__(self, dirname, root_id):
1620
1646
self.name = dirname
1621
1647
os.mkdir(dirname)
1622
self.wt = BzrDir.create_standalone_workingtree(dirname)
1648
self.wt = ControlDir.create_standalone_workingtree(dirname)
1623
1649
self.wt.set_root_id(root_id)
1624
1650
self.b = self.wt.branch
1625
1651
self.tt = TreeTransform(self.wt)
1735
1761
merge_modified = this.wt.merge_modified()
1736
1762
self.assertSubset(merge_modified, modified)
1737
1763
self.assertEqual(len(merge_modified), len(modified))
1738
file(this.wt.id2abspath('a'), 'wb').write('booga')
1764
with file(this.wt.id2abspath('a'), 'wb') as f: f.write('booga')
1739
1765
modified.pop(0)
1740
1766
merge_modified = this.wt.merge_modified()
1741
1767
self.assertSubset(merge_modified, modified)
1855
1881
def test_build_tree_with_symlinks(self):
1856
1882
self.requireFeature(SymlinkFeature)
1858
a = BzrDir.create_standalone_workingtree('a')
1884
a = ControlDir.create_standalone_workingtree('a')
1859
1885
os.mkdir('a/foo')
1860
file('a/foo/bar', 'wb').write('contents')
1886
with file('a/foo/bar', 'wb') as f: f.write('contents')
1861
1887
os.symlink('a/foo/bar', 'a/foo/baz')
1862
1888
a.add(['foo', 'foo/bar', 'foo/baz'])
1863
1889
a.commit('initial commit')
1864
b = BzrDir.create_standalone_workingtree('b')
1890
b = ControlDir.create_standalone_workingtree('b')
1865
1891
basis = a.basis_tree()
1866
1892
basis.lock_read()
1867
1893
self.addCleanup(basis.unlock)
1873
1899
def test_build_with_references(self):
1874
1900
tree = self.make_branch_and_tree('source',
1875
format='dirstate-with-subtree')
1901
format='development-subtree')
1876
1902
subtree = self.make_branch_and_tree('source/subtree',
1877
format='dirstate-with-subtree')
1903
format='development-subtree')
1878
1904
tree.add_reference(subtree)
1879
1905
tree.commit('a revision')
1880
1906
tree.branch.create_checkout('target')
2158
2184
def rot13(chunks, context=None):
2159
2185
return [''.join(chunks).encode('rot13')]
2160
2186
rot13filter = filters.ContentFilter(rot13, rot13)
2161
filters.register_filter_stack_map('rot13', {'yes': [rot13filter]}.get)
2187
filters.filter_stacks_registry.register(
2188
'rot13', {'yes': [rot13filter]}.get)
2162
2189
os.mkdir(self.test_home_dir + '/.bazaar')
2163
2190
rules_filename = self.test_home_dir + '/.bazaar/rules'
2164
2191
f = open(rules_filename, 'wb')
2194
2221
self.assertEqualStat(source_stat, target_stat)
2196
2223
def test_case_insensitive_build_tree_inventory(self):
2197
if (tests.CaseInsensitiveFilesystemFeature.available()
2198
or tests.CaseInsCasePresFilenameFeature.available()):
2224
if (features.CaseInsensitiveFilesystemFeature.available()
2225
or features.CaseInsCasePresFilenameFeature.available()):
2199
2226
raise tests.UnavailableFeature('Fully case sensitive filesystem')
2200
2227
source = self.make_branch_and_tree('source')
2201
2228
self.build_tree(['source/file', 'source/FILE'])
2384
2411
self.assertEqual('tree', revision.properties['branch-nick'])
2387
class TestBackupName(tests.TestCase):
2389
def test_deprecations(self):
2390
class MockTransform(object):
2392
def has_named_child(self, by_parent, parent_id, name):
2393
return name in by_parent.get(parent_id, [])
2395
class MockEntry(object):
2398
object.__init__(self)
2401
tt = MockTransform()
2402
name1 = self.applyDeprecated(
2403
symbol_versioning.deprecated_in((2, 3, 0)),
2404
transform.get_backup_name, MockEntry(), {'a':[]}, 'a', tt)
2405
self.assertEqual('name.~1~', name1)
2406
name2 = self.applyDeprecated(
2407
symbol_versioning.deprecated_in((2, 3, 0)),
2408
transform._get_backup_name, 'name', {'a':['name.~1~']}, 'a', tt)
2409
self.assertEqual('name.~2~', name2)
2412
2414
class TestFileMover(tests.TestCaseWithTransport):
2414
2416
def test_file_mover(self):
2767
2769
def test_iter_changes(self):
2768
2770
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2769
root = revision_tree.inventory.root.file_id
2771
root = revision_tree.get_root_id()
2770
2772
self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
2771
2773
(root, root), ('a', 'a'), ('file', 'file'),
2772
2774
(False, False))],
2776
2778
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2777
2779
changes = preview_tree.iter_changes(revision_tree,
2778
2780
include_unchanged=True)
2779
root = revision_tree.inventory.root.file_id
2781
root = revision_tree.get_root_id()
2781
2783
self.assertEqual([ROOT_ENTRY, A_ENTRY], list(changes))
3314
3316
self.assertEqual('contents', rev2_tree.get_file_text('file_id'))
3316
3318
def test_ascii_limbo_paths(self):
3317
self.requireFeature(tests.UnicodeFilenameFeature)
3319
self.requireFeature(features.UnicodeFilenameFeature)
3318
3320
branch = self.make_branch('any')
3319
3321
tree = branch.repository.revision_tree(_mod_revision.NULL_REVISION)
3320
3322
tt = TransformPreview(tree)
3338
3340
class TestSerializeTransform(tests.TestCaseWithTransport):
3340
_test_needs_features = [tests.UnicodeFilenameFeature]
3342
_test_needs_features = [features.UnicodeFilenameFeature]
3342
3344
def get_preview(self, tree=None):
3343
3345
if tree is None:
3418
3420
return self.make_records(attribs, contents)
3420
3422
def test_serialize_symlink_creation(self):
3421
self.requireFeature(tests.SymlinkFeature)
3423
self.requireFeature(features.SymlinkFeature)
3422
3424
tt = self.get_preview()
3423
3425
tt.new_symlink(u'foo\u1234', tt.root, u'bar\u1234')
3424
3426
self.assertSerializesTo(self.symlink_creation_records(), tt)
3426
3428
def test_deserialize_symlink_creation(self):
3427
self.requireFeature(tests.SymlinkFeature)
3429
self.requireFeature(features.SymlinkFeature)
3428
3430
tt = self.get_preview()
3429
3431
tt.deserialize(iter(self.symlink_creation_records()))
3430
3432
abspath = tt._limbo_name('new-1')
3608
3610
self.assertRaises(NotImplementedError, tt.new_orphan, 'foo', 'bar')
3610
3612
def _set_orphan_policy(self, wt, policy):
3611
wt.branch.get_config().set_user_option('bzr.transform.orphan_policy',
3613
wt.branch.get_config_stack().set('bzr.transform.orphan_policy',
3614
3616
def _prepare_orphan(self, wt):
3687
3689
self.assertEqual(('deleting parent', 'Not deleting', 'new-1'),
3688
3690
remaining_conflicts.pop())
3689
3691
self.assertLength(1, warnings)
3690
self.assertStartsWith(warnings[0], 'donttouchmypreciouuus')
3692
self.assertStartsWith(warnings[0], 'Value "donttouchmypreciouuus" ')
3695
class TestTransformHooks(tests.TestCaseWithTransport):
3698
super(TestTransformHooks, self).setUp()
3699
self.wt = self.make_branch_and_tree('.')
3702
def get_transform(self):
3703
transform = TreeTransform(self.wt)
3704
self.addCleanup(transform.finalize)
3705
return transform, transform.root
3707
def test_pre_commit_hooks(self):
3709
def record_pre_transform(tree, tt):
3710
calls.append((tree, tt))
3711
MutableTree.hooks.install_named_hook('pre_transform',
3712
record_pre_transform, "Pre transform")
3713
transform, root = self.get_transform()
3714
old_root_id = transform.tree_file_id(root)
3716
self.assertEqual(old_root_id, self.wt.get_root_id())
3717
self.assertEquals([(self.wt, transform)], calls)
3719
def test_post_commit_hooks(self):
3721
def record_post_transform(tree, tt):
3722
calls.append((tree, tt))
3723
MutableTree.hooks.install_named_hook('post_transform',
3724
record_post_transform, "Post transform")
3725
transform, root = self.get_transform()
3726
old_root_id = transform.tree_file_id(root)
3728
self.assertEqual(old_root_id, self.wt.get_root_id())
3729
self.assertEquals([(self.wt, transform)], calls)