~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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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
    )
1988.2.2 by Robert Collins
Add test script I forgotten - doh.
23
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
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
40
    def test_unversion_several_files(self):
41
        """After unversioning several files, they should not be versioned."""
42
        tree = self.make_branch_and_tree('.')
43
        self.build_tree(['a', 'b', 'c'])
44
        tree.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
45
        # within a lock unversion should take effect
46
        tree.lock_write()
47
        tree.unversion(['a-id', 'b-id'])
48
        self.assertFalse(tree.has_id('a-id'))
49
        self.assertFalse(tree.has_id('b-id'))
50
        self.assertTrue(tree.has_id('c-id'))
51
        self.assertTrue(tree.has_filename('a'))
52
        self.assertTrue(tree.has_filename('b'))
53
        self.assertTrue(tree.has_filename('c'))
54
        tree.unlock()
1988.2.3 by Robert Collins
Merge in commit test case for deletion-heuristic.
55
        # the changes should have persisted to disk - reopen the workingtree
56
        # to be sure.
57
        tree = tree.bzrdir.open_workingtree()
2255.2.46 by Robert Collins
Dirstate - unversion should set the tree state as dirty.
58
        tree.lock_read()
1988.2.2 by Robert Collins
Add test script I forgotten - doh.
59
        self.assertFalse(tree.has_id('a-id'))
60
        self.assertFalse(tree.has_id('b-id'))
61
        self.assertTrue(tree.has_id('c-id'))
62
        self.assertTrue(tree.has_filename('a'))
63
        self.assertTrue(tree.has_filename('b'))
64
        self.assertTrue(tree.has_filename('c'))
2255.2.46 by Robert Collins
Dirstate - unversion should set the tree state as dirty.
65
        tree.unlock()
2255.7.41 by John Arbash Meinel
WorkingTree.unversion() should not raise if unversioning a child and a parent.
66
1988.2.2 by Robert Collins
Add test script I forgotten - doh.
67
    def test_unversion_subtree(self):
68
        """Unversioning the root of a subtree unversions the entire subtree."""
69
        tree = self.make_branch_and_tree('.')
70
        self.build_tree(['a/', 'a/b', 'c'])
71
        tree.add(['a', 'a/b', 'c'], ['a-id', 'b-id', 'c-id'])
72
        # within a lock unversion should take effect
73
        tree.lock_write()
74
        tree.unversion(['a-id'])
75
        self.assertFalse(tree.has_id('a-id'))
76
        self.assertFalse(tree.has_id('b-id'))
77
        self.assertTrue(tree.has_id('c-id'))
78
        self.assertTrue(tree.has_filename('a'))
79
        self.assertTrue(tree.has_filename('a/b'))
80
        self.assertTrue(tree.has_filename('c'))
81
        tree.unlock()
2255.7.41 by John Arbash Meinel
WorkingTree.unversion() should not raise if unversioning a child and a parent.
82
83
    def test_unversion_subtree_and_children(self):
84
        """Passing a child id will raise NoSuchId.
85
86
        This is because the parent directory will have already been removed.
87
        """
88
        tree = self.make_branch_and_tree('.')
89
        self.build_tree(['a/', 'a/b', 'a/c', 'd'])
90
        tree.add(['a', 'a/b', 'a/c', 'd'], ['a-id', 'b-id', 'c-id', 'd-id'])
91
        tree.lock_write()
92
        try:
93
            tree.unversion(['b-id', 'a-id'])
94
            self.assertFalse(tree.has_id('a-id'))
95
            self.assertFalse(tree.has_id('b-id'))
96
            self.assertFalse(tree.has_id('c-id'))
97
            self.assertTrue(tree.has_id('d-id'))
98
            # The files are still on disk
99
            self.assertTrue(tree.has_filename('a'))
100
            self.assertTrue(tree.has_filename('a/b'))
101
            self.assertTrue(tree.has_filename('a/c'))
102
            self.assertTrue(tree.has_filename('d'))
103
        finally:
104
            tree.unlock()
2922.2.5 by John Arbash Meinel
Add a direct test for WT.unversion()
105
106
    def test_unversion_renamed(self):
107
        tree = self.make_branch_and_tree('a')
108
        self.build_tree(['a/dir/', 'a/dir/f1', 'a/dir/f2', 'a/dir/f3',
109
                         'a/dir2/'])
