1
# Copyright (C) 2006 Canonical Ltd
 
 
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.
 
 
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.
 
 
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
 
 
17
"""Test for 'bzr mv'"""
 
 
26
from bzrlib.tests import (
 
 
27
    TestCaseWithTransport,
 
 
32
class TestMove(TestCaseWithTransport):
 
 
34
    def assertMoved(self,from_path,to_path):
 
 
35
        """Assert that to_path is existing and versioned but from_path not. """
 
 
36
        self.failIfExists(from_path)
 
 
37
        self.assertNotInWorkingTree(from_path)
 
 
39
        self.failUnlessExists(to_path)
 
 
40
        self.assertInWorkingTree(to_path)
 
 
42
    def test_mv_modes(self):
 
 
43
        """Test two modes of operation for mv"""
 
 
44
        tree = self.make_branch_and_tree('.')
 
 
45
        files = self.build_tree(['a', 'c', 'subdir/'])
 
 
46
        tree.add(['a', 'c', 'subdir'])
 
 
48
        self.run_bzr('mv a b')
 
 
49
        self.assertMoved('a','b')
 
 
51
        self.run_bzr('mv b subdir')
 
 
52
        self.assertMoved('b','subdir/b')
 
 
54
        self.run_bzr('mv subdir/b a')
 
 
55
        self.assertMoved('subdir/b','a')
 
 
57
        self.run_bzr('mv a c subdir')
 
 
58
        self.assertMoved('a','subdir/a')
 
 
59
        self.assertMoved('c','subdir/c')
 
 
61
        self.run_bzr('mv subdir/a subdir/newa')
 
 
62
        self.assertMoved('subdir/a','subdir/newa')
 
 
64
    def test_mv_unversioned(self):
 
 
65
        self.build_tree(['unversioned.txt'])
 
 
67
            ["^bzr: ERROR: Could not rename unversioned.txt => elsewhere."
 
 
68
             " .*unversioned.txt is not versioned$"],
 
 
69
            'mv unversioned.txt elsewhere')
 
 
71
    def test_mv_nonexisting(self):
 
 
73
            ["^bzr: ERROR: Could not rename doesnotexist => somewhereelse."
 
 
74
             " .*doesnotexist is not versioned$"],
 
 
75
            'mv doesnotexist somewhereelse')
 
 
77
    def test_mv_unqualified(self):
 
 
78
        self.run_bzr_error(['^bzr: ERROR: missing file argument$'], 'mv')
 
 
80
    def test_mv_invalid(self):
 
 
81
        tree = self.make_branch_and_tree('.')
 
 
82
        self.build_tree(['test.txt', 'sub1/'])
 
 
83
        tree.add(['test.txt'])
 
 
86
            ["^bzr: ERROR: Could not move to sub1: sub1 is not versioned$"],
 
 
90
            ["^bzr: ERROR: Could not move test.txt => .*hello.txt: "
 
 
91
             "sub1 is not versioned$"],
 
 
92
            'mv test.txt sub1/hello.txt')
 
 
94
    def test_mv_dirs(self):
 
 
95
        tree = self.make_branch_and_tree('.')
 
 
96
        self.build_tree(['hello.txt', 'sub1/'])
 
 
97
        tree.add(['hello.txt', 'sub1'])
 
 
99
        self.run_bzr('mv sub1 sub2')
 
 
100
        self.assertMoved('sub1','sub2')
 
 
102
        self.run_bzr('mv hello.txt sub2')
 
 
103
        self.assertMoved('hello.txt','sub2/hello.txt')
 
 
105
        self.build_tree(['sub1/'])
 
 
107
        self.run_bzr('mv sub2/hello.txt sub1')
 
 
108
        self.assertMoved('sub2/hello.txt','sub1/hello.txt')
 
 
110
        self.run_bzr('mv sub2 sub1')
 
 
111
        self.assertMoved('sub2','sub1/sub2')
 
 
113
    def test_mv_relative(self):
 
 
