~bzr/ubuntu/lucid/bzr/beta-ppa

« back to all changes in this revision

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

  • Committer: Martin Pool
  • Date: 2010-07-02 07:29:40 UTC
  • mfrom: (129.1.7 packaging-karmic)
  • Revision ID: mbp@sourcefrog.net-20100702072940-hpzq5elg8wjve8rh
* PPA rebuild.
* PPA rebuild for Karmic.
* PPA rebuild for Jaunty.
* PPA rebuild for Hardy.
* From postinst, actually remove the example bash completion scripts.
  (LP: #249452)
* New upstream release.
* New upstream release.
* New upstream release.
* Revert change to Build-depends: Dapper does not have python-central.
  Should be python-support..
* Target ppa..
* Target ppa..
* Target ppa..
* Target ppa..
* New upstream release.
* Switch to dpkg-source 3.0 (quilt) format.
* Bump standards version to 3.8.4.
* Remove embedded copy of python-configobj. Closes: #555336
* Remove embedded copy of python-elementtree. Closes: #555343
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* debian/control: Fix obsolete-relation-form-in-source
  lintian warning. 
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Split out docs into bzr-doc package.
* New upstream release.
* Added John Francesco Ferlito to Uploaders.
* Fix install path to quick-reference guide
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to doc paths changing
* New upstream release.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to doc paths changing
* New upstream release.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to doc paths changing
* New upstream release.
* Fix FTBFS due to path changes, again, again.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to path changes.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Bump standards version to 3.8.3.
* Remove unused patch system.
* New upstream release.
* New upstream release.
* New upstream release.
* Fix copy and paste tab error in .install file
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
 + Fixes compatibility with Python 2.4. Closes: #537708
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream version.
* Bump standards version to 3.8.2.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Add python-pyrex to build-deps to ensure C extensions are always build.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Split documentation into bzr-doc package. ((LP: #385074)
* Multiple packaging changes to make us more linitan clean.
* New upstream release.
* Split documentation into bzr-doc package. ((LP: #385074)
* Multiple packaging changes to make us more linitan clean.
* New upstream release.
* Split documentation into bzr-doc package. ((LP: #385074)
* Multiple packaging changes to make us more linitan clean.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Fix API compatibility version. (Closes: #526233)
* New upstream release.
  + Fixes default format for upgrade command. (Closes: #464688)
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Add missing dependency on zlib development library. (Closes:
  #523595)
* Add zlib build-depends.
* Add zlib build-depends.
* Add zlib build-depends.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Move to section vcs.
* Bump standards version to 3.8.1.
* New upstream release.
* Remove temporary patch for missing .c files from distribution
* New upstream release.
* Remove temporary patch for missing .c files from distribution
* New upstream release.
* Remove temporary patch for missing .c files from distribution
* Add temporary patch for missing .c files from distribution
* Add temporary patch for missing .c files from distribution
* Add temporary patch for missing .c files from distribution
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Recommend ca-certificates. (Closes: #452024)
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Update watch file. bazaar now uses launchpad to host its sources.
* Remove patch for inventory root revision copy, applied upstream.
* New upstream release.
* New upstream release.
* New upstream release
* Force removal of files installed in error to /etc/bash_completion.d/
  (LP: #249452)
* New upstream release.
* New upstream release
* New upstream release.
* Bump standards version.
* Include patch for inventory root revision copy, required for bzr-svn.
* New upstream release.
* Remove unused lintian overrides.
* Correct the package version not to be native.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Final 1.5 release.
* New upstream release.
* New upstream release.
* New upstream release.
* Add myself as a co-maintainer.
* Add a Dm-Upload-Allowed: yes header.
* New upstream bugfix release.
* New upstream release.
* Final 1.3 release.
* New upstream release.
* First release candidate of the upcoming 1.3 release.
* Rebuild to fix the problem caused by a build with a broken python-central.
* New upstream release.
* Rebuild for dapper PPA.
* Apply Lamont's patches to fix build-dependencies on dapper.
  (See: https://bugs.launchpad.net/bzr/+bug/189915)

Show diffs side-by-side

added added

removed removed

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