102
102
tree = self.example_branch('b/a', format='development-colo')
103
103
tree.controldir.create_branch(name='somecolo')
104
104
out, err = self.run_bzr('branch %s,branch=somecolo' %
105
local_path_to_url('b/a'))
105
local_path_to_url('b/a'))
106
106
self.assertEqual('', out)
107
107
self.assertEqual('Branched 0 revisions.\n', err)
108
108
self.assertPathExists('a')
124
124
corrupt = b'\x00'
126
126
corrupt = b'\xFF'
127
f.write(corrupt) # make sure we corrupt something
127
f.write(corrupt) # make sure we corrupt something
128
128
self.run_bzr_error(['Corruption while decompressing repository file'],
129
'branch a b', retcode=3)
129
'branch a b', retcode=3)
131
131
def test_branch_switch_no_branch(self):
132
132
# No branch in the current directory:
134
134
self.example_branch('a')
135
135
self.make_repository('current')
136
136
self.run_bzr_error(['No WorkingTree exists for'],
137
'branch --switch ../a ../b', working_dir='current')
137
'branch --switch ../a ../b', working_dir='current')
138
138
a = branch.Branch.open('a')
139
139
b = branch.Branch.open('b')
140
140
self.assertEqual(a.last_revision(), b.last_revision())
146
146
self.example_branch('a')
147
147
self.make_branch('current')
148
148
self.run_bzr_error(['No WorkingTree exists for'],
149
'branch --switch ../a ../b', working_dir='current')
149
'branch --switch ../a ../b', working_dir='current')
150
150
a = branch.Branch.open('a')
151
151
b = branch.Branch.open('b')
152
152
self.assertEqual(a.last_revision(), b.last_revision())
161
161
tree = self.make_branch_and_tree('current')
162
162
c1 = tree.commit('some diverged change')
163
163
self.run_bzr_error(['Cannot switch a branch, only a checkout'],
164
'branch --switch ../a ../b', working_dir='current')
164
'branch --switch ../a ../b', working_dir='current')
165
165
a = branch.Branch.open('a')
166
166
b = branch.Branch.open('b')
167
167
self.assertEqual(a.last_revision(), b.last_revision())
281
281
b = branch.Branch.open('repo/target')
282
282
expected_repo_path = os.path.abspath('repo/target/.bzr/repository')
283
283
self.assertEqual(strip_trailing_slash(b.repository.base),
284
strip_trailing_slash(local_path_to_url(expected_repo_path)))
284
strip_trailing_slash(local_path_to_url(expected_repo_path)))
286
286
def test_branch_no_tree(self):
287
287
self.example_branch('source')
294
294
# existing dir with similar files but no .brz dir
295
295
self.build_tree_contents([('b/',)])
296
296
self.build_tree_contents([('b/hello', b'bar')]) # different content
297
self.build_tree_contents([('b/goodbye', b'baz')])# same content
297
self.build_tree_contents([('b/goodbye', b'baz')]) # same content
298
298
# fails without --use-existing-dir
299
299
out, err = self.run_bzr('branch a b', retcode=3)
300
300
self.assertEqual('', out)
301
301
self.assertEqual('brz: ERROR: Target directory "b" already exists.\n',
303
303
# force operation
304
304
self.run_bzr('branch a b --use-existing-dir')
305
305
# check conflicts
320
320
def test_branch_with_post_branch_init_hook(self):
322
322
branch.Branch.hooks.install_named_hook('post_branch_init',
324
324
self.assertLength(0, calls)
325
325
self.example_branch('a')
326
326
self.assertLength(1, calls)
330
330
def test_checkout_with_post_branch_init_hook(self):
332
332
branch.Branch.hooks.install_named_hook('post_branch_init',
334
334
self.assertLength(0, calls)
335
335
self.example_branch('a')
336
336
self.assertLength(1, calls)
340
340
def test_lightweight_checkout_with_post_branch_init_hook(self):
342
342
branch.Branch.hooks.install_named_hook('post_branch_init',
344
344
self.assertLength(0, calls)
345
345
self.example_branch('a')
346
346
self.assertLength(1, calls)
350
350
def test_branch_fetches_all_tags(self):
351
351
builder = self.make_branch_builder('source')
352
source, rev1, rev2 = fixtures.build_branch_with_non_ancestral_rev(builder)
352
source, rev1, rev2 = fixtures.build_branch_with_non_ancestral_rev(
353
354
source.tags.set_tag('tag-a', rev2)
354
355
source.get_config_stack().set('branch.fetch_tags', True)
355
356
# Now source has a tag not in its ancestry. Make a branch from it.
376
377
def assertRevisionsInBranchRepository(self, revid_list, branch_path):
377
378
repo = branch.Branch.open(branch_path).repository
378
379
self.assertEqual(set(revid_list),
379
repo.has_revisions(revid_list))
380
repo.has_revisions(revid_list))
381
382
def test_branch_stacked_branch_not_stacked(self):
382
383
"""Branching a stacked branch is not stacked by default"""
383
384
# We have a mainline
384
385
trunk_tree = self.make_branch_and_tree('target',
386
387
trunk_tree.commit('mainline')
387
388
# and a branch from it which is stacked
388
389
branch_tree = self.make_branch_and_tree('branch',
390
391
branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
391
392
# with some work on it
392
work_tree = trunk_tree.branch.controldir.sprout('local').open_workingtree()
393
work_tree = trunk_tree.branch.controldir.sprout(
394
'local').open_workingtree()
393
395
work_tree.commit('moar work plz')
394
396
work_tree.branch.push(branch_tree.branch)
395
397
# branching our local branch gives us a new stacked branch pointing at
397
399
out, err = self.run_bzr(['branch', 'branch', 'newbranch'])
398
400
self.assertEqual('', out)
399
401
self.assertEqual('Branched 2 revisions.\n',
401
403
# it should have preserved the branch format, and so it should be
402
404
# capable of supporting stacking, but not actually have a stacked_on
403
405
# branch configured
404
406
self.assertRaises(errors.NotStacked,
405
controldir.ControlDir.open('newbranch').open_branch().get_stacked_on_url)
407
controldir.ControlDir.open('newbranch').open_branch().get_stacked_on_url)
407
409
def test_branch_stacked_branch_stacked(self):
408
410
"""Asking to stack on a stacked branch does work"""
409
411
# We have a mainline
410
412
trunk_tree = self.make_branch_and_tree('target',
412
414
trunk_revid = trunk_tree.commit('mainline')
413
415
# and a branch from it which is stacked
414
416
branch_tree = self.make_branch_and_tree('branch',
416
418
branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
417
419
# with some work on it
418
work_tree = trunk_tree.branch.controldir.sprout('local').open_workingtree()
420
work_tree = trunk_tree.branch.controldir.sprout(
421
'local').open_workingtree()
419
422
branch_revid = work_tree.commit('moar work plz')
420
423
work_tree.branch.push(branch_tree.branch)
421
424
# you can chain branches on from there
422
425
out, err = self.run_bzr(['branch', 'branch', '--stacked', 'branch2'])
423
426
self.assertEqual('', out)
424
427
self.assertEqual('Created new stacked branch referring to %s.\n' %
425
branch_tree.branch.base, err)
428
branch_tree.branch.base, err)
426
429
self.assertEqual(branch_tree.branch.base,
427
branch.Branch.open('branch2').get_stacked_on_url())
430
branch.Branch.open('branch2').get_stacked_on_url())
428
431
branch2_tree = WorkingTree.open('branch2')
429
432
branch2_revid = work_tree.commit('work on second stacked branch')
430
433
work_tree.branch.push(branch2_tree.branch)
436
439
def test_branch_stacked(self):
437
440
# We have a mainline
438
441
trunk_tree = self.make_branch_and_tree('mainline',
440
443
original_revid = trunk_tree.commit('mainline')
441
444
self.assertRevisionInRepository('mainline', original_revid)
442
445
# and a branch from it which is stacked
443
446
out, err = self.run_bzr(['branch', '--stacked', 'mainline',
445
448
self.assertEqual('', out)
446
449
self.assertEqual('Created new stacked branch referring to %s.\n' %
447
trunk_tree.branch.base, err)
450
trunk_tree.branch.base, err)
448
451
self.assertRevisionNotInRepository('newbranch', original_revid)
449
452
new_branch = branch.Branch.open('newbranch')
450
453
self.assertEqual(trunk_tree.branch.base,
499
502
t.commit(message='commit %d' % count)
500
503
self.reset_smart_call_log()
501
504
out, err = self.run_bzr(['branch', self.get_url('from'),
502
self.get_url('target')])
505
self.get_url('target')])
503
506
# This figure represent the amount of work to perform this use case. It
504
507
# is entirely ok to reduce this number if a test fails due to rpc_count
505
508
# being too low. If rpc_count increases, more network roundtrips have
508
511
self.assertLength(2, self.hpss_connections)
509
512
self.assertLength(33, self.hpss_calls)
510
513
self.expectFailure("branching to the same branch requires VFS access",
511
self.assertThat, self.hpss_calls, ContainsNoVfsCalls)
514
self.assertThat, self.hpss_calls, ContainsNoVfsCalls)
513
516
def test_branch_from_trivial_branch_streaming_acceptance(self):
514
517
self.setup_smart_server_with_call_log()
517
520
t.commit(message='commit %d' % count)
518
521
self.reset_smart_call_log()
519
522
out, err = self.run_bzr(['branch', self.get_url('from'),
521
524
# This figure represent the amount of work to perform this use case. It
522
525
# is entirely ok to reduce this number if a test fails due to rpc_count
523
526
# being too low. If rpc_count increases, more network roundtrips have
533
536
for count in range(8):
534
537
t.commit(message='commit %d' % count)
535
538
tree2 = t.branch.controldir.sprout('feature', stacked=True
537
local_tree = t.branch.controldir.sprout('local-working').open_workingtree()
540
local_tree = t.branch.controldir.sprout(
541
'local-working').open_workingtree()
538
542
local_tree.commit('feature change')
539
543
local_tree.branch.push(tree2.branch)
540
544
self.reset_smart_call_log()
541
545
out, err = self.run_bzr(['branch', self.get_url('feature'),
543
547
# This figure represent the amount of work to perform this use case. It
544
548
# is entirely ok to reduce this number if a test fails due to rpc_count
545
549
# being too low. If rpc_count increases, more network roundtrips have
552
556
def test_branch_from_branch_with_tags(self):
553
557
self.setup_smart_server_with_call_log()
554
558
builder = self.make_branch_builder('source')
555
source, rev1, rev2 = fixtures.build_branch_with_non_ancestral_rev(builder)
559
source, rev1, rev2 = fixtures.build_branch_with_non_ancestral_rev(
556
561
source.get_config_stack().set('branch.fetch_tags', True)
557
562
source.tags.set_tag('tag-a', rev2)
558
563
source.tags.set_tag('tag-missing', b'missing-rev')
575
580
t.commit(message='commit %d' % count)
576
581
self.reset_smart_call_log()
577
582
out, err = self.run_bzr(['branch', '--stacked', self.get_url('from'),
579
584
# XXX: the number of hpss calls for this case isn't deterministic yet,
580
585
# so we can't easily assert about the number of calls.
581
586
#self.assertLength(XXX, self.hpss_calls)
588
593
self.assertLength(1, self.hpss_connections)
589
594
self.assertLength(0, readvs_of_rix_files)
590
595
self.expectFailure("branching to stacked requires VFS access",
591
self.assertThat, self.hpss_calls, ContainsNoVfsCalls)
596
self.assertThat, self.hpss_calls, ContainsNoVfsCalls)
593
598
def test_branch_from_branch_with_ghosts(self):
594
599
self.setup_smart_server_with_call_log()
599
604
t.commit(message='add commit with parent')
600
605
self.reset_smart_call_log()
601
606
out, err = self.run_bzr(['branch', self.get_url('from'),
603
608
# This figure represent the amount of work to perform this use case. It
604
609
# is entirely ok to reduce this number if a test fails due to rpc_count
605
610
# being too low. If rpc_count increases, more network roundtrips have