114
        self.build_tree(['sub1/', 'sub1/sub2/', 'sub1/hello.txt'])
 
 
115
        tree = self.make_branch_and_tree('.')
 
 
116
        tree.add(['sub1', 'sub1/sub2', 'sub1/hello.txt'])
 
 
118
        os.chdir('sub1/sub2')
 
 
119
        self.run_bzr('mv ../hello.txt .')
 
 
120
        self.failUnlessExists('./hello.txt')
 
 
123
        self.run_bzr('mv sub2/hello.txt .')
 
 
125
        self.assertMoved('sub1/sub2/hello.txt','sub1/hello.txt')
 
 
127
    def test_mv_smoke_aliases(self):
 
 
128
        # just test that aliases for mv exist, if their behaviour is changed in
 
 
129
        # the future, then extend the tests.
 
 
130
        self.build_tree(['a'])
 
 
131
        tree = self.make_branch_and_tree('.')
 
 
134
        self.run_bzr('move a b')
 
 
135
        self.run_bzr('rename b a')
 
 
137
    def test_mv_through_symlinks(self):
 
 
138
        if not osutils.has_symlinks():
 
 
139
            raise TestSkipped('Symlinks are not supported on this platform')
 
 
140
        tree = self.make_branch_and_tree('.')
 
 
141
        self.build_tree(['a/', 'a/b'])
 
 
144
        tree.add(['a', 'a/b', 'c'], ['a-id', 'b-id', 'c-id'])
 
 
145
        self.run_bzr('mv c/b b')
 
 
146
        tree = workingtree.WorkingTree.open('.')
 
 
147
        self.assertEqual('b-id', tree.path2id('b'))
 
 
149
    def test_mv_already_moved_file(self):
 
 
150
        """Test bzr mv original_file to moved_file.
 
 
152
        Tests if a file which has allready been moved by an external tool,
 
 
153
        is handled correctly by bzr mv.
 
 
154
        Setup: a is in the working tree, b does not exist.
 
 
155
        User does: mv a b; bzr mv a b
 
 
157
        self.build_tree(['a'])
 
 
158
        tree = self.make_branch_and_tree('.')
 
 
161
        osutils.rename('a', 'b')
 
 
162
        self.run_bzr('mv a b')
 
 
163
        self.assertMoved('a','b')
 
 
165
    def test_mv_already_moved_file_to_versioned_target(self):
 
 
166
        """Test bzr mv existing_file to versioned_file.
 
 
168
        Tests if an attempt to move an existing versioned file
 
 
169
        to another versiond file will fail.
 
 
170
        Setup: a and b are in the working tree.
 
 
171
        User does: rm b; mv a b; bzr mv a b
 
 
173
        self.build_tree(['a', 'b'])
 
 
174
        tree = self.make_branch_and_tree('.')
 
 
178
        osutils.rename('a', 'b')
 
 
180
            ["^bzr: ERROR: Could not move a => b. b is already versioned$"],
 
 
182
        #check that nothing changed
 
 
183
        self.failIfExists('a')
 
 
184
        self.failUnlessExists('b')
 
 
186
    def test_mv_already_moved_file_into_subdir(self):
 
 
187
        """Test bzr mv original_file to versioned_directory/file.
 
 
189
        Tests if a file which has already been moved into a versioned
 
 
190
        directory by an external tool, is handled correctly by bzr mv.
 
 
191
        Setup: a and sub/ are in the working tree.
 
 
192
        User does: mv a sub/a; bzr mv a sub/a
 
 
194
        self.build_tree(['a', 'sub/'])
 
 
195
        tree = self.make_branch_and_tree('.')
 
 
196
        tree.add(['a', 'sub'])
 
 
198
        osutils.rename('a', 'sub/a')
 
 
199
        self.run_bzr('mv a sub/a')
 
 
200
        self.assertMoved('a','sub/a')
 
 
202
    def test_mv_already_moved_file_into_unversioned_subdir(self):
 
 
203
        """Test bzr mv original_file to unversioned_directory/file.
 
 
