~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

merge merge tweaks from aaron, which includes latest .dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
 
 
17
 
"""Test for 'bzr mv'"""
18
 
 
19
 
import os
20
 
 
21
 
from bzrlib import (
22
 
    osutils,
23
 
    workingtree,
24
 
    )
25
 
 
26
 
from bzrlib.tests import (
27
 
    CaseInsensitiveFilesystemFeature,
28
 
    SymlinkFeature,
29
 
    TestCaseWithTransport,
30
 
    )
31
 
 
32
 
 
33
 
class TestMove(TestCaseWithTransport):
34
 
 
35
 
    def assertMoved(self,from_path,to_path):
36
 
        """Assert that to_path is existing and versioned but from_path not. """
37
 
        self.failIfExists(from_path)
38
 
        self.assertNotInWorkingTree(from_path)
39
 
 
40
 
        self.failUnlessExists(to_path)
41
 
        self.assertInWorkingTree(to_path)
42
 
 
43
 
    def test_mv_modes(self):
44
 
        """Test two modes of operation for mv"""
45
 
        tree = self.make_branch_and_tree('.')
46
 
        files = self.build_tree(['a', 'c', 'subdir/'])
47
 
        tree.add(['a', 'c', 'subdir'])
48
 
 
49
 
        self.run_bzr('mv a b')
50
 
        self.assertMoved('a','b')
51
 
 
52
 
        self.run_bzr('mv b subdir')
53
 
        self.assertMoved('b','subdir/b')
54
 
 
55
 
        self.run_bzr('mv subdir/b a')
56
 
        self.assertMoved('subdir/b','a')
57
 
 
58
 
        self.run_bzr('mv a c subdir')
59
 
        self.assertMoved('a','subdir/a')
60
 
        self.assertMoved('c','subdir/c')
61
 
 
62
 
        self.run_bzr('mv subdir/a subdir/newa')
63
 
        self.assertMoved('subdir/a','subdir/newa')
64
 
 
65
 
    def test_mv_unversioned(self):
66
 
        self.build_tree(['unversioned.txt'])
67
 
        self.run_bzr_error(
68
 
            ["^bzr: ERROR: Could not rename unversioned.txt => elsewhere."
69
 
             " .*unversioned.txt is not versioned\.$"],
70
 
            'mv unversioned.txt elsewhere')
71
 
 
72
 
    def test_mv_nonexisting(self):
73
 
        self.run_bzr_error(
74
 
            ["^bzr: ERROR: Could not rename doesnotexist => somewhereelse."
75
 
             " .*doesnotexist is not versioned\.$"],
76
 
            'mv doesnotexist somewhereelse')
77
 
 
78
 
    def test_mv_unqualified(self):
79
 
        self.run_bzr_error(['^bzr: ERROR: missing file argument$'], 'mv')
80
 
        
81
 
    def test_mv_invalid(self):
82
 
        tree = self.make_branch_and_tree('.')
83
 
        self.build_tree(['test.txt', 'sub1/'])
84
 
        tree.add(['test.txt'])
85
 
 
86
 
        self.run_bzr_error(
87
 
            ["^bzr: ERROR: Could not move to sub1: sub1 is not versioned\.$"],
88
 
            'mv test.txt sub1')
89
 
 
90
 
        self.run_bzr_error(
91
 
            ["^bzr: ERROR: Could not move test.txt => .*hello.txt: "
92
 
             "sub1 is not versioned\.$"],
93
 
            'mv test.txt sub1/hello.txt')
94
 
        
95
 
    def test_mv_dirs(self):
96
 
        tree = self.make_branch_and_tree('.')
97
 
        self.build_tree(['hello.txt', 'sub1/'])
98
 
        tree.add(['hello.txt', 'sub1'])
99
 
 
100
 
        self.run_bzr('mv sub1 sub2')
101
 
        self.assertMoved('sub1','sub2')
102
 
 
103
 
        self.run_bzr('mv hello.txt sub2')
104
 
        self.assertMoved('hello.txt','sub2/hello.txt')
105
 
 
106
 
        self.build_tree(['sub1/'])
107
 
        tree.add(['sub1'])
