~bzr-pqm/bzr/bzr.dev

2052.3.2 by John Arbash Meinel
Change Copyright .. by Canonical to Copyright ... Canonical
1
# Copyright (C) 2006 Canonical Ltd
1988.2.2 by Robert Collins
Add test script I forgotten - doh.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1988.2.2 by Robert Collins
Add test script I forgotten - doh.
16
17
"""Tests of the WorkingTree.unversion API."""
18
2922.2.6 by John Arbash Meinel
Add another direct test in unversion, because the other test
19
from bzrlib import (
20
    errors,
21
    osutils,
22
    )
4523.1.4 by Martin Pool
Rename remaining *_implementations tests
23
from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
1988.2.2 by Robert Collins
Add test script I forgotten - doh.
24
25
26
class TestUnversion(TestCaseWithWorkingTree):
27
28
    def test_unversion_requires_write_lock(self):
29
        """WT.unversion([]) in a read lock raises ReadOnlyError."""
30
        tree = self.make_branch_and_tree('.')
31
        tree.lock_read()
32
        self.assertRaises(errors.ReadOnlyError, tree.unversion, [])
33
        tree.unlock()
34
35
    def test_unversion_missing_file(self):
36
        """WT.unversion(['missing-id']) raises NoSuchId."""
37
        tree = self.make_branch_and_tree('.')
38
        self.assertRaises(errors.NoSuchId, tree.unversion, ['missing-id'])
39
4536.2.1 by Robert Collins
Fix WorkingTree4.unversion when unversioning the parents of files that were renamed from a basis tree. (Robert Collins, bug 187207)
40
    def test_unversion_parent_and_child_renamed_bug_187207(self):
41
        # When unversioning dirstate trees show a bug in dealing with
42
        # unversioning children of reparented children of unversioned
43
        # paths when relocation entries are present and the relocation
44
        # points later into the dirstate.
45
        tree = self.make_branch_and_tree(['.'])
46
        self.build_tree(['del/', 'del/sub/', 'del/sub/b'])
47
        tree.add(['del', 'del/sub', 'del/sub/b'], ['del', 'sub', 'b'])
48
        tree.commit('setup')
49
        tree.rename_one('del/sub', 'sub')
50
        self.assertEqual('sub/b', tree.id2path('b'))
51
        tree.unversion(['del', 'b'])
52
        self.assertRaises(errors.NoSuchId, tree.id2path, 'b')
53
1988.2.2 by Robert Collins
Add test script I forgotten - doh.
54
    def test_unversion_several_files(self):
55
        """After unversioning several files, they should not be versioned."""
56
        tree = self.make_branch_and_tree('.')
57
        self.build_tree(['a', 'b', 'c'])
58
        tree.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
59
        # within a lock unversion should take effect
60
        tree.lock_write()
61
        tree.unversion(['a-id', 'b-id'])
62
        self.assertFalse(tree.has_id('a-id'))
63
        self.assertFalse(tree.has_id('b-id'))
64
        self.assertTrue(tree.has_id('c-id'))
65
        self.assertTrue(tree.has_filename('a'))
66
        self.assertTrue(tree.has_filename('b'))
67
        self.assertTrue(tree.has_filename('c'))
68
        tree.unlock()
1988.2.3 by Robert Collins
Merge in commit test case for deletion-heuristic.
69
        # the changes should have persisted to disk - reopen the workingtree
70
        # to be sure.
71
        tree = tree.bzrdir.open_workingtree()
2255.2.46 by Robert Collins
Dirstate - unversion should set the tree state as dirty.
72
        tree.lock_read()
1988.2.2 by Robert Collins
Add test script I forgotten - doh.
73
        self.assertFalse(tree.has_id('a-id'))
74
        self.assertFalse(tree.has_id('b-id'))
75
        self.assertTrue(tree.has_id('c-id'))
76
        self.assertTrue(tree.has_filename('a'))
77
        self.assertTrue(tree.has_filename('b'))
78
        self.assertTrue(tree.has_filename('c'))
2255.2.46 by Robert Collins
Dirstate - unversion should set the tree state as dirty.
79
        tree.unlock()
2255.7.41 by John Arbash Meinel
WorkingTree.unversion() should not raise if unversioning a child and a parent.
80
1988.2.2 by Robert Collins
Add test script I forgotten - doh.
81
    def test_unversion_subtree(self):
82
        """Unversioning the root of a subtree unversions the entire subtree."""
83
        tree = self.make_branch_and_tree('.')
84
        self.build_tree(['a/', 'a/b', 'c'])
85
        tree.add(['a', 'a/b', 'c'], ['a-id', 'b-id', 'c-id'])
86
        # within a lock unversion should take effect
87
        tree.lock_write()
88
        tree.unversion(['a-id'])
89
        self.assertFalse(tree.has_id('a-id'))
90
        self.assertFalse(tree.has_id('b-id'))
91
        self.assertTrue(tree.has_id('c-id'))
92
        self.assertTrue(tree.has_filename('a'))
93
        self.assertTrue(tree.has_filename('a/b'))
94
        self.assertTrue(tree.has_filename('c'))
95
        tree.unlock()
2255.7.41 by John Arbash Meinel
WorkingTree.unversion() should not raise if unversioning a child and a parent.
96
97
    def test_unversion_subtree_and_children(self):
98
        """Passing a child id will raise NoSuchId.
99
100
        This is because the parent directory will have already been removed.
101
        """
102
        tree = self.make_branch_and_tree('.')
