49
from bzrlib.decorators import needs_read_lock, needs_write_lock
49
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
50
50
from bzrlib.hooks import HookPoint, Hooks
51
51
from bzrlib.inter import InterObject
52
from bzrlib.lock import _RelockDebugMixin
52
53
from bzrlib import registry
53
54
from bzrlib.symbol_versioning import (
446
447
# start_revision_id.
447
448
if self._merge_sorted_revisions_cache is None:
448
449
last_revision = self.last_revision()
449
graph = self.repository.get_graph()
450
parent_map = dict(((key, value) for key, value in
451
graph.iter_ancestry([last_revision]) if value is not None))
452
revision_graph = repository._strip_NULL_ghosts(parent_map)
453
revs = tsort.merge_sort(revision_graph, last_revision, None,
455
# Drop the sequence # before caching
456
self._merge_sorted_revisions_cache = [r[1:] for r in revs]
450
last_key = (last_revision,)
451
known_graph = self.repository.revisions.get_known_graph_ancestry(
453
self._merge_sorted_revisions_cache = known_graph.merge_sort(
458
455
filtered = self._filter_merge_sorted_revisions(
459
456
self._merge_sorted_revisions_cache, start_revision_id,
460
457
stop_revision_id, stop_rule)
470
467
"""Iterate over an inclusive range of sorted revisions."""
471
468
rev_iter = iter(merge_sorted_revisions)
472
469
if start_revision_id is not None:
473
for rev_id, depth, revno, end_of_merge in rev_iter:
470
for node in rev_iter:
471
rev_id = node.key[-1]
474
472
if rev_id != start_revision_id:
477
475
# The decision to include the start or not
478
476
# depends on the stop_rule if a stop is provided
480
iter([(rev_id, depth, revno, end_of_merge)]),
477
# so pop this node back into the iterator
478
rev_iter = chain(iter([node]), rev_iter)
483
480
if stop_revision_id is None:
484
for rev_id, depth, revno, end_of_merge in rev_iter:
485
yield rev_id, depth, revno, end_of_merge
482
for node in rev_iter:
483
rev_id = node.key[-1]
484
yield (rev_id, node.merge_depth, node.revno,
486
486
elif stop_rule == 'exclude':
487
for rev_id, depth, revno, end_of_merge in rev_iter:
487
for node in rev_iter:
488
rev_id = node.key[-1]
488
489
if rev_id == stop_revision_id:
490
yield rev_id, depth, revno, end_of_merge
491
yield (rev_id, node.merge_depth, node.revno,
491
493
elif stop_rule == 'include':
492
for rev_id, depth, revno, end_of_merge in rev_iter:
493
yield rev_id, depth, revno, end_of_merge
494
for node in rev_iter:
495
rev_id = node.key[-1]
496
yield (rev_id, node.merge_depth, node.revno,
494
498
if rev_id == stop_revision_id:
496
500
elif stop_rule == 'with-merges':
499
503
left_parent = stop_rev.parent_ids[0]
501
505
left_parent = _mod_revision.NULL_REVISION
502
for rev_id, depth, revno, end_of_merge in rev_iter:
506
for node in rev_iter:
507
rev_id = node.key[-1]
503
508
if rev_id == left_parent:
505
yield rev_id, depth, revno, end_of_merge
510
yield (rev_id, node.merge_depth, node.revno,
507
513
raise ValueError('invalid stop_rule %r' % stop_rule)
1147
1153
revision_id: if not None, the revision history in the new branch will
1148
1154
be truncated to end with revision_id.
1156
if (repository_policy is not None and
1157
repository_policy.requires_stacking()):
1158
to_bzrdir._format.require_stacking(_skip_repo=True)
1150
1159
result = to_bzrdir.create_branch()
1151
1160
result.lock_write()
2064
2073
BranchFormat.register_format(__format6)
2065
2074
BranchFormat.register_format(__format7)
2066
2075
BranchFormat.register_format(__format8)
2067
BranchFormat.set_default_format(__format6)
2076
BranchFormat.set_default_format(__format7)
2068
2077
_legacy_formats = [BzrBranchFormat4(),
2070
2079
network_format_registry.register(
2071
2080
_legacy_formats[0].network_name(), _legacy_formats[0].__class__)
2074
class BzrBranch(Branch):
2083
class BzrBranch(Branch, _RelockDebugMixin):
2075
2084
"""A branch stored in the actual filesystem.
2077
2086
Note that it's "local" in the context of the filesystem; it doesn't
2123
2132
return self.control_files.is_locked()
2125
2134
def lock_write(self, token=None):
2135
if not self.is_locked():
2136
self._note_lock('w')
2126
2137
# All-in-one needs to always unlock/lock.
2127
2138
repo_control = getattr(self.repository, 'control_files', None)
2128
2139
if self.control_files == repo_control or not self.is_locked():