1
# Copyright (C) 2007-2010 Canonical Ltd
2
# -*- coding: utf-8 -*-
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.
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.
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
19
"""Tests for the switch command of bzr."""
23
from bzrlib import osutils
24
from bzrlib.workingtree import WorkingTree
25
from bzrlib.tests import TestCaseWithTransport
26
from bzrlib.directory_service import directories
29
class TestSwitch(TestCaseWithTransport):
31
def _create_sample_tree(self):
32
tree = self.make_branch_and_tree('branch-1')
33
self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
40
def test_switch_up_to_date_light_checkout(self):
41
self.make_branch_and_tree('branch')
42
self.run_bzr('branch branch branch2')
43
self.run_bzr('checkout --lightweight branch checkout')
45
out, err = self.run_bzr('switch ../branch2')
46
self.assertContainsRe(err, 'Tree is up to date at revision 0.\n')
47
self.assertContainsRe(err, 'Switched to branch: .*/branch2.\n')
48
self.assertEqual('', out)
50
def test_switch_out_of_date_light_checkout(self):
51
self.make_branch_and_tree('branch')
52
self.run_bzr('branch branch branch2')
53
self.build_tree(['branch2/file'])
54
self.run_bzr('add branch2/file')
55
self.run_bzr('commit -m add-file branch2')
56
self.run_bzr('checkout --lightweight branch checkout')
58
out, err = self.run_bzr('switch ../branch2')
59
#self.assertContainsRe(err, '\+N file')
60
self.assertContainsRe(err, 'Updated to revision 1.\n')
61
self.assertContainsRe(err, 'Switched to branch: .*/branch2.\n')
62
self.assertEqual('', out)
64
def _test_switch_nick(self, lightweight):
65
"""Check that the nick gets switched too."""
66
tree1 = self.make_branch_and_tree('branch1')
67
tree2 = self.make_branch_and_tree('branch2')
68
tree2.pull(tree1.branch)
69
checkout = tree1.branch.create_checkout('checkout',
70
lightweight=lightweight)
71
self.assertEqual(checkout.branch.nick, tree1.branch.nick)
72
self.assertEqual(checkout.branch.get_config().has_explicit_nickname(),
74
self.run_bzr('switch branch2', working_dir='checkout')
76
# we need to get the tree again, otherwise we don't get the new branch
77
checkout = WorkingTree.open('checkout')
78
self.assertEqual(checkout.branch.nick, tree2.branch.nick)
79
self.assertEqual(checkout.branch.get_config().has_explicit_nickname(),
82
def test_switch_nick(self):
83
self._test_switch_nick(lightweight=False)
85
def test_switch_nick_lightweight(self):
86
self._test_switch_nick(lightweight=True)
88
def _test_switch_explicit_nick(self, lightweight):
89
"""Check that the nick gets switched too."""
90
tree1 = self.make_branch_and_tree('branch1')
91
tree2 = self.make_branch_and_tree('branch2')
92
tree2.pull(tree1.branch)
93
checkout = tree1.branch.create_checkout('checkout',
94
lightweight=lightweight)
95
self.assertEqual(checkout.branch.nick, tree1.branch.nick)
96
checkout.branch.nick = "explicit_nick"
97
self.assertEqual(checkout.branch.nick, "explicit_nick")
98
self.assertEqual(checkout.branch.get_config()._get_explicit_nickname(),
100
self.run_bzr('switch branch2', working_dir='checkout')
102
# we need to get the tree again, otherwise we don't get the new branch
103
checkout = WorkingTree.open('checkout')
104
self.assertEqual(checkout.branch.nick, tree2.branch.nick)
105
self.assertEqual(checkout.branch.get_config()._get_explicit_nickname(),
108
def test_switch_explicit_nick(self):
109
self._test_switch_explicit_nick(lightweight=False)
111
def test_switch_explicit_nick_lightweight(self):
112
self._test_switch_explicit_nick(lightweight=True)
114
def test_switch_finds_relative_branch(self):
115
"""Switch will find 'foo' relative to the branch the checkout is of."""
116
self.build_tree(['repo/'])
117
tree1 = self.make_branch_and_tree('repo/brancha')
119
tree2 = self.make_branch_and_tree('repo/branchb')
120
tree2.pull(tree1.branch)
121
branchb_id = tree2.commit('bar')
122
checkout = tree1.branch.create_checkout('checkout', lightweight=True)
123
self.run_bzr(['switch', 'branchb'], working_dir='checkout')
124
self.assertEqual(branchb_id, checkout.last_revision())
125
checkout = checkout.bzrdir.open_workingtree()
126
self.assertEqual(tree2.branch.base, checkout.branch.base)
128
def test_switch_finds_relative_bound_branch(self):
129
"""Using switch on a heavy checkout should find master sibling
131
The behaviour of lighweight and heavy checkouts should be
132
consistentwhen using the convenient "switch to sibling" feature
133
Both should switch to a sibling of the branch
134
they are bound to, and not a sibling of themself"""
136
self.build_tree(['repo/',
138
tree1 = self.make_branch_and_tree('repo/brancha')
140
tree2 = self.make_branch_and_tree('repo/branchb')
141
tree2.pull(tree1.branch)
142
branchb_id = tree2.commit('bar')
143
checkout = tree1.branch.create_checkout('heavyco/a', lightweight=False)
144
self.run_bzr(['switch', 'branchb'], working_dir='heavyco/a')
145
self.assertEqual(branchb_id, checkout.last_revision())
146
self.assertEqual(tree2.branch.base, checkout.branch.get_bound_location())
148
def test_switch_revision(self):
149
tree = self._create_sample_tree()
150
checkout = tree.branch.create_checkout('checkout', lightweight=True)
151
self.run_bzr(['switch', 'branch-1', '-r1'], working_dir='checkout')
152
self.failUnlessExists('checkout/file-1')
153
self.failIfExists('checkout/file-2')
155
def test_switch_only_revision(self):
156
tree = self._create_sample_tree()
157
checkout = tree.branch.create_checkout('checkout', lightweight=True)
158
self.failUnlessExists('checkout/file-1')
159
self.failUnlessExists('checkout/file-2')
160
self.run_bzr(['switch', '-r1'], working_dir='checkout')
161
self.failUnlessExists('checkout/file-1')
162
self.failIfExists('checkout/file-2')
163
# Check that we don't accept a range
165
['bzr switch --revision takes exactly one revision identifier'],
166
['switch', '-r0..2'], working_dir='checkout')
168
def prepare_lightweight_switch(self):
169
branch = self.make_branch('branch')
170
branch.create_checkout('tree', lightweight=True)
171
osutils.rename('branch', 'branch1')
173
def test_switch_lightweight_after_branch_moved(self):
174
self.prepare_lightweight_switch()
175
self.run_bzr('switch --force ../branch1', working_dir='tree')
176
branch_location = WorkingTree.open('tree').branch.base
177
self.assertEndsWith(branch_location, 'branch1/')
179
def test_switch_lightweight_after_branch_moved_relative(self):
180
self.prepare_lightweight_switch()
181
self.run_bzr('switch --force branch1', working_dir='tree')
182
branch_location = WorkingTree.open('tree').branch.base
183
self.assertEndsWith(branch_location, 'branch1/')
185
def test_create_branch_no_branch(self):
186
self.prepare_lightweight_switch()
187
self.run_bzr_error(['cannot create branch without source branch'],
188
'switch --create-branch ../branch2', working_dir='tree')
190
def test_create_branch(self):
191
branch = self.make_branch('branch')
192
tree = branch.create_checkout('tree', lightweight=True)
193
tree.commit('one', rev_id='rev-1')
194
self.run_bzr('switch --create-branch ../branch2', working_dir='tree')
195
tree = WorkingTree.open('tree')
196
self.assertEndsWith(tree.branch.base, '/branch2/')
198
def test_create_branch_local(self):
199
branch = self.make_branch('branch')
200
tree = branch.create_checkout('tree', lightweight=True)
201
tree.commit('one', rev_id='rev-1')
202
self.run_bzr('switch --create-branch branch2', working_dir='tree')
203
tree = WorkingTree.open('tree')
204
# The new branch should have been created at the same level as
205
# 'branch', because we did not have a '/' segment
206
self.assertEqual(branch.base[:-1] + '2/', tree.branch.base)
208
def test_create_branch_short_name(self):
209
branch = self.make_branch('branch')
210
tree = branch.create_checkout('tree', lightweight=True)
211
tree.commit('one', rev_id='rev-1')
212
self.run_bzr('switch -b branch2', working_dir='tree')
213
tree = WorkingTree.open('tree')
214
# The new branch should have been created at the same level as
215
# 'branch', because we did not have a '/' segment
216
self.assertEqual(branch.base[:-1] + '2/', tree.branch.base)
218
def test_create_branch_directory_services(self):
219
branch = self.make_branch('branch')
220
tree = branch.create_checkout('tree', lightweight=True)
221
class FooLookup(object):
222
def look_up(self, name, url):
224
directories.register('foo:', FooLookup, 'Create branches named foo-')
225
self.addCleanup(directories.remove, 'foo:')
226
self.run_bzr('switch -b foo:branch2', working_dir='tree')
227
tree = WorkingTree.open('tree')
228
self.assertEndsWith(tree.branch.base, 'foo-branch2/')
230
def test_switch_with_post_switch_hook(self):
231
from bzrlib import branch as _mod_branch
233
_mod_branch.Branch.hooks.install_named_hook('post_switch',
235
self.make_branch_and_tree('branch')
236
self.run_bzr('branch branch branch2')
237
self.run_bzr('checkout branch checkout')
239
self.assertLength(0, calls)
240
out, err = self.run_bzr('switch ../branch2')
241
self.assertLength(1, calls)
243
def test_switch_lightweight_co_with_post_switch_hook(self):
244
from bzrlib import branch as _mod_branch
246
_mod_branch.Branch.hooks.install_named_hook('post_switch',
248
self.make_branch_and_tree('branch')
249
self.run_bzr('branch branch branch2')
250
self.run_bzr('checkout --lightweight branch checkout')
252
self.assertLength(0, calls)
253
out, err = self.run_bzr('switch ../branch2')
254
self.assertLength(1, calls)
256
def test_switch_lightweight_directory(self):
257
"""Test --directory option"""
259
# create a source branch
260
a_tree = self.make_branch_and_tree('a')
261
self.build_tree_contents([('a/a', 'initial\n')])
263
a_tree.commit(message='initial')
265
# clone and add a differing revision
266
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
267
self.build_tree_contents([('b/a', 'initial\nmore\n')])
268
b_tree.commit(message='more')
270
self.run_bzr('checkout --lightweight a checkout')
271
self.run_bzr('switch --directory checkout b')
272
self.assertFileEqual('initial\nmore\n', 'checkout/a')