~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Ian Clatworthy
  • Date: 2007-08-13 14:33:10 UTC
  • mto: (2733.1.1 ianc-integration)
  • mto: This revision was merged to the branch mainline in revision 2734.
  • Revision ID: ian.clatworthy@internode.on.net-20070813143310-twhj4la0qnupvze8
Added Quick Start Summary

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2010 Canonical Ltd
2
 
# -*- coding: utf-8 -*-
3
 
#
4
 
# This program is free software; you can redistribute it and/or modify
5
 
# it under the terms of the GNU General Public License as published by
6
 
# the Free Software Foundation; either version 2 of the License, or
7
 
# (at your option) any later version.
8
 
#
9
 
# This program is distributed in the hope that it will be useful,
10
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
# GNU General Public License for more details.
13
 
#
14
 
# You should have received a copy of the GNU General Public License
15
 
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 
 
18
 
 
19
 
"""Tests for the switch command of bzr."""
20
 
 
21
 
import os
22
 
 
23
 
from bzrlib import (
24
 
        osutils,
25
 
        urlutils,
26
 
        branch,
27
 
        )
28
 
from bzrlib.workingtree import WorkingTree
29
 
from bzrlib.tests import (
30
 
        TestCaseWithTransport,
31
 
        script,
32
 
        )
33
 
from bzrlib.directory_service import directories
34
 
 
35
 
 
36
 
class TestSwitch(TestCaseWithTransport):
37
 
 
38
 
    def _create_sample_tree(self):
39
 
        tree = self.make_branch_and_tree('branch-1')
40
 
        self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
41
 
        tree.add('file-1')
42
 
        tree.commit('rev1')
43
 
        tree.add('file-2')
44
 
        tree.commit('rev2')
45
 
        return tree
46
 
 
47
 
    def test_switch_up_to_date_light_checkout(self):
48
 
        self.make_branch_and_tree('branch')
49
 
        self.run_bzr('branch branch branch2')
50
 
        self.run_bzr('checkout --lightweight branch checkout')
51
 
        os.chdir('checkout')
52
 
        out, err = self.run_bzr('switch ../branch2')
53
 
        self.assertContainsRe(err, 'Tree is up to date at revision 0.\n')
54
 
        self.assertContainsRe(err, 'Switched to branch: .*/branch2.\n')
55
 
        self.assertEqual('', out)
56
 
 
57
 
    def test_switch_out_of_date_light_checkout(self):
58
 
        self.make_branch_and_tree('branch')
59
 
        self.run_bzr('branch branch branch2')
60
 
        self.build_tree(['branch2/file'])
61
 
        self.run_bzr('add branch2/file')
62
 
        self.run_bzr('commit -m add-file branch2')
63
 
        self.run_bzr('checkout --lightweight branch checkout')
64
 
        os.chdir('checkout')
65
 
        out, err = self.run_bzr('switch ../branch2')
66
 
        #self.assertContainsRe(err, '\+N  file')
67
 
        self.assertContainsRe(err, 'Updated to revision 1.\n')
68
 
        self.assertContainsRe(err, 'Switched to branch: .*/branch2.\n')
69
 
        self.assertEqual('', out)
70
 
 
71
 
    def _test_switch_nick(self, lightweight):
72
 
        """Check that the nick gets switched too."""
73
 
        tree1 = self.make_branch_and_tree('branch1')
74
 
        tree2 = self.make_branch_and_tree('branch2')
75
 
        tree2.pull(tree1.branch)
76
 
        checkout =  tree1.branch.create_checkout('checkout',
77
 
            lightweight=lightweight)
78
 
        self.assertEqual(checkout.branch.nick, tree1.branch.nick)
79
 
        self.assertEqual(checkout.branch.get_config().has_explicit_nickname(),
80
 
            False)
81
 
        self.run_bzr('switch branch2', working_dir='checkout')
82
 
 
83
 
        # we need to get the tree again, otherwise we don't get the new branch
84
 
        checkout = WorkingTree.open('checkout')
85
 
        self.assertEqual(checkout.branch.nick, tree2.branch.nick)
86
 
        self.assertEqual(checkout.branch.get_config().has_explicit_nickname(),
87
 
            False)
88
 
 
89
 
    def test_switch_nick(self):
90
 
        self._test_switch_nick(lightweight=False)
91
 
 
92
 
    def test_switch_nick_lightweight(self):
93
 
        self._test_switch_nick(lightweight=True)
94
 
 
95
 
    def _test_switch_explicit_nick(self, lightweight):