108
 
        self.run_bzr('mv sub2/hello.txt sub1')
109
 
        self.assertMoved('sub2/hello.txt','sub1/hello.txt')
110
 
 
111
 
        self.run_bzr('mv sub2 sub1')
112
 
        self.assertMoved('sub2','sub1/sub2')
113
 
 
114
 
    def test_mv_relative(self):
115
 
        self.build_tree(['sub1/', 'sub1/sub2/', 'sub1/hello.txt'])
116
 
        tree = self.make_branch_and_tree('.')
117
 
        tree.add(['sub1', 'sub1/sub2', 'sub1/hello.txt'])
118
 
 
119
 
        os.chdir('sub1/sub2')
120
 
        self.run_bzr('mv ../hello.txt .')
121
 
        self.failUnlessExists('./hello.txt')
122
 
 
123
 
        os.chdir('..')
124
 
        self.run_bzr('mv sub2/hello.txt .')
125
 
        os.chdir('..')
126
 
        self.assertMoved('sub1/sub2/hello.txt','sub1/hello.txt')
127
 
 
128
 
    def test_mv_change_case_file(self):
129
 
        # test for bug #77740 (mv unable change filename case on Windows)
130
 
        tree = self.make_branch_and_tree('.')
131
 
        self.build_tree(['test.txt'])
132
 
        tree.add(['test.txt'])
133
 
        self.run_bzr('mv test.txt Test.txt')
134
 
        # we can't use failUnlessExists on case-insensitive filesystem
135
 
        # so try to check shape of the tree
136
 
        shape = sorted(os.listdir(u'.'))
137
 
        self.assertEqual(['.bzr', 'Test.txt'], shape)
138
 
        self.assertInWorkingTree('Test.txt')
139
 
        self.assertNotInWorkingTree('test.txt')
140
 
 
141
 
    def test_mv_change_case_dir(self):
142
 
        tree = self.make_branch_and_tree('.')
143
 
        self.build_tree(['foo/'])
144
 
        tree.add(['foo'])
145
 
        self.run_bzr('mv foo Foo')
146
 
        # we can't use failUnlessExists on case-insensitive filesystem
147
 
        # so try to check shape of the tree
148
 
        shape = sorted(os.listdir(u'.'))
149
 
        self.assertEqual(['.bzr', 'Foo'], shape)
150
 
        self.assertInWorkingTree('Foo')
151
 
        self.assertNotInWorkingTree('foo')
152
 
 
153
 
    def test_mv_change_case_dir_w_files(self):
154
 
        tree = self.make_branch_and_tree('.')
155
 
        self.build_tree(['foo/', 'foo/bar'])
156
 
        tree.add(['foo'])
157
 
        self.run_bzr('mv foo Foo')
158
 
        # we can't use failUnlessExists on case-insensitive filesystem
159
 
        # so try to check shape of the tree
160
 
        shape = sorted(os.listdir(u'.'))
161
 
        self.assertEqual(['.bzr', 'Foo'], shape)
162
 
        self.assertInWorkingTree('Foo')
163
 
        self.assertNotInWorkingTree('foo')
164
 
 
165
 
    def test_mv_file_to_wrong_case_dir(self):
166
 
        self.requireFeature(CaseInsensitiveFilesystemFeature)
167
 
        tree = self.make_branch_and_tree('.')
168
 
        self.build_tree(['foo/', 'bar'])
169
 
        tree.add(['foo', 'bar'])
170
 
        out, err = self.run_bzr('mv bar Foo', retcode=3)
171
 
        self.assertEquals('', out)
172
 
        self.assertEquals(
173
 
            'bzr: ERROR: Could not move to Foo: Foo is not versioned.\n',
174
 
            err)
175
 
 
176
 
    def test_mv_smoke_aliases(self):
177
 
        # just test that aliases for mv exist, if their behaviour is changed in
178
 
        # the future, then extend the tests.
179
 
        self.build_tree(['a'])
180
 
        tree = self.make_branch_and_tree('.')
181
 
        tree.add(['a'])
182
 
 
183
 
        self.run_bzr('move a b')
184
 
        self.run_bzr('rename b a')