205
        Tests if an attempt to move an existing versioned file
 
 
206
        into an unversioned directory will fail.
 
 
207
        Setup: a is in the working tree, sub/ is not.
 
 
208
        User does: mv a sub/a; bzr mv a sub/a
 
 
210
        self.build_tree(['a', 'sub/'])
 
 
211
        tree = self.make_branch_and_tree('.')
 
 
214
        osutils.rename('a', 'sub/a')
 
 
216
            ["^bzr: ERROR: Could not move a => a: sub is not versioned$"],
 
 
218
        self.failIfExists('a')
 
 
219
        self.failUnlessExists('sub/a')
 
 
221
    def test_mv_already_moved_files_into_subdir(self):
 
 
222
        """Test bzr mv original_files to versioned_directory.
 
 
224
        Tests if files which has already been moved into a versioned
 
 
225
        directory by an external tool, is handled correctly by bzr mv.
 
 
226
        Setup: a1, a2, sub are in the working tree.
 
 
227
        User does: mv a1 sub/.; bzr mv a1 a2 sub
 
 
229
        self.build_tree(['a1', 'a2', 'sub/'])
 
 
230
        tree = self.make_branch_and_tree('.')
 
 
231
        tree.add(['a1', 'a2', 'sub'])
 
 
233
        osutils.rename('a1', 'sub/a1')
 
 
234
        self.run_bzr('mv a1 a2 sub')
 
 
235
        self.assertMoved('a1','sub/a1')
 
 
236
        self.assertMoved('a2','sub/a2')
 
 
238
    def test_mv_already_moved_files_into_unversioned_subdir(self):
 
 
239
        """Test bzr mv original_file to unversioned_directory.
 
 
241
        Tests if an attempt to move existing versioned file
 
 
242
        into an unversioned directory will fail.
 
 
243
        Setup: a1, a2 are in the working tree, sub is not.
 
 
244
        User does: mv a1 sub/.; bzr mv a1 a2 sub
 
 
246
        self.build_tree(['a1', 'a2', 'sub/'])
 
 
247
        tree = self.make_branch_and_tree('.')
 
 
248
        tree.add(['a1', 'a2'])
 
 
250
        osutils.rename('a1', 'sub/a1')
 
 
252
            ["^bzr: ERROR: Could not move to sub. sub is not versioned$"],
 
 
254
        self.failIfExists('a1')
 
 
255
        self.failUnlessExists('sub/a1')
 
 
256
        self.failUnlessExists('a2')
 
 
257
        self.failIfExists('sub/a2')
 
 
259
    def test_mv_already_moved_file_forcing_after(self):
 
 
260
        """Test bzr mv versioned_file to unversioned_file.
 
 
262
        Tests if an attempt to move an existing versioned file to an existing
 
 
263
        unversioned file will fail, informing the user to use the --after
 
 
264
        option to force this.
 
 
265
        Setup: a is in the working tree, b not versioned.
 
 
266
        User does: mv a b; touch a; bzr mv a b
 
 
268
        self.build_tree(['a', 'b'])
 
 
269
        tree = self.make_branch_and_tree('.')
 
 
272
        osutils.rename('a', 'b')
 
 
273
        self.build_tree(['a']) #touch a
 
 
275
            ["^bzr: ERROR: Could not rename a => b because both files exist."
 
 
276
             " \(Use --after to update the Bazaar id\)$"],
 
 
278
        self.failUnlessExists('a')
 
 
279
        self.failUnlessExists('b')
 
 
281
    def test_mv_already_moved_file_using_after(self):
 
 
282
        """Test bzr mv --after versioned_file to unversioned_file.
 
 
284
        Tests if an existing versioned file can be forced to move to an
 
 
285
        existing unversioned file using the --after option. With the result
 
 
286
        that bazaar considers the unversioned_file to be moved from
 
 