96
 
        """Check that the nick gets switched too."""
97
 
        tree1 = self.make_branch_and_tree('branch1')
98
 
        tree2 = self.make_branch_and_tree('branch2')
99
 
        tree2.pull(tree1.branch)
100
 
        checkout =  tree1.branch.create_checkout('checkout',
101
 
            lightweight=lightweight)
102
 
        self.assertEqual(checkout.branch.nick, tree1.branch.nick)
103
 
        checkout.branch.nick = "explicit_nick"
104
 
        self.assertEqual(checkout.branch.nick, "explicit_nick")
105
 
        self.assertEqual(checkout.branch.get_config()._get_explicit_nickname(),
106
 
            "explicit_nick")
107
 
        self.run_bzr('switch branch2', working_dir='checkout')
108
 
 
109
 
        # we need to get the tree again, otherwise we don't get the new branch
110
 
        checkout = WorkingTree.open('checkout')
111
 
        self.assertEqual(checkout.branch.nick, tree2.branch.nick)
112
 
        self.assertEqual(checkout.branch.get_config()._get_explicit_nickname(),
113
 
            tree2.branch.nick)
114
 
 
115
 
    def test_switch_explicit_nick(self):
116
 
        self._test_switch_explicit_nick(lightweight=False)
117
 
 
118
 
    def test_switch_explicit_nick_lightweight(self):
119
 
        self._test_switch_explicit_nick(lightweight=True)
120
 
 
121
 
    def test_switch_finds_relative_branch(self):
122
 
        """Switch will find 'foo' relative to the branch the checkout is of."""
123
 
        self.build_tree(['repo/'])
124
 
        tree1 = self.make_branch_and_tree('repo/brancha')
125
 
        tree1.commit('foo')
126
 
        tree2 = self.make_branch_and_tree('repo/branchb')
127
 
        tree2.pull(tree1.branch)
128
 
        branchb_id = tree2.commit('bar')
129
 
        checkout =  tree1.branch.create_checkout('checkout', lightweight=True)
130
 
        self.run_bzr(['switch', 'branchb'], working_dir='checkout')
131
 
        self.assertEqual(branchb_id, checkout.last_revision())
132
 
        checkout = checkout.bzrdir.open_workingtree()
133
 
        self.assertEqual(tree2.branch.base, checkout.branch.base)
134
 
 
135
 
    def test_switch_finds_relative_bound_branch(self):
136
 
        """Using switch on a heavy checkout should find master sibling
137
 
 
138
 
        The behaviour of lighweight and heavy checkouts should be
139
 
        consistent when using the convenient "switch to sibling" feature
140
 
        Both should switch to a sibling of the branch
141
 
        they are bound to, and not a sibling of themself"""
142
 
 
143
 
        self.build_tree(['repo/',
144
 
                         'heavyco/'])
145
 
        tree1 = self.make_branch_and_tree('repo/brancha')
146
 
        tree1.commit('foo')
147
 
        tree2 = self.make_branch_and_tree('repo/branchb')
148
 
        tree2.pull(tree1.branch)
149
 
        branchb_id = tree2.commit('bar')
150
 
        checkout = tree1.branch.create_checkout('heavyco/a', lightweight=False)
151
 
        self.run_bzr(['switch', 'branchb'], working_dir='heavyco/a')
152
 
        self.assertEqual(branchb_id, checkout.last_revision())
153
 
        self.assertEqual(tree2.branch.base, checkout.branch.get_bound_location())
154
 
 
155
 
    def test_switch_revision(self):
156
 
        tree = self._create_sample_tree()
157
 
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
158
 
        self.run_bzr(['switch', 'branch-1', '-r1'], working_dir='checkout')
159
 
        self.assertPathExists('checkout/file-1')
160
 
        self.assertPathDoesNotExist('checkout/file-2')
161
 
 
162
 
    def test_switch_only_revision(self):
163
 
        tree = self._create_sample_tree()
164
 
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
165
 
        self.assertPathExists('checkout/file-1')
166
 
        self.assertPathExists('checkout/file-2')
167
 
        self.run_bzr(['switch', '-r1'], working_dir='checkout')
168
 
        self.assertPathExists('checkout/file-1')
169
 
        self.assertPathDoesNotExist('checkout/file-2')
170
 
        # Check that we don't accept a range
171
 
        self.run_bzr_error(
172
 
            ['bzr switch --revision takes exactly one revision identifier'],
173
 
            ['switch', '-r0..2'], working_dir='checkout')
174
 
 
175
 
    def prepare_lightweight_switch(self):
