19
19
from bzrlib.bzrdir import BzrDir
20
from bzrlib.conflicts import (DuplicateEntry, DuplicateID, MissingParent,
21
UnversionedParent, ParentLoop)
22
20
from bzrlib.errors import (DuplicateKey, MalformedTransform, NoSuchFile,
23
21
ReusingTransform, CantMoveRoot, NotVersionedError,
24
22
ExistingLimbo, ImmortalLimbo, LockError)
25
23
from bzrlib.osutils import file_kind, has_symlinks, pathjoin
26
24
from bzrlib.merge import Merge3Merger
27
from bzrlib.tests import TestCaseInTempDir, TestSkipped, TestCase
25
from bzrlib.tests import TestCaseInTempDir, TestSkipped
28
26
from bzrlib.transform import (TreeTransform, ROOT_PARENT, FinalPaths,
29
27
resolve_conflicts, cook_conflicts,
30
find_interesting, build_tree, get_backup_name)
28
conflicts_strings, find_interesting, build_tree)
32
30
class TestTreeTransform(TestCaseInTempDir):
79
77
transform.create_file('contents', trans_id2)
80
78
transform.set_executability(False, trans_id2)
81
79
transform.version_file('my_pretties2', trans_id2)
82
modified_paths = transform.apply().modified_paths
83
81
self.assertEqual('contents', self.wt.get_file_byname('name').read())
84
82
self.assertEqual(self.wt.path2id('name'), 'my_pretties')
85
83
self.assertIs(self.wt.is_executable('my_pretties'), True)
86
84
self.assertIs(self.wt.is_executable('my_pretties2'), False)
87
85
self.assertEqual('directory', file_kind(self.wt.abspath('oz')))
88
self.assertEqual(len(modified_paths), 3)
89
tree_mod_paths = [self.wt.id2abspath(f) for f in
90
('ozzie', 'my_pretties', 'my_pretties2')]
91
self.assertSubset(tree_mod_paths, modified_paths)
92
86
# is it safe to finalize repeatedly?
93
87
transform.finalize()
94
88
transform.finalize()
190
184
transform3.adjust_path('tip', root_id, tip_id)
191
185
transform3.apply()
193
def test_add_del(self):
194
start, root = self.get_transform()
195
start.new_directory('a', root, 'a')
197
transform, root = self.get_transform()
198
transform.delete_versioned(transform.trans_id_tree_file_id('a'))
199
transform.new_directory('a', root, 'a')
202
187
def test_unversioning(self):
203
188
create_tree, root = self.get_transform()
204
189
parent_id = create_tree.new_directory('parent', root, 'parent-id')
403
388
tt, emerald, oz, old_dorothy, new_dorothy = self.get_conflicted()
404
389
raw_conflicts = resolve_conflicts(tt)
405
390
cooked_conflicts = cook_conflicts(raw_conflicts, tt)
406
duplicate = DuplicateEntry('Moved existing file to', 'dorothy.moved',
407
'dorothy', None, 'dorothy-id')
391
duplicate = ('duplicate', 'Moved existing file to', 'dorothy.moved',
392
None, 'dorothy', 'dorothy-id')
408
393
self.assertEqual(cooked_conflicts[0], duplicate)
409
duplicate_id = DuplicateID('Unversioned existing file',
410
'dorothy.moved', 'dorothy', None,
394
duplicate_id = ('duplicate id', 'Unversioned existing file',
395
'dorothy.moved', None, 'dorothy', 'dorothy-id')
412
396
self.assertEqual(cooked_conflicts[1], duplicate_id)
413
missing_parent = MissingParent('Not deleting', 'oz', 'oz-id')
397
missing_parent = ('missing parent', 'Not deleting', 'oz', 'oz-id')
414
398
self.assertEqual(cooked_conflicts[2], missing_parent)
415
unversioned_parent = UnversionedParent('Versioned directory', 'oz',
399
unversioned_parent = ('unversioned parent',
400
'Versioned directory', 'oz', 'oz-id')
417
401
self.assertEqual(cooked_conflicts[3], unversioned_parent)
418
parent_loop = ParentLoop('Cancelled move', 'oz/emeraldcity',
419
'oz/emeraldcity', 'emerald-id', 'emerald-id')
402
parent_loop = ('parent loop', 'Cancelled move', 'oz/emeraldcity',
403
'emerald-id', 'oz/emeraldcity', 'emerald-id')
420
404
self.assertEqual(cooked_conflicts[4], parent_loop)
421
405
self.assertEqual(len(cooked_conflicts), 5)
426
410
raw_conflicts = resolve_conflicts(tt)
427
411
cooked_conflicts = cook_conflicts(raw_conflicts, tt)
429
conflicts_s = [str(c) for c in cooked_conflicts]
413
conflicts_s = list(conflicts_strings(cooked_conflicts))
430
414
self.assertEqual(len(cooked_conflicts), len(conflicts_s))
431
415
self.assertEqual(conflicts_s[0], 'Conflict adding file dorothy. '
432
416
'Moved existing file to '
570
554
self.assertEqual(this.wt.get_file_byname('i.OTHER').read(),
572
556
self.assertEqual(os.path.exists(this.wt.abspath('i.BASE')), False)
573
modified = ['a', 'b', 'c', 'h', 'i']
574
merge_modified = this.wt.merge_modified()
575
self.assertSubset(merge_modified, modified)
576
self.assertEqual(len(merge_modified), len(modified))
577
file(this.wt.id2abspath('a'), 'wb').write('booga')
579
merge_modified = this.wt.merge_modified()
580
self.assertSubset(merge_modified, modified)
581
self.assertEqual(len(merge_modified), len(modified))
585
558
def test_file_merge(self):
586
559
if not has_symlinks():
702
675
self.assertIs(os.path.isdir('b/foo'), True)
703
676
self.assertEqual(file('b/foo/bar', 'rb').read(), "contents")
704
677
self.assertEqual(os.readlink('b/foo/baz'), 'a/foo/bar')
706
class MockTransform(object):
708
def has_named_child(self, by_parent, parent_id, name):
709
for child_id in by_parent[parent_id]:
713
elif name == "name.~%s~" % child_id:
717
class MockEntry(object):
719
object.__init__(self)
722
class TestGetBackupName(TestCase):
723
def test_get_backup_name(self):
725
name = get_backup_name(MockEntry(), {'a':[]}, 'a', tt)
726
self.assertEqual(name, 'name.~1~')
727
name = get_backup_name(MockEntry(), {'a':['1']}, 'a', tt)
728
self.assertEqual(name, 'name.~2~')
729
name = get_backup_name(MockEntry(), {'a':['2']}, 'a', tt)
730
self.assertEqual(name, 'name.~1~')
731
name = get_backup_name(MockEntry(), {'a':['2'], 'b':[]}, 'b', tt)
732
self.assertEqual(name, 'name.~1~')
733
name = get_backup_name(MockEntry(), {'a':['1', '2', '3']}, 'a', tt)
734
self.assertEqual(name, 'name.~4~')