287
        versioned_file and versioned_file will become unversioned.
 
 
288
        Setup: a is in the working tree and b exists.
 
 
289
        User does: mv a b; touch a; bzr mv a b --after
 
 
290
        Resulting in a => b and a is unknown.
 
 
292
        self.build_tree(['a', 'b'])
 
 
293
        tree = self.make_branch_and_tree('.')
 
 
295
        osutils.rename('a', 'b')
 
 
296
        self.build_tree(['a']) #touch a
 
 
298
        self.run_bzr('mv a b --after')
 
 
299
        self.failUnlessExists('a')
 
 
300
        self.assertNotInWorkingTree('a')#a should be unknown now.
 
 
301
        self.failUnlessExists('b')
 
 
302
        self.assertInWorkingTree('b')
 
 
304
    def test_mv_already_moved_files_forcing_after(self):
 
 
305
        """Test bzr mv versioned_files to directory/unversioned_file.
 
 
307
        Tests if an attempt to move an existing versioned file to an existing
 
 
308
        unversioned file in some other directory will fail, informing the user
 
 
309
        to use the --after option to force this.
 
 
311
        Setup: a1, a2, sub are versioned and in the working tree,
 
 
312
               sub/a1, sub/a2 are in working tree.
 
 
313
        User does: mv a* sub; touch a1; touch a2; bzr mv a1 a2 sub
 
 
315
        self.build_tree(['a1', 'a2', 'sub/', 'sub/a1', 'sub/a2'])
 
 
316
        tree = self.make_branch_and_tree('.')
 
 
317
        tree.add(['a1', 'a2', 'sub'])
 
 
318
        osutils.rename('a1', 'sub/a1')
 
 
319
        osutils.rename('a2', 'sub/a2')
 
 
320
        self.build_tree(['a1']) #touch a1
 
 
321
        self.build_tree(['a2']) #touch a2
 
 
324
            ["^bzr: ERROR: Could not rename a1 => sub/a1 because both files exist."
 
 
325
             " \(Use --after to update the Bazaar id\)$"],
 
 
327
        self.failUnlessExists('a1')
 
 
328
        self.failUnlessExists('a2')
 
 
329
        self.failUnlessExists('sub/a1')
 
 
330
        self.failUnlessExists('sub/a2')
 
 
332
    def test_mv_already_moved_files_using_after(self):
 
 
333
        """Test bzr mv --after versioned_file to directory/unversioned_file.
 
 
335
        Tests if an existing versioned file can be forced to move to an
 
 
336
        existing unversioned file in some other directory using the --after
 
 
337
        option. With the result that bazaar considers
 
 
338
        directory/unversioned_file to be moved from versioned_file and
 
 
339
        versioned_file will become unversioned.
 
 
341
        Setup: a1, a2, sub are versioned and in the working tree,
 
 
342
               sub/a1, sub/a2 are in working tree.
 
 
343
        User does: mv a* sub; touch a1; touch a2; bzr mv a1 a2 sub --after
 
 
345
        self.build_tree(['a1', 'a2', 'sub/', 'sub/a1', 'sub/a2'])
 
 
346
        tree = self.make_branch_and_tree('.')
 
 
347
        tree.add(['a1', 'a2', 'sub'])
 
 
348
        osutils.rename('a1', 'sub/a1')
 
 
349
        osutils.rename('a2', 'sub/a2')
 
 
350
        self.build_tree(['a1']) #touch a1
 
 
351
        self.build_tree(['a2']) #touch a2
 
 
353
        self.run_bzr('mv a1 a2 sub --after')
 
 
354
        self.failUnlessExists('a1')
 
 
355
        self.failUnlessExists('a2')
 
 
356
        self.failUnlessExists('sub/a1')
 
 
357
        self.failUnlessExists('sub/a2')
 
 
358
        self.assertInWorkingTree('sub/a1')
 
 
359
        self.assertInWorkingTree('sub/a2')