176
 
        branch = self.make_branch('branch')
177
 
        branch.create_checkout('tree', lightweight=True)
178
 
        osutils.rename('branch', 'branch1')
179
 
 
180
 
    def test_switch_lightweight_after_branch_moved(self):
181
 
        self.prepare_lightweight_switch()
182
 
        self.run_bzr('switch --force ../branch1', working_dir='tree')
183
 
        branch_location = WorkingTree.open('tree').branch.base
184
 
        self.assertEndsWith(branch_location, 'branch1/')
185
 
 
186
 
    def test_switch_lightweight_after_branch_moved_relative(self):
187
 
        self.prepare_lightweight_switch()
188
 
        self.run_bzr('switch --force branch1', working_dir='tree')
189
 
        branch_location = WorkingTree.open('tree').branch.base
190
 
        self.assertEndsWith(branch_location, 'branch1/')
191
 
 
192
 
    def test_create_branch_no_branch(self):
193
 
        self.prepare_lightweight_switch()
194
 
        self.run_bzr_error(['cannot create branch without source branch'],
195
 
            'switch --create-branch ../branch2', working_dir='tree')
196
 
 
197
 
    def test_create_branch(self):
198
 
        branch = self.make_branch('branch')
199
 
        tree = branch.create_checkout('tree', lightweight=True)
200
 
        tree.commit('one', rev_id='rev-1')
201
 
        self.run_bzr('switch --create-branch ../branch2', working_dir='tree')
202
 
        tree = WorkingTree.open('tree')
203
 
        self.assertEndsWith(tree.branch.base, '/branch2/')
204
 
 
205
 
    def test_create_branch_local(self):
206
 
        branch = self.make_branch('branch')
207
 
        tree = branch.create_checkout('tree', lightweight=True)
208
 
        tree.commit('one', rev_id='rev-1')
209
 
        self.run_bzr('switch --create-branch branch2', working_dir='tree')
210
 
        tree = WorkingTree.open('tree')
211
 
        # The new branch should have been created at the same level as
212
 
        # 'branch', because we did not have a '/' segment
213
 
        self.assertEqual(branch.base[:-1] + '2/', tree.branch.base)
214
 
 
215
 
    def test_create_branch_short_name(self):
216
 
        branch = self.make_branch('branch')
217
 
        tree = branch.create_checkout('tree', lightweight=True)
218
 
        tree.commit('one', rev_id='rev-1')
219
 
        self.run_bzr('switch -b branch2', working_dir='tree')
220
 
        tree = WorkingTree.open('tree')
221
 
        # The new branch should have been created at the same level as
222
 
        # 'branch', because we did not have a '/' segment
223
 
        self.assertEqual(branch.base[:-1] + '2/', tree.branch.base)
224
 
 
225
 
    def test_create_branch_directory_services(self):
226
 
        branch = self.make_branch('branch')
227
 
        tree = branch.create_checkout('tree', lightweight=True)
228
 
        class FooLookup(object):
229
 
            def look_up(self, name, url):
230
 
                return 'foo-'+name
231
 
        directories.register('foo:', FooLookup, 'Create branches named foo-')
232
 
        self.addCleanup(directories.remove, 'foo:')
233
 
        self.run_bzr('switch -b foo:branch2', working_dir='tree')
234
 
        tree = WorkingTree.open('tree')
235
 
        self.assertEndsWith(tree.branch.base, 'foo-branch2/')
236
 
 
237
 
    def test_switch_with_post_switch_hook(self):
238
 
        from bzrlib import branch as _mod_branch
239
 
        calls = []
240
 
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
241
 
            calls.append, None)
242
 
        self.make_branch_and_tree('branch')
243
 
        self.run_bzr('branch branch branch2')
244
 
        self.run_bzr('checkout branch checkout')
245
 
        os.chdir('checkout')
246
 
        self.assertLength(0, calls)
247
 
        out, err = self.run_bzr('switch ../branch2')
248
 
        self.assertLength(1, calls)
249
 
 
250
 
    def test_switch_lightweight_co_with_post_switch_hook(self):
251
 
        from bzrlib import branch as _mod_branch
252
 
        calls = []
253
 
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
254
 
            calls.append, None)
255
 
        self.make_branch_and_tree('branch')
256
 
        self.run_bzr('branch branch branch2')
257
 
        self.run_bzr('checkout --lightweight branch checkout')
258
 
        os.chdir('checkout')
259
 
        self.assertLength(0, calls)
260
 
        out, err = self.run_bzr('switch ../branch2')
