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('.')
45
self.build_tree(paths)
47
file_id = path.replace('/', '_').encode('utf-8') + _id
48
tree.add(path, file_id)
53
def assertFilesDeleted(self, files):
55
id = f.encode('utf-8') + _id
56
self.assertNotInWorkingTree(f)
57
self.assertPathDoesNotExist(f)
59
def assertFilesUnversioned(self, files):
61
self.assertNotInWorkingTree(f)
62
self.assertPathExists(f)
64
def changeFile(self, file_name):
65
with open(file_name, 'ab') as f:
66
f.write(b"\nsome other new content!")
68
def run_bzr_remove_changed_files(self, files_to_remove, working_dir=None):
69
self.run_bzr(['remove'] + list(files_to_remove),
70
working_dir=working_dir)
72
def test_remove_new_no_files_specified(self):
73
tree = self.make_branch_and_tree('.')
74
self.run_bzr_error(["brz: ERROR: No matching files."], 'remove --new')
76
["brz: ERROR: No matching files."], 'remove --new .')
78
def test_remove_no_files_specified(self):
79
tree = self._make_tree_and_add(['foo'])
80
out, err = self.run_bzr(['rm'])
81
self.assertEqual('', err)
82
self.assertEqual('', out)
83
self.assertInWorkingTree('foo', tree=tree)
84
self.assertPathExists('foo')
86
def test_remove_no_files_specified_missing_dir_and_contents(self):
87
tree = self._make_tree_and_add(
88
['foo', 'dir/', 'dir/missing/', 'dir/missing/child'])
89
self.get_transport('.').delete_tree('dir/missing')
90
out, err = self.run_bzr(['rm'])
91
self.assertEqual('', out)
93
'removed dir/missing/child\n'
94
'removed dir/missing\n',
96
# non-missing paths not touched:
97
self.assertInWorkingTree('foo', tree=tree)
98
self.assertPathExists('foo')
99
self.assertInWorkingTree('dir', tree=tree)
100
self.assertPathExists('dir')
101
# missing files unversioned
102
self.assertNotInWorkingTree('dir/missing', tree=tree)
103
self.assertNotInWorkingTree('dir/missing/child', tree=tree)
105
def test_remove_no_files_specified_already_deleted(self):
106
tree = self._make_tree_and_add(['foo', 'bar'])
107
tree.commit('save foo and bar')
110
self.assertFalse(tree.is_versioned('bar'))
111
# Running rm with a deleted file does not error.
112
out, err = self.run_bzr(['rm'])
113
self.assertEqual('', out)
114
self.assertEqual('', err)
116
def test_remove_no_files_specified_missing_file(self):
117
tree = self._make_tree_and_add(['foo', 'bar'])
119
out, err = self.run_bzr(['rm'])
120
self.assertEqual('', out)
121
self.assertEqual('removed bar\n', err)
122
# non-missing files not touched:
123
self.assertInWorkingTree('foo', tree=tree)
124
self.assertPathExists('foo')
125
# missing files unversioned
126
self.assertNotInWorkingTree('bar', tree=tree)
128
def test_remove_no_files_specified_missing_link(self):
129
self.requireFeature(features.SymlinkFeature)
130
tree = self._make_tree_and_add(['foo'])
131
os.symlink('foo', 'linkname')
132
tree.add(['linkname'])
133
os.unlink('linkname')
134
out, err = self.run_bzr(['rm'])
135
self.assertEqual('', out)
136
self.assertEqual('removed linkname\n', err)
137
# non-missing files not touched:
138
self.assertInWorkingTree('foo', tree=tree)
139
self.assertPathExists('foo')
140
# missing files unversioned
141
self.assertNotInWorkingTree('linkname', tree=tree)
143
def test_rm_one_file(self):
144
tree = self._make_tree_and_add([a])
145
self.run_bzr("commit -m 'added a'")
146
self.run_bzr('rm a', error_regexes=["deleted a"])
147
self.assertFilesDeleted([a])
149
def test_remove_one_file(self):
150
tree = self._make_tree_and_add([a])
151
self.run_bzr("commit -m 'added a'")
152
self.run_bzr('remove a', error_regexes=["deleted a"])
153
self.assertFilesDeleted([a])
155
def test_remove_keep_one_file(self):
156
tree = self._make_tree_and_add([a])
157
self.run_bzr('remove --keep a', error_regexes=["removed a"])
158
self.assertFilesUnversioned([a])
160
def test_remove_one_deleted_file(self):
161
tree = self._make_tree_and_add([a])
162
self.run_bzr("commit -m 'added a'")
164
self.assertInWorkingTree(a)
165
self.run_bzr('remove a')
166
self.assertNotInWorkingTree(a)
168
def test_remove_invalid_files(self):
169
self.build_tree(files)
170
tree = self.make_branch_and_tree('.')
171
self.run_bzr(['remove', '.', 'xyz', 'abc/def'])
173
def test_remove_unversioned_files(self):
174
self.build_tree(files)
175
tree = self.make_branch_and_tree('.')
176
self.run_bzr_remove_changed_files(files)
178
def test_remove_changed_files(self):
179
tree = self._make_tree_and_add(files)
180
self.run_bzr("commit -m 'added files'")
183
self.run_bzr_remove_changed_files(files)
185
def test_remove_changed_ignored_files(self):
186
tree = self._make_tree_and_add(['a'])
187
self.run_bzr(['ignore', 'a'])
188
self.run_bzr_remove_changed_files(['a'])
190
def test_remove_changed_files_from_child_dir(self):
191
if sys.platform == 'win32':
192
raise TestSkipped("Windows unable to remove '.' directory")
193
tree = self._make_tree_and_add(files)
194
self.run_bzr("commit -m 'added files'")
197
self.run_bzr_remove_changed_files(
198
['../a', 'c', '.', '../d'], working_dir='b')
199
self.assertNotInWorkingTree(files)
200
self.assertPathDoesNotExist(files)
202
def test_remove_keep_unversioned_files(self):
203
self.build_tree(files)
204
tree = self.make_branch_and_tree('.')
205
self.run_bzr('remove --keep a', error_regexes=["a is not versioned."])
206
self.assertFilesUnversioned(files)
208
def test_remove_no_backup_unversioned_files(self):
209
self.build_tree(files)
210
tree = self.make_branch_and_tree('.')
211
script.ScriptRunner().run_script(self, '''
212
$ brz remove --no-backup a b/ b/c d/
214
2>removed b/c (but kept a copy: b/c.~1~)
218
self.assertFilesDeleted(files)
220
def test_remove_deleted_files(self):
221
tree = self._make_tree_and_add(files)
222
self.run_bzr("commit -m 'added files'")
223
my_files = [f for f in files]
224
my_files.sort(reverse=True)
226
osutils.delete_any(f)
227
self.assertInWorkingTree(files)
228
self.assertPathDoesNotExist(files)
229
self.run_bzr('remove ' + ' '.join(files))
230
self.assertNotInWorkingTree(a)
231
self.assertPathDoesNotExist(files)
233
def test_remove_non_existing_files(self):
234
tree = self._make_tree_and_add([])
235
self.run_bzr(['remove', 'b'])
237
def test_remove_keep_non_existing_files(self):
238
tree = self._make_tree_and_add([])
239
self.run_bzr('remove --keep b', error_regexes=["b is not versioned."])
241
def test_remove_files(self):
242
tree = self._make_tree_and_add(files)
243
self.run_bzr("commit -m 'added files'")
244
self.run_bzr('remove a b b/c d',
245
error_regexes=["deleted a", "deleted b", "deleted b/c",
247
self.assertFilesDeleted(files)
249
def test_remove_keep_files(self):
250
tree = self._make_tree_and_add(files)
251
self.run_bzr("commit -m 'added files'")
252
self.run_bzr('remove --keep a b b/c d',
253
error_regexes=["removed a", "removed b", "removed b/c",
255
self.assertFilesUnversioned(files)
257
def test_remove_with_new(self):
258
tree = self._make_tree_and_add(files)
259
self.run_bzr('remove --new --keep',
260
error_regexes=["removed a", "removed b", "removed b/c"])
261
self.assertFilesUnversioned(files)
263
def test_remove_with_new_in_dir1(self):
264
tree = self._make_tree_and_add(files)
265
self.run_bzr('remove --new --keep b b/c',
266
error_regexes=["removed b", "removed b/c"])
267
tree = WorkingTree.open('.')
268
self.assertInWorkingTree(a)
269
self.assertEqual(tree.path2id(a), a.encode('utf-8') + _id)
270
self.assertFilesUnversioned([b, c])
272
def test_remove_with_new_in_dir2(self):
273
tree = self._make_tree_and_add(files)
274
self.run_bzr('remove --new --keep .',
275
error_regexes=["removed a", "removed b", "removed b/c"])
276
tree = WorkingTree.open('.')
277
self.assertFilesUnversioned(files)
279
def test_remove_backslash(self):
281
if os.path.sep == '\\':
282
raise TestNotApplicable(
283
'unable to add filenames with backslashes where '
284
' it is the path separator')
285
tree = self.make_branch_and_tree('.')
286
self.build_tree(['\\'])
287
self.assertEqual('adding \\\n', self.run_bzr('add \\\\')[0])
288
self.assertEqual('\\\n', self.run_bzr('ls --versioned')[0])
289
self.assertEqual('', self.run_bzr('rm \\\\')[0])
290
self.assertEqual('', self.run_bzr('ls --versioned')[0])