103
        self.build_tree(['a/', 'a/b', 'a/c', 'd'])
104
        tree.add(['a', 'a/b', 'a/c', 'd'], ['a-id', 'b-id', 'c-id', 'd-id'])
105
        tree.lock_write()
106
        try:
107
            tree.unversion(['b-id', 'a-id'])
108
            self.assertFalse(tree.has_id('a-id'))
109
            self.assertFalse(tree.has_id('b-id'))
110
            self.assertFalse(tree.has_id('c-id'))
111
            self.assertTrue(tree.has_id('d-id'))
112
            # The files are still on disk
113
            self.assertTrue(tree.has_filename('a'))
114
            self.assertTrue(tree.has_filename('a/b'))
115
            self.assertTrue(tree.has_filename('a/c'))
116
            self.assertTrue(tree.has_filename('d'))
117
        finally:
118
            tree.unlock()
2922.2.5 by John Arbash Meinel
Add a direct test for WT.unversion()
119
120
    def test_unversion_renamed(self):
121
        tree = self.make_branch_and_tree('a')
122
        self.build_tree(['a/dir/', 'a/dir/f1', 'a/dir/f2', 'a/dir/f3',
123
                         'a/dir2/'])
124
        tree.add(['dir', 'dir/f1', 'dir/f2', 'dir/f3', 'dir2'],
125
                 ['dir-id', 'f1-id', 'f2-id', 'f3-id', 'dir2-id'])
126
        rev_id1 = tree.commit('init')
127
        # Start off by renaming entries, and then unversion a bunch of entries
128
        # https://bugs.launchpad.net/bzr/+bug/114615
129
        tree.rename_one('dir/f1', 'dir/a')
130
        tree.rename_one('dir/f2', 'dir/z')
131
        tree.move(['dir/f3'], 'dir2')
132
133
        tree.lock_read()
134
        try:
2946.3.3 by John Arbash Meinel
Prefer tree.get_root_id() as more explicit than tree.path2id('')
135
            root_id = tree.get_root_id()
2922.2.5 by John Arbash Meinel
Add a direct test for WT.unversion()
136
            paths = [(path, ie.file_id)
137
                     for path, ie in tree.iter_entries_by_dir()]
138
        finally:
139
            tree.unlock()
140
        self.assertEqual([('', root_id),
141
                          ('dir', 'dir-id'),
142
                          ('dir2', 'dir2-id'),
143
                          ('dir/a', 'f1-id'),
144
                          ('dir/z', 'f2-id'),
145
                          ('dir2/f3', 'f3-id'),
146
                         ], paths)
147
148
        tree.unversion(set(['dir-id']))
149
        paths = [(path, ie.file_id)
150
                 for path, ie in tree.iter_entries_by_dir()]
151
152
        self.assertEqual([('', root_id),
153
                          ('dir2', 'dir2-id'),
154
                          ('dir2/f3', 'f3-id'),
155
                         ], paths)
156
2922.2.6 by John Arbash Meinel
Add another direct test in unversion, because the other test
157
    def test_unversion_after_conflicted_merge(self):
158
        # Test for bug #114615
159
        tree_a = self.make_branch_and_tree('A')
160
        self.build_tree(['A/a/', 'A/a/m', 'A/a/n'])
161
        tree_a.add(['a', 'a/m', 'a/n'], ['a-id', 'm-id', 'n-id'])
162
        tree_a.commit('init')
163
164
        tree_a.lock_read()
165
        try:
2946.3.3 by John Arbash Meinel
Prefer tree.get_root_id() as more explicit than tree.path2id('')
166
            root_id = tree_a.get_root_id()
2922.2.6 by John Arbash Meinel
Add another direct test in unversion, because the other test
167
        finally:
168
            tree_a.unlock()
169
170
        tree_b = tree_a.bzrdir.sprout('B').open_workingtree()
171
        self.build_tree(['B/xyz/'])
172
        tree_b.add(['xyz'], ['xyz-id'])
173
        tree_b.rename_one('a/m', 'xyz/m')
174
        tree_b.unversion(['a-id'])
175
        tree_b.commit('delete in B')
176
177
        paths = [(path, ie.file_id)
178
                 for path, ie in tree_b.iter_entries_by_dir()]
179
        self.assertEqual([('', root_id),
180
                          ('xyz', 'xyz-id'),
181
                          ('xyz/m', 'm-id'),
182
                         ], paths)
183
184
        self.build_tree_contents([('A/a/n', 'new contents for n\n')])
185
        tree_a.commit('change n in A')
186
187
        # Merging from A should introduce conflicts because 'n' was modified
188
        # and removed, so 'a' needs to be restored. We also have a conflict
189
        # because 'a' is still an existing directory
190
        num_conflicts = tree_b.merge_from_branch(tree_a.branch)
191
        self.assertEqual(4, num_conflicts)
192
        paths = [(path, ie.file_id)
193
                 for path, ie in tree_b.iter_entries_by_dir()]
194
        self.assertEqual([('', root_id),
195
                          ('a', 'a-id'),
196
                          ('xyz', 'xyz-id'),
197
                          ('a/n.OTHER', 'n-id'),
198
                          ('xyz/m', 'm-id'),
199
                         ], paths)
200
        tree_b.unversion(['a-id'])
201
        paths = [(path, ie.file_id)
202
                 for path, ie in tree_b.iter_entries_by_dir()]
203
        self.assertEqual([('', root_id),
204
                          ('xyz', 'xyz-id'),
205
                          ('xyz/m', 'm-id'),
206
                         ], paths)