14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""Test for 'bzr mv'"""
17
"""Test for 'brz mv'"""
27
from bzrlib.tests import (
27
from breezy.tests import (
28
TestCaseWithTransport,
31
from breezy.tests.features import (
28
32
CaseInsensitiveFilesystemFeature,
30
TestCaseWithTransport,
34
UnicodeFilenameFeature,
34
38
class TestMove(TestCaseWithTransport):
36
def assertMoved(self,from_path,to_path):
40
def assertMoved(self, from_path, to_path):
37
41
"""Assert that to_path is existing and versioned but from_path not. """
38
self.failIfExists(from_path)
42
self.assertPathDoesNotExist(from_path)
39
43
self.assertNotInWorkingTree(from_path)
41
self.failUnlessExists(to_path)
45
self.assertPathExists(to_path)
42
46
self.assertInWorkingTree(to_path)
44
48
def test_mv_modes(self):
48
52
tree.add(['a', 'c', 'subdir'])
50
54
self.run_bzr('mv a b')
51
self.assertMoved('a','b')
55
self.assertMoved('a', 'b')
53
57
self.run_bzr('mv b subdir')
54
self.assertMoved('b','subdir/b')
58
self.assertMoved('b', 'subdir/b')
56
60
self.run_bzr('mv subdir/b a')
57
self.assertMoved('subdir/b','a')
61
self.assertMoved('subdir/b', 'a')
59
63
self.run_bzr('mv a c subdir')
60
self.assertMoved('a','subdir/a')
61
self.assertMoved('c','subdir/c')
64
self.assertMoved('a', 'subdir/a')
65
self.assertMoved('c', 'subdir/c')
63
67
self.run_bzr('mv subdir/a subdir/newa')
64
self.assertMoved('subdir/a','subdir/newa')
68
self.assertMoved('subdir/a', 'subdir/newa')
66
70
def test_mv_unversioned(self):
67
71
self.build_tree(['unversioned.txt'])
68
72
self.run_bzr_error(
69
["^bzr: ERROR: Could not rename unversioned.txt => elsewhere."
70
" .*unversioned.txt is not versioned\.$"],
73
["^brz: ERROR: Could not rename unversioned.txt => elsewhere."
74
" .*unversioned.txt is not versioned\\.$"],
71
75
'mv unversioned.txt elsewhere')
73
77
def test_mv_nonexisting(self):
74
78
self.run_bzr_error(
75
["^bzr: ERROR: Could not rename doesnotexist => somewhereelse."
76
" .*doesnotexist is not versioned\.$"],
79
["^brz: ERROR: Could not rename doesnotexist => somewhereelse."
80
" .*doesnotexist is not versioned\\.$"],
77
81
'mv doesnotexist somewhereelse')
79
83
def test_mv_unqualified(self):
80
self.run_bzr_error(['^bzr: ERROR: missing file argument$'], 'mv')
84
self.run_bzr_error(['^brz: ERROR: missing file argument$'], 'mv')
82
86
def test_mv_invalid(self):
83
87
tree = self.make_branch_and_tree('.')
99
103
tree.add(['hello.txt', 'sub1'])
101
105
self.run_bzr('mv sub1 sub2')
102
self.assertMoved('sub1','sub2')
106
self.assertMoved('sub1', 'sub2')
104
108
self.run_bzr('mv hello.txt sub2')
105
self.assertMoved('hello.txt','sub2/hello.txt')
109
self.assertMoved('hello.txt', 'sub2/hello.txt')
107
111
self.build_tree(['sub1/'])
108
112
tree.add(['sub1'])
109
113
self.run_bzr('mv sub2/hello.txt sub1')
110
self.assertMoved('sub2/hello.txt','sub1/hello.txt')
114
self.assertMoved('sub2/hello.txt', 'sub1/hello.txt')
112
116
self.run_bzr('mv sub2 sub1')
113
self.assertMoved('sub2','sub1/sub2')
117
self.assertMoved('sub2', 'sub1/sub2')
115
119
def test_mv_relative(self):
116
120
self.build_tree(['sub1/', 'sub1/sub2/', 'sub1/hello.txt'])
117
121
tree = self.make_branch_and_tree('.')
118
122
tree.add(['sub1', 'sub1/sub2', 'sub1/hello.txt'])
120
os.chdir('sub1/sub2')
121
self.run_bzr('mv ../hello.txt .')
122
self.failUnlessExists('./hello.txt')
124
self.run_bzr('mv ../hello.txt .', working_dir='sub1/sub2')
125
self.assertPathExists('sub1/sub2/hello.txt')
125
self.run_bzr('mv sub2/hello.txt .')
127
self.assertMoved('sub1/sub2/hello.txt','sub1/hello.txt')
127
self.run_bzr('mv sub2/hello.txt .', working_dir='sub1')
128
self.assertMoved('sub1/sub2/hello.txt', 'sub1/hello.txt')
129
130
def test_mv_change_case_file(self):
130
131
# test for bug #77740 (mv unable change filename case on Windows)
169
170
self.build_tree(['foo/', 'bar'])
170
171
tree.add(['foo', 'bar'])
171
172
out, err = self.run_bzr('mv bar Foo', retcode=3)
172
self.assertEquals('', out)
174
'bzr: ERROR: Could not move to Foo: Foo is not versioned.\n',
173
self.assertEqual('', out)
175
'brz: ERROR: Could not move to Foo: Foo is not versioned.\n',
177
178
def test_mv_smoke_aliases(self):
184
185
self.run_bzr('move a b')
185
186
self.run_bzr('rename b a')
188
def test_mv_no_root(self):
189
tree = self.make_branch_and_tree('.')
191
["brz: ERROR: can not move root of branch"],
187
194
def test_mv_through_symlinks(self):
188
195
self.requireFeature(SymlinkFeature)
189
196
tree = self.make_branch_and_tree('.')
190
197
self.build_tree(['a/', 'a/b'])
191
198
os.symlink('a', 'c')
192
199
os.symlink('.', 'd')
193
tree.add(['a', 'a/b', 'c'], ['a-id', 'b-id', 'c-id'])
200
tree.add(['a', 'a/b', 'c'], [b'a-id', b'b-id', b'c-id'])
194
201
self.run_bzr('mv c/b b')
195
202
tree = workingtree.WorkingTree.open('.')
196
self.assertEqual('b-id', tree.path2id('b'))
203
self.assertEqual(b'b-id', tree.path2id('b'))
198
205
def test_mv_already_moved_file(self):
199
"""Test bzr mv original_file to moved_file.
206
"""Test brz mv original_file to moved_file.
201
208
Tests if a file which has allready been moved by an external tool,
202
is handled correctly by bzr mv.
209
is handled correctly by brz mv.
203
210
Setup: a is in the working tree, b does not exist.
204
User does: mv a b; bzr mv a b
211
User does: mv a b; brz mv a b
206
213
self.build_tree(['a'])
207
214
tree = self.make_branch_and_tree('.')
210
217
osutils.rename('a', 'b')
211
218
self.run_bzr('mv a b')
212
self.assertMoved('a','b')
219
self.assertMoved('a', 'b')
214
221
def test_mv_already_moved_file_to_versioned_target(self):
215
"""Test bzr mv existing_file to versioned_file.
222
"""Test brz mv existing_file to versioned_file.
217
224
Tests if an attempt to move an existing versioned file
218
225
to another versiond file will fail.
219
226
Setup: a and b are in the working tree.
220
User does: rm b; mv a b; bzr mv a b
227
User does: rm b; mv a b; brz mv a b
222
229
self.build_tree(['a', 'b'])
223
230
tree = self.make_branch_and_tree('.')
227
234
osutils.rename('a', 'b')
228
235
self.run_bzr_error(
229
["^bzr: ERROR: Could not move a => b. b is already versioned\.$"],
236
["^brz: ERROR: Could not move a => b. b is already versioned\\.$"],
231
#check that nothing changed
232
self.failIfExists('a')
233
self.failUnlessExists('b')
238
# check that nothing changed
239
self.assertPathDoesNotExist('a')
240
self.assertPathExists('b')
235
242
def test_mv_already_moved_file_into_subdir(self):
236
"""Test bzr mv original_file to versioned_directory/file.
243
"""Test brz mv original_file to versioned_directory/file.
238
245
Tests if a file which has already been moved into a versioned
239
directory by an external tool, is handled correctly by bzr mv.
246
directory by an external tool, is handled correctly by brz mv.
240
247
Setup: a and sub/ are in the working tree.
241
User does: mv a sub/a; bzr mv a sub/a
248
User does: mv a sub/a; brz mv a sub/a
243
250
self.build_tree(['a', 'sub/'])
244
251
tree = self.make_branch_and_tree('.')
247
254
osutils.rename('a', 'sub/a')
248
255
self.run_bzr('mv a sub/a')
249
self.assertMoved('a','sub/a')
256
self.assertMoved('a', 'sub/a')
251
258
def test_mv_already_moved_file_into_unversioned_subdir(self):
252
"""Test bzr mv original_file to unversioned_directory/file.
259
"""Test brz mv original_file to unversioned_directory/file.
254
261
Tests if an attempt to move an existing versioned file
255
262
into an unversioned directory will fail.
256
263
Setup: a is in the working tree, sub/ is not.
257
User does: mv a sub/a; bzr mv a sub/a
264
User does: mv a sub/a; brz mv a sub/a
259
266
self.build_tree(['a', 'sub/'])
260
267
tree = self.make_branch_and_tree('.')
263
270
osutils.rename('a', 'sub/a')
264
271
self.run_bzr_error(
265
["^bzr: ERROR: Could not move a => a: sub is not versioned\.$"],
272
["^brz: ERROR: Could not move a => a: sub is not versioned\\.$"],
267
self.failIfExists('a')
268
self.failUnlessExists('sub/a')
274
self.assertPathDoesNotExist('a')
275
self.assertPathExists('sub/a')
270
277
def test_mv_already_moved_files_into_subdir(self):
271
"""Test bzr mv original_files to versioned_directory.
278
"""Test brz mv original_files to versioned_directory.
273
280
Tests if files which has already been moved into a versioned
274
directory by an external tool, is handled correctly by bzr mv.
281
directory by an external tool, is handled correctly by brz mv.
275
282
Setup: a1, a2, sub are in the working tree.
276
User does: mv a1 sub/.; bzr mv a1 a2 sub
283
User does: mv a1 sub/.; brz mv a1 a2 sub
278
285
self.build_tree(['a1', 'a2', 'sub/'])
279
286
tree = self.make_branch_and_tree('.')
282
289
osutils.rename('a1', 'sub/a1')
283
290
self.run_bzr('mv a1 a2 sub')
284
self.assertMoved('a1','sub/a1')
285
self.assertMoved('a2','sub/a2')
291
self.assertMoved('a1', 'sub/a1')
292
self.assertMoved('a2', 'sub/a2')
287
294
def test_mv_already_moved_files_into_unversioned_subdir(self):
288
"""Test bzr mv original_file to unversioned_directory.
295
"""Test brz mv original_file to unversioned_directory.
290
297
Tests if an attempt to move existing versioned file
291
298
into an unversioned directory will fail.
292
299
Setup: a1, a2 are in the working tree, sub is not.
293
User does: mv a1 sub/.; bzr mv a1 a2 sub
300
User does: mv a1 sub/.; brz mv a1 a2 sub
295
302
self.build_tree(['a1', 'a2', 'sub/'])
296
303
tree = self.make_branch_and_tree('.')
299
306
osutils.rename('a1', 'sub/a1')
300
307
self.run_bzr_error(
301
["^bzr: ERROR: Could not move to sub. sub is not versioned\.$"],
308
["^brz: ERROR: Could not move to sub. sub is not versioned\\.$"],
303
self.failIfExists('a1')
304
self.failUnlessExists('sub/a1')
305
self.failUnlessExists('a2')
306
self.failIfExists('sub/a2')
310
self.assertPathDoesNotExist('a1')
311
self.assertPathExists('sub/a1')
312
self.assertPathExists('a2')
313
self.assertPathDoesNotExist('sub/a2')
308
315
def test_mv_already_moved_file_forcing_after(self):
309
"""Test bzr mv versioned_file to unversioned_file.
316
"""Test brz mv versioned_file to unversioned_file.
311
318
Tests if an attempt to move an existing versioned file to an existing
312
319
unversioned file will fail, informing the user to use the --after
313
320
option to force this.
314
321
Setup: a is in the working tree, b not versioned.
315
User does: mv a b; touch a; bzr mv a b
322
User does: mv a b; touch a; brz mv a b
317
324
self.build_tree(['a', 'b'])
318
325
tree = self.make_branch_and_tree('.')
321
328
osutils.rename('a', 'b')
322
self.build_tree(['a']) #touch a
329
self.build_tree(['a']) # touch a
323
330
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"
331
["^brz: ERROR: Could not rename a => b because both files exist."
332
" \\(Use --after to tell brz about a rename that has already"
328
self.failUnlessExists('a')
329
self.failUnlessExists('b')
335
self.assertPathExists('a')
336
self.assertPathExists('b')
331
338
def test_mv_already_moved_file_using_after(self):
332
"""Test bzr mv --after versioned_file to unversioned_file.
339
"""Test brz mv --after versioned_file to unversioned_file.
334
341
Tests if an existing versioned file can be forced to move to an
335
342
existing unversioned file using the --after option. With the result
336
343
that bazaar considers the unversioned_file to be moved from
337
344
versioned_file and versioned_file will become unversioned.
338
345
Setup: a is in the working tree and b exists.
339
User does: mv a b; touch a; bzr mv a b --after
346
User does: mv a b; touch a; brz mv a b --after
340
347
Resulting in a => b and a is unknown.
342
349
self.build_tree(['a', 'b'])
343
350
tree = self.make_branch_and_tree('.')
345
352
osutils.rename('a', 'b')
346
self.build_tree(['a']) #touch a
353
self.build_tree(['a']) # touch a
348
355
self.run_bzr('mv a b --after')
349
self.failUnlessExists('a')
350
self.assertNotInWorkingTree('a')#a should be unknown now.
351
self.failUnlessExists('b')
356
self.assertPathExists('a')
357
self.assertNotInWorkingTree('a') # a should be unknown now.
358
self.assertPathExists('b')
352
359
self.assertInWorkingTree('b')
354
361
def test_mv_already_moved_files_forcing_after(self):
355
"""Test bzr mv versioned_files to directory/unversioned_file.
362
"""Test brz mv versioned_files to directory/unversioned_file.
357
364
Tests if an attempt to move an existing versioned file to an existing
358
365
unversioned file in some other directory will fail, informing the user
361
368
Setup: a1, a2, sub are versioned and in the working tree,
362
369
sub/a1, sub/a2 are in working tree.
363
User does: mv a* sub; touch a1; touch a2; bzr mv a1 a2 sub
370
User does: mv a* sub; touch a1; touch a2; brz mv a1 a2 sub
365
372
self.build_tree(['a1', 'a2', 'sub/', 'sub/a1', 'sub/a2'])
366
373
tree = self.make_branch_and_tree('.')
367
374
tree.add(['a1', 'a2', 'sub'])
368
375
osutils.rename('a1', 'sub/a1')
369
376
osutils.rename('a2', 'sub/a2')
370
self.build_tree(['a1']) #touch a1
371
self.build_tree(['a2']) #touch a2
377
self.build_tree(['a1']) # touch a1
378
self.build_tree(['a2']) # touch a2
373
380
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"
381
["^brz: ERROR: Could not rename a1 => sub/a1 because both files"
382
" exist. \\(Use --after to tell brz about a rename that has already"
378
self.failUnlessExists('a1')
379
self.failUnlessExists('a2')
380
self.failUnlessExists('sub/a1')
381
self.failUnlessExists('sub/a2')
385
self.assertPathExists('a1')
386
self.assertPathExists('a2')
387
self.assertPathExists('sub/a1')
388
self.assertPathExists('sub/a2')
383
390
def test_mv_already_moved_files_using_after(self):
384
"""Test bzr mv --after versioned_file to directory/unversioned_file.
391
"""Test brz mv --after versioned_file to directory/unversioned_file.
386
393
Tests if an existing versioned file can be forced to move to an
387
394
existing unversioned file in some other directory using the --after
392
399
Setup: a1, a2, sub are versioned and in the working tree,
393
400
sub/a1, sub/a2 are in working tree.
394
User does: mv a* sub; touch a1; touch a2; bzr mv a1 a2 sub --after
401
User does: mv a* sub; touch a1; touch a2; brz mv a1 a2 sub --after
396
403
self.build_tree(['a1', 'a2', 'sub/', 'sub/a1', 'sub/a2'])
397
404
tree = self.make_branch_and_tree('.')
398
405
tree.add(['a1', 'a2', 'sub'])
399
406
osutils.rename('a1', 'sub/a1')
400
407
osutils.rename('a2', 'sub/a2')
401
self.build_tree(['a1']) #touch a1
402
self.build_tree(['a2']) #touch a2
408
self.build_tree(['a1']) # touch a1
409
self.build_tree(['a2']) # touch a2
404
411
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')
412
self.assertPathExists('a1')
413
self.assertPathExists('a2')
414
self.assertPathExists('sub/a1')
415
self.assertPathExists('sub/a2')
409
416
self.assertInWorkingTree('sub/a1')
410
417
self.assertInWorkingTree('sub/a2')
412
419
def test_mv_already_moved_directory(self):
413
"""Use `bzr mv a b` to mark a directory as renamed.
420
"""Use `brz mv a b` to mark a directory as renamed.
415
422
https://bugs.launchpad.net/bzr/+bug/107967/
421
428
osutils.rename('c', 'd')
422
429
# mv a b should work just like it does for already renamed files
423
430
self.run_bzr('mv a b')
424
self.failIfExists('a')
431
self.assertPathDoesNotExist('a')
425
432
self.assertNotInWorkingTree('a')
426
self.failUnlessExists('b')
433
self.assertPathExists('b')
427
434
self.assertInWorkingTree('b')
428
435
# and --after should work, too (technically it's ignored)
429
436
self.run_bzr('mv --after c d')
430
self.failIfExists('c')
437
self.assertPathDoesNotExist('c')
431
438
self.assertNotInWorkingTree('c')
432
self.failUnlessExists('d')
439
self.assertPathExists('d')
433
440
self.assertInWorkingTree('d')
435
442
def make_abcd_tree(self):
447
454
self.assertEqual(out, '')
448
455
self.assertEqual(err, 'a => b\nc => d\n')
449
456
tree = workingtree.WorkingTree.open('tree')
450
self.assertIsNot(None, tree.path2id('b'))
451
self.assertIsNot(None, tree.path2id('d'))
457
self.assertTrue(tree.is_versioned('b'))
458
self.assertTrue(tree.is_versioned('d'))
453
460
def test_mv_auto_one_path(self):
454
461
self.make_abcd_tree()
456
463
self.assertEqual(out, '')
457
464
self.assertEqual(err, 'a => b\nc => d\n')
458
465
tree = workingtree.WorkingTree.open('tree')
459
self.assertIsNot(None, tree.path2id('b'))
460
self.assertIsNot(None, tree.path2id('d'))
466
self.assertTrue(tree.is_versioned('b'))
467
self.assertTrue(tree.is_versioned('d'))
462
469
def test_mv_auto_two_paths(self):
463
470
self.make_abcd_tree()
464
471
out, err = self.run_bzr('mv --auto tree tree2', retcode=3)
465
self.assertEqual('bzr: ERROR: Only one path may be specified to'
472
self.assertEqual('brz: ERROR: Only one path may be specified to'
466
473
' --auto.\n', err)
468
475
def test_mv_auto_dry_run(self):
471
478
self.assertEqual(out, '')
472
479
self.assertEqual(err, 'a => b\nc => d\n')
473
480
tree = workingtree.WorkingTree.open('tree')
474
self.assertIsNot(None, tree.path2id('a'))
475
self.assertIsNot(None, tree.path2id('c'))
481
self.assertTrue(tree.is_versioned('a'))
482
self.assertTrue(tree.is_versioned('c'))
477
484
def test_mv_no_auto_dry_run(self):
478
485
self.make_abcd_tree()
479
486
out, err = self.run_bzr('mv c d --dry-run',
480
487
working_dir='tree', retcode=3)
481
self.assertEqual('bzr: ERROR: --dry-run requires --auto.\n', err)
488
self.assertEqual('brz: ERROR: --dry-run requires --auto.\n', err)
483
490
def test_mv_auto_after(self):
484
491
self.make_abcd_tree()
485
492
out, err = self.run_bzr('mv --auto --after', working_dir='tree',
487
self.assertEqual('bzr: ERROR: --after cannot be specified with'
494
self.assertEqual('brz: ERROR: --after cannot be specified with'
488
495
' --auto.\n', err)
490
497
def test_mv_quiet(self):
498
505
def test_mv_readonly_lightweight_checkout(self):
499
506
branch = self.make_branch('foo')
500
branch = bzrlib.branch.Branch.open(self.get_readonly_url('foo'))
507
branch = breezy.branch.Branch.open(self.get_readonly_url('foo'))
501
508
tree = branch.create_checkout('tree', lightweight=True)
502
509
self.build_tree(['tree/path'])
504
511
# If this fails, the tree is trying to acquire a branch lock, which it
506
513
self.run_bzr(['mv', 'tree/path', 'tree/path2'])
515
def test_mv_unversioned_non_ascii(self):
516
"""Clear error on mv of an unversioned non-ascii file, see lp:707954"""
517
self.requireFeature(UnicodeFilenameFeature)
518
tree = self.make_branch_and_tree(".")
519
self.build_tree([u"\xA7"])
520
out, err = self.run_bzr_error(["Could not rename", "not versioned"],
521
["mv", u"\xA7", "b"])
523
def test_mv_removed_non_ascii(self):
524
"""Clear error on mv of a removed non-ascii file, see lp:898541"""
525
self.requireFeature(UnicodeFilenameFeature)
526
tree = self.make_branch_and_tree(".")
527
self.build_tree([u"\xA7"])
529
tree.commit(u"Adding \xA7")
531
out, err = self.run_bzr_error(["Could not rename", "not exist"],
532
["mv", u"\xA7", "b"])
534
def test_dupe_move(self):
535
self.script_runner = script.ScriptRunner()
536
self.script_runner.run_script(self, '''
538
Created a standalone tree (format: 2a)
543
$ echo text >> dir/test.txt
546
$ brz ci -m "Add files"
547
2>Committing to: .../brz-bug/
550
2>Committed revision 1.
552
$ mv dir2/test.txt dir2/test2.txt
568
$ brz mv dir/test.txt dir2/test2.txt
569
dir/test.txt => dir2/test2.txt