233
244
transform3.adjust_path('tip', root_id, tip_id)
234
245
transform3.apply()
247
def test_conflict_on_case_insensitive(self):
248
tree = self.make_branch_and_tree('tree')
249
# Don't try this at home, kids!
250
# Force the tree to report that it is case sensitive, for conflict
252
tree.case_sensitive = True
253
transform = TreeTransform(tree)
254
self.addCleanup(transform.finalize)
255
transform.new_file('file', transform.root, 'content')
256
transform.new_file('FiLe', transform.root, 'content')
257
result = transform.find_conflicts()
258
self.assertEqual([], result)
260
# Force the tree to report that it is case insensitive, for conflict
262
tree.case_sensitive = False
263
transform = TreeTransform(tree)
264
self.addCleanup(transform.finalize)
265
transform.new_file('file', transform.root, 'content')
266
transform.new_file('FiLe', transform.root, 'content')
267
result = transform.find_conflicts()
268
self.assertEqual([('duplicate', 'new-1', 'new-2', 'file')], result)
270
def test_conflict_on_case_insensitive_existing(self):
271
tree = self.make_branch_and_tree('tree')
272
self.build_tree(['tree/FiLe'])
273
# Don't try this at home, kids!
274
# Force the tree to report that it is case sensitive, for conflict
276
tree.case_sensitive = True
277
transform = TreeTransform(tree)
278
self.addCleanup(transform.finalize)
279
transform.new_file('file', transform.root, 'content')
280
result = transform.find_conflicts()
281
self.assertEqual([], result)
283
# Force the tree to report that it is case insensitive, for conflict
285
tree.case_sensitive = False
286
transform = TreeTransform(tree)
287
self.addCleanup(transform.finalize)
288
transform.new_file('file', transform.root, 'content')
289
result = transform.find_conflicts()
290
self.assertEqual([('duplicate', 'new-1', 'new-2', 'file')], result)
292
def test_resolve_case_insensitive_conflict(self):
293
tree = self.make_branch_and_tree('tree')
294
# Don't try this at home, kids!
295
# Force the tree to report that it is case insensitive, for conflict
297
tree.case_sensitive = False
298
transform = TreeTransform(tree)
299
self.addCleanup(transform.finalize)
300
transform.new_file('file', transform.root, 'content')
301
transform.new_file('FiLe', transform.root, 'content')
302
resolve_conflicts(transform)
304
self.failUnlessExists('tree/file')
305
self.failUnlessExists('tree/FiLe.moved')
307
def test_resolve_checkout_case_conflict(self):
308
tree = self.make_branch_and_tree('tree')
309
# Don't try this at home, kids!
310
# Force the tree to report that it is case insensitive, for conflict
312
tree.case_sensitive = False
313
transform = TreeTransform(tree)
314
self.addCleanup(transform.finalize)
315
transform.new_file('file', transform.root, 'content')
316
transform.new_file('FiLe', transform.root, 'content')
317
resolve_conflicts(transform,
318
pass_func=lambda t, c: resolve_checkout(t, c, []))
320
self.failUnlessExists('tree/file')
321
self.failUnlessExists('tree/FiLe.moved')
323
def test_apply_case_conflict(self):
324
"""Ensure that a transform with case conflicts can always be applied"""
325
tree = self.make_branch_and_tree('tree')
326
transform = TreeTransform(tree)
327
self.addCleanup(transform.finalize)
328
transform.new_file('file', transform.root, 'content')
329
transform.new_file('FiLe', transform.root, 'content')
330
dir = transform.new_directory('dir', transform.root)
331
transform.new_file('dirfile', dir, 'content')
332
transform.new_file('dirFiLe', dir, 'content')
333
resolve_conflicts(transform)
335
self.failUnlessExists('tree/file')
336
if not os.path.exists('tree/FiLe.moved'):
337
self.failUnlessExists('tree/FiLe')
338
self.failUnlessExists('tree/dir/dirfile')
339
if not os.path.exists('tree/dir/dirFiLe.moved'):
340
self.failUnlessExists('tree/dir/dirFiLe')
342
def test_case_insensitive_limbo(self):
343
tree = self.make_branch_and_tree('tree')
344
# Don't try this at home, kids!
345
# Force the tree to report that it is case insensitive
346
tree.case_sensitive = False
347
transform = TreeTransform(tree)
348
self.addCleanup(transform.finalize)
349
dir = transform.new_directory('dir', transform.root)
350
first = transform.new_file('file', dir, 'content')
351
second = transform.new_file('FiLe', dir, 'content')
352
self.assertContainsRe(transform._limbo_name(first), 'new-1/file')
353
self.assertNotContainsRe(transform._limbo_name(second), 'new-1/FiLe')
236
355
def test_add_del(self):
237
356
start, root = self.get_transform()
238
357
start.new_directory('a', root, 'a')
499
638
self.assertEqual(conflicts_s[6], 'Conflict moving oz/emeraldcity into'
500
639
' oz/emeraldcity. Cancelled move.')
641
def prepare_wrong_parent_kind(self):
642
tt, root = self.get_transform()
643
tt.new_file('parent', root, 'contents', 'parent-id')
645
tt, root = self.get_transform()
646
parent_id = tt.trans_id_file_id('parent-id')
647
tt.new_file('child,', parent_id, 'contents2', 'file-id')
650
def test_find_conflicts_wrong_parent_kind(self):
651
tt = self.prepare_wrong_parent_kind()
654
def test_resolve_conflicts_wrong_existing_parent_kind(self):
655
tt = self.prepare_wrong_parent_kind()
656
raw_conflicts = resolve_conflicts(tt)
657
self.assertEqual(set([('non-directory parent', 'Created directory',
658
'new-3')]), raw_conflicts)
659
cooked_conflicts = cook_conflicts(raw_conflicts, tt)
660
self.assertEqual([NonDirectoryParent('Created directory', 'parent.new',
661
'parent-id')], cooked_conflicts)
663
self.assertEqual(None, self.wt.path2id('parent'))
664
self.assertEqual('parent-id', self.wt.path2id('parent.new'))
666
def test_resolve_conflicts_wrong_new_parent_kind(self):
667
tt, root = self.get_transform()
668
parent_id = tt.new_directory('parent', root, 'parent-id')
669
tt.new_file('child,', parent_id, 'contents2', 'file-id')
671
tt, root = self.get_transform()
672
parent_id = tt.trans_id_file_id('parent-id')
673
tt.delete_contents(parent_id)
674
tt.create_file('contents', parent_id)
675
raw_conflicts = resolve_conflicts(tt)
676
self.assertEqual(set([('non-directory parent', 'Created directory',
677
'new-3')]), raw_conflicts)
679
self.assertEqual(None, self.wt.path2id('parent'))
680
self.assertEqual('parent-id', self.wt.path2id('parent.new'))
682
def test_resolve_conflicts_wrong_parent_kind_unversioned(self):
683
tt, root = self.get_transform()
684
parent_id = tt.new_directory('parent', root)
685
tt.new_file('child,', parent_id, 'contents2')
687
tt, root = self.get_transform()
688
parent_id = tt.trans_id_tree_path('parent')
689
tt.delete_contents(parent_id)
690
tt.create_file('contents', parent_id)
691
resolve_conflicts(tt)
693
self.assertIs(None, self.wt.path2id('parent'))
694
self.assertIs(None, self.wt.path2id('parent.new'))
502
696
def test_moving_versioned_directories(self):
503
697
create, root = self.get_transform()
504
698
kansas = create.new_directory('kansas', root, 'kansas-id')
963
1161
self.callDeprecated([txt], change_entry, None, None, None, None, None,
964
1162
None, None, None)
1164
def test_case_insensitive_clash(self):
1165
self.requireFeature(CaseInsensitiveFilesystemFeature)
1167
wt = self.make_branch_and_tree('.')
1168
tt = TreeTransform(wt) # TreeTransform obtains write lock
1170
tt.new_file('foo', tt.root, 'bar')
1171
tt.new_file('Foo', tt.root, 'spam')
1172
# Lie to tt that we've already resolved all conflicts.
1173
tt.apply(no_conflicts=True)
1177
err = self.assertRaises(errors.FileExists, tt_helper)
1178
self.assertContainsRe(str(err),
1179
"^File exists: .+/foo")
1181
def test_two_directories_clash(self):
1183
wt = self.make_branch_and_tree('.')
1184
tt = TreeTransform(wt) # TreeTransform obtains write lock
1186
foo_1 = tt.new_directory('foo', tt.root)
1187
tt.new_directory('bar', foo_1)
1188
foo_2 = tt.new_directory('foo', tt.root)
1189
tt.new_directory('baz', foo_2)
1190
# Lie to tt that we've already resolved all conflicts.
1191
tt.apply(no_conflicts=True)
1195
err = self.assertRaises(errors.FileExists, tt_helper)
1196
self.assertContainsRe(str(err),
1197
"^File exists: .+/foo")
1199
def test_two_directories_clash_finalize(self):
1201
wt = self.make_branch_and_tree('.')
1202
tt = TreeTransform(wt) # TreeTransform obtains write lock
1204
foo_1 = tt.new_directory('foo', tt.root)
1205
tt.new_directory('bar', foo_1)
1206
foo_2 = tt.new_directory('foo', tt.root)
1207
tt.new_directory('baz', foo_2)
1208
# Lie to tt that we've already resolved all conflicts.
1209
tt.apply(no_conflicts=True)
1213
err = self.assertRaises(errors.FileExists, tt_helper)
1214
self.assertContainsRe(str(err),
1215
"^File exists: .+/foo")
967
1218
class TransformGroup(object):
968
1220
def __init__(self, dirname, root_id):
969
1221
self.name = dirname
970
1222
os.mkdir(dirname)
1319
1573
# children of non-root directories should not be renamed
1320
1574
self.assertEqual(2, transform_result.rename_count)
1576
def test_build_tree_accelerator_tree(self):
1577
source = self.make_branch_and_tree('source')
1578
self.build_tree_contents([('source/file1', 'A')])
1579
self.build_tree_contents([('source/file2', 'B')])
1580
source.add(['file1', 'file2'], ['file1-id', 'file2-id'])
1581
source.commit('commit files')
1582
self.build_tree_contents([('source/file2', 'C')])
1584
real_source_get_file = source.get_file
1585
def get_file(file_id, path=None):
1586
calls.append(file_id)
1587
return real_source_get_file(file_id, path)
1588
source.get_file = get_file
1590
self.addCleanup(source.unlock)
1591
target = self.make_branch_and_tree('target')
1592
revision_tree = source.basis_tree()
1593
revision_tree.lock_read()
1594
self.addCleanup(revision_tree.unlock)
1595
build_tree(revision_tree, target, source)
1596
self.assertEqual(['file1-id'], calls)
1598
self.addCleanup(target.unlock)
1599
self.assertEqual([], list(target._iter_changes(revision_tree)))
1601
def test_build_tree_accelerator_tree_missing_file(self):
1602
source = self.make_branch_and_tree('source')
1603
self.build_tree_contents([('source/file1', 'A')])
1604
self.build_tree_contents([('source/file2', 'B')])
1605
source.add(['file1', 'file2'])
1606
source.commit('commit files')
1607
os.unlink('source/file1')
1608
source.remove(['file2'])
1609
target = self.make_branch_and_tree('target')
1610
revision_tree = source.basis_tree()
1611
revision_tree.lock_read()
1612
self.addCleanup(revision_tree.unlock)
1613
build_tree(revision_tree, target, source)
1615
self.addCleanup(target.unlock)
1616
self.assertEqual([], list(target._iter_changes(revision_tree)))
1618
def test_build_tree_accelerator_wrong_kind(self):
1619
self.requireFeature(SymlinkFeature)
1620
source = self.make_branch_and_tree('source')
1621
self.build_tree_contents([('source/file1', '')])
1622
self.build_tree_contents([('source/file2', '')])
1623
source.add(['file1', 'file2'], ['file1-id', 'file2-id'])
1624
source.commit('commit files')
1625
os.unlink('source/file2')
1626
self.build_tree_contents([('source/file2/', 'C')])
1627
os.unlink('source/file1')
1628
os.symlink('file2', 'source/file1')
1630
real_source_get_file = source.get_file
1631
def get_file(file_id, path=None):
1632
calls.append(file_id)
1633
return real_source_get_file(file_id, path)
1634
source.get_file = get_file
1636
self.addCleanup(source.unlock)
1637
target = self.make_branch_and_tree('target')
1638
revision_tree = source.basis_tree()
1639
revision_tree.lock_read()
1640
self.addCleanup(revision_tree.unlock)
1641
build_tree(revision_tree, target, source)
1642
self.assertEqual([], calls)
1644
self.addCleanup(target.unlock)
1645
self.assertEqual([], list(target._iter_changes(revision_tree)))
1647
def test_build_tree_accelerator_tree_moved(self):
1648
source = self.make_branch_and_tree('source')
1649
self.build_tree_contents([('source/file1', 'A')])
1650
source.add(['file1'], ['file1-id'])
1651
source.commit('commit files')
1652
source.rename_one('file1', 'file2')
1654
self.addCleanup(source.unlock)
1655
target = self.make_branch_and_tree('target')
1656
revision_tree = source.basis_tree()
1657
revision_tree.lock_read()
1658
self.addCleanup(revision_tree.unlock)
1659
build_tree(revision_tree, target, source)
1661
self.addCleanup(target.unlock)
1662
self.assertEqual([], list(target._iter_changes(revision_tree)))
1323
1665
class MockTransform(object):
1469
1812
_mover=self.ExceptionFileMover(bad_target='d'))
1470
1813
self.failUnlessExists('a')
1471
1814
self.failUnlessExists('a/b')
1816
def test_resolve_no_parent(self):
1817
wt = self.make_branch_and_tree('.')
1818
tt = TreeTransform(wt)
1819
self.addCleanup(tt.finalize)
1820
parent = tt.trans_id_file_id('parent-id')
1821
tt.new_file('file', parent, 'Contents')
1822
resolve_conflicts(tt)
1825
class TestTransformPreview(tests.TestCaseWithTransport):
1827
def create_tree(self):
1828
tree = self.make_branch_and_tree('.')
1829
self.build_tree_contents([('a', 'content 1')])
1830
tree.add('a', 'a-id')
1831
tree.commit('rev1', rev_id='rev1')
1832
return tree.branch.repository.revision_tree('rev1')
1834
def get_empty_preview(self):
1835
repository = self.make_repository('repo')
1836
tree = repository.revision_tree(_mod_revision.NULL_REVISION)
1837
preview = TransformPreview(tree)
1838
self.addCleanup(preview.finalize)
1841
def test_transform_preview(self):
1842
revision_tree = self.create_tree()
1843
preview = TransformPreview(revision_tree)
1844
self.addCleanup(preview.finalize)
1846
def test_transform_preview_tree(self):
1847
revision_tree = self.create_tree()
1848
preview = TransformPreview(revision_tree)
1849
self.addCleanup(preview.finalize)
1850
preview.get_preview_tree()
1852
def test_transform_new_file(self):
1853
revision_tree = self.create_tree()
1854
preview = TransformPreview(revision_tree)
1855
self.addCleanup(preview.finalize)
1856
preview.new_file('file2', preview.root, 'content B\n', 'file2-id')
1857
preview_tree = preview.get_preview_tree()
1858
self.assertEqual(preview_tree.kind('file2-id'), 'file')
1860
preview_tree.get_file('file2-id').read(), 'content B\n')
1862
def test_diff_preview_tree(self):
1863
revision_tree = self.create_tree()
1864
preview = TransformPreview(revision_tree)
1865
self.addCleanup(preview.finalize)
1866
preview.new_file('file2', preview.root, 'content B\n', 'file2-id')
1867
preview_tree = preview.get_preview_tree()
1869
show_diff_trees(revision_tree, preview_tree, out)
1870
lines = out.getvalue().splitlines()
1871
self.assertEqual(lines[0], "=== added file 'file2'")
1872
# 3 lines of diff administrivia
1873
self.assertEqual(lines[4], "+content B")
1875
def test_transform_conflicts(self):
1876
revision_tree = self.create_tree()
1877
preview = TransformPreview(revision_tree)
1878
self.addCleanup(preview.finalize)
1879
preview.new_file('a', preview.root, 'content 2')
1880
resolve_conflicts(preview)
1881
trans_id = preview.trans_id_file_id('a-id')
1882
self.assertEqual('a.moved', preview.final_name(trans_id))
1884
def get_tree_and_preview_tree(self):
1885
revision_tree = self.create_tree()
1886
preview = TransformPreview(revision_tree)
1887
self.addCleanup(preview.finalize)
1888
a_trans_id = preview.trans_id_file_id('a-id')
1889
preview.delete_contents(a_trans_id)
1890
preview.create_file('b content', a_trans_id)
1891
preview_tree = preview.get_preview_tree()
1892
return revision_tree, preview_tree
1894
def test_iter_changes(self):
1895
revision_tree, preview_tree = self.get_tree_and_preview_tree()
1896
root = revision_tree.inventory.root.file_id
1897
self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
1898
(root, root), ('a', 'a'), ('file', 'file'),
1900
list(preview_tree._iter_changes(revision_tree)))
1902
def test_wrong_tree_value_error(self):
1903
revision_tree, preview_tree = self.get_tree_and_preview_tree()
1904
e = self.assertRaises(ValueError, preview_tree._iter_changes,
1906
self.assertEqual('from_tree must be transform source tree.', str(e))
1908
def test_include_unchanged_value_error(self):
1909
revision_tree, preview_tree = self.get_tree_and_preview_tree()
1910
e = self.assertRaises(ValueError, preview_tree._iter_changes,
1911
revision_tree, include_unchanged=True)
1912
self.assertEqual('include_unchanged is not supported', str(e))
1914
def test_specific_files(self):
1915
revision_tree, preview_tree = self.get_tree_and_preview_tree()
1916
e = self.assertRaises(ValueError, preview_tree._iter_changes,
1917
revision_tree, specific_files=['pete'])
1918
self.assertEqual('specific_files is not supported', str(e))
1920
def test_want_unversioned_value_error(self):
1921
revision_tree, preview_tree = self.get_tree_and_preview_tree()
1922
e = self.assertRaises(ValueError, preview_tree._iter_changes,
1923
revision_tree, want_unversioned=True)
1924
self.assertEqual('want_unversioned is not supported', str(e))
1926
def test_ignore_extra_trees_no_specific_files(self):
1927
# extra_trees is harmless without specific_files, so we'll silently
1928
# accept it, even though we won't use it.
1929
revision_tree, preview_tree = self.get_tree_and_preview_tree()
1930
preview_tree._iter_changes(revision_tree, extra_trees=[preview_tree])
1932
def test_ignore_require_versioned_no_specific_files(self):
1933
# require_versioned is meaningless without specific_files.
1934
revision_tree, preview_tree = self.get_tree_and_preview_tree()
1935
preview_tree._iter_changes(revision_tree, require_versioned=False)
1937
def test_ignore_pb(self):
1938
# pb could be supported, but TT.iter_changes doesn't support it.
1939
revision_tree, preview_tree = self.get_tree_and_preview_tree()
1940
preview_tree._iter_changes(revision_tree, pb=progress.DummyProgress())
1942
def test_kind(self):
1943
revision_tree = self.create_tree()
1944
preview = TransformPreview(revision_tree)
1945
self.addCleanup(preview.finalize)
1946
preview.new_file('file', preview.root, 'contents', 'file-id')
1947
preview.new_directory('directory', preview.root, 'dir-id')
1948
preview_tree = preview.get_preview_tree()
1949
self.assertEqual('file', preview_tree.kind('file-id'))
1950
self.assertEqual('directory', preview_tree.kind('dir-id'))
1952
def test_get_file_mtime(self):
1953
preview = self.get_empty_preview()
1954
file_trans_id = preview.new_file('file', preview.root, 'contents',
1956
limbo_path = preview._limbo_name(file_trans_id)
1957
preview_tree = preview.get_preview_tree()
1958
self.assertEqual(os.stat(limbo_path).st_mtime,
1959
preview_tree.get_file_mtime('file-id'))
1961
def test_get_file(self):
1962
preview = self.get_empty_preview()
1963
preview.new_file('file', preview.root, 'contents', 'file-id')
1964
preview_tree = preview.get_preview_tree()
1965
tree_file = preview_tree.get_file('file-id')
1967
self.assertEqual('contents', tree_file.read())