261
 
        self.assertLength(1, calls)
262
 
 
263
 
    def test_switch_lightweight_directory(self):
264
 
        """Test --directory option"""
265
 
 
266
 
        # create a source branch
267
 
        a_tree = self.make_branch_and_tree('a')
268
 
        self.build_tree_contents([('a/a', 'initial\n')])
269
 
        a_tree.add('a')
270
 
        a_tree.commit(message='initial')
271
 
 
272
 
        # clone and add a differing revision
273
 
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
274
 
        self.build_tree_contents([('b/a', 'initial\nmore\n')])
275
 
        b_tree.commit(message='more')
276
 
 
277
 
        self.run_bzr('checkout --lightweight a checkout')
278
 
        self.run_bzr('switch --directory checkout b')
279
 
        self.assertFileEqual('initial\nmore\n', 'checkout/a')
280
 
 
281
 
 
282
 
class TestSwitchParentLocationBase(TestCaseWithTransport):
283
 
 
284
 
    def setUp(self):
285
 
        """Set up a repository and branch ready for testing."""
286
 
        super(TestSwitchParentLocationBase, self).setUp()
287
 
        self.script_runner = script.ScriptRunner()
288
 
        self.script_runner.run_script(self, '''
289
 
                $ bzr init-repo --no-trees repo
290
 
                Shared repository...
291
 
                Location:
292
 
                  shared repository: repo
293
 
                $ bzr init repo/trunk
294
 
                Created a repository branch...
295
 
                Using shared repository: ...
296
 
                ''')
297
 
 
298
 
    def assertParent(self, expected_parent, branch):
299
 
        """Verify that the parent is not None and is set correctly."""
300
 
        actual_parent = branch.get_parent()
301
 
        self.assertIsSameRealPath(urlutils.local_path_to_url(expected_parent),
302
 
                                  branch.get_parent())
303
 
 
304
 
 
305
 
class TestSwitchParentLocation(TestSwitchParentLocationBase):
306
 
 
307
 
    def _checkout_and_switch(self, option=''):
308
 
        self.script_runner.run_script(self, '''
309
 
                $ bzr checkout %(option)s repo/trunk checkout
310
 
                $ cd checkout
311
 
                $ bzr switch --create-branch switched
312
 
                2>Tree is up to date at revision 0.
313
 
                2>Switched to branch:...switched...
314
 
                $ cd ..
315
 
                ''' % locals())
316
 
        bound_branch = branch.Branch.open_containing('checkout')[0]
317
 
        master_branch = branch.Branch.open_containing('repo/switched')[0]
318
 
        return (bound_branch, master_branch)
319
 
 
320
 
    def test_switch_parent_lightweight(self):
321
 
        """Lightweight checkout using bzr switch."""
322
 
        bb, mb = self._checkout_and_switch(option='--lightweight')
323
 
        self.assertParent('repo/trunk', bb)
324
 
        self.assertParent('repo/trunk', mb)
325
 
 
326
 
    def test_switch_parent_heavyweight(self):
327
 
        """Heavyweight checkout using bzr switch."""
328
 
        bb, mb = self._checkout_and_switch()
329
 
        self.assertParent('repo/trunk', bb)
330
 
        self.assertParent('repo/trunk', mb)
331
 
 
332
 
 
333
 
class TestSwitchDoesntOpenMasterBranch(TestCaseWithTransport):
334
 
    # See https://bugs.launchpad.net/bzr/+bug/812285
335
 
    # "bzr switch --create-branch" can point the new branch's parent to the
336
 
    # master branch, but it doesn't have to open it to do so.
337
 
 
338
 
    def test_switch_create_doesnt_open_master_branch(self):
339
 
        master = self.make_branch_and_tree('master')
340
 
        master.commit('one')
341
 
        # Note: not a lightweight checkout
342
 
        checkout = master.branch.create_checkout('checkout')
343
 
        opened = []
344
 
        def open_hook(branch):
345
 
            # Just append the final directory of the branch
346
 
            name = branch.base.rstrip('/').rsplit('/', 1)[1]
347
 
            opened.append(name)
348
 
        branch.Branch.hooks.install_named_hook('open', open_hook,
349
 
                                               'open_hook_logger')
350
 
        self.run_bzr('switch --create-branch -d checkout feature')
351
 
        # We only open the master branch 1 time.
352
 
        # This test should be cleaner to write, but see bug:
353
 
        #  https://bugs.launchpad.net/bzr/+bug/812295
354
 
        self.assertEqual(1, opened.count('master'))