38
37
from bzrlib.decorators import needs_read_lock, needs_write_lock
39
38
from bzrlib.repository import (
41
40
IsInWriteGroupError,
43
MetaDirRepositoryFormat,
41
RepositoryFormatMetaDir,
43
from bzrlib.vf_repository import (
44
InterSameDataRepository,
45
MetaDirVersionedFileRepository,
46
MetaDirVersionedFileRepositoryFormat,
47
VersionedFileCommitBuilder,
48
VersionedFileRootCommitBuilder,
50
from bzrlib import symbol_versioning
49
53
class _KnitParentsProvider(object):
116
120
def __init__(self, _format, a_bzrdir, control_files, _commit_builder_class,
118
MetaDirRepository.__init__(self, _format, a_bzrdir, control_files)
122
super(KnitRepository, self).__init__(_format, a_bzrdir, control_files)
119
123
self._commit_builder_class = _commit_builder_class
120
124
self._serializer = _serializer
121
125
self._reconcile_fixes_text_parents = True
177
181
result.get_parent_map([('A',)])
180
def fileid_involved_between_revs(self, from_revid, to_revid):
181
"""Find file_id(s) which are involved in the changes between revisions.
183
This determines the set of revisions which are involved, and then
184
finds all file ids affected by those revisions.
186
vf = self._get_revision_vf()
187
from_set = set(vf.get_ancestry(from_revid))
188
to_set = set(vf.get_ancestry(to_revid))
189
changed = to_set.difference(from_set)
190
return self._fileid_involved_by_set(changed)
192
def fileid_involved(self, last_revid=None):
193
"""Find all file_ids modified in the ancestry of last_revid.
195
:param last_revid: If None, last_revision() will be used.
198
changed = set(self.all_revision_ids())
200
changed = set(self.get_ancestry(last_revid))
203
return self._fileid_involved_by_set(changed)
206
185
def get_revision(self, revision_id):
207
186
"""Return the Revision object for a named revision"""
232
211
def _make_parents_provider(self):
233
212
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.
272
class RepositoryFormatKnit(MetaDirRepositoryFormat):
215
class RepositoryFormatKnit(MetaDirVersionedFileRepositoryFormat):
273
216
"""Bzr repository knit format (generalized).
275
218
This repository format has:
504
453
_matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
506
def get_format_string(self):
456
def get_format_string(cls):
507
457
"""See RepositoryFormat.get_format_string()."""
508
458
return 'Bazaar Knit Repository Format 4 (bzr 1.0)\n'
510
460
def get_format_description(self):
511
461
"""See RepositoryFormat.get_format_description()."""
512
462
return "Knit repository format 4"
465
class InterKnitRepo(InterSameDataRepository):
466
"""Optimised code paths between Knit based repositories."""
469
def _get_repo_format_to_test(self):
470
return RepositoryFormatKnit1()
473
def is_compatible(source, target):
474
"""Be compatible with known Knit formats.
476
We don't test for the stores being of specific types because that
477
could lead to confusing results, and there is no need to be
481
are_knits = (isinstance(source._format, RepositoryFormatKnit) and
482
isinstance(target._format, RepositoryFormatKnit))
483
except AttributeError:
485
return are_knits and InterRepository._same_model(source, target)
488
def search_missing_revision_ids(self,
489
revision_id=symbol_versioning.DEPRECATED_PARAMETER,
490
find_ghosts=True, revision_ids=None, if_present_ids=None,
492
"""See InterRepository.search_missing_revision_ids()."""
493
if symbol_versioning.deprecated_passed(revision_id):
494
symbol_versioning.warn(
495
'search_missing_revision_ids(revision_id=...) was '
496
'deprecated in 2.4. Use revision_ids=[...] instead.',
497
DeprecationWarning, stacklevel=2)
498
if revision_ids is not None:
499
raise AssertionError(
500
'revision_ids is mutually exclusive with revision_id')
501
if revision_id is not None:
502
revision_ids = [revision_id]
504
source_ids_set = self._present_source_revisions_for(
505
revision_ids, if_present_ids)
506
# source_ids is the worst possible case we may need to pull.
507
# now we want to filter source_ids against what we actually
508
# have in target, but don't try to check for existence where we know
509
# we do not have a revision as that would be pointless.
510
target_ids = set(self.target.all_revision_ids())
511
possibly_present_revisions = target_ids.intersection(source_ids_set)
512
actually_present_revisions = set(
513
self.target._eliminate_revisions_not_present(possibly_present_revisions))
514
required_revisions = source_ids_set.difference(actually_present_revisions)
515
if revision_ids is not None:
516
# we used get_ancestry to determine source_ids then we are assured all
517
# revisions referenced are present as they are installed in topological order.
518
# and the tip revision was validated by get_ancestry.
519
result_set = required_revisions
521
# if we just grabbed the possibly available ids, then
522
# we only have an estimate of whats available and need to validate
523
# that against the revision records.
525
self.source._eliminate_revisions_not_present(required_revisions))
526
if limit is not None:
527
topo_ordered = self.source.get_graph().iter_topo_order(result_set)
528
result_set = set(itertools.islice(topo_ordered, limit))
529
return self.source.revision_ids_to_search_result(result_set)
532
InterRepository.register_optimiser(InterKnitRepo)