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
from bzrlib import tests
19
20
from bzrlib.bzrdir import BzrDir
20
21
from bzrlib.conflicts import (DuplicateEntry, DuplicateID, MissingParent,
21
UnversionedParent, ParentLoop)
22
UnversionedParent, ParentLoop, DeletingParent,)
22
23
from bzrlib.errors import (DuplicateKey, MalformedTransform, NoSuchFile,
23
24
ReusingTransform, CantMoveRoot,
24
25
PathsNotVersionedError, ExistingLimbo,
416
421
'dorothy.moved', 'dorothy', None,
418
423
self.assertEqual(cooked_conflicts[1], duplicate_id)
419
missing_parent = MissingParent('Not deleting', 'oz', 'oz-id')
424
missing_parent = MissingParent('Created directory', 'munchkincity',
426
deleted_parent = DeletingParent('Not deleting', 'oz', 'oz-id')
420
427
self.assertEqual(cooked_conflicts[2], missing_parent)
421
unversioned_parent = UnversionedParent('Versioned directory', 'oz',
428
unversioned_parent = UnversionedParent('Versioned directory',
431
unversioned_parent2 = UnversionedParent('Versioned directory', 'oz',
423
433
self.assertEqual(cooked_conflicts[3], unversioned_parent)
424
434
parent_loop = ParentLoop('Cancelled move', 'oz/emeraldcity',
425
435
'oz/emeraldcity', 'emerald-id', 'emerald-id')
426
self.assertEqual(cooked_conflicts[4], parent_loop)
427
self.assertEqual(len(cooked_conflicts), 5)
436
self.assertEqual(cooked_conflicts[4], deleted_parent)
437
self.assertEqual(cooked_conflicts[5], unversioned_parent2)
438
self.assertEqual(cooked_conflicts[6], parent_loop)
439
self.assertEqual(len(cooked_conflicts), 7)
430
442
def test_string_conflicts(self):
440
452
self.assertEqual(conflicts_s[1], 'Conflict adding id to dorothy. '
441
453
'Unversioned existing file '
442
454
'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'
455
self.assertEqual(conflicts_s[2], 'Conflict adding files to'
456
' munchkincity. Created directory.')
457
self.assertEqual(conflicts_s[3], 'Conflict because munchkincity is not'
458
' versioned, but has versioned'
459
' children. Versioned directory.')
460
self.assertEqualDiff(conflicts_s[4], "Conflict: can't delete oz because it"
461
" is not empty. Not deleting.")
462
self.assertEqual(conflicts_s[5], 'Conflict because oz is not'
463
' versioned, but has versioned'
464
' children. Versioned directory.')
465
self.assertEqual(conflicts_s[6], 'Conflict moving oz/emeraldcity into'
448
466
' oz/emeraldcity. Cancelled move.')
450
468
def test_moving_versioned_directories(self):
729
748
self.assertIs(os.path.isdir('b/foo'), True)
730
749
self.assertEqual(file('b/foo/bar', 'rb').read(), "contents")
731
750
self.assertEqual(os.readlink('b/foo/baz'), 'a/foo/bar')
752
def test_file_conflict_handling(self):
753
"""Ensure that when building trees, conflict handling is done"""
754
source = self.make_branch_and_tree('source')
755
target = self.make_branch_and_tree('target')
756
self.build_tree(['source/file', 'target/file'])
757
source.add('file', 'new-file')
758
source.commit('added file')
759
build_tree(source.basis_tree(), target)
760
self.assertEqual([DuplicateEntry('Moved existing file to',
761
'file.moved', 'file', None, 'new-file')],
763
target2 = self.make_branch_and_tree('target2')
764
target_file = file('target2/file', 'wb')
766
source_file = file('source/file', 'rb')
768
target_file.write(source_file.read())
773
build_tree(source.basis_tree(), target2)
774
self.assertEqual([], target2.conflicts())
776
def test_symlink_conflict_handling(self):
777
"""Ensure that when building trees, conflict handling is done"""
778
if not has_symlinks():
779
raise TestSkipped('Test requires symlink support')
780
source = self.make_branch_and_tree('source')
781
os.symlink('foo', 'source/symlink')
782
source.add('symlink', 'new-symlink')
783
source.commit('added file')
784
target = self.make_branch_and_tree('target')
785
os.symlink('bar', 'target/symlink')
786
build_tree(source.basis_tree(), target)
787
self.assertEqual([DuplicateEntry('Moved existing file to',
788
'symlink.moved', 'symlink', None, 'new-symlink')],
790
target = self.make_branch_and_tree('target2')
791
os.symlink('foo', 'target2/symlink')
792
build_tree(source.basis_tree(), target)
793
self.assertEqual([], target.conflicts())
795
def test_directory_conflict_handling(self):
796
"""Ensure that when building trees, conflict handling is done"""
797
source = self.make_branch_and_tree('source')
798
target = self.make_branch_and_tree('target')
799
self.build_tree(['source/dir1/', 'source/dir1/file', 'target/dir1/'])
800
source.add(['dir1', 'dir1/file'], ['new-dir1', 'new-file'])
801
source.commit('added file')
802
build_tree(source.basis_tree(), target)
803
self.assertEqual([], target.conflicts())
804
self.failUnlessExists('target/dir1/file')
806
# Ensure contents are merged
807
target = self.make_branch_and_tree('target2')
808
self.build_tree(['target2/dir1/', 'target2/dir1/file2'])
809
build_tree(source.basis_tree(), target)
810
self.assertEqual([], target.conflicts())
811
self.failUnlessExists('target2/dir1/file2')
812
self.failUnlessExists('target2/dir1/file')
814
# Ensure new contents are suppressed for existing branches
815
target = self.make_branch_and_tree('target3')
816
self.make_branch('target3/dir1')
817
self.build_tree(['target3/dir1/file2'])
818
build_tree(source.basis_tree(), target)
819
self.failIfExists('target3/dir1/file')
820
self.failUnlessExists('target3/dir1/file2')
821
self.failUnlessExists('target3/dir1.diverted/file')
822
self.assertEqual([DuplicateEntry('Diverted to',
823
'dir1.diverted', 'dir1', 'new-dir1', None)],
826
target = self.make_branch_and_tree('target4')
827
self.build_tree(['target4/dir1/'])
828
self.make_branch('target4/dir1/file')
829
build_tree(source.basis_tree(), target)
830
self.failUnlessExists('target4/dir1/file')
831
self.assertEqual('directory', file_kind('target4/dir1/file'))
832
self.failUnlessExists('target4/dir1/file.diverted')
833
self.assertEqual([DuplicateEntry('Diverted to',
834
'dir1/file.diverted', 'dir1/file', 'new-file', None)],
837
def test_mixed_conflict_handling(self):
838
"""Ensure that when building trees, conflict handling is done"""
839
source = self.make_branch_and_tree('source')
840
target = self.make_branch_and_tree('target')
841
self.build_tree(['source/name', 'target/name/'])
842
source.add('name', 'new-name')
843
source.commit('added file')
844
build_tree(source.basis_tree(), target)
845
self.assertEqual([DuplicateEntry('Moved existing file to',
846
'name.moved', 'name', None, 'new-name')], target.conflicts())
848
def test_raises_in_populated(self):
849
source = self.make_branch_and_tree('source')
850
self.build_tree(['source/name'])
852
source.commit('added name')
853
target = self.make_branch_and_tree('target')
854
self.build_tree(['target/name'])
856
self.assertRaises(AssertionError, build_tree, source.basis_tree(),
733
860
class MockTransform(object):
735
862
def has_named_child(self, by_parent, parent_id, name):