260
228
transform3.adjust_path('tip', root_id, tip_id)
261
229
transform3.apply()
263
def test_conflict_on_case_insensitive(self):
264
tree = self.make_branch_and_tree('tree')
265
# Don't try this at home, kids!
266
# Force the tree to report that it is case sensitive, for conflict
268
tree.case_sensitive = True
269
transform = TreeTransform(tree)
270
self.addCleanup(transform.finalize)
271
transform.new_file('file', transform.root, 'content')
272
transform.new_file('FiLe', transform.root, 'content')
273
result = transform.find_conflicts()
274
self.assertEqual([], result)
276
# Force the tree to report that it is case insensitive, for conflict
278
tree.case_sensitive = False
279
transform = TreeTransform(tree)
280
self.addCleanup(transform.finalize)
281
transform.new_file('file', transform.root, 'content')
282
transform.new_file('FiLe', transform.root, 'content')
283
result = transform.find_conflicts()
284
self.assertEqual([('duplicate', 'new-1', 'new-2', 'file')], result)
286
def test_conflict_on_case_insensitive_existing(self):
287
tree = self.make_branch_and_tree('tree')
288
self.build_tree(['tree/FiLe'])
289
# Don't try this at home, kids!
290
# Force the tree to report that it is case sensitive, for conflict
292
tree.case_sensitive = True
293
transform = TreeTransform(tree)
294
self.addCleanup(transform.finalize)
295
transform.new_file('file', transform.root, 'content')
296
result = transform.find_conflicts()
297
self.assertEqual([], result)
299
# Force the tree to report that it is case insensitive, for conflict
301
tree.case_sensitive = False
302
transform = TreeTransform(tree)
303
self.addCleanup(transform.finalize)
304
transform.new_file('file', transform.root, 'content')
305
result = transform.find_conflicts()
306
self.assertEqual([('duplicate', 'new-1', 'new-2', 'file')], result)
308
def test_resolve_case_insensitive_conflict(self):
309
tree = self.make_branch_and_tree('tree')
310
# Don't try this at home, kids!
311
# Force the tree to report that it is case insensitive, for conflict
313
tree.case_sensitive = False
314
transform = TreeTransform(tree)
315
self.addCleanup(transform.finalize)
316
transform.new_file('file', transform.root, 'content')
317
transform.new_file('FiLe', transform.root, 'content')
318
resolve_conflicts(transform)
320
self.failUnlessExists('tree/file')
321
self.failUnlessExists('tree/FiLe.moved')
323
def test_resolve_checkout_case_conflict(self):
324
tree = self.make_branch_and_tree('tree')
325
# Don't try this at home, kids!
326
# Force the tree to report that it is case insensitive, for conflict
328
tree.case_sensitive = False
329
transform = TreeTransform(tree)
330
self.addCleanup(transform.finalize)
331
transform.new_file('file', transform.root, 'content')
332
transform.new_file('FiLe', transform.root, 'content')
333
resolve_conflicts(transform,
334
pass_func=lambda t, c: resolve_checkout(t, c, []))
336
self.failUnlessExists('tree/file')
337
self.failUnlessExists('tree/FiLe.moved')
339
def test_apply_case_conflict(self):
340
"""Ensure that a transform with case conflicts can always be applied"""
341
tree = self.make_branch_and_tree('tree')
342
transform = TreeTransform(tree)
343
self.addCleanup(transform.finalize)
344
transform.new_file('file', transform.root, 'content')
345
transform.new_file('FiLe', transform.root, 'content')
346
dir = transform.new_directory('dir', transform.root)
347
transform.new_file('dirfile', dir, 'content')
348
transform.new_file('dirFiLe', dir, 'content')
349
resolve_conflicts(transform)
351
self.failUnlessExists('tree/file')
352
if not os.path.exists('tree/FiLe.moved'):
353
self.failUnlessExists('tree/FiLe')
354
self.failUnlessExists('tree/dir/dirfile')
355
if not os.path.exists('tree/dir/dirFiLe.moved'):
356
self.failUnlessExists('tree/dir/dirFiLe')
358
def test_case_insensitive_limbo(self):
359
tree = self.make_branch_and_tree('tree')
360
# Don't try this at home, kids!
361
# Force the tree to report that it is case insensitive
362
tree.case_sensitive = False
363
transform = TreeTransform(tree)
364
self.addCleanup(transform.finalize)
365
dir = transform.new_directory('dir', transform.root)
366
first = transform.new_file('file', dir, 'content')
367
second = transform.new_file('FiLe', dir, 'content')
368
self.assertContainsRe(transform._limbo_name(first), 'new-1/file')
369
self.assertNotContainsRe(transform._limbo_name(second), 'new-1/FiLe')
371
231
def test_add_del(self):
372
232
start, root = self.get_transform()
373
233
start.new_directory('a', root, 'a')
867
659
old = transform.trans_id_tree_path('old')
868
660
subdir = transform.trans_id_tree_file_id('subdir-id')
869
661
new = transform.trans_id_tree_path('new')
870
self.assertEqual([], list(transform.iter_changes()))
662
self.assertEqual([], list(transform._iter_changes()))
872
664
#content deletion
873
665
transform.delete_contents(old)
874
666
self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
875
667
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', None),
876
(False, False))], list(transform.iter_changes()))
668
(False, False))], list(transform._iter_changes()))
879
671
transform.create_file('blah', old)
880
672
self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
881
673
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
882
(False, False))], list(transform.iter_changes()))
674
(False, False))], list(transform._iter_changes()))
883
675
transform.cancel_deletion(old)
884
676
self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
885
677
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
886
(False, False))], list(transform.iter_changes()))
678
(False, False))], list(transform._iter_changes()))
887
679
transform.cancel_creation(old)
889
681
# move file_id to a different file
890
self.assertEqual([], list(transform.iter_changes()))
682
self.assertEqual([], list(transform._iter_changes()))
891
683
transform.unversion_file(old)
892
684
transform.version_file('id-1', new)
893
685
transform.adjust_path('old', root, new)
894
686
self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
895
687
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
896
(False, False))], list(transform.iter_changes()))
688
(False, False))], list(transform._iter_changes()))
897
689
transform.cancel_versioning(new)
898
690
transform._removed_id = set()
901
self.assertEqual([], list(transform.iter_changes()))
693
self.assertEqual([], list(transform._iter_changes()))
902
694
transform.set_executability(True, old)
903
695
self.assertEqual([('id-1', ('old', 'old'), False, (True, True),
904
696
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
905
(False, True))], list(transform.iter_changes()))
697
(False, True))], list(transform._iter_changes()))
906
698
transform.set_executability(None, old)
909
self.assertEqual([], list(transform.iter_changes()))
701
self.assertEqual([], list(transform._iter_changes()))
910
702
transform.adjust_path('new', root, old)
911
703
transform._new_parent = {}
912
704
self.assertEqual([('id-1', ('old', 'new'), False, (True, True),
913
705
('eert_toor', 'eert_toor'), ('old', 'new'), ('file', 'file'),
914
(False, False))], list(transform.iter_changes()))
706
(False, False))], list(transform._iter_changes()))
915
707
transform._new_name = {}
917
709
# parent directory
918
self.assertEqual([], list(transform.iter_changes()))
710
self.assertEqual([], list(transform._iter_changes()))
919
711
transform.adjust_path('new', subdir, old)
920
712
transform._new_name = {}
921
713
self.assertEqual([('id-1', ('old', 'subdir/old'), False,
922
714
(True, True), ('eert_toor', 'subdir-id'), ('old', 'old'),
923
715
('file', 'file'), (False, False))],
924
list(transform.iter_changes()))
716
list(transform._iter_changes()))
925
717
transform._new_path = {}
1162
954
transform.cancel_creation(parent)
1163
955
transform.finalize()
1165
def test_case_insensitive_clash(self):
1166
self.requireFeature(CaseInsensitiveFilesystemFeature)
1168
wt = self.make_branch_and_tree('.')
1169
tt = TreeTransform(wt) # TreeTransform obtains write lock
1171
tt.new_file('foo', tt.root, 'bar')
1172
tt.new_file('Foo', tt.root, 'spam')
1173
# Lie to tt that we've already resolved all conflicts.
1174
tt.apply(no_conflicts=True)
1178
err = self.assertRaises(errors.FileExists, tt_helper)
1179
self.assertContainsRe(str(err),
1180
"^File exists: .+/foo")
1182
def test_two_directories_clash(self):
1184
wt = self.make_branch_and_tree('.')
1185
tt = TreeTransform(wt) # TreeTransform obtains write lock
1187
foo_1 = tt.new_directory('foo', tt.root)
1188
tt.new_directory('bar', foo_1)
1189
foo_2 = tt.new_directory('foo', tt.root)
1190
tt.new_directory('baz', foo_2)
1191
# Lie to tt that we've already resolved all conflicts.
1192
tt.apply(no_conflicts=True)
1196
err = self.assertRaises(errors.FileExists, tt_helper)
1197
self.assertContainsRe(str(err),
1198
"^File exists: .+/foo")
1200
def test_two_directories_clash_finalize(self):
1202
wt = self.make_branch_and_tree('.')
1203
tt = TreeTransform(wt) # TreeTransform obtains write lock
1205
foo_1 = tt.new_directory('foo', tt.root)
1206
tt.new_directory('bar', foo_1)
1207
foo_2 = tt.new_directory('foo', tt.root)
1208
tt.new_directory('baz', foo_2)
1209
# Lie to tt that we've already resolved all conflicts.
1210
tt.apply(no_conflicts=True)
1214
err = self.assertRaises(errors.FileExists, tt_helper)
1215
self.assertContainsRe(str(err),
1216
"^File exists: .+/foo")
1218
def test_file_to_directory(self):
1219
wt = self.make_branch_and_tree('.')
1220
self.build_tree(['foo'])
1223
tt = TreeTransform(wt)
1224
self.addCleanup(tt.finalize)
1225
foo_trans_id = tt.trans_id_tree_path("foo")
1226
tt.delete_contents(foo_trans_id)
1227
tt.create_directory(foo_trans_id)
1228
bar_trans_id = tt.trans_id_tree_path("foo/bar")
1229
tt.create_file(["aa\n"], bar_trans_id)
1230
tt.version_file("bar-1", bar_trans_id)
1232
self.failUnlessExists("foo/bar")
1235
self.assertEqual(wt.inventory.get_file_kind(wt.path2id("foo")),
1240
changes = wt.changes_from(wt.basis_tree())
1241
self.assertFalse(changes.has_changed(), changes)
1243
def test_file_to_symlink(self):
1244
self.requireFeature(SymlinkFeature)
1245
wt = self.make_branch_and_tree('.')
1246
self.build_tree(['foo'])
1249
tt = TreeTransform(wt)
1250
self.addCleanup(tt.finalize)
1251
foo_trans_id = tt.trans_id_tree_path("foo")
1252
tt.delete_contents(foo_trans_id)
1253
tt.create_symlink("bar", foo_trans_id)
1255
self.failUnlessExists("foo")
1257
self.addCleanup(wt.unlock)
1258
self.assertEqual(wt.inventory.get_file_kind(wt.path2id("foo")),
1261
def test_dir_to_file(self):
1262
wt = self.make_branch_and_tree('.')
1263
self.build_tree(['foo/', 'foo/bar'])
1264
wt.add(['foo', 'foo/bar'])
1266
tt = TreeTransform(wt)
1267
self.addCleanup(tt.finalize)
1268
foo_trans_id = tt.trans_id_tree_path("foo")
1269
bar_trans_id = tt.trans_id_tree_path("foo/bar")
1270
tt.delete_contents(foo_trans_id)
1271
tt.delete_versioned(bar_trans_id)
1272
tt.create_file(["aa\n"], foo_trans_id)
1274
self.failUnlessExists("foo")
1276
self.addCleanup(wt.unlock)
1277
self.assertEqual(wt.inventory.get_file_kind(wt.path2id("foo")),
1280
def test_dir_to_hardlink(self):
1281
self.requireFeature(HardlinkFeature)
1282
wt = self.make_branch_and_tree('.')
1283
self.build_tree(['foo/', 'foo/bar'])
1284
wt.add(['foo', 'foo/bar'])
1286
tt = TreeTransform(wt)
1287
self.addCleanup(tt.finalize)
1288
foo_trans_id = tt.trans_id_tree_path("foo")
1289
bar_trans_id = tt.trans_id_tree_path("foo/bar")
1290
tt.delete_contents(foo_trans_id)
1291
tt.delete_versioned(bar_trans_id)
1292
self.build_tree(['baz'])
1293
tt.create_hardlink("baz", foo_trans_id)
1295
self.failUnlessExists("foo")
1296
self.failUnlessExists("baz")
1298
self.addCleanup(wt.unlock)
1299
self.assertEqual(wt.inventory.get_file_kind(wt.path2id("foo")),
1302
def test_no_final_path(self):
1303
transform, root = self.get_transform()
1304
trans_id = transform.trans_id_file_id('foo')
1305
transform.create_file('bar', trans_id)
1306
transform.cancel_creation(trans_id)
957
def test_change_entry(self):
958
txt = 'bzrlib.transform.change_entry was deprecated in version 0.90.'
959
self.callDeprecated([txt], change_entry, None, None, None, None, None,
1310
963
class TransformGroup(object):
1312
964
def __init__(self, dirname, root_id):
1313
965
self.name = dirname
1314
966
os.mkdir(dirname)
1665
1318
# children of non-root directories should not be renamed
1666
1319
self.assertEqual(2, transform_result.rename_count)
1668
def create_ab_tree(self):
1669
"""Create a committed test tree with two files"""
1670
source = self.make_branch_and_tree('source')
1671
self.build_tree_contents([('source/file1', 'A')])
1672
self.build_tree_contents([('source/file2', 'B')])
1673
source.add(['file1', 'file2'], ['file1-id', 'file2-id'])
1674
source.commit('commit files')
1676
self.addCleanup(source.unlock)
1679
def test_build_tree_accelerator_tree(self):
1680
source = self.create_ab_tree()
1681
self.build_tree_contents([('source/file2', 'C')])
1683
real_source_get_file = source.get_file
1684
def get_file(file_id, path=None):
1685
calls.append(file_id)
1686
return real_source_get_file(file_id, path)
1687
source.get_file = get_file
1688
target = self.make_branch_and_tree('target')
1689
revision_tree = source.basis_tree()
1690
revision_tree.lock_read()
1691
self.addCleanup(revision_tree.unlock)
1692
build_tree(revision_tree, target, source)
1693
self.assertEqual(['file1-id'], calls)
1695
self.addCleanup(target.unlock)
1696
self.assertEqual([], list(target.iter_changes(revision_tree)))
1698
def test_build_tree_accelerator_tree_missing_file(self):
1699
source = self.create_ab_tree()
1700
os.unlink('source/file1')
1701
source.remove(['file2'])
1702
target = self.make_branch_and_tree('target')
1703
revision_tree = source.basis_tree()
1704
revision_tree.lock_read()
1705
self.addCleanup(revision_tree.unlock)
1706
build_tree(revision_tree, target, source)
1708
self.addCleanup(target.unlock)
1709
self.assertEqual([], list(target.iter_changes(revision_tree)))
1711
def test_build_tree_accelerator_wrong_kind(self):
1712
self.requireFeature(SymlinkFeature)
1713
source = self.make_branch_and_tree('source')
1714
self.build_tree_contents([('source/file1', '')])
1715
self.build_tree_contents([('source/file2', '')])
1716
source.add(['file1', 'file2'], ['file1-id', 'file2-id'])
1717
source.commit('commit files')
1718
os.unlink('source/file2')
1719
self.build_tree_contents([('source/file2/', 'C')])
1720
os.unlink('source/file1')
1721
os.symlink('file2', 'source/file1')
1723
real_source_get_file = source.get_file
1724
def get_file(file_id, path=None):
1725
calls.append(file_id)
1726
return real_source_get_file(file_id, path)
1727
source.get_file = get_file
1728
target = self.make_branch_and_tree('target')
1729
revision_tree = source.basis_tree()
1730
revision_tree.lock_read()
1731
self.addCleanup(revision_tree.unlock)
1732
build_tree(revision_tree, target, source)
1733
self.assertEqual([], calls)
1735
self.addCleanup(target.unlock)
1736
self.assertEqual([], list(target.iter_changes(revision_tree)))
1738
def test_build_tree_hardlink(self):
1739
self.requireFeature(HardlinkFeature)
1740
source = self.create_ab_tree()
1741
target = self.make_branch_and_tree('target')
1742
revision_tree = source.basis_tree()
1743
revision_tree.lock_read()
1744
self.addCleanup(revision_tree.unlock)
1745
build_tree(revision_tree, target, source, hardlink=True)
1747
self.addCleanup(target.unlock)
1748
self.assertEqual([], list(target.iter_changes(revision_tree)))
1749
source_stat = os.stat('source/file1')
1750
target_stat = os.stat('target/file1')
1751
self.assertEqual(source_stat, target_stat)
1753
# Explicitly disallowing hardlinks should prevent them.
1754
target2 = self.make_branch_and_tree('target2')
1755
build_tree(revision_tree, target2, source, hardlink=False)
1757
self.addCleanup(target2.unlock)
1758
self.assertEqual([], list(target2.iter_changes(revision_tree)))
1759
source_stat = os.stat('source/file1')
1760
target2_stat = os.stat('target2/file1')
1761
self.assertNotEqual(source_stat, target2_stat)
1763
def test_build_tree_accelerator_tree_moved(self):
1764
source = self.make_branch_and_tree('source')
1765
self.build_tree_contents([('source/file1', 'A')])
1766
source.add(['file1'], ['file1-id'])
1767
source.commit('commit files')
1768
source.rename_one('file1', 'file2')
1770
self.addCleanup(source.unlock)
1771
target = self.make_branch_and_tree('target')
1772
revision_tree = source.basis_tree()
1773
revision_tree.lock_read()
1774
self.addCleanup(revision_tree.unlock)
1775
build_tree(revision_tree, target, source)
1777
self.addCleanup(target.unlock)
1778
self.assertEqual([], list(target.iter_changes(revision_tree)))
1780
def test_build_tree_hardlinks_preserve_execute(self):
1781
self.requireFeature(HardlinkFeature)
1782
source = self.create_ab_tree()
1783
tt = TreeTransform(source)
1784
trans_id = tt.trans_id_tree_file_id('file1-id')
1785
tt.set_executability(True, trans_id)
1787
self.assertTrue(source.is_executable('file1-id'))
1788
target = self.make_branch_and_tree('target')
1789
revision_tree = source.basis_tree()
1790
revision_tree.lock_read()
1791
self.addCleanup(revision_tree.unlock)
1792
build_tree(revision_tree, target, source, hardlink=True)
1794
self.addCleanup(target.unlock)
1795
self.assertEqual([], list(target.iter_changes(revision_tree)))
1796
self.assertTrue(source.is_executable('file1-id'))
1798
def test_case_insensitive_build_tree_inventory(self):
1799
source = self.make_branch_and_tree('source')
1800
self.build_tree(['source/file', 'source/FILE'])
1801
source.add(['file', 'FILE'], ['lower-id', 'upper-id'])
1802
source.commit('added files')
1803
# Don't try this at home, kids!
1804
# Force the tree to report that it is case insensitive
1805
target = self.make_branch_and_tree('target')
1806
target.case_sensitive = False
1807
build_tree(source.basis_tree(), target, source, delta_from_tree=True)
1808
self.assertEqual('file.moved', target.id2path('lower-id'))
1809
self.assertEqual('FILE', target.id2path('upper-id'))
1812
1322
class MockTransform(object):
1959
1468
_mover=self.ExceptionFileMover(bad_target='d'))
1960
1469
self.failUnlessExists('a')
1961
1470
self.failUnlessExists('a/b')
1963
def test_resolve_no_parent(self):
1964
wt = self.make_branch_and_tree('.')
1965
tt = TreeTransform(wt)
1966
self.addCleanup(tt.finalize)
1967
parent = tt.trans_id_file_id('parent-id')
1968
tt.new_file('file', parent, 'Contents')
1969
resolve_conflicts(tt)
1972
class TestTransformPreview(tests.TestCaseWithTransport):
1974
def create_tree(self):
1975
tree = self.make_branch_and_tree('.')
1976
self.build_tree_contents([('a', 'content 1')])
1977
tree.add('a', 'a-id')
1978
tree.commit('rev1', rev_id='rev1')
1979
return tree.branch.repository.revision_tree('rev1')
1981
def get_empty_preview(self):
1982
repository = self.make_repository('repo')
1983
tree = repository.revision_tree(_mod_revision.NULL_REVISION)
1984
preview = TransformPreview(tree)
1985
self.addCleanup(preview.finalize)
1988
def test_transform_preview(self):
1989
revision_tree = self.create_tree()
1990
preview = TransformPreview(revision_tree)
1991
self.addCleanup(preview.finalize)
1993
def test_transform_preview_tree(self):
1994
revision_tree = self.create_tree()
1995
preview = TransformPreview(revision_tree)
1996
self.addCleanup(preview.finalize)
1997
preview.get_preview_tree()
1999
def test_transform_new_file(self):
2000
revision_tree = self.create_tree()
2001
preview = TransformPreview(revision_tree)
2002
self.addCleanup(preview.finalize)
2003
preview.new_file('file2', preview.root, 'content B\n', 'file2-id')
2004
preview_tree = preview.get_preview_tree()
2005
self.assertEqual(preview_tree.kind('file2-id'), 'file')
2007
preview_tree.get_file('file2-id').read(), 'content B\n')
2009
def test_diff_preview_tree(self):
2010
revision_tree = self.create_tree()
2011
preview = TransformPreview(revision_tree)
2012
self.addCleanup(preview.finalize)
2013
preview.new_file('file2', preview.root, 'content B\n', 'file2-id')
2014
preview_tree = preview.get_preview_tree()
2016
show_diff_trees(revision_tree, preview_tree, out)
2017
lines = out.getvalue().splitlines()
2018
self.assertEqual(lines[0], "=== added file 'file2'")
2019
# 3 lines of diff administrivia
2020
self.assertEqual(lines[4], "+content B")
2022
def test_transform_conflicts(self):
2023
revision_tree = self.create_tree()
2024
preview = TransformPreview(revision_tree)
2025
self.addCleanup(preview.finalize)
2026
preview.new_file('a', preview.root, 'content 2')
2027
resolve_conflicts(preview)
2028
trans_id = preview.trans_id_file_id('a-id')
2029
self.assertEqual('a.moved', preview.final_name(trans_id))
2031
def get_tree_and_preview_tree(self):
2032
revision_tree = self.create_tree()
2033
preview = TransformPreview(revision_tree)
2034
self.addCleanup(preview.finalize)
2035
a_trans_id = preview.trans_id_file_id('a-id')
2036
preview.delete_contents(a_trans_id)
2037
preview.create_file('b content', a_trans_id)
2038
preview_tree = preview.get_preview_tree()
2039
return revision_tree, preview_tree
2041
def test_iter_changes(self):
2042
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2043
root = revision_tree.inventory.root.file_id
2044
self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
2045
(root, root), ('a', 'a'), ('file', 'file'),
2047
list(preview_tree.iter_changes(revision_tree)))
2049
def test_wrong_tree_value_error(self):
2050
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2051
e = self.assertRaises(ValueError, preview_tree.iter_changes,
2053
self.assertEqual('from_tree must be transform source tree.', str(e))
2055
def test_include_unchanged_value_error(self):
2056
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2057
e = self.assertRaises(ValueError, preview_tree.iter_changes,
2058
revision_tree, include_unchanged=True)
2059
self.assertEqual('include_unchanged is not supported', str(e))
2061
def test_specific_files(self):
2062
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2063
e = self.assertRaises(ValueError, preview_tree.iter_changes,
2064
revision_tree, specific_files=['pete'])
2065
self.assertEqual('specific_files is not supported', str(e))
2067
def test_want_unversioned_value_error(self):
2068
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2069
e = self.assertRaises(ValueError, preview_tree.iter_changes,
2070
revision_tree, want_unversioned=True)
2071
self.assertEqual('want_unversioned is not supported', str(e))
2073
def test_ignore_extra_trees_no_specific_files(self):
2074
# extra_trees is harmless without specific_files, so we'll silently
2075
# accept it, even though we won't use it.
2076
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2077
preview_tree.iter_changes(revision_tree, extra_trees=[preview_tree])
2079
def test_ignore_require_versioned_no_specific_files(self):
2080
# require_versioned is meaningless without specific_files.
2081
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2082
preview_tree.iter_changes(revision_tree, require_versioned=False)
2084
def test_ignore_pb(self):
2085
# pb could be supported, but TT.iter_changes doesn't support it.
2086
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2087
preview_tree.iter_changes(revision_tree, pb=progress.DummyProgress())
2089
def test_kind(self):
2090
revision_tree = self.create_tree()
2091
preview = TransformPreview(revision_tree)
2092
self.addCleanup(preview.finalize)
2093
preview.new_file('file', preview.root, 'contents', 'file-id')
2094
preview.new_directory('directory', preview.root, 'dir-id')
2095
preview_tree = preview.get_preview_tree()
2096
self.assertEqual('file', preview_tree.kind('file-id'))
2097
self.assertEqual('directory', preview_tree.kind('dir-id'))
2099
def test_get_file_mtime(self):
2100
preview = self.get_empty_preview()
2101
file_trans_id = preview.new_file('file', preview.root, 'contents',
2103
limbo_path = preview._limbo_name(file_trans_id)
2104
preview_tree = preview.get_preview_tree()
2105
self.assertEqual(os.stat(limbo_path).st_mtime,
2106
preview_tree.get_file_mtime('file-id'))
2108
def test_get_file(self):
2109
preview = self.get_empty_preview()
2110
preview.new_file('file', preview.root, 'contents', 'file-id')
2111
preview_tree = preview.get_preview_tree()
2112
tree_file = preview_tree.get_file('file-id')
2114
self.assertEqual('contents', tree_file.read())
2118
def test_get_symlink_target(self):
2119
self.requireFeature(SymlinkFeature)
2120
preview = self.get_empty_preview()
2121
preview.new_symlink('symlink', preview.root, 'target', 'symlink-id')
2122
preview_tree = preview.get_preview_tree()
2123
self.assertEqual('target',
2124
preview_tree.get_symlink_target('symlink-id'))
2126
def test_all_file_ids(self):
2127
tree = self.make_branch_and_tree('tree')
2128
self.build_tree(['tree/a', 'tree/b', 'tree/c'])
2129
tree.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
2130
preview = TransformPreview(tree)
2131
self.addCleanup(preview.finalize)
2132
preview.unversion_file(preview.trans_id_file_id('b-id'))
2133
c_trans_id = preview.trans_id_file_id('c-id')
2134
preview.unversion_file(c_trans_id)
2135
preview.version_file('c-id', c_trans_id)
2136
preview_tree = preview.get_preview_tree()
2137
self.assertEqual(set(['a-id', 'c-id', tree.get_root_id()]),
2138
preview_tree.all_file_ids())
2140
def test_path2id_deleted_unchanged(self):
2141
tree = self.make_branch_and_tree('tree')
2142
self.build_tree(['tree/unchanged', 'tree/deleted'])
2143
tree.add(['unchanged', 'deleted'], ['unchanged-id', 'deleted-id'])
2144
preview = TransformPreview(tree)
2145
self.addCleanup(preview.finalize)
2146
preview.unversion_file(preview.trans_id_file_id('deleted-id'))
2147
preview_tree = preview.get_preview_tree()
2148
self.assertEqual('unchanged-id', preview_tree.path2id('unchanged'))
2149
self.assertIs(None, preview_tree.path2id('deleted'))
2151
def test_path2id_created(self):
2152
tree = self.make_branch_and_tree('tree')
2153
self.build_tree(['tree/unchanged'])
2154
tree.add(['unchanged'], ['unchanged-id'])
2155
preview = TransformPreview(tree)
2156
self.addCleanup(preview.finalize)
2157
preview.new_file('new', preview.trans_id_file_id('unchanged-id'),
2158
'contents', 'new-id')
2159
preview_tree = preview.get_preview_tree()
2160
self.assertEqual('new-id', preview_tree.path2id('unchanged/new'))
2162
def test_path2id_moved(self):
2163
tree = self.make_branch_and_tree('tree')
2164
self.build_tree(['tree/old_parent/', 'tree/old_parent/child'])
2165
tree.add(['old_parent', 'old_parent/child'],
2166
['old_parent-id', 'child-id'])
2167
preview = TransformPreview(tree)
2168
self.addCleanup(preview.finalize)
2169
new_parent = preview.new_directory('new_parent', preview.root,
2171
preview.adjust_path('child', new_parent,
2172
preview.trans_id_file_id('child-id'))
2173
preview_tree = preview.get_preview_tree()
2174
self.assertIs(None, preview_tree.path2id('old_parent/child'))
2175
self.assertEqual('child-id', preview_tree.path2id('new_parent/child'))
2177
def test_path2id_renamed_parent(self):
2178
tree = self.make_branch_and_tree('tree')
2179
self.build_tree(['tree/old_name/', 'tree/old_name/child'])
2180
tree.add(['old_name', 'old_name/child'],
2181
['parent-id', 'child-id'])
2182
preview = TransformPreview(tree)
2183
self.addCleanup(preview.finalize)
2184
preview.adjust_path('new_name', preview.root,
2185
preview.trans_id_file_id('parent-id'))
2186
preview_tree = preview.get_preview_tree()
2187
self.assertIs(None, preview_tree.path2id('old_name/child'))
2188
self.assertEqual('child-id', preview_tree.path2id('new_name/child'))
2190
def assertMatchingIterEntries(self, tt, specific_file_ids=None):
2191
preview_tree = tt.get_preview_tree()
2192
preview_result = list(preview_tree.iter_entries_by_dir(
2196
actual_result = list(tree.iter_entries_by_dir(specific_file_ids))
2197
self.assertEqual(actual_result, preview_result)
2199
def test_iter_entries_by_dir_new(self):
2200
tree = self.make_branch_and_tree('tree')
2201
tt = TreeTransform(tree)
2202
tt.new_file('new', tt.root, 'contents', 'new-id')
2203
self.assertMatchingIterEntries(tt)
2205
def test_iter_entries_by_dir_deleted(self):
2206
tree = self.make_branch_and_tree('tree')
2207
self.build_tree(['tree/deleted'])
2208
tree.add('deleted', 'deleted-id')
2209
tt = TreeTransform(tree)
2210
tt.delete_contents(tt.trans_id_file_id('deleted-id'))
2211
self.assertMatchingIterEntries(tt)
2213
def test_iter_entries_by_dir_unversioned(self):
2214
tree = self.make_branch_and_tree('tree')
2215
self.build_tree(['tree/removed'])
2216
tree.add('removed', 'removed-id')
2217
tt = TreeTransform(tree)
2218
tt.unversion_file(tt.trans_id_file_id('removed-id'))
2219
self.assertMatchingIterEntries(tt)
2221
def test_iter_entries_by_dir_moved(self):
2222
tree = self.make_branch_and_tree('tree')
2223
self.build_tree(['tree/moved', 'tree/new_parent/'])
2224
tree.add(['moved', 'new_parent'], ['moved-id', 'new_parent-id'])
2225
tt = TreeTransform(tree)
2226
tt.adjust_path('moved', tt.trans_id_file_id('new_parent-id'),
2227
tt.trans_id_file_id('moved-id'))
2228
self.assertMatchingIterEntries(tt)
2230
def test_iter_entries_by_dir_specific_file_ids(self):
2231
tree = self.make_branch_and_tree('tree')
2232
tree.set_root_id('tree-root-id')
2233
self.build_tree(['tree/parent/', 'tree/parent/child'])
2234
tree.add(['parent', 'parent/child'], ['parent-id', 'child-id'])
2235
tt = TreeTransform(tree)
2236
self.assertMatchingIterEntries(tt, ['tree-root-id', 'child-id'])
2238
def test_symlink_content_summary(self):
2239
self.requireFeature(SymlinkFeature)
2240
preview = self.get_empty_preview()
2241
preview.new_symlink('path', preview.root, 'target', 'path-id')
2242
summary = preview.get_preview_tree().path_content_summary('path')
2243
self.assertEqual(('symlink', None, None, 'target'), summary)
2245
def test_missing_content_summary(self):
2246
preview = self.get_empty_preview()
2247
summary = preview.get_preview_tree().path_content_summary('path')
2248
self.assertEqual(('missing', None, None, None), summary)
2250
def test_deleted_content_summary(self):
2251
tree = self.make_branch_and_tree('tree')
2252
self.build_tree(['tree/path/'])
2254
preview = TransformPreview(tree)
2255
self.addCleanup(preview.finalize)
2256
preview.delete_contents(preview.trans_id_tree_path('path'))
2257
summary = preview.get_preview_tree().path_content_summary('path')
2258
self.assertEqual(('missing', None, None, None), summary)
2260
def test_file_content_summary_executable(self):
2261
if not osutils.supports_executable():
2262
raise TestNotApplicable()
2263
preview = self.get_empty_preview()
2264
path_id = preview.new_file('path', preview.root, 'contents', 'path-id')
2265
preview.set_executability(True, path_id)
2266
summary = preview.get_preview_tree().path_content_summary('path')
2267
self.assertEqual(4, len(summary))
2268
self.assertEqual('file', summary[0])
2269
# size must be known
2270
self.assertEqual(len('contents'), summary[1])
2272
self.assertEqual(True, summary[2])
2273
# will not have hash (not cheap to determine)
2274
self.assertIs(None, summary[3])
2276
def test_change_executability(self):
2277
if not osutils.supports_executable():
2278
raise TestNotApplicable()
2279
tree = self.make_branch_and_tree('tree')
2280
self.build_tree(['tree/path'])
2282
preview = TransformPreview(tree)
2283
self.addCleanup(preview.finalize)
2284
path_id = preview.trans_id_tree_path('path')
2285
preview.set_executability(True, path_id)
2286
summary = preview.get_preview_tree().path_content_summary('path')
2287
self.assertEqual(True, summary[2])
2289
def test_file_content_summary_non_exec(self):
2290
preview = self.get_empty_preview()
2291
preview.new_file('path', preview.root, 'contents', 'path-id')
2292
summary = preview.get_preview_tree().path_content_summary('path')
2293
self.assertEqual(4, len(summary))
2294
self.assertEqual('file', summary[0])
2295
# size must be known
2296
self.assertEqual(len('contents'), summary[1])
2298
if osutils.supports_executable():
2299
self.assertEqual(False, summary[2])
2301
self.assertEqual(None, summary[2])
2302
# will not have hash (not cheap to determine)
2303
self.assertIs(None, summary[3])
2305
def test_dir_content_summary(self):
2306
preview = self.get_empty_preview()
2307
preview.new_directory('path', preview.root, 'path-id')
2308
summary = preview.get_preview_tree().path_content_summary('path')
2309
self.assertEqual(('directory', None, None, None), summary)
2311
def test_tree_content_summary(self):
2312
preview = self.get_empty_preview()
2313
path = preview.new_directory('path', preview.root, 'path-id')
2314
preview.set_tree_reference('rev-1', path)
2315
summary = preview.get_preview_tree().path_content_summary('path')
2316
self.assertEqual(4, len(summary))
2317
self.assertEqual('tree-reference', summary[0])
2319
def test_annotate(self):
2320
tree = self.make_branch_and_tree('tree')
2321
self.build_tree_contents([('tree/file', 'a\n')])
2322
tree.add('file', 'file-id')
2323
tree.commit('a', rev_id='one')
2324
self.build_tree_contents([('tree/file', 'a\nb\n')])
2325
preview = TransformPreview(tree)
2326
self.addCleanup(preview.finalize)
2327
file_trans_id = preview.trans_id_file_id('file-id')
2328
preview.delete_contents(file_trans_id)
2329
preview.create_file('a\nb\nc\n', file_trans_id)
2330
preview_tree = preview.get_preview_tree()
2336
annotation = preview_tree.annotate_iter('file-id', 'me:')
2337
self.assertEqual(expected, annotation)
2339
def test_annotate_missing(self):
2340
preview = self.get_empty_preview()
2341
preview.new_file('file', preview.root, 'a\nb\nc\n', 'file-id')
2342
preview_tree = preview.get_preview_tree()
2348
annotation = preview_tree.annotate_iter('file-id', 'me:')
2349
self.assertEqual(expected, annotation)
2351
def test_annotate_rename(self):
2352
tree = self.make_branch_and_tree('tree')
2353
self.build_tree_contents([('tree/file', 'a\n')])
2354
tree.add('file', 'file-id')
2355
tree.commit('a', rev_id='one')
2356
preview = TransformPreview(tree)
2357
self.addCleanup(preview.finalize)
2358
file_trans_id = preview.trans_id_file_id('file-id')
2359
preview.adjust_path('newname', preview.root, file_trans_id)
2360
preview_tree = preview.get_preview_tree()
2364
annotation = preview_tree.annotate_iter('file-id', 'me:')
2365
self.assertEqual(expected, annotation)
2367
def test_annotate_deleted(self):
2368
tree = self.make_branch_and_tree('tree')
2369
self.build_tree_contents([('tree/file', 'a\n')])
2370
tree.add('file', 'file-id')
2371
tree.commit('a', rev_id='one')
2372
self.build_tree_contents([('tree/file', 'a\nb\n')])
2373
preview = TransformPreview(tree)
2374
self.addCleanup(preview.finalize)
2375
file_trans_id = preview.trans_id_file_id('file-id')
2376
preview.delete_contents(file_trans_id)
2377
preview_tree = preview.get_preview_tree()
2378
annotation = preview_tree.annotate_iter('file-id', 'me:')
2379
self.assertIs(None, annotation)
2381
def test_stored_kind(self):
2382
preview = self.get_empty_preview()
2383
preview.new_file('file', preview.root, 'a\nb\nc\n', 'file-id')
2384
preview_tree = preview.get_preview_tree()
2385
self.assertEqual('file', preview_tree.stored_kind('file-id'))
2387
def test_is_executable(self):
2388
preview = self.get_empty_preview()
2389
preview.new_file('file', preview.root, 'a\nb\nc\n', 'file-id')
2390
preview.set_executability(True, preview.trans_id_file_id('file-id'))
2391
preview_tree = preview.get_preview_tree()
2392
self.assertEqual(True, preview_tree.is_executable('file-id'))
2394
def test_get_set_parent_ids(self):
2395
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2396
self.assertEqual([], preview_tree.get_parent_ids())
2397
preview_tree.set_parent_ids(['rev-1'])
2398
self.assertEqual(['rev-1'], preview_tree.get_parent_ids())
2400
def test_plan_file_merge(self):
2401
work_a = self.make_branch_and_tree('wta')
2402
self.build_tree_contents([('wta/file', 'a\nb\nc\nd\n')])
2403
work_a.add('file', 'file-id')
2404
base_id = work_a.commit('base version')
2405
tree_b = work_a.bzrdir.sprout('wtb').open_workingtree()
2406
preview = TransformPreview(work_a)
2407
self.addCleanup(preview.finalize)
2408
trans_id = preview.trans_id_file_id('file-id')
2409
preview.delete_contents(trans_id)
2410
preview.create_file('b\nc\nd\ne\n', trans_id)
2411
self.build_tree_contents([('wtb/file', 'a\nc\nd\nf\n')])
2412
tree_a = preview.get_preview_tree()
2413
tree_a.set_parent_ids([base_id])
2415
('killed-a', 'a\n'),
2416
('killed-b', 'b\n'),
2417
('unchanged', 'c\n'),
2418
('unchanged', 'd\n'),
2421
], list(tree_a.plan_file_merge('file-id', tree_b)))
2423
def test_plan_file_merge_revision_tree(self):
2424
work_a = self.make_branch_and_tree('wta')
2425
self.build_tree_contents([('wta/file', 'a\nb\nc\nd\n')])
2426
work_a.add('file', 'file-id')
2427
base_id = work_a.commit('base version')
2428
tree_b = work_a.bzrdir.sprout('wtb').open_workingtree()
2429
preview = TransformPreview(work_a.basis_tree())
2430
self.addCleanup(preview.finalize)
2431
trans_id = preview.trans_id_file_id('file-id')
2432
preview.delete_contents(trans_id)
2433
preview.create_file('b\nc\nd\ne\n', trans_id)
2434
self.build_tree_contents([('wtb/file', 'a\nc\nd\nf\n')])
2435
tree_a = preview.get_preview_tree()
2436
tree_a.set_parent_ids([base_id])
2438
('killed-a', 'a\n'),
2439
('killed-b', 'b\n'),
2440
('unchanged', 'c\n'),
2441
('unchanged', 'd\n'),
2444
], list(tree_a.plan_file_merge('file-id', tree_b)))
2446
def test_walkdirs(self):
2447
preview = self.get_empty_preview()
2448
preview.version_file('tree-root', preview.root)
2449
preview_tree = preview.get_preview_tree()
2450
file_trans_id = preview.new_file('a', preview.root, 'contents',
2452
expected = [(('', 'tree-root'),
2453
[('a', 'a', 'file', None, 'a-id', 'file')])]
2454
self.assertEqual(expected, list(preview_tree.walkdirs()))