232
232
def _make_parents_provider(self):
233
233
return _KnitsParentsProvider(self.revisions)
235
def _find_inconsistent_revision_parents(self, revisions_iterator=None):
236
"""Find revisions with different parent lists in the revision object
237
and in the index graph.
239
:param revisions_iterator: None, or an iterator of (revid,
240
Revision-or-None). This iterator controls the revisions checked.
241
:returns: an iterator yielding tuples of (revison-id, parents-in-index,
242
parents-in-revision).
244
if not self.is_locked():
245
raise AssertionError()
247
if revisions_iterator is None:
248
revisions_iterator = self._iter_revisions(None)
249
for revid, revision in revisions_iterator:
252
parent_map = vf.get_parent_map([(revid,)])
253
parents_according_to_index = tuple(parent[-1] for parent in
254
parent_map[(revid,)])
255
parents_according_to_revision = tuple(revision.parent_ids)
256
if parents_according_to_index != parents_according_to_revision:
257
yield (revid, parents_according_to_index,
258
parents_according_to_revision)
260
def _check_for_inconsistent_revision_parents(self):
261
inconsistencies = list(self._find_inconsistent_revision_parents())
263
raise errors.BzrCheckError(
264
"Revision knit has inconsistent parents.")
266
def revision_graph_can_have_wrong_parents(self):
267
# The revision.kndx could potentially claim a revision has a different
268
# parent to the revision text.
236
272
class RepositoryFormatKnit(MetaDirRepositoryFormat):
237
273
"""Bzr repository knit format (generalized).
268
304
_fetch_order = 'topological'
269
305
_fetch_uses_deltas = True
270
306
fast_deltas = False
271
supports_funky_characters = True
272
supports_full_versioned_files = True
273
# The revision.kndx could potentially claim a revision has a different
274
# parent to the revision text.
275
revision_graph_can_have_wrong_parents = True
277
308
def _get_inventories(self, repo_transport, repo, name='inventory'):
278
309
mapper = versionedfile.ConstantMapper(name)
479
510
def get_format_description(self):
480
511
"""See RepositoryFormat.get_format_description()."""
481
512
return "Knit repository format 4"
484
class InterKnitRepo(InterSameDataRepository):
485
"""Optimised code paths between Knit based repositories."""
488
def _get_repo_format_to_test(self):
489
return RepositoryFormatKnit1()
492
def is_compatible(source, target):
493
"""Be compatible with known Knit formats.
495
We don't test for the stores being of specific types because that
496
could lead to confusing results, and there is no need to be
500
are_knits = (isinstance(source._format, RepositoryFormatKnit) and
501
isinstance(target._format, RepositoryFormatKnit))
502
except AttributeError:
504
return are_knits and InterRepository._same_model(source, target)
507
def search_missing_revision_ids(self,
508
revision_id=symbol_versioning.DEPRECATED_PARAMETER,
509
find_ghosts=True, revision_ids=None, if_present_ids=None):
510
"""See InterRepository.search_missing_revision_ids()."""
511
if symbol_versioning.deprecated_passed(revision_id):
512
symbol_versioning.warn(
513
'search_missing_revision_ids(revision_id=...) was '
514
'deprecated in 2.4. Use revision_ids=[...] instead.',
515
DeprecationWarning, stacklevel=2)
516
if revision_ids is not None:
517
raise AssertionError(
518
'revision_ids is mutually exclusive with revision_id')
519
if revision_id is not None:
520
revision_ids = [revision_id]
522
source_ids_set = self._present_source_revisions_for(
523
revision_ids, if_present_ids)
524
# source_ids is the worst possible case we may need to pull.
525
# now we want to filter source_ids against what we actually
526
# have in target, but don't try to check for existence where we know
527
# we do not have a revision as that would be pointless.
528
target_ids = set(self.target.all_revision_ids())
529
possibly_present_revisions = target_ids.intersection(source_ids_set)
530
actually_present_revisions = set(
531
self.target._eliminate_revisions_not_present(possibly_present_revisions))
532
required_revisions = source_ids_set.difference(actually_present_revisions)
533
if revision_ids is not None:
534
# we used get_ancestry to determine source_ids then we are assured all
535
# revisions referenced are present as they are installed in topological order.
536
# and the tip revision was validated by get_ancestry.
537
result_set = required_revisions
539
# if we just grabbed the possibly available ids, then
540
# we only have an estimate of whats available and need to validate
541
# that against the revision records.
543
self.source._eliminate_revisions_not_present(required_revisions))
544
return self.source.revision_ids_to_search_result(result_set)
547
InterRepository.register_optimiser(InterKnitRepo)