524
524
self._revision_store._add_revision(revision, StringIO(text),
525
525
self.get_transaction())
528
def _all_possible_ids(self):
529
"""Return all the possible revisions that we could find."""
530
return self.get_inventory_weave().versions()
532
527
def all_revision_ids(self):
533
528
"""Returns a list of all the revision ids in the repository.
536
531
reachable from a particular revision, and ignore any other revisions
537
532
that might be present. There is no direct replacement method.
534
if 'evil' in debug.debug_flags:
535
mutter_callsite(2, "all_revision_ids is linear with history.")
539
536
return self._all_revision_ids()
542
538
def _all_revision_ids(self):
543
539
"""Returns a list of all the revision ids in the repository.
545
541
These are in as much topological order as the underlying store can
546
present: for weaves ghosts may lead to a lack of correctness until
547
the reweave updates the parents list.
549
if self._revision_store.text_store.listable():
550
return self._revision_store.all_revision_ids(self.get_transaction())
551
result = self._all_possible_ids()
552
# TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
553
# ids. (It should, since _revision_store's API should change to
554
# return utf8 revision_ids)
555
return self._eliminate_revisions_not_present(result)
544
raise NotImplementedError(self._all_revision_ids)
557
546
def break_lock(self):
558
547
"""Break a lock if one is present from another instance.
903
892
self.get_transaction())
895
def get_revision(self, revision_id):
896
"""Return the Revision object for a named revision."""
897
return self.get_revisions([revision_id])[0]
906
900
def get_revision_reconcile(self, revision_id):
907
901
"""'reconcile' helper routine that allows access to a revision always.
911
905
be used by reconcile, or reconcile-alike commands that are correcting
912
906
or testing the revision graph.
914
if not revision_id or not isinstance(revision_id, basestring):
915
raise errors.InvalidRevisionId(revision_id=revision_id,
917
return self.get_revisions([revision_id])[0]
908
return self._get_revisions([revision_id])[0]
920
911
def get_revisions(self, revision_ids):
912
"""Get many revisions at once."""
913
return self._get_revisions(revision_ids)
916
def _get_revisions(self, revision_ids):
917
"""Core work logic to get many revisions without sanity checks."""
921
918
revision_ids = [osutils.safe_revision_id(r) for r in revision_ids]
919
for rev_id in revision_ids:
920
if not rev_id or not isinstance(rev_id, basestring):
921
raise errors.InvalidRevisionId(revision_id=rev_id, branch=self)
922
922
revs = self._revision_store.get_revisions(revision_ids,
923
923
self.get_transaction())
941
941
return rev_tmp.getvalue()
944
def get_revision(self, revision_id):
945
"""Return the Revision object for a named revision"""
946
# TODO: jam 20070210 get_revision_reconcile should do this for us
947
revision_id = osutils.safe_revision_id(revision_id)
948
r = self.get_revision_reconcile(revision_id)
949
# weave corruption can lead to absent revision markers that should be
951
# the following test is reasonably cheap (it needs a single weave read)
952
# and the weave is cached in read transactions. In write transactions
953
# it is not cached but typically we only read a small number of
954
# revisions. For knits when they are introduced we will probably want
955
# to ensure that caching write transactions are in use.
956
inv = self.get_inventory_weave()
957
self._check_revision_parents(r, inv)
961
944
def get_deltas_for_revisions(self, revisions):
962
945
"""Produce a generator of revision deltas.
988
971
r = self.get_revision(revision_id)
989
972
return list(self.get_deltas_for_revisions([r]))[0]
991
def _check_revision_parents(self, revision, inventory):
992
"""Private to Repository and Fetch.
994
This checks the parentage of revision in an inventory weave for
995
consistency and is only applicable to inventory-weave-for-ancestry
996
using repository formats & fetchers.
998
weave_parents = inventory.get_parents(revision.revision_id)
999
weave_names = inventory.versions()
1000
for parent_id in revision.parent_ids:
1001
if parent_id in weave_names:
1002
# this parent must not be a ghost.
1003
if not parent_id in weave_parents:
1005
raise errors.CorruptRepository(self)
1007
974
@needs_write_lock
1008
975
def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
1009
976
revision_id = osutils.safe_revision_id(revision_id)
1220
1187
@needs_read_lock
1221
1188
def get_revision_graph(self, revision_id=None):
1222
1189
"""Return a dictionary containing the revision graph.
1191
NB: This method should not be used as it accesses the entire graph all
1192
at once, which is much more data than most operations should require.
1224
1194
:param revision_id: The revision_id to get a graph from. If None, then
1225
1195
the entire revision graph is returned. This is a deprecated mode of
1226
1196
operation and will be removed in the future.
1227
1197
:return: a dictionary of revision_id->revision_parents_list.
1229
if 'evil' in debug.debug_flags:
1231
"get_revision_graph scales with size of history.")
1232
# special case NULL_REVISION
1233
if revision_id == _mod_revision.NULL_REVISION:
1235
revision_id = osutils.safe_revision_id(revision_id)
1236
a_weave = self.get_inventory_weave()
1237
all_revisions = self._eliminate_revisions_not_present(
1239
entire_graph = dict([(node, tuple(a_weave.get_parents(node))) for
1240
node in all_revisions])
1241
if revision_id is None:
1243
elif revision_id not in entire_graph:
1244
raise errors.NoSuchRevision(self, revision_id)
1246
# add what can be reached from revision_id
1248
pending = set([revision_id])
1249
while len(pending) > 0:
1250
node = pending.pop()
1251
result[node] = entire_graph[node]
1252
for revision_id in result[node]:
1253
if revision_id not in result:
1254
pending.add(revision_id)
1199
raise NotImplementedError(self.get_revision_graph)
1257
1201
@needs_read_lock
1258
1202
def get_revision_graph_with_ghosts(self, revision_ids=None):
2060
2004
class InterWeaveRepo(InterSameDataRepository):
2061
"""Optimised code paths between Weave based repositories."""
2005
"""Optimised code paths between Weave based repositories.
2007
This should be in bzrlib/repofmt/weaverepo.py but we have not yet
2008
implemented lazy inter-object optimisation.
2064
2012
def _get_repo_format_to_test(self):
2221
2169
assert source_ids[0] is None
2222
2170
source_ids.pop(0)
2224
source_ids = self.source._all_possible_ids()
2172
source_ids = self.source.all_revision_ids()
2225
2173
source_ids_set = set(source_ids)
2226
2174
# source_ids is the worst possible case we may need to pull.
2227
2175
# now we want to filter source_ids against what we actually
2228
2176
# have in target, but don't try to check for existence where we know
2229
2177
# we do not have a revision as that would be pointless.
2230
target_ids = set(self.target._all_possible_ids())
2178
target_ids = set(self.target.all_revision_ids())
2231
2179
possibly_present_revisions = target_ids.intersection(source_ids_set)
2232
2180
actually_present_revisions = set(self.target._eliminate_revisions_not_present(possibly_present_revisions))
2233
2181
required_revisions = source_ids_set.difference(actually_present_revisions)