185
 
 
186
 
    def test_mv_through_symlinks(self):
187
 
        self.requireFeature(SymlinkFeature)
188
 
        tree = self.make_branch_and_tree('.')
189
 
        self.build_tree(['a/', 'a/b'])
190
 
        os.symlink('a', 'c')
191
 
        os.symlink('.', 'd')
192
 
        tree.add(['a', 'a/b', 'c'], ['a-id', 'b-id', 'c-id'])
193
 
        self.run_bzr('mv c/b b')
194
 
        tree = workingtree.WorkingTree.open('.')
195
 
        self.assertEqual('b-id', tree.path2id('b'))
196
 
 
197
 
    def test_mv_already_moved_file(self):
198
 
        """Test bzr mv original_file to moved_file.
199
 
 
200
 
        Tests if a file which has allready been moved by an external tool,
201
 
        is handled correctly by bzr mv.
202
 
        Setup: a is in the working tree, b does not exist.
203
 
        User does: mv a b; bzr mv a b
204
 
        """
205
 
        self.build_tree(['a'])
206
 
        tree = self.make_branch_and_tree('.')
207
 
        tree.add(['a'])
208
 
 
209
 
        osutils.rename('a', 'b')
210
 
        self.run_bzr('mv a b')
211
 
        self.assertMoved('a','b')
212
 
 
213
 
    def test_mv_already_moved_file_to_versioned_target(self):
214
 
        """Test bzr mv existing_file to versioned_file.
215
 
 
216
 
        Tests if an attempt to move an existing versioned file
217
 
        to another versiond file will fail.
218
 
        Setup: a and b are in the working tree.
219
 
        User does: rm b; mv a b; bzr mv a b
220
 
        """
221
 
        self.build_tree(['a', 'b'])
222
 
        tree = self.make_branch_and_tree('.')
223
 
        tree.add(['a', 'b'])
224
 
 
225
 
        os.remove('b')
226
 
        osutils.rename('a', 'b')
227
 
        self.run_bzr_error(
228
 
            ["^bzr: ERROR: Could not move a => b. b is already versioned\.$"],
229
 
            'mv a b')
230
 
        #check that nothing changed
231
 
        self.failIfExists('a')
232
 
        self.failUnlessExists('b')
233
 
 
234
 
    def test_mv_already_moved_file_into_subdir(self):
235
 
        """Test bzr mv original_file to versioned_directory/file.
236
 
 
237
 
        Tests if a file which has already been moved into a versioned
238
 
        directory by an external tool, is handled correctly by bzr mv.
239
 
        Setup: a and sub/ are in the working tree.
240
 
        User does: mv a sub/a; bzr mv a sub/a
241
 
        """
242
 
        self.build_tree(['a', 'sub/'])
243
 
        tree = self.make_branch_and_tree('.')
244
 
        tree.add(['a', 'sub'])
245
 
 
246
 
        osutils.rename('a', 'sub/a')
247
 
        self.run_bzr('mv a sub/a')
248
 
        self.assertMoved('a','sub/a')
249
 
 
250
 
    def test_mv_already_moved_file_into_unversioned_subdir(self):
251
 
        """Test bzr mv original_file to unversioned_directory/file.
252
 
 
253
 
        Tests if an attempt to move an existing versioned file
254
 
        into an unversioned directory will fail.
255
 
        Setup: a is in the working tree, sub/ is not.
256
 
        User does: mv a sub/a; bzr mv a sub/a
257
 
        """
258
 
        self.build_tree(['a', 'sub/'])
259
 
        tree = self.make_branch_and_tree('.')
260
 
        tree.add(['a'])
261
 
 
262
 
        osutils.rename('a', 'sub/a')
263
 
        self.run_bzr_error(
264
 
            ["^bzr: ERROR: Could not move a => a: sub is not versioned\.$"],
265
 
            'mv a sub/a')
266
 
        self.failIfExists('a')
267
 
        self.failUnlessExists('sub/a')
268
 
 
269
 
    def test_mv_already_moved_files_into_subdir(self):
