~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/blackbox/test_mv.py

  • Committer: Patch Queue Manager
  • Date: 2012-02-23 19:11:01 UTC
  • mfrom: (6472.1.1 merge-2.5)
  • Revision ID: pqm@pqm.ubuntu.com-20120223191101-x6g60ci59rhkvp3e
(jelmer) Merge bzr/2.5. (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 by Canonical Ltd
 
1
# Copyright (C) 2006-2012 Canonical Ltd
2
2
#
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
12
12
#
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
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Test for 'bzr mv'"""
18
18
 
19
19
import os
20
20
 
21
 
from bzrlib.tests import TestCaseWithTransport
 
21
import bzrlib.branch
 
22
from bzrlib import (
 
23
    osutils,
 
24
    workingtree,
 
25
    )
 
26
 
 
27
from bzrlib.tests import (
 
28
    TestCaseWithTransport,
 
29
    )
 
30
from bzrlib.tests.features import (
 
31
    CaseInsensitiveFilesystemFeature,
 
32
    SymlinkFeature,
 
33
    UnicodeFilenameFeature,
 
34
    )
22
35
 
23
36
 
24
37
class TestMove(TestCaseWithTransport):
25
38
 
 
39
    def assertMoved(self,from_path,to_path):
 
40
        """Assert that to_path is existing and versioned but from_path not. """
 
41
        self.assertPathDoesNotExist(from_path)
 
42
        self.assertNotInWorkingTree(from_path)
 
43
 
 
44
        self.assertPathExists(to_path)
 
45
        self.assertInWorkingTree(to_path)
 
46
 
26
47
    def test_mv_modes(self):
27
48
        """Test two modes of operation for mv"""
28
49
        tree = self.make_branch_and_tree('.')
29
50
        files = self.build_tree(['a', 'c', 'subdir/'])
30
51
        tree.add(['a', 'c', 'subdir'])
31
52
 
32
 
        self.run_bzr('mv', 'a', 'b')
33
 
        self.failUnlessExists('b')
34
 
        self.failIfExists('a')
35
 
 
36
 
        self.run_bzr('mv', 'b', 'subdir')
37
 
        self.failUnlessExists('subdir/b')
38
 
        self.failIfExists('b')
39
 
 
40
 
        self.run_bzr('mv', 'subdir/b', 'a')
41
 
        self.failUnlessExists('a')
42
 
        self.failIfExists('subdir/b')
43
 
 
44
 
        self.run_bzr('mv', 'a', 'c', 'subdir')
45
 
        self.failUnlessExists('subdir/a')
46
 
        self.failUnlessExists('subdir/c')
47
 
        self.failIfExists('a')
48
 
        self.failIfExists('c')
49
 
 
50
 
        self.run_bzr('mv', 'subdir/a', 'subdir/newa')
51
 
        self.failUnlessExists('subdir/newa')
52
 
        self.failIfExists('subdir/a')
 
53
        self.run_bzr('mv a b')
 
54
        self.assertMoved('a','b')
 
55
 
 
56
        self.run_bzr('mv b subdir')
 
57
        self.assertMoved('b','subdir/b')
 
58
 
 
59
        self.run_bzr('mv subdir/b a')
 
60
        self.assertMoved('subdir/b','a')
 
61
 
 
62
        self.run_bzr('mv a c subdir')
 
63
        self.assertMoved('a','subdir/a')
 
64
        self.assertMoved('c','subdir/c')
 
65
 
 
66
        self.run_bzr('mv subdir/a subdir/newa')
 
67
        self.assertMoved('subdir/a','subdir/newa')
53
68
 
54
69
    def test_mv_unversioned(self):
55
70
        self.build_tree(['unversioned.txt'])
56
71
        self.run_bzr_error(
57
 
            ["^bzr: ERROR: can't rename: old name .* is not versioned$"],
58
 
            'mv', 'unversioned.txt', 'elsewhere')
 
72
            ["^bzr: ERROR: Could not rename unversioned.txt => elsewhere."
 
73
             " .*unversioned.txt is not versioned\.$"],
 
74
            'mv unversioned.txt elsewhere')
59
75
 
60
76
    def test_mv_nonexisting(self):
61
77
        self.run_bzr_error(
62
 
            ["^bzr: ERROR: can't rename: old working file .* does not exist$"],
63
 
            'mv', 'doesnotexist', 'somewhereelse')
 
78
            ["^bzr: ERROR: Could not rename doesnotexist => somewhereelse."
 
79
             " .*doesnotexist is not versioned\.$"],
 
80
            'mv doesnotexist somewhereelse')
64
81
 
65
82
    def test_mv_unqualified(self):
66
83
        self.run_bzr_error(['^bzr: ERROR: missing file argument$'], 'mv')
67
 
        
 
84
 
68
85
    def test_mv_invalid(self):
69
86
        tree = self.make_branch_and_tree('.')
70
87
        self.build_tree(['test.txt', 'sub1/'])
71
88
        tree.add(['test.txt'])
72
89
 
73
90
        self.run_bzr_error(
74
 
            ["^bzr: ERROR: destination u'sub1' is not a versioned directory$"],
75
 
            'mv', 'test.txt', 'sub1')
76
 
        
 
91
            ["^bzr: ERROR: Could not move to sub1: sub1 is not versioned\.$"],
 
92
            'mv test.txt sub1')
 
93
 
77
94
        self.run_bzr_error(
78
 
            ["^bzr: ERROR: can't determine destination directory id for u'sub1'$"],
79
 
            'mv', 'test.txt', 'sub1/hello.txt')
80
 
        
 
95
            ["^bzr: ERROR: Could not move test.txt => .*hello.txt: "
 
96
             "sub1 is not versioned\.$"],
 
97
            'mv test.txt sub1/hello.txt')
 
98
 
81
99
    def test_mv_dirs(self):
82
100
        tree = self.make_branch_and_tree('.')
83
101
        self.build_tree(['hello.txt', 'sub1/'])
84
102
        tree.add(['hello.txt', 'sub1'])
85
103
 
86
 
        self.run_bzr('mv', 'sub1', 'sub2')
87
 
        self.failUnlessExists('sub2')
88
 
        self.failIfExists('sub1')
89
 
        self.run_bzr('mv', 'hello.txt', 'sub2')
90
 
        self.failUnlessExists("sub2/hello.txt")
91
 
        self.failIfExists("hello.txt")
 
104
        self.run_bzr('mv sub1 sub2')
 
105
        self.assertMoved('sub1','sub2')
92
106
 
93
 
        tree.read_working_inventory()
94
 
        tree.commit('commit with some things moved to subdirs')
 
107
        self.run_bzr('mv hello.txt sub2')
 
108
        self.assertMoved('hello.txt','sub2/hello.txt')
95
109
 
96
110
        self.build_tree(['sub1/'])
97
111
        tree.add(['sub1'])
98
 
        self.run_bzr('mv', 'sub2/hello.txt', 'sub1')
99
 
        self.failIfExists('sub2/hello.txt')
100
 
        self.failUnlessExists('sub1/hello.txt')
101
 
        self.run_bzr('mv', 'sub2', 'sub1')
102
 
        self.failIfExists('sub2')
103
 
        self.failUnlessExists('sub1/sub2')
 
112
        self.run_bzr('mv sub2/hello.txt sub1')
 
113
        self.assertMoved('sub2/hello.txt','sub1/hello.txt')
 
114
 
 
115
        self.run_bzr('mv sub2 sub1')
 
116
        self.assertMoved('sub2','sub1/sub2')
104
117
 
105
118
    def test_mv_relative(self):
106
119
        self.build_tree(['sub1/', 'sub1/sub2/', 'sub1/hello.txt'])
107
120
        tree = self.make_branch_and_tree('.')
108
121
        tree.add(['sub1', 'sub1/sub2', 'sub1/hello.txt'])
109
 
        tree.commit('initial tree')
110
 
 
111
 
        os.chdir('sub1/sub2')
112
 
        self.run_bzr('mv', '../hello.txt', '.')
113
 
        self.failUnlessExists('./hello.txt')
114
 
        tree.read_working_inventory()
115
 
        tree.commit('move to parent directory')
116
 
 
117
 
        os.chdir('..')
118
 
 
119
 
        self.run_bzr('mv', 'sub2/hello.txt', '.')
120
 
        self.failUnlessExists('hello.txt')
 
122
 
 
123
        self.run_bzr('mv ../hello.txt .', working_dir='sub1/sub2')
 
124
        self.assertPathExists('sub1/sub2/hello.txt')
 
125
 
 
126
        self.run_bzr('mv sub2/hello.txt .', working_dir='sub1')
 
127
        self.assertMoved('sub1/sub2/hello.txt','sub1/hello.txt')
 
128
 
 
129
    def test_mv_change_case_file(self):
 
130
        # test for bug #77740 (mv unable change filename case on Windows)
 
131
        tree = self.make_branch_and_tree('.')
 
132
        self.build_tree(['test.txt'])
 
133
        tree.add(['test.txt'])
 
134
        self.run_bzr('mv test.txt Test.txt')
 
135
        # we can't use failUnlessExists on case-insensitive filesystem
 
136
        # so try to check shape of the tree
 
137
        shape = sorted(os.listdir(u'.'))
 
138
        self.assertEqual(['.bzr', 'Test.txt'], shape)
 
139
        self.assertInWorkingTree('Test.txt')
 
140
        self.assertNotInWorkingTree('test.txt')
 
141
 
 
142
    def test_mv_change_case_dir(self):
 
143
        tree = self.make_branch_and_tree('.')
 
144
        self.build_tree(['foo/'])
 
145
        tree.add(['foo'])
 
146
        self.run_bzr('mv foo Foo')
 
147
        # we can't use failUnlessExists on case-insensitive filesystem
 
148
        # so try to check shape of the tree
 
149
        shape = sorted(os.listdir(u'.'))
 
150
        self.assertEqual(['.bzr', 'Foo'], shape)
 
151
        self.assertInWorkingTree('Foo')
 
152
        self.assertNotInWorkingTree('foo')
 
153
 
 
154
    def test_mv_change_case_dir_w_files(self):
 
155
        tree = self.make_branch_and_tree('.')
 
156
        self.build_tree(['foo/', 'foo/bar'])
 
157
        tree.add(['foo'])
 
158
        self.run_bzr('mv foo Foo')
 
159
        # we can't use failUnlessExists on case-insensitive filesystem
 
160
        # so try to check shape of the tree
 
161
        shape = sorted(os.listdir(u'.'))
 
162
        self.assertEqual(['.bzr', 'Foo'], shape)
 
163
        self.assertInWorkingTree('Foo')
 
164
        self.assertNotInWorkingTree('foo')
 
165
 
 
166
    def test_mv_file_to_wrong_case_dir(self):
 
167
        self.requireFeature(CaseInsensitiveFilesystemFeature)
 
168
        tree = self.make_branch_and_tree('.')
 
169
        self.build_tree(['foo/', 'bar'])
 
170
        tree.add(['foo', 'bar'])
 
171
        out, err = self.run_bzr('mv bar Foo', retcode=3)
 
172
        self.assertEquals('', out)
 
173
        self.assertEquals(
 
174
            'bzr: ERROR: Could not move to Foo: Foo is not versioned.\n',
 
175
            err)
121
176
 
122
177
    def test_mv_smoke_aliases(self):
123
178
        # just test that aliases for mv exist, if their behaviour is changed in
126
181
        tree = self.make_branch_and_tree('.')
127
182
        tree.add(['a'])
128
183
 
129
 
        self.run_bzr('move', 'a', 'b')
130
 
        self.run_bzr('rename', 'b', 'a')
 
184
        self.run_bzr('move a b')
 
185
        self.run_bzr('rename b a')
 
186
 
 
187
    def test_mv_no_root(self):
 
188
        tree = self.make_branch_and_tree('.')
 
189
        self.run_bzr_error(
 
190
            ["bzr: ERROR: can not move root of branch"],
 
191
            'mv . a')
 
192
 
 
193
    def test_mv_through_symlinks(self):
 
194
        self.requireFeature(SymlinkFeature)
 
195
        tree = self.make_branch_and_tree('.')
 
196
        self.build_tree(['a/', 'a/b'])
 
197
        os.symlink('a', 'c')
 
198
        os.symlink('.', 'd')
 
199
        tree.add(['a', 'a/b', 'c'], ['a-id', 'b-id', 'c-id'])
 
200
        self.run_bzr('mv c/b b')
 
201
        tree = workingtree.WorkingTree.open('.')
 
202
        self.assertEqual('b-id', tree.path2id('b'))
 
203
 
 
204
    def test_mv_already_moved_file(self):
 
205
        """Test bzr mv original_file to moved_file.
 
206
 
 
207
        Tests if a file which has allready been moved by an external tool,
 
208
        is handled correctly by bzr mv.
 
209
        Setup: a is in the working tree, b does not exist.
 
210
        User does: mv a b; bzr mv a b
 
211
        """
 
212
        self.build_tree(['a'])
 
213
        tree = self.make_branch_and_tree('.')
 
214
        tree.add(['a'])
 
215
 
 
216
        osutils.rename('a', 'b')
 
217
        self.run_bzr('mv a b')
 
218
        self.assertMoved('a','b')
 
219
 
 
220
    def test_mv_already_moved_file_to_versioned_target(self):
 
221
        """Test bzr mv existing_file to versioned_file.
 
222
 
 
223
        Tests if an attempt to move an existing versioned file
 
224
        to another versiond file will fail.
 
225
        Setup: a and b are in the working tree.
 
226
        User does: rm b; mv a b; bzr mv a b
 
227
        """
 
228
        self.build_tree(['a', 'b'])
 
229
        tree = self.make_branch_and_tree('.')
 
230
        tree.add(['a', 'b'])
 
231
 
 
232
        os.remove('b')
 
233
        osutils.rename('a', 'b')
 
234
        self.run_bzr_error(
 
235
            ["^bzr: ERROR: Could not move a => b. b is already versioned\.$"],
 
236
            'mv a b')
 
237
        #check that nothing changed
 
238
        self.assertPathDoesNotExist('a')
 
239
        self.assertPathExists('b')
 
240
 
 
241
    def test_mv_already_moved_file_into_subdir(self):
 
242
        """Test bzr mv original_file to versioned_directory/file.
 
243
 
 
244
        Tests if a file which has already been moved into a versioned
 
245
        directory by an external tool, is handled correctly by bzr mv.
 
246
        Setup: a and sub/ are in the working tree.
 
247
        User does: mv a sub/a; bzr mv a sub/a
 
248
        """
 
249
        self.build_tree(['a', 'sub/'])
 
250
        tree = self.make_branch_and_tree('.')
 
251
        tree.add(['a', 'sub'])
 
252
 
 
253
        osutils.rename('a', 'sub/a')
 
254
        self.run_bzr('mv a sub/a')
 
255
        self.assertMoved('a','sub/a')
 
256
 
 
257
    def test_mv_already_moved_file_into_unversioned_subdir(self):
 
258
        """Test bzr mv original_file to unversioned_directory/file.
 
259
 
 
260
        Tests if an attempt to move an existing versioned file
 
261
        into an unversioned directory will fail.
 
262
        Setup: a is in the working tree, sub/ is not.
 
263
        User does: mv a sub/a; bzr mv a sub/a
 
264
        """
 
265
        self.build_tree(['a', 'sub/'])
 
266
        tree = self.make_branch_and_tree('.')
 
267
        tree.add(['a'])
 
268
 
 
269
        osutils.rename('a', 'sub/a')
 
270
        self.run_bzr_error(
 
271
            ["^bzr: ERROR: Could not move a => a: sub is not versioned\.$"],
 
272
            'mv a sub/a')
 
273
        self.assertPathDoesNotExist('a')
 
274
        self.assertPathExists('sub/a')
 
275
 
 
276
    def test_mv_already_moved_files_into_subdir(self):
 
277
        """Test bzr mv original_files to versioned_directory.
 
278
 
 
279
        Tests if files which has already been moved into a versioned
 
280
        directory by an external tool, is handled correctly by bzr mv.
 
281
        Setup: a1, a2, sub are in the working tree.
 
282
        User does: mv a1 sub/.; bzr mv a1 a2 sub
 
283
        """
 
284
        self.build_tree(['a1', 'a2', 'sub/'])
 
285
        tree = self.make_branch_and_tree('.')
 
286
        tree.add(['a1', 'a2', 'sub'])
 
287
 
 
288
        osutils.rename('a1', 'sub/a1')
 
289
        self.run_bzr('mv a1 a2 sub')
 
290
        self.assertMoved('a1','sub/a1')
 
291
        self.assertMoved('a2','sub/a2')
 
292
 
 
293
    def test_mv_already_moved_files_into_unversioned_subdir(self):
 
294
        """Test bzr mv original_file to unversioned_directory.
 
295
 
 
296
        Tests if an attempt to move existing versioned file
 
297
        into an unversioned directory will fail.
 
298
        Setup: a1, a2 are in the working tree, sub is not.
 
299
        User does: mv a1 sub/.; bzr mv a1 a2 sub
 
300
        """
 
301
        self.build_tree(['a1', 'a2', 'sub/'])
 
302
        tree = self.make_branch_and_tree('.')
 
303
        tree.add(['a1', 'a2'])
 
304
 
 
305
        osutils.rename('a1', 'sub/a1')
 
306
        self.run_bzr_error(
 
307
            ["^bzr: ERROR: Could not move to sub. sub is not versioned\.$"],
 
308
            'mv a1 a2 sub')
 
309
        self.assertPathDoesNotExist('a1')
 
310
        self.assertPathExists('sub/a1')
 
311
        self.assertPathExists('a2')
 
312
        self.assertPathDoesNotExist('sub/a2')
 
313
 
 
314
    def test_mv_already_moved_file_forcing_after(self):
 
315
        """Test bzr mv versioned_file to unversioned_file.
 
316
 
 
317
        Tests if an attempt to move an existing versioned file to an existing
 
318
        unversioned file will fail, informing the user to use the --after
 
319
        option to force this.
 
320
        Setup: a is in the working tree, b not versioned.
 
321
        User does: mv a b; touch a; bzr mv a b
 
322
        """
 
323
        self.build_tree(['a', 'b'])
 
324
        tree = self.make_branch_and_tree('.')
 
325
        tree.add(['a'])
 
326
 
 
327
        osutils.rename('a', 'b')
 
328
        self.build_tree(['a']) #touch a
 
329
        self.run_bzr_error(
 
330
            ["^bzr: ERROR: Could not rename a => b because both files exist."
 
331
             " \(Use --after to tell bzr about a rename that has already"
 
332
             " happened\)$"],
 
333
            'mv a b')
 
334
        self.assertPathExists('a')
 
335
        self.assertPathExists('b')
 
336
 
 
337
    def test_mv_already_moved_file_using_after(self):
 
338
        """Test bzr mv --after versioned_file to unversioned_file.
 
339
 
 
340
        Tests if an existing versioned file can be forced to move to an
 
341
        existing unversioned file using the --after option. With the result
 
342
        that bazaar considers the unversioned_file to be moved from
 
343
        versioned_file and versioned_file will become unversioned.
 
344
        Setup: a is in the working tree and b exists.
 
345
        User does: mv a b; touch a; bzr mv a b --after
 
346
        Resulting in a => b and a is unknown.
 
347
        """
 
348
        self.build_tree(['a', 'b'])
 
349
        tree = self.make_branch_and_tree('.')
 
350
        tree.add(['a'])
 
351
        osutils.rename('a', 'b')
 
352
        self.build_tree(['a']) #touch a
 
353
 
 
354
        self.run_bzr('mv a b --after')
 
355
        self.assertPathExists('a')
 
356
        self.assertNotInWorkingTree('a')#a should be unknown now.
 
357
        self.assertPathExists('b')
 
358
        self.assertInWorkingTree('b')
 
359
 
 
360
    def test_mv_already_moved_files_forcing_after(self):
 
361
        """Test bzr mv versioned_files to directory/unversioned_file.
 
362
 
 
363
        Tests if an attempt to move an existing versioned file to an existing
 
364
        unversioned file in some other directory will fail, informing the user
 
365
        to use the --after option to force this.
 
366
 
 
367
        Setup: a1, a2, sub are versioned and in the working tree,
 
368
               sub/a1, sub/a2 are in working tree.
 
369
        User does: mv a* sub; touch a1; touch a2; bzr mv a1 a2 sub
 
370
        """
 
371
        self.build_tree(['a1', 'a2', 'sub/', 'sub/a1', 'sub/a2'])
 
372
        tree = self.make_branch_and_tree('.')
 
373
        tree.add(['a1', 'a2', 'sub'])
 
374
        osutils.rename('a1', 'sub/a1')
 
375
        osutils.rename('a2', 'sub/a2')
 
376
        self.build_tree(['a1']) #touch a1
 
377
        self.build_tree(['a2']) #touch a2
 
378
 
 
379
        self.run_bzr_error(
 
380
            ["^bzr: ERROR: Could not rename a1 => sub/a1 because both files"
 
381
             " exist. \(Use --after to tell bzr about a rename that has already"
 
382
             " happened\)$"],
 
383
            'mv a1 a2 sub')
 
384
        self.assertPathExists('a1')
 
385
        self.assertPathExists('a2')
 
386
        self.assertPathExists('sub/a1')
 
387
        self.assertPathExists('sub/a2')
 
388
 
 
389
    def test_mv_already_moved_files_using_after(self):
 
390
        """Test bzr mv --after versioned_file to directory/unversioned_file.
 
391
 
 
392
        Tests if an existing versioned file can be forced to move to an
 
393
        existing unversioned file in some other directory using the --after
 
394
        option. With the result that bazaar considers
 
395
        directory/unversioned_file to be moved from versioned_file and
 
396
        versioned_file will become unversioned.
 
397
 
 
398
        Setup: a1, a2, sub are versioned and in the working tree,
 
399
               sub/a1, sub/a2 are in working tree.
 
400
        User does: mv a* sub; touch a1; touch a2; bzr mv a1 a2 sub --after
 
401
        """
 
402
        self.build_tree(['a1', 'a2', 'sub/', 'sub/a1', 'sub/a2'])
 
403
        tree = self.make_branch_and_tree('.')
 
404
        tree.add(['a1', 'a2', 'sub'])
 
405
        osutils.rename('a1', 'sub/a1')
 
406
        osutils.rename('a2', 'sub/a2')
 
407
        self.build_tree(['a1']) #touch a1
 
408
        self.build_tree(['a2']) #touch a2
 
409
 
 
410
        self.run_bzr('mv a1 a2 sub --after')
 
411
        self.assertPathExists('a1')
 
412
        self.assertPathExists('a2')
 
413
        self.assertPathExists('sub/a1')
 
414
        self.assertPathExists('sub/a2')
 
415
        self.assertInWorkingTree('sub/a1')
 
416
        self.assertInWorkingTree('sub/a2')
 
417
 
 
418
    def test_mv_already_moved_directory(self):
 
419
        """Use `bzr mv a b` to mark a directory as renamed.
 
420
 
 
421
        https://bugs.launchpad.net/bzr/+bug/107967/
 
422
        """
 
423
        self.build_tree(['a/', 'c/'])
 
424
        tree = self.make_branch_and_tree('.')
 
425
        tree.add(['a', 'c'])
 
426
        osutils.rename('a', 'b')
 
427
        osutils.rename('c', 'd')
 
428
        # mv a b should work just like it does for already renamed files
 
429
        self.run_bzr('mv a b')
 
430
        self.assertPathDoesNotExist('a')
 
431
        self.assertNotInWorkingTree('a')
 
432
        self.assertPathExists('b')
 
433
        self.assertInWorkingTree('b')
 
434
        # and --after should work, too (technically it's ignored)
 
435
        self.run_bzr('mv --after c d')
 
436
        self.assertPathDoesNotExist('c')
 
437
        self.assertNotInWorkingTree('c')
 
438
        self.assertPathExists('d')
 
439
        self.assertInWorkingTree('d')
 
440
 
 
441
    def make_abcd_tree(self):
 
442
        tree = self.make_branch_and_tree('tree')
 
443
        self.build_tree(['tree/a', 'tree/c'])
 
444
        tree.add(['a', 'c'])
 
445
        tree.commit('record old names')
 
446
        osutils.rename('tree/a', 'tree/b')
 
447
        osutils.rename('tree/c', 'tree/d')
 
448
        return tree
 
449
 
 
450
    def test_mv_auto(self):
 
451
        self.make_abcd_tree()
 
452
        out, err = self.run_bzr('mv --auto', working_dir='tree')
 
453
        self.assertEqual(out, '')
 
454
        self.assertEqual(err, 'a => b\nc => d\n')
 
455
        tree = workingtree.WorkingTree.open('tree')
 
456
        self.assertIsNot(None, tree.path2id('b'))
 
457
        self.assertIsNot(None, tree.path2id('d'))
 
458
 
 
459
    def test_mv_auto_one_path(self):
 
460
        self.make_abcd_tree()
 
461
        out, err = self.run_bzr('mv --auto tree')
 
462
        self.assertEqual(out, '')
 
463
        self.assertEqual(err, 'a => b\nc => d\n')
 
464
        tree = workingtree.WorkingTree.open('tree')
 
465
        self.assertIsNot(None, tree.path2id('b'))
 
466
        self.assertIsNot(None, tree.path2id('d'))
 
467
 
 
468
    def test_mv_auto_two_paths(self):
 
469
        self.make_abcd_tree()
 
470
        out, err = self.run_bzr('mv --auto tree tree2', retcode=3)
 
471
        self.assertEqual('bzr: ERROR: Only one path may be specified to'
 
472
                         ' --auto.\n', err)
 
473
 
 
474
    def test_mv_auto_dry_run(self):
 
475
        self.make_abcd_tree()
 
476
        out, err = self.run_bzr('mv --auto --dry-run', working_dir='tree')
 
477
        self.assertEqual(out, '')
 
478
        self.assertEqual(err, 'a => b\nc => d\n')
 
479
        tree = workingtree.WorkingTree.open('tree')
 
480
        self.assertIsNot(None, tree.path2id('a'))
 
481
        self.assertIsNot(None, tree.path2id('c'))
 
482
 
 
483
    def test_mv_no_auto_dry_run(self):
 
484
        self.make_abcd_tree()
 
485
        out, err = self.run_bzr('mv c d --dry-run',
 
486
                                working_dir='tree', retcode=3)
 
487
        self.assertEqual('bzr: ERROR: --dry-run requires --auto.\n', err)
 
488
 
 
489
    def test_mv_auto_after(self):
 
490
        self.make_abcd_tree()
 
491
        out, err = self.run_bzr('mv --auto --after', working_dir='tree',
 
492
                                retcode=3)
 
493
        self.assertEqual('bzr: ERROR: --after cannot be specified with'
 
494
                         ' --auto.\n', err)
 
495
 
 
496
    def test_mv_quiet(self):
 
497
        tree = self.make_branch_and_tree('.')
 
498
        self.build_tree(['aaa'])
 
499
        tree.add(['aaa'])
 
500
        out, err = self.run_bzr('mv --quiet aaa bbb')
 
501
        self.assertEqual(out, '')
 
502
        self.assertEqual(err, '')
 
503
 
 
504
    def test_mv_readonly_lightweight_checkout(self):
 
505
        branch = self.make_branch('foo')
 
506
        branch = bzrlib.branch.Branch.open(self.get_readonly_url('foo'))
 
507
        tree = branch.create_checkout('tree', lightweight=True)
 
508
        self.build_tree(['tree/path'])
 
509
        tree.add('path')
 
510
        # If this fails, the tree is trying to acquire a branch lock, which it
 
511
        # shouldn't.
 
512
        self.run_bzr(['mv', 'tree/path', 'tree/path2'])
 
513
 
 
514
    def test_mv_unversioned_non_ascii(self):
 
515
        """Clear error on mv of an unversioned non-ascii file, see lp:707954"""
 
516
        self.requireFeature(UnicodeFilenameFeature)
 
517
        tree = self.make_branch_and_tree(".")
 
518
        self.build_tree([u"\xA7"])
 
519
        out, err = self.run_bzr_error(["Could not rename", "not versioned"],
 
520
            ["mv", u"\xA7", "b"])
 
521
 
 
522
    def test_mv_removed_non_ascii(self):
 
523
        """Clear error on mv of a removed non-ascii file, see lp:898541"""
 
524
        self.requireFeature(UnicodeFilenameFeature)
 
525
        tree = self.make_branch_and_tree(".")
 
526
        self.build_tree([u"\xA7"])
 
527
        tree.add([u"\xA7"])
 
528
        tree.commit(u"Adding \xA7")
 
529
        os.remove(u"\xA7")
 
530
        out, err = self.run_bzr_error(["Could not rename", "not exist"],
 
531
            ["mv", u"\xA7", "b"])