~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Martin Pool
  • Date: 2007-01-24 07:12:09 UTC
  • mto: This revision was merged to the branch mainline in revision 2244.
  • Revision ID: mbp@sourcefrog.net-20070124071209-yqiths20n6wxqaqr
Change RepositoryFormat to use a Registry rather than ad-hoc dictionary

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Test for 'bzr mv'"""
18
18
 
19
19
import os
20
20
 
21
 
import bzrlib.branch
22
21
from bzrlib import (
23
22
    osutils,
24
23
    workingtree,
25
24
    )
26
25
 
27
26
from bzrlib.tests import (
28
 
    CaseInsensitiveFilesystemFeature,
29
 
    SymlinkFeature,
30
27
    TestCaseWithTransport,
 
28
    TestSkipped,
31
29
    )
32
30
 
33
31
 
34
32
class TestMove(TestCaseWithTransport):
35
33
 
 
34
    def assertInWorkingTree(self,path):
 
35
        tree = workingtree.WorkingTree.open('.')
 
36
        self.assertIsNot(tree.path2id(path), None,
 
37
            path+' not in working tree.')
 
38
 
 
39
    def assertNotInWorkingTree(self,path):
 
40
        tree = workingtree.WorkingTree.open('.')
 
41
        self.assertIs(tree.path2id(path), None, path+' in working tree.')
 
42
 
36
43
    def assertMoved(self,from_path,to_path):
37
44
        """Assert that to_path is existing and versioned but from_path not. """
38
45
        self.failIfExists(from_path)
47
54
        files = self.build_tree(['a', 'c', 'subdir/'])
48
55
        tree.add(['a', 'c', 'subdir'])
49
56
 
50
 
        self.run_bzr('mv a b')
 
57
        self.run_bzr('mv', 'a', 'b')
51
58
        self.assertMoved('a','b')
52
59
 
53
 
        self.run_bzr('mv b subdir')
 
60
        self.run_bzr('mv', 'b', 'subdir')
54
61
        self.assertMoved('b','subdir/b')
55
62
 
56
 
        self.run_bzr('mv subdir/b a')
 
63
        self.run_bzr('mv', 'subdir/b', 'a')
57
64
        self.assertMoved('subdir/b','a')
58
65
 
59
 
        self.run_bzr('mv a c subdir')
 
66
        self.run_bzr('mv', 'a', 'c', 'subdir')
60
67
        self.assertMoved('a','subdir/a')
61
68
        self.assertMoved('c','subdir/c')
62
69
 
63
 
        self.run_bzr('mv subdir/a subdir/newa')
 
70
        self.run_bzr('mv', 'subdir/a', 'subdir/newa')
64
71
        self.assertMoved('subdir/a','subdir/newa')
65
72
 
66
73
    def test_mv_unversioned(self):
67
74
        self.build_tree(['unversioned.txt'])
68
75
        self.run_bzr_error(
69
76
            ["^bzr: ERROR: Could not rename unversioned.txt => elsewhere."
70
 
             " .*unversioned.txt is not versioned\.$"],
71
 
            'mv unversioned.txt elsewhere')
 
77
             " .*unversioned.txt is not versioned$"],
 
78
            'mv', 'unversioned.txt', 'elsewhere')
72
79
 
73
80
    def test_mv_nonexisting(self):
74
81
        self.run_bzr_error(
75
82
            ["^bzr: ERROR: Could not rename doesnotexist => somewhereelse."
76
 
             " .*doesnotexist is not versioned\.$"],
77
 
            'mv doesnotexist somewhereelse')
 
83
             " .*doesnotexist is not versioned$"],
 
84
            'mv', 'doesnotexist', 'somewhereelse')
78
85
 
79
86
    def test_mv_unqualified(self):
80
87
        self.run_bzr_error(['^bzr: ERROR: missing file argument$'], 'mv')
81
 
 
 
88
        
82
89
    def test_mv_invalid(self):
83
90
        tree = self.make_branch_and_tree('.')
84
91
        self.build_tree(['test.txt', 'sub1/'])
85
92
        tree.add(['test.txt'])
86
93
 
87
94
        self.run_bzr_error(
88
 
            ["^bzr: ERROR: Could not move to sub1: sub1 is not versioned\.$"],
89
 
            'mv test.txt sub1')
 
95
            ["^bzr: ERROR: Could not move to sub1: sub1 is not versioned$"],
 
96
            'mv', 'test.txt', 'sub1')
90
97
 
91
98
        self.run_bzr_error(
92
99
            ["^bzr: ERROR: Could not move test.txt => .*hello.txt: "
93
 
             "sub1 is not versioned\.$"],
94
 
            'mv test.txt sub1/hello.txt')
95
 
 
 
100
             "sub1 is not versioned$"],
 
101
            'mv', 'test.txt', 'sub1/hello.txt')
 
102
        
96
103
    def test_mv_dirs(self):
97
104
        tree = self.make_branch_and_tree('.')
98
105
        self.build_tree(['hello.txt', 'sub1/'])
99
106
        tree.add(['hello.txt', 'sub1'])
100
107
 
101
 
        self.run_bzr('mv sub1 sub2')
 
108
        self.run_bzr('mv', 'sub1', 'sub2')
102
109
        self.assertMoved('sub1','sub2')
103
110
 
104
 
        self.run_bzr('mv hello.txt sub2')
 
111
        self.run_bzr('mv', 'hello.txt', 'sub2')
105
112
        self.assertMoved('hello.txt','sub2/hello.txt')
106
113
 
 
114
        tree.read_working_inventory()
 
115
 
107
116
        self.build_tree(['sub1/'])
108
117
        tree.add(['sub1'])
109
 
        self.run_bzr('mv sub2/hello.txt sub1')
 
118
        self.run_bzr('mv', 'sub2/hello.txt', 'sub1')
110
119
        self.assertMoved('sub2/hello.txt','sub1/hello.txt')
111
120
 
112
 
        self.run_bzr('mv sub2 sub1')
 
121
        self.run_bzr('mv', 'sub2', 'sub1')
113
122
        self.assertMoved('sub2','sub1/sub2')
114
123
 
115
124
    def test_mv_relative(self):
118
127
        tree.add(['sub1', 'sub1/sub2', 'sub1/hello.txt'])
119
128
 
120
129
        os.chdir('sub1/sub2')
121
 
        self.run_bzr('mv ../hello.txt .')
 
130
        self.run_bzr('mv', '../hello.txt', '.')
122
131
        self.failUnlessExists('./hello.txt')
 
132
        tree.read_working_inventory()
123
133
 
124
134
        os.chdir('..')
125
 
        self.run_bzr('mv sub2/hello.txt .')
 
135
        self.run_bzr('mv', 'sub2/hello.txt', '.')
126
136
        os.chdir('..')
127
137
        self.assertMoved('sub1/sub2/hello.txt','sub1/hello.txt')
128
138
 
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
139
    def test_mv_smoke_aliases(self):
178
140
        # just test that aliases for mv exist, if their behaviour is changed in
179
141
        # the future, then extend the tests.
181
143
        tree = self.make_branch_and_tree('.')
182
144
        tree.add(['a'])
183
145
 
184
 
        self.run_bzr('move a b')
185
 
        self.run_bzr('rename b a')
 
146
        self.run_bzr('move', 'a', 'b')
 
147
        self.run_bzr('rename', 'b', 'a')
186
148
 
187
149
    def test_mv_through_symlinks(self):
188
 
        self.requireFeature(SymlinkFeature)
 
150
        if not osutils.has_symlinks():
 
151
            raise TestSkipped('Symlinks are not supported on this platform')
189
152
        tree = self.make_branch_and_tree('.')
190
153
        self.build_tree(['a/', 'a/b'])
191
154
        os.symlink('a', 'c')
192
155
        os.symlink('.', 'd')
193
156
        tree.add(['a', 'a/b', 'c'], ['a-id', 'b-id', 'c-id'])
194
 
        self.run_bzr('mv c/b b')
 
157
        self.run_bzr('mv', 'c/b', 'b')
195
158
        tree = workingtree.WorkingTree.open('.')
196
159
        self.assertEqual('b-id', tree.path2id('b'))
197
160
 
207
170
        tree = self.make_branch_and_tree('.')
208
171
        tree.add(['a'])
209
172
 
210
 
        osutils.rename('a', 'b')
211
 
        self.run_bzr('mv a b')
 
173
        os.rename('a', 'b')
 
174
        self.run_bzr('mv', 'a', 'b')
212
175
        self.assertMoved('a','b')
213
176
 
214
177
    def test_mv_already_moved_file_to_versioned_target(self):
224
187
        tree.add(['a', 'b'])
225
188
 
226
189
        os.remove('b')
227
 
        osutils.rename('a', 'b')
 
190
        os.rename('a', 'b')
228
191
        self.run_bzr_error(
229
 
            ["^bzr: ERROR: Could not move a => b. b is already versioned\.$"],
230
 
            'mv a b')
 
192
            ["^bzr: ERROR: Could not move a => b. b is already versioned$"],
 
193
            'mv', 'a', 'b')
231
194
        #check that nothing changed
232
195
        self.failIfExists('a')
233
196
        self.failUnlessExists('b')
244
207
        tree = self.make_branch_and_tree('.')
245
208
        tree.add(['a', 'sub'])
246
209
 
247
 
        osutils.rename('a', 'sub/a')
248
 
        self.run_bzr('mv a sub/a')
 
210
        os.rename('a', 'sub/a')
 
211
        self.run_bzr('mv', 'a', 'sub/a')
249
212
        self.assertMoved('a','sub/a')
250
213
 
251
214
    def test_mv_already_moved_file_into_unversioned_subdir(self):
260
223
        tree = self.make_branch_and_tree('.')
261
224
        tree.add(['a'])
262
225
 
263
 
        osutils.rename('a', 'sub/a')
 
226
        os.rename('a', 'sub/a')
264
227
        self.run_bzr_error(
265
 
            ["^bzr: ERROR: Could not move a => a: sub is not versioned\.$"],
266
 
            'mv a sub/a')
 
228
            ["^bzr: ERROR: Could not move a => a: sub is not versioned$"],
 
229
            'mv', 'a', 'sub/a')
267
230
        self.failIfExists('a')
268
231
        self.failUnlessExists('sub/a')
269
232
 
279
242
        tree = self.make_branch_and_tree('.')
280
243
        tree.add(['a1', 'a2', 'sub'])
281
244
 
282
 
        osutils.rename('a1', 'sub/a1')
283
 
        self.run_bzr('mv a1 a2 sub')
 
245
        os.rename('a1', 'sub/a1')
 
246
        self.run_bzr('mv', 'a1', 'a2', 'sub')
284
247
        self.assertMoved('a1','sub/a1')
285
248
        self.assertMoved('a2','sub/a2')
286
249
 
296
259
        tree = self.make_branch_and_tree('.')
297
260
        tree.add(['a1', 'a2'])
298
261
 
299
 
        osutils.rename('a1', 'sub/a1')
 
262
        os.rename('a1', 'sub/a1')
300
263
        self.run_bzr_error(
301
 
            ["^bzr: ERROR: Could not move to sub. sub is not versioned\.$"],
302
 
            'mv a1 a2 sub')
 
264
            ["^bzr: ERROR: Could not move to sub. sub is not versioned$"],
 
265
            'mv', 'a1', 'a2', 'sub')
303
266
        self.failIfExists('a1')
304
267
        self.failUnlessExists('sub/a1')
305
268
        self.failUnlessExists('a2')
318
281
        tree = self.make_branch_and_tree('.')
319
282
        tree.add(['a'])
320
283
 
321
 
        osutils.rename('a', 'b')
 
284
        os.rename('a', 'b')
322
285
        self.build_tree(['a']) #touch a
323
286
        self.run_bzr_error(
324
287
            ["^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')
 
288
             " \(Use --after to update the Bazaar id\)$"],
 
289
            'mv', 'a', 'b')
328
290
        self.failUnlessExists('a')
329
291
        self.failUnlessExists('b')
330
292
 
342
304
        self.build_tree(['a', 'b'])
343
305
        tree = self.make_branch_and_tree('.')
344
306
        tree.add(['a'])
345
 
        osutils.rename('a', 'b')
 
307
        os.rename('a', 'b')
346
308
        self.build_tree(['a']) #touch a
347
309
 
348
 
        self.run_bzr('mv a b --after')
 
310
        self.run_bzr('mv', 'a', 'b', '--after')
349
311
        self.failUnlessExists('a')
350
312
        self.assertNotInWorkingTree('a')#a should be unknown now.
351
313
        self.failUnlessExists('b')
365
327
        self.build_tree(['a1', 'a2', 'sub/', 'sub/a1', 'sub/a2'])
366
328
        tree = self.make_branch_and_tree('.')
367
329
        tree.add(['a1', 'a2', 'sub'])
368
 
        osutils.rename('a1', 'sub/a1')
369
 
        osutils.rename('a2', 'sub/a2')
 
330
        os.rename('a1', 'sub/a1')
 
331
        os.rename('a2', 'sub/a2')
370
332
        self.build_tree(['a1']) #touch a1
371
333
        self.build_tree(['a2']) #touch a2
372
334
 
373
335
        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')
 
336
            ["^bzr: ERROR: Could not rename a1 => sub/a1 because both files exist."
 
337
             " \(Use --after to update the Bazaar id\)$"],
 
338
            'mv', 'a1', 'a2', 'sub')
378
339
        self.failUnlessExists('a1')
379
340
        self.failUnlessExists('a2')
380
341
        self.failUnlessExists('sub/a1')
396
357
        self.build_tree(['a1', 'a2', 'sub/', 'sub/a1', 'sub/a2'])
397
358
        tree = self.make_branch_and_tree('.')
398
359
        tree.add(['a1', 'a2', 'sub'])
399
 
        osutils.rename('a1', 'sub/a1')
400
 
        osutils.rename('a2', 'sub/a2')
 
360
        os.rename('a1', 'sub/a1')
 
361
        os.rename('a2', 'sub/a2')
401
362
        self.build_tree(['a1']) #touch a1
402
363
        self.build_tree(['a2']) #touch a2
403
364
 
404
 
        self.run_bzr('mv a1 a2 sub --after')
 
365
        self.run_bzr('mv', 'a1', 'a2', 'sub', '--after')
405
366
        self.failUnlessExists('a1')
406
367
        self.failUnlessExists('a2')
407
368
        self.failUnlessExists('sub/a1')
408
369
        self.failUnlessExists('sub/a2')
409
370
        self.assertInWorkingTree('sub/a1')
410
371
        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'])