110
        tree.add(['dir', 'dir/f1', 'dir/f2', 'dir/f3', 'dir2'],
111
                 ['dir-id', 'f1-id', 'f2-id', 'f3-id', 'dir2-id'])
112
        rev_id1 = tree.commit('init')
113
        # Start off by renaming entries, and then unversion a bunch of entries
114
        # https://bugs.launchpad.net/bzr/+bug/114615
115
        tree.rename_one('dir/f1', 'dir/a')
116
        tree.rename_one('dir/f2', 'dir/z')
117
        tree.move(['dir/f3'], 'dir2')
118
119
        tree.lock_read()
120
        try:
2946.3.3 by John Arbash Meinel
Prefer tree.get_root_id() as more explicit than tree.path2id('')
121
            root_id = tree.get_root_id()
2922.2.5 by John Arbash Meinel
Add a direct test for WT.unversion()
122
            paths = [(path, ie.file_id)
123
                     for path, ie in tree.iter_entries_by_dir()]
124
        finally:
125
            tree.unlock()
126
        self.assertEqual([('', root_id),
127
                          ('dir', 'dir-id'),
128
                          ('dir2', 'dir2-id'),
129
                          ('dir/a', 'f1-id'),
130
                          ('dir/z', 'f2-id'),
131
                          ('dir2/f3', 'f3-id'),
132
                         ], paths)
133
134
        tree.unversion(set(['dir-id']))
135
        paths = [(path, ie.file_id)
136
                 for path, ie in tree.iter_entries_by_dir()]
137
138
        self.assertEqual([('', root_id),
139
                          ('dir2', 'dir2-id'),
140
                          ('dir2/f3', 'f3-id'),
141
                         ], paths)
142
2922.2.6 by John Arbash Meinel
Add another direct test in unversion, because the other test
143
    def test_unversion_after_conflicted_merge(self):
144
        # Test for bug #114615
145
        tree_a = self.make_branch_and_tree('A')
146
        self.build_tree(['A/a/', 'A/a/m', 'A/a/n'])
147
        tree_a.add(['a', 'a/m', 'a/n'], ['a-id', 'm-id', 'n-id'])
148
        tree_a.commit('init')
149
150
        tree_a.lock_read()
151
        try:
2946.3.3 by John Arbash Meinel
Prefer tree.get_root_id() as more explicit than tree.path2id('')
152
            root_id = tree_a.get_root_id()
2922.2.6 by John Arbash Meinel
Add another direct test in unversion, because the other test
153
        finally:
154
            tree_a.unlock()
155
156
        tree_b = tree_a.bzrdir.sprout('B').open_workingtree()
157
        self.build_tree(['B/xyz/'])
158
        tree_b.add(['xyz'], ['xyz-id'])
159
        tree_b.rename_one('a/m', 'xyz/m')
160
        tree_b.unversion(['a-id'])
161
        tree_b.commit('delete in B')
162
163
        paths = [(path, ie.file_id)
164
                 for path, ie in tree_b.iter_entries_by_dir()]
165
        self.assertEqual([('', root_id),
166
                          ('xyz', 'xyz-id'),
167
                          ('xyz/m', 'm-id'),
168
                         ], paths)
169
170
        self.build_tree_contents([('A/a/n', 'new contents for n\n')])
171
        tree_a.commit('change n in A')
172
173
        # Merging from A should introduce conflicts because 'n' was modified
174
        # and removed, so 'a' needs to be restored. We also have a conflict
175
        # because 'a' is still an existing directory
176
        num_conflicts = tree_b.merge_from_branch(tree_a.branch)
177
        self.assertEqual(4, num_conflicts)
178
        paths = [(path, ie.file_id)
179
                 for path, ie in tree_b.iter_entries_by_dir()]
180
        self.assertEqual([('', root_id),
181
                          ('a', 'a-id'),
182
                          ('xyz', 'xyz-id'),
183
                          ('a/n.OTHER', 'n-id'),
184
                          ('xyz/m', 'm-id'),
185
                         ], paths)
186
        tree_b.unversion(['a-id'])
187
        paths = [(path, ie.file_id)
188
                 for path, ie in tree_b.iter_entries_by_dir()]
189
        self.assertEqual([('', root_id),
190
                          ('xyz', 'xyz-id'),
191
                          ('xyz/m', 'm-id'),
192
                         ], paths)