153
142
branchb_id = tree2.commit('bar')
154
143
checkout = tree1.branch.create_checkout('heavyco/a', lightweight=False)
155
144
self.run_bzr(['switch', 'branchb'], working_dir='heavyco/a')
156
# Refresh checkout as 'switch' modified it
157
checkout = checkout.controldir.open_workingtree()
158
self.assertEqual(branchb_id, checkout.last_revision())
159
self.assertEqual(tree2.branch.base,
160
checkout.branch.get_bound_location())
162
def test_switch_finds_relative_unicode_branch(self):
163
"""Switch will find 'foo' relative to the branch the checkout is of."""
164
self.requireFeature(UnicodeFilenameFeature)
165
self.build_tree(['repo/'])
166
tree1 = self.make_branch_and_tree('repo/brancha')
168
tree2 = self.make_branch_and_tree(u'repo/branch\xe9')
169
tree2.pull(tree1.branch)
170
branchb_id = tree2.commit('bar')
171
checkout = tree1.branch.create_checkout('checkout', lightweight=True)
172
self.run_bzr(['switch', u'branch\xe9'], working_dir='checkout')
173
self.assertEqual(branchb_id, checkout.last_revision())
174
checkout = checkout.controldir.open_workingtree()
175
self.assertEqual(tree2.branch.base, checkout.branch.base)
177
def test_switch_finds_relative_unicode_branch(self):
178
"""Switch will find 'foo' relative to the branch the checkout is of."""
179
self.requireFeature(UnicodeFilenameFeature)
180
self.build_tree(['repo/'])
181
tree1 = self.make_branch_and_tree('repo/brancha')
183
tree2 = self.make_branch_and_tree(u'repo/branch\xe9')
184
tree2.pull(tree1.branch)
185
branchb_id = tree2.commit('bar')
186
checkout = tree1.branch.create_checkout('checkout', lightweight=True)
187
self.run_bzr(['switch', u'branch\xe9'], working_dir='checkout')
188
self.assertEqual(branchb_id, checkout.last_revision())
189
checkout = checkout.controldir.open_workingtree()
190
self.assertEqual(tree2.branch.base, checkout.branch.base)
145
self.assertEqual(branchb_id, checkout.last_revision())
146
self.assertEqual(tree2.branch.base, checkout.branch.get_bound_location())
192
148
def test_switch_revision(self):
193
149
tree = self._create_sample_tree()
194
150
checkout = tree.branch.create_checkout('checkout', lightweight=True)
195
151
self.run_bzr(['switch', 'branch-1', '-r1'], working_dir='checkout')
196
self.assertPathExists('checkout/file-1')
197
self.assertPathDoesNotExist('checkout/file-2')
199
def test_switch_into_colocated(self):
200
# Create a new colocated branch from an existing non-colocated branch.
201
tree = self.make_branch_and_tree('.', format='development-colo')
202
self.build_tree(['file-1', 'file-2'])
204
revid1 = tree.commit('rev1')
206
revid2 = tree.commit('rev2')
207
self.run_bzr(['switch', '-b', 'anotherbranch'])
209
{'', 'anotherbranch'},
210
set(tree.branch.controldir.branch_names()))
212
def test_switch_into_unrelated_colocated(self):
213
# Create a new colocated branch from an existing non-colocated branch.
214
tree = self.make_branch_and_tree('.', format='development-colo')
215
self.build_tree(['file-1', 'file-2'])
217
revid1 = tree.commit('rev1')
219
revid2 = tree.commit('rev2')
220
tree.controldir.create_branch(name='foo')
221
self.run_bzr_error(['Cannot switch a branch, only a checkout.'],
223
self.run_bzr(['switch', '--force', 'foo'])
225
def test_switch_existing_colocated(self):
226
# Create a branch branch-1 that initially is a checkout of 'foo'
227
# Use switch to change it to 'anotherbranch'
228
repo = self.make_repository('branch-1', format='development-colo')
229
target_branch = repo.controldir.create_branch(name='foo')
230
repo.controldir.set_branch_reference(target_branch)
231
tree = repo.controldir.create_workingtree()
232
self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
234
revid1 = tree.commit('rev1')
236
revid2 = tree.commit('rev2')
237
otherbranch = tree.controldir.create_branch(name='anotherbranch')
238
otherbranch.generate_revision_history(revid1)
239
self.run_bzr(['switch', 'anotherbranch'], working_dir='branch-1')
240
tree = WorkingTree.open("branch-1")
241
self.assertEqual(tree.last_revision(), revid1)
242
self.assertEqual(tree.branch.control_url, otherbranch.control_url)
244
def test_switch_new_colocated(self):
245
# Create a branch branch-1 that initially is a checkout of 'foo'
246
# Use switch to create 'anotherbranch' which derives from that
247
repo = self.make_repository('branch-1', format='development-colo')
248
target_branch = repo.controldir.create_branch(name='foo')
249
repo.controldir.set_branch_reference(target_branch)
250
tree = repo.controldir.create_workingtree()
251
self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
253
revid1 = tree.commit('rev1')
254
self.run_bzr(['switch', '-b', 'anotherbranch'], working_dir='branch-1')
255
bzrdir = ControlDir.open("branch-1")
257
{b.name for b in bzrdir.list_branches()},
258
{"foo", "anotherbranch"})
259
self.assertEqual(bzrdir.open_branch().name, "anotherbranch")
260
self.assertEqual(bzrdir.open_branch().last_revision(), revid1)
262
def test_switch_new_colocated_unicode(self):
263
# Create a branch branch-1 that initially is a checkout of 'foo'
264
# Use switch to create 'branch\xe9' which derives from that
265
self.requireFeature(UnicodeFilenameFeature)
266
repo = self.make_repository('branch-1', format='development-colo')
267
target_branch = repo.controldir.create_branch(name='foo')
268
repo.controldir.set_branch_reference(target_branch)
269
tree = repo.controldir.create_workingtree()
270
self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
272
revid1 = tree.commit('rev1')
273
self.run_bzr(['switch', '-b', u'branch\xe9'], working_dir='branch-1')
274
bzrdir = ControlDir.open("branch-1")
276
{b.name for b in bzrdir.list_branches()},
277
{"foo", u"branch\xe9"})
278
self.assertEqual(bzrdir.open_branch().name, u"branch\xe9")
279
self.assertEqual(bzrdir.open_branch().last_revision(), revid1)
152
self.failUnlessExists('checkout/file-1')
153
self.failIfExists('checkout/file-2')
281
155
def test_switch_only_revision(self):
282
156
tree = self._create_sample_tree()
283
157
checkout = tree.branch.create_checkout('checkout', lightweight=True)
284
self.assertPathExists('checkout/file-1')
285
self.assertPathExists('checkout/file-2')
158
self.failUnlessExists('checkout/file-1')
159
self.failUnlessExists('checkout/file-2')
286
160
self.run_bzr(['switch', '-r1'], working_dir='checkout')
287
self.assertPathExists('checkout/file-1')
288
self.assertPathDoesNotExist('checkout/file-2')
161
self.failUnlessExists('checkout/file-1')
162
self.failIfExists('checkout/file-2')
289
163
# Check that we don't accept a range
290
164
self.run_bzr_error(
291
['brz switch --revision takes exactly one revision identifier'],
165
['bzr switch --revision takes exactly one revision identifier'],
292
166
['switch', '-r0..2'], working_dir='checkout')
294
168
def prepare_lightweight_switch(self):
387
259
# create a source branch
388
260
a_tree = self.make_branch_and_tree('a')
389
self.build_tree_contents([('a/a', b'initial\n')])
261
self.build_tree_contents([('a/a', 'initial\n')])
391
263
a_tree.commit(message='initial')
393
265
# clone and add a differing revision
394
b_tree = a_tree.controldir.sprout('b').open_workingtree()
395
self.build_tree_contents([('b/a', b'initial\nmore\n')])
266
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
267
self.build_tree_contents([('b/a', 'initial\nmore\n')])
396
268
b_tree.commit(message='more')
398
270
self.run_bzr('checkout --lightweight a checkout')
399
271
self.run_bzr('switch --directory checkout b')
400
self.assertFileEqual(b'initial\nmore\n', 'checkout/a')
403
class TestSwitchParentLocationBase(TestCaseWithTransport):
406
"""Set up a repository and branch ready for testing."""
407
super(TestSwitchParentLocationBase, self).setUp()
408
self.script_runner = script.ScriptRunner()
409
self.script_runner.run_script(self, '''
410
$ brz init-shared-repo --no-trees repo
413
shared repository: repo
414
$ brz init repo/trunk
415
Created a repository branch...
416
Using shared repository: ...
419
def assertParent(self, expected_parent, branch):
420
"""Verify that the parent is not None and is set correctly."""
421
actual_parent = branch.get_parent()
422
self.assertIsSameRealPath(urlutils.local_path_to_url(expected_parent),
426
class TestSwitchParentLocation(TestSwitchParentLocationBase):
428
def _checkout_and_switch(self, option=''):
429
self.script_runner.run_script(self, '''
430
$ brz checkout %(option)s repo/trunk checkout
432
$ brz switch --create-branch switched
433
2>Tree is up to date at revision 0.
434
2>Switched to branch at .../switched/
437
bound_branch = branch.Branch.open_containing('checkout')[0]
438
master_branch = branch.Branch.open_containing('repo/switched')[0]
439
return (bound_branch, master_branch)
441
def test_switch_parent_lightweight(self):
442
"""Lightweight checkout using brz switch."""
443
bb, mb = self._checkout_and_switch(option='--lightweight')
444
self.assertParent('repo/trunk', bb)
445
self.assertParent('repo/trunk', mb)
447
def test_switch_parent_heavyweight(self):
448
"""Heavyweight checkout using brz switch."""
449
bb, mb = self._checkout_and_switch()
450
self.assertParent('repo/trunk', bb)
451
self.assertParent('repo/trunk', mb)
454
class TestSwitchDoesntOpenMasterBranch(TestCaseWithTransport):
455
# See https://bugs.launchpad.net/bzr/+bug/812285
456
# "brz switch --create-branch" can point the new branch's parent to the
457
# master branch, but it doesn't have to open it to do so.
459
def test_switch_create_doesnt_open_master_branch(self):
460
master = self.make_branch_and_tree('master')
462
# Note: not a lightweight checkout
463
checkout = master.branch.create_checkout('checkout')
466
def open_hook(branch):
467
# Just append the final directory of the branch
468
name = branch.base.rstrip('/').rsplit('/', 1)[1]
470
branch.Branch.hooks.install_named_hook('open', open_hook,
472
self.run_bzr('switch --create-branch -d checkout feature')
473
# We only open the master branch 1 time.
474
# This test should be cleaner to write, but see bug:
475
# https://bugs.launchpad.net/bzr/+bug/812295
476
self.assertEqual(1, opened.count('master'))
479
class TestSmartServerSwitch(TestCaseWithTransport):
481
def test_switch_lightweight(self):
482
self.setup_smart_server_with_call_log()
483
t = self.make_branch_and_tree('from')
484
for count in range(9):
485
t.commit(message='commit %d' % count)
486
out, err = self.run_bzr(['checkout', '--lightweight', self.get_url('from'),
488
self.reset_smart_call_log()
489
self.run_bzr(['switch', self.get_url('from')], working_dir='target')
490
# This figure represent the amount of work to perform this use case. It
491
# is entirely ok to reduce this number if a test fails due to rpc_count
492
# being too low. If rpc_count increases, more network roundtrips have
493
# become necessary for this use case. Please do not adjust this number
494
# upwards without agreement from bzr's network support maintainers.
495
self.assertLength(21, self.hpss_calls)
496
self.assertLength(3, self.hpss_connections)
497
self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
500
class TestSwitchUncommitted(TestCaseWithTransport):
503
tree = self.make_branch_and_tree('orig')
505
tree.branch.controldir.sprout('new')
506
checkout = tree.branch.create_checkout('checkout', lightweight=True)
507
self.build_tree(['checkout/a'])
508
self.assertPathExists('checkout/a')
512
def test_store_and_restore_uncommitted(self):
513
checkout = self.prepare()
514
self.run_bzr(['switch', '--store', '-d', 'checkout', 'new'])
515
self.build_tree(['checkout/b'])
517
self.assertPathDoesNotExist('checkout/a')
518
self.assertPathExists('checkout/b')
519
self.run_bzr(['switch', '--store', '-d', 'checkout', 'orig'])
520
self.assertPathExists('checkout/a')
521
self.assertPathDoesNotExist('checkout/b')
523
def test_does_not_store(self):
525
self.run_bzr(['switch', '-d', 'checkout', 'new'])
526
self.assertPathExists('checkout/a')
528
def test_does_not_restore_changes(self):
530
self.run_bzr(['switch', '--store', '-d', 'checkout', 'new'])
531
self.assertPathDoesNotExist('checkout/a')
532
self.run_bzr(['switch', '-d', 'checkout', 'orig'])
533
self.assertPathDoesNotExist('checkout/a')
536
class TestSwitchStandAloneCorruption(TestCaseWithTransport):
538
def test_empty_tree_switch(self):
539
"""switch . on an empty tree gets infinite recursion
541
Inspired by: https://bugs.launchpad.net/bzr/+bug/1018628
543
self.script_runner = script.ScriptRunner()
544
self.script_runner.run_script(self, '''
546
Created a standalone tree (format: 2a)
548
2>brz: ERROR: switching would create a branch reference loop. Use the "bzr up" command to switch to a different revision.
551
def test_switch_on_previous_rev(self):
552
"""switch to previous rev in a standalone directory
554
Inspired by: https://bugs.launchpad.net/brz/+bug/1018628
556
self.script_runner = script.ScriptRunner()
557
self.script_runner.run_script(self, '''
559
Created a standalone tree (format: 2a)
560
$ brz commit -m 1 --unchanged
561
$ brz commit -m 2 --unchanged
563
2>brz: ERROR: switching would create a branch reference loop. Use the "bzr up" command to switch to a different revision.''',
564
null_output_matches_anything=True)
566
def test_switch_create_colo_locks_repo_path(self):
567
self.script_runner = script.ScriptRunner()
568
self.script_runner.run_script(self, '''
572
Created a standalone tree (format: 2a)
573
$ echo A > a && brz add a && brz commit -m A
580
''', null_output_matches_anything=True)
582
def test_switch_to_new_branch_on_old_rev(self):
583
"""switch to previous rev in a standalone directory
585
Inspired by: https://bugs.launchpad.net/brz/+bug/933362
587
self.script_runner = script.ScriptRunner()
588
self.script_runner.run_script(self, '''
590
Created a standalone tree (format: 2a)
591
$ brz switch -b trunk
592
2>Tree is up to date at revision 0.
593
2>Switched to branch trunk
594
$ brz commit -m 1 --unchanged
596
2>Committed revision 1.
597
$ brz commit -m 2 --unchanged
599
2>Committed revision 2.
600
$ brz switch -b blah -r1
601
2>Updated to revision 1.
602
2>Switched to branch blah
272
self.assertFileEqual('initial\nmore\n', 'checkout/a')