114
116
tree_a.add('vla', 'file2')
115
117
tree_a.commit('rev2', rev_id='rev2')
117
delta = tree_a.branch.get_revision_delta(1)
119
delta = self.applyDeprecated(symbol_versioning.deprecated_in(
120
(2, 5, 0)), tree_a.branch.get_revision_delta, 1)
118
121
self.assertIsInstance(delta, _mod_delta.TreeDelta)
119
122
self.assertEqual([('foo', 'file1', 'file')], delta.added)
120
delta = tree_a.branch.get_revision_delta(2)
123
delta = self.applyDeprecated(symbol_versioning.deprecated_in(
124
(2, 5, 0)), tree_a.branch.get_revision_delta, 2)
121
125
self.assertIsInstance(delta, _mod_delta.TreeDelta)
122
126
self.assertEqual([('vla', 'file2', 'file')], delta.added)
245
255
self.get_branch().repository.get_revision,
249
# compare the gpg-to-sign info for a commit with a ghost and
250
# an identical tree without a ghost
251
# fetch missing should rewrite the TOC of weaves to list newly available parents.
253
def test_sign_existing_revision(self):
254
wt = self.make_branch_and_tree('.')
256
wt.commit("base", allow_pointless=True, rev_id='A')
257
from bzrlib.testament import Testament
258
strategy = gpg.LoopbackGPGStrategy(None)
259
branch.repository.lock_write()
260
branch.repository.start_write_group()
261
branch.repository.sign_revision('A', strategy)
262
branch.repository.commit_write_group()
263
branch.repository.unlock()
264
self.assertEqual('-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
265
Testament.from_revision(branch.repository,
266
'A').as_short_text() +
267
'-----END PSEUDO-SIGNED CONTENT-----\n',
268
branch.repository.get_signature_text('A'))
270
def test_store_signature(self):
271
wt = self.make_branch_and_tree('.')
275
branch.repository.start_write_group()
277
branch.repository.store_revision_signature(
278
gpg.LoopbackGPGStrategy(None), 'FOO', 'A')
280
branch.repository.abort_write_group()
283
branch.repository.commit_write_group()
286
# A signature without a revision should not be accessible.
287
self.assertRaises(errors.NoSuchRevision,
288
branch.repository.has_signature_for_revision_id,
290
wt.commit("base", allow_pointless=True, rev_id='A')
291
self.assertEqual('-----BEGIN PSEUDO-SIGNED CONTENT-----\n'
292
'FOO-----END PSEUDO-SIGNED CONTENT-----\n',
293
branch.repository.get_signature_text('A'))
295
def test_branch_keeps_signatures(self):
296
wt = self.make_branch_and_tree('source')
297
wt.commit('A', allow_pointless=True, rev_id='A')
298
repo = wt.branch.repository
300
repo.start_write_group()
301
repo.sign_revision('A', gpg.LoopbackGPGStrategy(None))
302
repo.commit_write_group()
304
#FIXME: clone should work to urls,
305
# wt.clone should work to disks.
306
self.build_tree(['target/'])
307
d2 = repo.bzrdir.clone(urlutils.local_path_to_url('target'))
308
self.assertEqual(repo.get_signature_text('A'),
309
d2.open_repository().get_signature_text('A'))
311
258
def test_nicks_bzr(self):
312
259
"""Test the behaviour of branch nicks specific to bzr branches.
374
321
repo = self.make_repository('.', shared=True)
375
322
except errors.IncompatibleFormat:
324
if repo.bzrdir._format.colocated_branches:
325
raise tests.TestNotApplicable(
326
"control dir does not support colocated branches")
377
327
self.assertEquals(0, len(repo.bzrdir.list_branches()))
328
if not self.bzrdir_format.colocated_branches:
329
raise tests.TestNotApplicable("control dir format does not support "
330
"colocated branches")
379
332
child_branch1 = self.branch_format.initialize(repo.bzrdir,
381
except (errors.UninitializableFormat, errors.NoColocatedBranchSupport):
334
except errors.UninitializableFormat:
382
335
# branch references are not default init'able and
383
336
# not all bzrdirs support colocated branches.
419
372
repo = self.make_repository('.', shared=True)
420
373
except errors.IncompatibleFormat:
374
raise tests.TestNotApplicable("requires shared repository support")
422
375
child_transport = repo.bzrdir.root_transport.clone('child')
423
376
child_transport.mkdir('.')
425
378
child_dir = self.bzrdir_format.initialize_on_transport(child_transport)
426
379
except errors.UninitializableFormat:
380
raise tests.TestNotApplicable("control dir format not initializable")
429
382
child_branch = self.branch_format.initialize(child_dir)
430
383
except errors.UninitializableFormat:
453
406
"""Create a fake revision history easily."""
454
407
tree = self.make_branch_and_tree('.')
455
408
rev1 = tree.commit('foo')
456
orig_history = tree.branch.revision_history()
410
self.addCleanup(tree.unlock)
411
graph = tree.branch.repository.get_graph()
413
graph.iter_lefthand_ancestry(
414
tree.branch.last_revision(), [revision.NULL_REVISION]))
457
415
rev2 = tree.commit('bar', allow_pointless=True)
458
416
tree.branch.generate_revision_history(rev1)
459
self.assertEqual(orig_history, tree.branch.revision_history())
417
self.assertEqual(orig_history, list(
418
graph.iter_lefthand_ancestry(
419
tree.branch.last_revision(), [revision.NULL_REVISION])))
461
421
def test_generate_revision_history_NULL_REVISION(self):
462
422
tree = self.make_branch_and_tree('.')
463
423
rev1 = tree.commit('foo')
425
self.addCleanup(tree.unlock)
464
426
tree.branch.generate_revision_history(revision.NULL_REVISION)
465
self.assertEqual([], tree.branch.revision_history())
427
self.assertEqual(revision.NULL_REVISION, tree.branch.last_revision())
467
429
def test_create_checkout(self):
468
430
tree_a = self.make_branch_and_tree('a')
489
451
tree_a = self.make_branch_and_tree('a')
490
452
rev_id = tree_a.commit('put some content in the branch')
491
453
# open the branch via a readonly transport
492
source_branch = _mod_branch.Branch.open(self.get_readonly_url('a'))
454
url = self.get_readonly_url(urlutils.basename(tree_a.branch.base))
455
t = transport.get_transport_from_url(url)
456
if not tree_a.branch.bzrdir._format.supports_transport(t):
457
raise tests.TestNotApplicable("format does not support transport")
458
source_branch = _mod_branch.Branch.open(url)
493
459
# sanity check that the test will be valid
494
460
self.assertRaises((errors.LockError, errors.TransportNotPossible),
495
461
source_branch.lock_write)
501
467
tree_a = self.make_branch_and_tree('a')
502
468
rev_id = tree_a.commit('put some content in the branch')
503
469
# open the branch via a readonly transport
504
source_branch = _mod_branch.Branch.open(self.get_readonly_url('a'))
470
url = self.get_readonly_url(
471
osutils.basename(tree_a.branch.base.rstrip('/')))
472
t = transport.get_transport_from_url(url)
473
if not tree_a.branch.bzrdir._format.supports_transport(t):
474
raise tests.TestNotApplicable("format does not support transport")
475
source_branch = _mod_branch.Branch.open(url)
505
476
# sanity check that the test will be valid
506
477
self.assertRaises((errors.LockError, errors.TransportNotPossible),
507
478
source_branch.lock_write)
508
479
checkout = source_branch.create_checkout('c')
509
480
self.assertEqual(rev_id, checkout.last_revision())
511
def test_set_revision_history(self):
512
tree = self.make_branch_and_tree('a')
513
tree.commit('a commit', rev_id='rev1')
515
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
516
br.set_revision_history, ["rev1"])
517
self.assertEquals(br.revision_history(), ["rev1"])
518
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
519
br.set_revision_history, [])
520
self.assertEquals(br.revision_history(), [])
522
482
def test_heads_to_fetch(self):
523
483
# heads_to_fetch is a method that returns a collection of revids that
524
484
# need to be fetched to copy this branch into another repo. At a
810
773
self.assertEqual(None, branch.get_master_branch())
812
def test_unlocked_does_not_cache_master_branch(self):
813
"""Unlocked branches do not cache the result of get_master_branch."""
814
master = self.make_branch('master')
815
branch1 = self.make_branch('branch')
818
except errors.UpgradeRequired:
819
raise tests.TestNotApplicable('Format does not support binding')
821
branch2 = branch1.bzrdir.open_branch()
822
self.assertNotEqual(None, branch1.get_master_branch())
823
# Unbind the branch via branch2. branch1 isn't locked so will
824
# immediately return the new value for get_master_branch.
826
self.assertEqual(None, branch1.get_master_branch())
828
775
def test_bind_clears_cached_master_branch(self):
829
776
"""b.bind clears any cached value of b.get_master_branch."""
830
777
master1 = self.make_branch('master1')
895
842
def test_fallbacks_not_opened(self):
896
843
stacked = self.make_branch_with_fallback()
897
844
self.get_transport('').rename('fallback', 'moved')
898
reopened = stacked.bzrdir.open_branch(ignore_fallbacks=True)
845
reopened_dir = controldir.ControlDir.open(stacked.base)
846
reopened = reopened_dir.open_branch(ignore_fallbacks=True)
899
847
self.assertEqual([], reopened.repository._fallback_repositories)
901
849
def test_fallbacks_are_opened(self):
902
850
stacked = self.make_branch_with_fallback()
903
reopened = stacked.bzrdir.open_branch(ignore_fallbacks=False)
851
reopened_dir = controldir.ControlDir.open(stacked.base)
852
reopened = reopened_dir.open_branch(ignore_fallbacks=False)
904
853
self.assertLength(1, reopened.repository._fallback_repositories)
1109
1061
# above the control dir but we might need to relax that?
1110
1062
self.assertEqual(br.control_url.find(br.user_url), 0)
1111
1063
self.assertEqual(br.control_url, br.control_transport.base)
1066
class FakeShelfCreator(object):
1068
def __init__(self, branch):
1069
self.branch = branch
1071
def write_shelf(self, shelf_file, message=None):
1072
tree = self.branch.repository.revision_tree(revision.NULL_REVISION)
1073
with transform.TransformPreview(tree) as tt:
1074
shelf.ShelfCreator._write_shelf(
1075
shelf_file, tt, revision.NULL_REVISION)
1078
@contextlib.contextmanager
1079
def skip_if_storing_uncommitted_unsupported():
1082
except errors.StoringUncommittedNotSupported:
1083
raise tests.TestNotApplicable('Cannot store uncommitted changes.')
1086
class TestUncommittedChanges(per_branch.TestCaseWithBranch):
1088
def bind(self, branch, master):
1091
except errors.UpgradeRequired:
1092
raise tests.TestNotApplicable('Branch cannot be bound.')
1094
def test_store_uncommitted(self):
1095
tree = self.make_branch_and_tree('b')
1096
branch = tree.branch
1097
creator = FakeShelfCreator(branch)
1098
with skip_if_storing_uncommitted_unsupported():
1099
self.assertIs(None, branch.get_unshelver(tree))
1100
branch.store_uncommitted(creator)
1101
self.assertIsNot(None, branch.get_unshelver(tree))
1103
def test_store_uncommitted_bound(self):
1104
tree = self.make_branch_and_tree('b')
1105
branch = tree.branch
1106
master = self.make_branch('master')
1107
self.bind(branch, master)
1108
creator = FakeShelfCreator(tree.branch)
1109
self.assertIs(None, tree.branch.get_unshelver(tree))
1110
self.assertIs(None, master.get_unshelver(tree))
1111
tree.branch.store_uncommitted(creator)
1112
self.assertIsNot(None, master.get_unshelver(tree))
1114
def test_store_uncommitted_already_stored(self):
1115
branch = self.make_branch('b')
1116
with skip_if_storing_uncommitted_unsupported():
1117
branch.store_uncommitted(FakeShelfCreator(branch))
1118
self.assertRaises(errors.ChangesAlreadyStored,
1119
branch.store_uncommitted, FakeShelfCreator(branch))
1121
def test_store_uncommitted_none(self):
1122
branch = self.make_branch('b')
1123
with skip_if_storing_uncommitted_unsupported():
1124
branch.store_uncommitted(FakeShelfCreator(branch))
1125
branch.store_uncommitted(None)
1126
self.assertIs(None, branch.get_unshelver(None))
1128
def test_get_unshelver(self):
1129
tree = self.make_branch_and_tree('tree')
1131
self.build_tree_contents([('tree/file', 'contents1')])
1133
with skip_if_storing_uncommitted_unsupported():
1134
tree.store_uncommitted()
1135
unshelver = tree.branch.get_unshelver(tree)
1136
self.assertIsNot(None, unshelver)
1138
def test_get_unshelver_bound(self):
1139
tree = self.make_branch_and_tree('tree')
1141
self.build_tree_contents([('tree/file', 'contents1')])
1143
with skip_if_storing_uncommitted_unsupported():
1144
tree.store_uncommitted()
1145
branch = self.make_branch('branch')
1146
self.bind(branch, tree.branch)
1147
unshelver = branch.get_unshelver(tree)
1148
self.assertIsNot(None, unshelver)