270
 
        """Test bzr mv original_files to versioned_directory.
271
 
 
272
 
        Tests if files which has already been moved into a versioned
273
 
        directory by an external tool, is handled correctly by bzr mv.
274
 
        Setup: a1, a2, sub are in the working tree.
275
 
        User does: mv a1 sub/.; bzr mv a1 a2 sub
276
 
        """
277
 
        self.build_tree(['a1', 'a2', 'sub/'])
278
 
        tree = self.make_branch_and_tree('.')
279
 
        tree.add(['a1', 'a2', 'sub'])
280
 
 
281
 
        osutils.rename('a1', 'sub/a1')
282
 
        self.run_bzr('mv a1 a2 sub')
283
 
        self.assertMoved('a1','sub/a1')
284
 
        self.assertMoved('a2','sub/a2')
285
 
 
286
 
    def test_mv_already_moved_files_into_unversioned_subdir(self):
287
 
        """Test bzr mv original_file to unversioned_directory.
288
 
 
289
 
        Tests if an attempt to move existing versioned file
290
 
        into an unversioned directory will fail.
291
 
        Setup: a1, a2 are in the working tree, sub is not.
292
 
        User does: mv a1 sub/.; bzr mv a1 a2 sub
293
 
        """
294
 
        self.build_tree(['a1', 'a2', 'sub/'])
295
 
        tree = self.make_branch_and_tree('.')
296
 
        tree.add(['a1', 'a2'])
297
 
 
298
 
        osutils.rename('a1', 'sub/a1')
299
 
        self.run_bzr_error(
300
 
            ["^bzr: ERROR: Could not move to sub. sub is not versioned\.$"],
301
 
            'mv a1 a2 sub')
302
 
        self.failIfExists('a1')
303
 
        self.failUnlessExists('sub/a1')
304
 
        self.failUnlessExists('a2')
305
 
        self.failIfExists('sub/a2')
306
 
 
307
 
    def test_mv_already_moved_file_forcing_after(self):
308
 
        """Test bzr mv versioned_file to unversioned_file.
309
 
 
310
 
        Tests if an attempt to move an existing versioned file to an existing
311
 
        unversioned file will fail, informing the user to use the --after
312
 
        option to force this.
313
 
        Setup: a is in the working tree, b not versioned.
314
 
        User does: mv a b; touch a; bzr mv a b
315
 
        """
316
 
        self.build_tree(['a', 'b'])
317
 
        tree = self.make_branch_and_tree('.')
318
 
        tree.add(['a'])
319
 
 
320
 
        osutils.rename('a', 'b')
321
 
        self.build_tree(['a']) #touch a
322
 
        self.run_bzr_error(
323
 
            ["^bzr: ERROR: Could not rename a => b because both files exist."
324
 
             " \(Use --after to tell bzr about a rename that has already"
325
 
             " happened\)$"],
326
 
            'mv a b')
327
 
        self.failUnlessExists('a')
328
 
        self.failUnlessExists('b')
329
 
 
330
 
    def test_mv_already_moved_file_using_after(self):
331
 
        """Test bzr mv --after versioned_file to unversioned_file.
332
 
 
333
 
        Tests if an existing versioned file can be forced to move to an
334
 
        existing unversioned file using the --after option. With the result
335
 
        that bazaar considers the unversioned_file to be moved from
336
 
        versioned_file and versioned_file will become unversioned.
337
 
        Setup: a is in the working tree and b exists.
338
 
        User does: mv a b; touch a; bzr mv a b --after
339
 
        Resulting in a => b and a is unknown.
340
 
        """
341
 
        self.build_tree(['a', 'b'])
342
 
        tree = self.make_branch_and_tree('.')
343
 
        tree.add(['a'])
344
 
        osutils.rename('a', 'b')
345
 
        self.build_tree(['a']) #touch a
346
 
 
347
 
        self.run_bzr('mv a b --after')
348
 
        self.failUnlessExists('a')
349
 
        self.assertNotInWorkingTree('a')#a should be unknown now.
350
 
        self.failUnlessExists('b')
351
 
        self.assertInWorkingTree('b')
352
 
 
353
 
    def test_mv_already_moved_files_forcing_after(self):
