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
22
UnversionedParent, ParentLoop)
22
23
from bzrlib.errors import (DuplicateKey, MalformedTransform, NoSuchFile,
23
ReusingTransform, CantMoveRoot, NotVersionedError,
24
ExistingLimbo, ImmortalLimbo, LockError)
24
ReusingTransform, CantMoveRoot,
25
PathsNotVersionedError, ExistingLimbo,
26
ImmortalLimbo, LockError)
25
27
from bzrlib.osutils import file_kind, has_symlinks, pathjoin
26
28
from bzrlib.merge import Merge3Merger
27
29
from bzrlib.tests import TestCaseInTempDir, TestSkipped, TestCase
28
30
from bzrlib.transform import (TreeTransform, ROOT_PARENT, FinalPaths,
29
31
resolve_conflicts, cook_conflicts,
30
32
find_interesting, build_tree, get_backup_name)
33
import bzrlib.urlutils as urlutils
32
35
class TestTreeTransform(TestCaseInTempDir):
34
38
super(TestTreeTransform, self).setUp()
35
39
self.wt = BzrDir.create_standalone_workingtree('.')
488
495
self.assertEqual(find_interesting(wt, wt, ['vfile']),
489
496
set(['myfile-id']))
490
self.assertRaises(NotVersionedError, find_interesting, wt, wt,
497
self.assertRaises(PathsNotVersionedError, find_interesting, wt, wt,
500
def test_set_executability_order(self):
501
"""Ensure that executability behaves the same, no matter what order.
503
- create file and set executability simultaneously
504
- create file and set executability afterward
505
- unsetting the executability of a file whose executability has not been
506
declared should throw an exception (this may happen when a
507
merge attempts to create a file with a duplicate ID)
509
transform, root = self.get_transform()
511
transform.new_file('set_on_creation', root, 'Set on creation', 'soc',
513
sac = transform.new_file('set_after_creation', root, 'Set after creation', 'sac')
514
transform.set_executability(True, sac)
515
uws = transform.new_file('unset_without_set', root, 'Unset badly', 'uws')
516
self.assertRaises(KeyError, transform.set_executability, None, uws)
518
self.assertTrue(wt.is_executable('soc'))
519
self.assertTrue(wt.is_executable('sac'))
494
522
class TransformGroup(object):
495
523
def __init__(self, dirname):
702
731
self.assertIs(os.path.isdir('b/foo'), True)
703
732
self.assertEqual(file('b/foo/bar', 'rb').read(), "contents")
704
733
self.assertEqual(os.readlink('b/foo/baz'), 'a/foo/bar')
735
def test_file_conflict_handling(self):
736
"""Ensure that when building trees, conflict handling is done"""
737
source = self.make_branch_and_tree('source')
738
target = self.make_branch_and_tree('target')
739
self.build_tree(['source/file', 'target/file'])
740
source.add('file', 'new-file')
741
source.commit('added file')
742
build_tree(source.basis_tree(), target)
743
self.assertEqual([DuplicateEntry('Moved existing file to',
744
'file.moved', 'file', None, 'new-file')],
746
target2 = self.make_branch_and_tree('target2')
747
target_file = file('target2/file', 'wb')
749
source_file = file('source/file', 'rb')
751
target_file.write(source_file.read())
756
build_tree(source.basis_tree(), target2)
757
self.assertEqual([], target2.conflicts())
759
def test_symlink_conflict_handling(self):
760
"""Ensure that when building trees, conflict handling is done"""
761
if not has_symlinks():
762
raise TestSkipped('Test requires symlink support')
763
source = self.make_branch_and_tree('source')
764
os.symlink('foo', 'source/symlink')
765
source.add('symlink', 'new-symlink')
766
source.commit('added file')
767
target = self.make_branch_and_tree('target')
768
os.symlink('bar', 'target/symlink')
769
build_tree(source.basis_tree(), target)
770
self.assertEqual([DuplicateEntry('Moved existing file to',
771
'symlink.moved', 'symlink', None, 'new-symlink')],
773
target = self.make_branch_and_tree('target2')
774
os.symlink('foo', 'target2/symlink')
775
build_tree(source.basis_tree(), target)
776
self.assertEqual([], target.conflicts())
778
def test_directory_conflict_handling(self):
779
"""Ensure that when building trees, conflict handling is done"""
780
source = self.make_branch_and_tree('source')
781
target = self.make_branch_and_tree('target')
782
self.build_tree(['source/dir1/', 'source/dir1/file', 'target/dir1/'])
783
source.add(['dir1', 'dir1/file'], ['new-dir1', 'new-file'])
784
source.commit('added file')
785
build_tree(source.basis_tree(), target)
786
self.assertEqual([], target.conflicts())
787
self.failUnlessExists('target/dir1/file')
789
# Ensure contents are merged
790
target = self.make_branch_and_tree('target2')
791
self.build_tree(['target2/dir1/', 'target2/dir1/file2'])
792
build_tree(source.basis_tree(), target)
793
self.assertEqual([], target.conflicts())
794
self.failUnlessExists('target2/dir1/file2')
795
self.failUnlessExists('target2/dir1/file')
797
# Ensure new contents are suppressed for existing branches
798
target = self.make_branch_and_tree('target3')
799
self.make_branch('target3/dir1')
800
self.build_tree(['target3/dir1/file2'])
801
build_tree(source.basis_tree(), target)
802
self.failIfExists('target3/dir1/file')
803
self.failUnlessExists('target3/dir1/file2')
804
self.failUnlessExists('target3/dir1.diverted/file')
805
self.assertEqual([DuplicateEntry('Diverted to',
806
'dir1.diverted', 'dir1', 'new-dir1', None)],
809
target = self.make_branch_and_tree('target4')
810
self.build_tree(['target4/dir1/'])
811
self.make_branch('target4/dir1/file')
812
build_tree(source.basis_tree(), target)
813
self.failUnlessExists('target4/dir1/file')
814
self.assertEqual('directory', file_kind('target4/dir1/file'))
815
self.failUnlessExists('target4/dir1/file.diverted')
816
self.assertEqual([DuplicateEntry('Diverted to',
817
'dir1/file.diverted', 'dir1/file', 'new-file', None)],
820
def test_mixed_conflict_handling(self):
821
"""Ensure that when building trees, conflict handling is done"""
822
source = self.make_branch_and_tree('source')
823
target = self.make_branch_and_tree('target')
824
self.build_tree(['source/name', 'target/name/'])
825
source.add('name', 'new-name')
826
source.commit('added file')
827
build_tree(source.basis_tree(), target)
828
self.assertEqual([DuplicateEntry('Moved existing file to',
829
'name.moved', 'name', None, 'new-name')], target.conflicts())
831
def test_raises_in_populated(self):
832
source = self.make_branch_and_tree('source')
833
self.build_tree(['source/name'])
835
source.commit('added name')
836
target = self.make_branch_and_tree('target')
837
self.build_tree(['target/name'])
839
self.assertRaises(AssertionError, build_tree, source.basis_tree(),
706
843
class MockTransform(object):
708
845
def has_named_child(self, by_parent, parent_id, name):