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