1
# Copyright (C) 2006-2010 Canonical Ltd
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
from breezy.tests import (
24
TestCaseWithTransport,
28
from breezy.workingtree import WorkingTree
29
from breezy import osutils
39
class TestRemove(TestCaseWithTransport):
41
def _make_tree_and_add(self, paths):
42
tree = self.make_branch_and_tree('.')
43
with tree.lock_write():
44
self.build_tree(paths)
46
file_id = path.replace('/', '_').encode('utf-8') + _id
47
tree.add(path, file_id)
50
def assertFilesDeleted(self, files):
52
id = f.encode('utf-8') + _id
53
self.assertNotInWorkingTree(f)
54
self.assertPathDoesNotExist(f)
56
def assertFilesUnversioned(self, files):
58
self.assertNotInWorkingTree(f)
59
self.assertPathExists(f)
61
def changeFile(self, file_name):
62
with open(file_name, 'ab') as f:
63
f.write(b"\nsome other new content!")
65
def run_bzr_remove_changed_files(self, files_to_remove, working_dir=None):
66
self.run_bzr(['remove'] + list(files_to_remove),
67
working_dir=working_dir)
69
def test_remove_new_no_files_specified(self):
70
tree = self.make_branch_and_tree('.')
71
self.run_bzr_error(["brz: ERROR: No matching files."], 'remove --new')
73
["brz: ERROR: No matching files."], 'remove --new .')
75
def test_remove_no_files_specified(self):
76
tree = self._make_tree_and_add(['foo'])
77
out, err = self.run_bzr(['rm'])
78
self.assertEqual('', err)
79
self.assertEqual('', out)
80
self.assertInWorkingTree('foo', tree=tree)
81
self.assertPathExists('foo')
83
def test_remove_no_files_specified_missing_dir_and_contents(self):
84
tree = self._make_tree_and_add(
85
['foo', 'dir/', 'dir/missing/', 'dir/missing/child'])
86
self.get_transport('.').delete_tree('dir/missing')
87
out, err = self.run_bzr(['rm'])
88
self.assertEqual('', out)
90
'removed dir/missing/child\n'
91
'removed dir/missing\n',
93
# non-missing paths not touched:
94
self.assertInWorkingTree('foo', tree=tree)
95
self.assertPathExists('foo')
96
self.assertInWorkingTree('dir', tree=tree)
97
self.assertPathExists('dir')
98
# missing files unversioned
99
self.assertNotInWorkingTree('dir/missing', tree=tree)
100
self.assertNotInWorkingTree('dir/missing/child', tree=tree)
102
def test_remove_no_files_specified_already_deleted(self):
103
tree = self._make_tree_and_add(['foo', 'bar'])
104
tree.commit('save foo and bar')
107
self.assertFalse(tree.is_versioned('bar'))
108
# Running rm with a deleted file does not error.
109
out, err = self.run_bzr(['rm'])
110
self.assertEqual('', out)
111
self.assertEqual('', err)
113
def test_remove_no_files_specified_missing_file(self):
114
tree = self._make_tree_and_add(['foo', 'bar'])
116
out, err = self.run_bzr(['rm'])
117
self.assertEqual('', out)
118
self.assertEqual('removed bar\n', err)
119
# non-missing files not touched:
120
self.assertInWorkingTree('foo', tree=tree)
121
self.assertPathExists('foo')
122
# missing files unversioned
123
self.assertNotInWorkingTree('bar', tree=tree)
125
def test_remove_no_files_specified_missing_link(self):
126
self.requireFeature(features.SymlinkFeature)
127
tree = self._make_tree_and_add(['foo'])
128
os.symlink('foo', 'linkname')
129
tree.add(['linkname'])
130
os.unlink('linkname')
131
out, err = self.run_bzr(['rm'])
132
self.assertEqual('', out)
133
self.assertEqual('removed linkname\n', err)
134
# non-missing files not touched:
135
self.assertInWorkingTree('foo', tree=tree)
136
self.assertPathExists('foo')
137
# missing files unversioned
138
self.assertNotInWorkingTree('linkname', tree=tree)
140
def test_rm_one_file(self):
141
tree = self._make_tree_and_add([a])
142
self.run_bzr("commit -m 'added a'")
143
self.run_bzr('rm a', error_regexes=["deleted a"])
144
self.assertFilesDeleted([a])
146
def test_remove_one_file(self):
147
tree = self._make_tree_and_add([a])
148
self.run_bzr("commit -m 'added a'")
149
self.run_bzr('remove a', error_regexes=["deleted a"])
150
self.assertFilesDeleted([a])
152
def test_remove_keep_one_file(self):
153
tree = self._make_tree_and_add([a])
154
self.run_bzr('remove --keep a', error_regexes=["removed a"])
155
self.assertFilesUnversioned([a])
157
def test_remove_one_deleted_file(self):
158
tree = self._make_tree_and_add([a])
159
self.run_bzr("commit -m 'added a'")
161
self.assertInWorkingTree(a)
162
self.run_bzr('remove a')
163
self.assertNotInWorkingTree(a)
165
def test_remove_invalid_files(self):
166
self.build_tree(files)
167
tree = self.make_branch_and_tree('.')
168
self.run_bzr(['remove', '.', 'xyz', 'abc/def'])
170
def test_remove_unversioned_files(self):
171
self.build_tree(files)
172
tree = self.make_branch_and_tree('.')
173
self.run_bzr_remove_changed_files(files)
175
def test_remove_changed_files(self):
176
tree = self._make_tree_and_add(files)
177
self.run_bzr("commit -m 'added files'")
180
self.run_bzr_remove_changed_files(files)
182
def test_remove_changed_ignored_files(self):
183
tree = self._make_tree_and_add(['a'])
184
self.run_bzr(['ignore', 'a'])
185
self.run_bzr_remove_changed_files(['a'])
187
def test_remove_changed_files_from_child_dir(self):
188
if sys.platform == 'win32':
189
raise TestSkipped("Windows unable to remove '.' directory")
190
tree = self._make_tree_and_add(files)
191
self.run_bzr("commit -m 'added files'")
194
self.run_bzr_remove_changed_files(
195
['../a', 'c', '.', '../d'], working_dir='b')
196
self.assertNotInWorkingTree(files)
197
self.assertPathDoesNotExist(files)
199
def test_remove_keep_unversioned_files(self):
200
self.build_tree(files)
201
tree = self.make_branch_and_tree('.')
202
self.run_bzr('remove --keep a', error_regexes=["a is not versioned."])
203
self.assertFilesUnversioned(files)
205
def test_remove_no_backup_unversioned_files(self):
206
self.build_tree(files)
207
tree = self.make_branch_and_tree('.')
208
script.ScriptRunner().run_script(self, '''
209
$ brz remove --no-backup a b/ b/c d/
211
2>removed b/c (but kept a copy: b/c.~1~)
215
self.assertFilesDeleted(files)
217
def test_remove_deleted_files(self):
218
tree = self._make_tree_and_add(files)
219
self.run_bzr("commit -m 'added files'")
220
my_files = [f for f in files]
221
my_files.sort(reverse=True)
223
osutils.delete_any(f)
224
self.assertInWorkingTree(files)
225
self.assertPathDoesNotExist(files)
226
self.run_bzr('remove ' + ' '.join(files))
227
self.assertNotInWorkingTree(a)
228
self.assertPathDoesNotExist(files)
230
def test_remove_non_existing_files(self):
231
tree = self._make_tree_and_add([])
232
self.run_bzr(['remove', 'b'])
234
def test_remove_keep_non_existing_files(self):
235
tree = self._make_tree_and_add([])
236
self.run_bzr('remove --keep b', error_regexes=["b is not versioned."])
238
def test_remove_files(self):
239
tree = self._make_tree_and_add(files)
240
self.run_bzr("commit -m 'added files'")
241
self.run_bzr('remove a b b/c d',
242
error_regexes=["deleted a", "deleted b", "deleted b/c",
244
self.assertFilesDeleted(files)
246
def test_remove_keep_files(self):
247
tree = self._make_tree_and_add(files)
248
self.run_bzr("commit -m 'added files'")
249
self.run_bzr('remove --keep a b b/c d',
250
error_regexes=["removed a", "removed b", "removed b/c",
252
self.assertFilesUnversioned(files)
254
def test_remove_with_new(self):
255
tree = self._make_tree_and_add(files)
256
self.run_bzr('remove --new --keep',
257
error_regexes=["removed a", "removed b", "removed b/c"])
258
self.assertFilesUnversioned(files)
260
def test_remove_with_new_in_dir1(self):
261
tree = self._make_tree_and_add(files)
262
self.run_bzr('remove --new --keep b b/c',
263
error_regexes=["removed b", "removed b/c"])
264
tree = WorkingTree.open('.')
265
self.assertInWorkingTree(a)
266
self.assertEqual(tree.path2id(a), a.encode('utf-8') + _id)
267
self.assertFilesUnversioned([b, c])
269
def test_remove_with_new_in_dir2(self):
270
tree = self._make_tree_and_add(files)
271
self.run_bzr('remove --new --keep .',
272
error_regexes=["removed a", "removed b", "removed b/c"])
273
tree = WorkingTree.open('.')
274
self.assertFilesUnversioned(files)
276
def test_remove_backslash(self):
278
if os.path.sep == '\\':
279
raise TestNotApplicable(
280
'unable to add filenames with backslashes where '
281
' it is the path separator')
282
tree = self.make_branch_and_tree('.')
283
self.build_tree(['\\'])
284
self.assertEqual('adding \\\n', self.run_bzr('add \\\\')[0])
285
self.assertEqual('\\\n', self.run_bzr('ls --versioned')[0])
286
self.assertEqual('', self.run_bzr('rm \\\\')[0])
287
self.assertEqual('', self.run_bzr('ls --versioned')[0])