1
1
# Copyright (C) 2006 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
# GNU General Public License for more details.
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
25
from bzrlib.bzrdir import BzrDir
20
26
from bzrlib.conflicts import (DuplicateEntry, DuplicateID, MissingParent,
21
UnversionedParent, ParentLoop)
27
UnversionedParent, ParentLoop, DeletingParent,)
22
28
from bzrlib.errors import (DuplicateKey, MalformedTransform, NoSuchFile,
23
29
ReusingTransform, CantMoveRoot,
24
30
PathsNotVersionedError, ExistingLimbo,
416
426
'dorothy.moved', 'dorothy', None,
418
428
self.assertEqual(cooked_conflicts[1], duplicate_id)
419
missing_parent = MissingParent('Not deleting', 'oz', 'oz-id')
429
missing_parent = MissingParent('Created directory', 'munchkincity',
431
deleted_parent = DeletingParent('Not deleting', 'oz', 'oz-id')
420
432
self.assertEqual(cooked_conflicts[2], missing_parent)
421
unversioned_parent = UnversionedParent('Versioned directory', 'oz',
433
unversioned_parent = UnversionedParent('Versioned directory',
436
unversioned_parent2 = UnversionedParent('Versioned directory', 'oz',
423
438
self.assertEqual(cooked_conflicts[3], unversioned_parent)
424
439
parent_loop = ParentLoop('Cancelled move', 'oz/emeraldcity',
425
440
'oz/emeraldcity', 'emerald-id', 'emerald-id')
426
self.assertEqual(cooked_conflicts[4], parent_loop)
427
self.assertEqual(len(cooked_conflicts), 5)
441
self.assertEqual(cooked_conflicts[4], deleted_parent)
442
self.assertEqual(cooked_conflicts[5], unversioned_parent2)
443
self.assertEqual(cooked_conflicts[6], parent_loop)
444
self.assertEqual(len(cooked_conflicts), 7)
430
447
def test_string_conflicts(self):
440
457
self.assertEqual(conflicts_s[1], 'Conflict adding id to dorothy. '
441
458
'Unversioned existing file '
442
459
'dorothy.moved.')
443
self.assertEqual(conflicts_s[2], 'Conflict adding files to oz. '
445
self.assertEqual(conflicts_s[3], 'Conflict adding versioned files to '
446
'oz. Versioned directory.')
447
self.assertEqual(conflicts_s[4], 'Conflict moving oz/emeraldcity into'
460
self.assertEqual(conflicts_s[2], 'Conflict adding files to'
461
' munchkincity. Created directory.')
462
self.assertEqual(conflicts_s[3], 'Conflict because munchkincity is not'
463
' versioned, but has versioned'
464
' children. Versioned directory.')
465
self.assertEqualDiff(conflicts_s[4], "Conflict: can't delete oz because it"
466
" is not empty. Not deleting.")
467
self.assertEqual(conflicts_s[5], 'Conflict because oz is not'
468
' versioned, but has versioned'
469
' children. Versioned directory.')
470
self.assertEqual(conflicts_s[6], 'Conflict moving oz/emeraldcity into'
448
471
' oz/emeraldcity. Cancelled move.')
450
473
def test_moving_versioned_directories(self):
517
540
self.assertTrue(wt.is_executable('soc'))
518
541
self.assertTrue(wt.is_executable('sac'))
543
def test__set_mode_stats_correctly(self):
544
"""_set_mode stats to determine file mode."""
545
if sys.platform == 'win32':
546
raise TestSkipped('chmod has no effect on win32')
550
def instrumented_stat(path):
551
stat_paths.append(path)
552
return real_stat(path)
554
transform, root = self.get_transform()
556
bar1_id = transform.new_file('bar', root, 'bar contents 1\n',
557
file_id='bar-id-1', executable=False)
560
transform, root = self.get_transform()
561
bar1_id = transform.trans_id_tree_path('bar')
562
bar2_id = transform.trans_id_tree_path('bar2')
564
os.stat = instrumented_stat
565
transform.create_file('bar2 contents\n', bar2_id, mode_id=bar1_id)
570
bar1_abspath = self.wt.abspath('bar')
571
self.assertEqual([bar1_abspath], stat_paths)
521
574
class TransformGroup(object):
522
575
def __init__(self, dirname):
729
784
self.assertIs(os.path.isdir('b/foo'), True)
730
785
self.assertEqual(file('b/foo/bar', 'rb').read(), "contents")
731
786
self.assertEqual(os.readlink('b/foo/baz'), 'a/foo/bar')
788
def test_file_conflict_handling(self):
789
"""Ensure that when building trees, conflict handling is done"""
790
source = self.make_branch_and_tree('source')
791
target = self.make_branch_and_tree('target')
792
self.build_tree(['source/file', 'target/file'])
793
source.add('file', 'new-file')
794
source.commit('added file')
795
build_tree(source.basis_tree(), target)
796
self.assertEqual([DuplicateEntry('Moved existing file to',
797
'file.moved', 'file', None, 'new-file')],
799
target2 = self.make_branch_and_tree('target2')
800
target_file = file('target2/file', 'wb')
802
source_file = file('source/file', 'rb')
804
target_file.write(source_file.read())
809
build_tree(source.basis_tree(), target2)
810
self.assertEqual([], target2.conflicts())
812
def test_symlink_conflict_handling(self):
813
"""Ensure that when building trees, conflict handling is done"""
814
if not has_symlinks():
815
raise TestSkipped('Test requires symlink support')
816
source = self.make_branch_and_tree('source')
817
os.symlink('foo', 'source/symlink')
818
source.add('symlink', 'new-symlink')
819
source.commit('added file')
820
target = self.make_branch_and_tree('target')
821
os.symlink('bar', 'target/symlink')
822
build_tree(source.basis_tree(), target)
823
self.assertEqual([DuplicateEntry('Moved existing file to',
824
'symlink.moved', 'symlink', None, 'new-symlink')],
826
target = self.make_branch_and_tree('target2')
827
os.symlink('foo', 'target2/symlink')
828
build_tree(source.basis_tree(), target)
829
self.assertEqual([], target.conflicts())
831
def test_directory_conflict_handling(self):
832
"""Ensure that when building trees, conflict handling is done"""
833
source = self.make_branch_and_tree('source')
834
target = self.make_branch_and_tree('target')
835
self.build_tree(['source/dir1/', 'source/dir1/file', 'target/dir1/'])
836
source.add(['dir1', 'dir1/file'], ['new-dir1', 'new-file'])
837
source.commit('added file')
838
build_tree(source.basis_tree(), target)
839
self.assertEqual([], target.conflicts())
840
self.failUnlessExists('target/dir1/file')
842
# Ensure contents are merged
843
target = self.make_branch_and_tree('target2')
844
self.build_tree(['target2/dir1/', 'target2/dir1/file2'])
845
build_tree(source.basis_tree(), target)
846
self.assertEqual([], target.conflicts())
847
self.failUnlessExists('target2/dir1/file2')
848
self.failUnlessExists('target2/dir1/file')
850
# Ensure new contents are suppressed for existing branches
851
target = self.make_branch_and_tree('target3')
852
self.make_branch('target3/dir1')
853
self.build_tree(['target3/dir1/file2'])
854
build_tree(source.basis_tree(), target)
855
self.failIfExists('target3/dir1/file')
856
self.failUnlessExists('target3/dir1/file2')
857
self.failUnlessExists('target3/dir1.diverted/file')
858
self.assertEqual([DuplicateEntry('Diverted to',
859
'dir1.diverted', 'dir1', 'new-dir1', None)],
862
target = self.make_branch_and_tree('target4')
863
self.build_tree(['target4/dir1/'])
864
self.make_branch('target4/dir1/file')
865
build_tree(source.basis_tree(), target)
866
self.failUnlessExists('target4/dir1/file')
867
self.assertEqual('directory', file_kind('target4/dir1/file'))
868
self.failUnlessExists('target4/dir1/file.diverted')
869
self.assertEqual([DuplicateEntry('Diverted to',
870
'dir1/file.diverted', 'dir1/file', 'new-file', None)],
873
def test_mixed_conflict_handling(self):
874
"""Ensure that when building trees, conflict handling is done"""
875
source = self.make_branch_and_tree('source')
876
target = self.make_branch_and_tree('target')
877
self.build_tree(['source/name', 'target/name/'])
878
source.add('name', 'new-name')
879
source.commit('added file')
880
build_tree(source.basis_tree(), target)
881
self.assertEqual([DuplicateEntry('Moved existing file to',
882
'name.moved', 'name', None, 'new-name')], target.conflicts())
884
def test_raises_in_populated(self):
885
source = self.make_branch_and_tree('source')
886
self.build_tree(['source/name'])
888
source.commit('added name')
889
target = self.make_branch_and_tree('target')
890
self.build_tree(['target/name'])
892
self.assertRaises(AssertionError, build_tree, source.basis_tree(),
733
896
class MockTransform(object):
735
898
def has_named_child(self, by_parent, parent_id, name):