91
90
self._revision_history_cache = None
92
91
self._revision_id_to_revno_cache = None
93
92
self._partial_revision_id_to_revno_cache = {}
93
self._partial_revision_history_cache = []
94
94
self._last_revision_info_cache = None
95
95
self._merge_sorted_revisions_cache = None
101
101
def _open_hook(self):
102
102
"""Called by init to allow simpler extension of the base class."""
104
def _activate_fallback_location(self, url, lock_style):
104
def _activate_fallback_location(self, url):
105
105
"""Activate the branch/repository from url as a fallback repository."""
106
106
repo = self._get_fallback_repository(url)
107
if lock_style == 'write':
109
elif lock_style == 'read':
107
if repo.has_same_location(self.repository):
108
raise errors.UnstackableLocationError(self.base, url)
111
109
self.repository.add_fallback_repository(repo)
113
111
def break_lock(self):
129
127
raise errors.UnstackableRepositoryFormat(self.repository._format,
130
128
self.repository.base)
130
def _extend_partial_history(self, stop_index=None, stop_revision=None):
131
"""Extend the partial history to include a given index
133
If a stop_index is supplied, stop when that index has been reached.
134
If a stop_revision is supplied, stop when that revision is
135
encountered. Otherwise, stop when the beginning of history is
138
:param stop_index: The index which should be present. When it is
139
present, history extension will stop.
140
:param stop_revision: The revision id which should be present. When
141
it is encountered, history extension will stop.
143
if len(self._partial_revision_history_cache) == 0:
144
self._partial_revision_history_cache = [self.last_revision()]
145
repository._iter_for_revno(
146
self.repository, self._partial_revision_history_cache,
147
stop_index=stop_index, stop_revision=stop_revision)
148
if self._partial_revision_history_cache[-1] == _mod_revision.NULL_REVISION:
149
self._partial_revision_history_cache.pop()
133
152
def open(base, _unsupported=False, possible_transports=None):
134
153
"""Open the branch rooted at base.
503
522
raise errors.UpgradeRequired(self.base)
524
def set_append_revisions_only(self, enabled):
525
if not self._format.supports_set_append_revisions_only():
526
raise errors.UpgradeRequired(self.base)
531
self.get_config().set_user_option('append_revisions_only', value,
505
534
def set_reference_info(self, file_id, tree_path, branch_location):
506
535
"""Set the branch location to use for a tree reference."""
507
536
raise errors.UnsupportedOperation(self.set_reference_info, self)
656
685
self.repository.fetch(source_repository, revision_id,
657
686
find_ghosts=True)
659
self._activate_fallback_location(url, 'write')
688
self._activate_fallback_location(url)
660
689
# write this out after the repository is stacked to avoid setting a
661
690
# stacked config that doesn't work.
662
691
self._set_config_location('stacked_on_location', url)
702
731
self._revision_id_to_revno_cache = None
703
732
self._last_revision_info_cache = None
704
733
self._merge_sorted_revisions_cache = None
734
self._partial_revision_history_cache = []
735
self._partial_revision_id_to_revno_cache = {}
706
737
def _gen_revision_history(self):
707
738
"""Return sequence of revision hashes on to this branch.
746
777
"""Older format branches cannot bind or unbind."""
747
778
raise errors.UpgradeRequired(self.base)
749
def set_append_revisions_only(self, enabled):
750
"""Older format branches are never restricted to append-only"""
751
raise errors.UpgradeRequired(self.base)
753
780
def last_revision(self):
754
781
"""Return last revision id, or NULL_REVISION."""
755
782
return self.last_revision_info()[1]
835
862
except ValueError:
836
863
raise errors.NoSuchRevision(self, revision_id)
838
866
def get_rev_id(self, revno, history=None):
839
867
"""Find the revision id of the specified revno."""
841
869
return _mod_revision.NULL_REVISION
843
history = self.revision_history()
844
if revno <= 0 or revno > len(history):
870
last_revno, last_revid = self.last_revision_info()
871
if revno == last_revno:
873
if revno <= 0 or revno > last_revno:
845
874
raise errors.NoSuchRevision(self, revno)
846
return history[revno - 1]
875
distance_from_last = last_revno - revno
876
if len(self._partial_revision_history_cache) <= distance_from_last:
877
self._extend_partial_history(distance_from_last)
878
return self._partial_revision_history_cache[distance_from_last]
848
880
@needs_write_lock
849
881
def pull(self, source, overwrite=False, stop_revision=None,
967
def get_child_submit_format(self):
968
"""Return the preferred format of submissions to this branch."""
969
return self.get_config().get_user_option("child_submit_format")
935
971
def get_submit_branch(self):
936
972
"""Return the submit location of the branch.
1085
1121
source_revno, source_revision_id = self.last_revision_info()
1086
1122
if revision_id is None:
1087
1123
revno, revision_id = source_revno, source_revision_id
1088
elif source_revision_id == revision_id:
1089
# we know the revno without needing to walk all of history
1090
revno = source_revno
1092
# To figure out the revno for a random revision, we need to build
1093
# the revision history, and count its length.
1094
# We don't care about the order, just how long it is.
1095
# Alternatively, we could start at the current location, and count
1096
# backwards. But there is no guarantee that we will find it since
1097
# it may be a merged revision.
1098
revno = len(list(self.repository.iter_reverse_revision_history(
1125
graph = self.repository.get_graph()
1127
revno = graph.find_distance_to_null(revision_id,
1128
[(source_revision_id, source_revno)])
1129
except errors.GhostRevisionsHaveNoRevno:
1130
# Default to 1, if we can't find anything else
1100
1132
destination.set_last_revision_info(revno, revision_id)
1102
1134
@needs_read_lock
1148
1180
:return: A BranchCheckResult.
1182
ret = BranchCheckResult(self)
1150
1183
mainline_parent_id = None
1151
1184
last_revno, last_revision_id = self.last_revision_info()
1152
real_rev_history = list(self.repository.iter_reverse_revision_history(
1185
real_rev_history = []
1187
for revid in self.repository.iter_reverse_revision_history(
1189
real_rev_history.append(revid)
1190
except errors.RevisionNotPresent:
1191
ret.ghosts_in_mainline = True
1193
ret.ghosts_in_mainline = False
1154
1194
real_rev_history.reverse()
1155
1195
if len(real_rev_history) != last_revno:
1156
1196
raise errors.BzrCheckError('revno does not match len(mainline)'
1172
1212
"parents of {%s}"
1173
1213
% (mainline_parent_id, revision_id))
1174
1214
mainline_parent_id = revision_id
1175
return BranchCheckResult(self)
1177
1217
def _get_checkout_format(self):
1178
1218
"""Return the most suitable metadir for a checkout of this branch.
1503
1545
def set_default_format(klass, format):
1504
1546
klass._default_format = format
1548
def supports_set_append_revisions_only(self):
1549
"""True if this format supports set_append_revisions_only."""
1506
1552
def supports_stacking(self):
1507
1553
"""True if this format records a stacked-on branch."""
2366
2420
raise AssertionError(
2367
2421
"'transform_fallback_location' hook %s returned "
2368
2422
"None, not a URL." % hook_name)
2369
self._activate_fallback_location(url, None)
2423
self._activate_fallback_location(url)
2371
2425
def __init__(self, *args, **kwargs):
2372
2426
self._ignore_fallbacks = kwargs.get('ignore_fallbacks', False)
2373
2427
super(BzrBranch8, self).__init__(*args, **kwargs)
2374
2428
self._last_revision_info_cache = None
2375
self._partial_revision_history_cache = []
2376
2429
self._reference_info = None
2378
2431
def _clear_cached_state(self):
2379
2432
super(BzrBranch8, self)._clear_cached_state()
2380
2433
self._last_revision_info_cache = None
2381
self._partial_revision_history_cache = []
2382
2434
self._reference_info = None
2384
2436
def _last_revision_info(self):
2440
2492
self._extend_partial_history(stop_index=last_revno-1)
2441
2493
return list(reversed(self._partial_revision_history_cache))
2443
def _extend_partial_history(self, stop_index=None, stop_revision=None):
2444
"""Extend the partial history to include a given index
2446
If a stop_index is supplied, stop when that index has been reached.
2447
If a stop_revision is supplied, stop when that revision is
2448
encountered. Otherwise, stop when the beginning of history is
2451
:param stop_index: The index which should be present. When it is
2452
present, history extension will stop.
2453
:param revision_id: The revision id which should be present. When
2454
it is encountered, history extension will stop.
2456
repo = self.repository
2457
if len(self._partial_revision_history_cache) == 0:
2458
iterator = repo.iter_reverse_revision_history(self.last_revision())
2460
start_revision = self._partial_revision_history_cache[-1]
2461
iterator = repo.iter_reverse_revision_history(start_revision)
2462
#skip the last revision in the list
2463
next_revision = iterator.next()
2464
for revision_id in iterator:
2465
self._partial_revision_history_cache.append(revision_id)
2466
if (stop_index is not None and
2467
len(self._partial_revision_history_cache) > stop_index):
2469
if revision_id == stop_revision:
2472
2495
def _write_revision_history(self, history):
2473
2496
"""Factored out of set_revision_history.
2617
2640
raise errors.NotStacked(self)
2618
2641
return stacked_url
2620
def set_append_revisions_only(self, enabled):
2625
self.get_config().set_user_option('append_revisions_only', value,
2628
2643
def _get_append_revisions_only(self):
2629
2644
value = self.get_config().get_user_option('append_revisions_only')
2630
2645
return value == 'True'
2781
2796
def __init__(self, branch):
2782
2797
self.branch = branch
2798
self.ghosts_in_mainline = False
2784
2800
def report_results(self, verbose):
2785
2801
"""Report the check results via trace.note.
2790
2806
note('checked branch %s format %s',
2791
2807
self.branch.base,
2792
2808
self.branch._format)
2809
if self.ghosts_in_mainline:
2810
note('branch contains ghosts in mainline')
2795
2813
class Converter5to6(object):
2891
2909
def _get_branch_formats_to_test():
2892
2910
"""Return a tuple with the Branch formats to use when testing."""
2893
raise NotImplementedError(self._get_branch_formats_to_test)
2911
raise NotImplementedError(InterBranch._get_branch_formats_to_test)
2895
2913
def pull(self, overwrite=False, stop_revision=None,
2896
2914
possible_transports=None, local=False):
3051
3069
_override_hook_source_branch=_override_hook_source_branch)
3053
3071
self.source.unlock()
3056
3073
def _push_with_bound_branches(self, overwrite, stop_revision,
3057
3074
_override_hook_source_branch=None):