354
 
        """Test bzr mv versioned_files to directory/unversioned_file.
355
 
 
356
 
        Tests if an attempt to move an existing versioned file to an existing
357
 
        unversioned file in some other directory will fail, informing the user
358
 
        to use the --after option to force this.
359
 
 
360
 
        Setup: a1, a2, sub are versioned and in the working tree,
361
 
               sub/a1, sub/a2 are in working tree.
362
 
        User does: mv a* sub; touch a1; touch a2; bzr mv a1 a2 sub
363
 
        """
364
 
        self.build_tree(['a1', 'a2', 'sub/', 'sub/a1', 'sub/a2'])
365
 
        tree = self.make_branch_and_tree('.')
366
 
        tree.add(['a1', 'a2', 'sub'])
367
 
        osutils.rename('a1', 'sub/a1')
368
 
        osutils.rename('a2', 'sub/a2')
369
 
        self.build_tree(['a1']) #touch a1
370
 
        self.build_tree(['a2']) #touch a2
371
 
 
372
 
        self.run_bzr_error(
373
 
            ["^bzr: ERROR: Could not rename a1 => sub/a1 because both files"
374
 
             " exist. \(Use --after to tell bzr about a rename that has already"
375
 
             " happened\)$"],
376
 
            'mv a1 a2 sub')
377
 
        self.failUnlessExists('a1')
378
 
        self.failUnlessExists('a2')
379
 
        self.failUnlessExists('sub/a1')
380
 
        self.failUnlessExists('sub/a2')
381
 
 
382
 
    def test_mv_already_moved_files_using_after(self):
383
 
        """Test bzr mv --after versioned_file to directory/unversioned_file.
384
 
 
385
 
        Tests if an existing versioned file can be forced to move to an
386
 
        existing unversioned file in some other directory using the --after
387
 
        option. With the result that bazaar considers
388
 
        directory/unversioned_file to be moved from versioned_file and
389
 
        versioned_file will become unversioned.
390
 
 
391
 
        Setup: a1, a2, sub are versioned and in the working tree,
392
 
               sub/a1, sub/a2 are in working tree.
393
 
        User does: mv a* sub; touch a1; touch a2; bzr mv a1 a2 sub --after
394
 
        """
395
 
        self.build_tree(['a1', 'a2', 'sub/', 'sub/a1', 'sub/a2'])
396
 
        tree = self.make_branch_and_tree('.')
397
 
        tree.add(['a1', 'a2', 'sub'])
398
 
        osutils.rename('a1', 'sub/a1')
399
 
        osutils.rename('a2', 'sub/a2')
400
 
        self.build_tree(['a1']) #touch a1
401
 
        self.build_tree(['a2']) #touch a2
402
 
 
403
 
        self.run_bzr('mv a1 a2 sub --after')
404
 
        self.failUnlessExists('a1')
405
 
        self.failUnlessExists('a2')
406
 
        self.failUnlessExists('sub/a1')
407
 
        self.failUnlessExists('sub/a2')
408
 
        self.assertInWorkingTree('sub/a1')
409
 
        self.assertInWorkingTree('sub/a2')
410
 
 
411
 
    def test_mv_already_moved_directory(self):
412
 
        """Use `bzr mv a b` to mark a directory as renamed.
413
 
 
414
 
        https://bugs.launchpad.net/bzr/+bug/107967/
415
 
        """
416
 
        self.build_tree(['a/', 'c/'])
417
 
        tree = self.make_branch_and_tree('.')
418
 
        tree.add(['a', 'c'])
419
 
        osutils.rename('a', 'b')
420
 
        osutils.rename('c', 'd')
421
 
        # mv a b should work just like it does for already renamed files
422
 
        self.run_bzr('mv a b')
423
 
        self.failIfExists('a')
424
 
        self.assertNotInWorkingTree('a')
425
 
        self.failUnlessExists('b')
426
 
        self.assertInWorkingTree('b')
427
 
        # and --after should work, too (technically it's ignored)
428
 
        self.run_bzr('mv --after c d')
429
 
        self.failIfExists('c')
430
 
        self.assertNotInWorkingTree('c')
431
 
        self.failUnlessExists('d')
432
 
        self.assertInWorkingTree('d')