14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
from bzrlib.lazy_import import lazy_import
17
from __future__ import absolute_import
19
from ..lazy_import import lazy_import
18
20
lazy_import(globals(), """
39
from ..decorators import needs_read_lock, needs_write_lock
40
from ..repository import (
43
RepositoryFormatMetaDir,
38
from bzrlib.decorators import needs_read_lock, needs_write_lock
39
from bzrlib.repository import (
42
MetaDirRepositoryFormat,
45
from ..vf_repository import (
46
InterSameDataRepository,
47
MetaDirVersionedFileRepository,
48
MetaDirVersionedFileRepositoryFormat,
49
VersionedFileCommitBuilder,
50
VersionedFileRootCommitBuilder,
115
121
def __init__(self, _format, a_bzrdir, control_files, _commit_builder_class,
117
MetaDirRepository.__init__(self, _format, a_bzrdir, control_files)
123
super(KnitRepository, self).__init__(_format, a_bzrdir, control_files)
118
124
self._commit_builder_class = _commit_builder_class
119
125
self._serializer = _serializer
120
126
self._reconcile_fixes_text_parents = True
176
182
result.get_parent_map([('A',)])
179
def fileid_involved_between_revs(self, from_revid, to_revid):
180
"""Find file_id(s) which are involved in the changes between revisions.
182
This determines the set of revisions which are involved, and then
183
finds all file ids affected by those revisions.
185
vf = self._get_revision_vf()
186
from_set = set(vf.get_ancestry(from_revid))
187
to_set = set(vf.get_ancestry(to_revid))
188
changed = to_set.difference(from_set)
189
return self._fileid_involved_by_set(changed)
191
def fileid_involved(self, last_revid=None):
192
"""Find all file_ids modified in the ancestry of last_revid.
194
:param last_revid: If None, last_revision() will be used.
197
changed = set(self.all_revision_ids())
199
changed = set(self.get_ancestry(last_revid))
202
return self._fileid_involved_by_set(changed)
205
186
def get_revision(self, revision_id):
206
187
"""Return the Revision object for a named revision"""
229
212
def _make_parents_provider(self):
230
213
return _KnitsParentsProvider(self.revisions)
232
def _find_inconsistent_revision_parents(self, revisions_iterator=None):
233
"""Find revisions with different parent lists in the revision object
234
and in the index graph.
236
:param revisions_iterator: None, or an iterator of (revid,
237
Revision-or-None). This iterator controls the revisions checked.
238
:returns: an iterator yielding tuples of (revison-id, parents-in-index,
239
parents-in-revision).
241
if not self.is_locked():
242
raise AssertionError()
244
if revisions_iterator is None:
245
revisions_iterator = self._iter_revisions(None)
246
for revid, revision in revisions_iterator:
249
parent_map = vf.get_parent_map([(revid,)])
250
parents_according_to_index = tuple(parent[-1] for parent in
251
parent_map[(revid,)])
252
parents_according_to_revision = tuple(revision.parent_ids)
253
if parents_according_to_index != parents_according_to_revision:
254
yield (revid, parents_according_to_index,
255
parents_according_to_revision)
257
def _check_for_inconsistent_revision_parents(self):
258
inconsistencies = list(self._find_inconsistent_revision_parents())
260
raise errors.BzrCheckError(
261
"Revision knit has inconsistent parents.")
263
def revision_graph_can_have_wrong_parents(self):
264
# The revision.kndx could potentially claim a revision has a different
265
# parent to the revision text.
269
class RepositoryFormatKnit(MetaDirRepositoryFormat):
216
class RepositoryFormatKnit(MetaDirVersionedFileRepositoryFormat):
270
217
"""Bzr repository knit format (generalized).
272
219
This repository format has:
301
248
_fetch_order = 'topological'
302
249
_fetch_uses_deltas = True
303
250
fast_deltas = False
251
supports_funky_characters = True
252
# The revision.kndx could potentially claim a revision has a different
253
# parent to the revision text.
254
revision_graph_can_have_wrong_parents = True
305
256
def _get_inventories(self, repo_transport, repo, name='inventory'):
306
257
mapper = versionedfile.ConstantMapper(name)
452
404
return xml7.serializer_v7
454
406
def _get_matching_bzrdir(self):
455
return bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
407
return controldir.format_registry.make_bzrdir('dirstate-with-subtree')
457
409
def _ignore_setting_bzrdir(self, format):
460
412
_matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
462
def get_format_string(self):
415
def get_format_string(cls):
463
416
"""See RepositoryFormat.get_format_string()."""
464
417
return "Bazaar Knit Repository Format 3 (bzr 0.15)\n"
493
446
return xml6.serializer_v6
495
448
def _get_matching_bzrdir(self):
496
return bzrdir.format_registry.make_bzrdir('rich-root')
449
return controldir.format_registry.make_bzrdir('rich-root')
498
451
def _ignore_setting_bzrdir(self, format):
501
454
_matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
503
def get_format_string(self):
457
def get_format_string(cls):
504
458
"""See RepositoryFormat.get_format_string()."""
505
459
return 'Bazaar Knit Repository Format 4 (bzr 1.0)\n'
507
461
def get_format_description(self):
508
462
"""See RepositoryFormat.get_format_description()."""
509
463
return "Knit repository format 4"
466
class InterKnitRepo(InterSameDataRepository):
467
"""Optimised code paths between Knit based repositories."""
470
def _get_repo_format_to_test(self):
471
return RepositoryFormatKnit1()
474
def is_compatible(source, target):
475
"""Be compatible with known Knit formats.
477
We don't test for the stores being of specific types because that
478
could lead to confusing results, and there is no need to be
482
are_knits = (isinstance(source._format, RepositoryFormatKnit) and
483
isinstance(target._format, RepositoryFormatKnit))
484
except AttributeError:
486
return are_knits and InterRepository._same_model(source, target)
489
def search_missing_revision_ids(self,
490
find_ghosts=True, revision_ids=None, if_present_ids=None,
492
"""See InterRepository.search_missing_revision_ids()."""
493
source_ids_set = self._present_source_revisions_for(
494
revision_ids, if_present_ids)
495
# source_ids is the worst possible case we may need to pull.
496
# now we want to filter source_ids against what we actually
497
# have in target, but don't try to check for existence where we know
498
# we do not have a revision as that would be pointless.
499
target_ids = set(self.target.all_revision_ids())
500
possibly_present_revisions = target_ids.intersection(source_ids_set)
501
actually_present_revisions = set(
502
self.target._eliminate_revisions_not_present(possibly_present_revisions))
503
required_revisions = source_ids_set.difference(actually_present_revisions)
504
if revision_ids is not None:
505
# we used get_ancestry to determine source_ids then we are assured all
506
# revisions referenced are present as they are installed in topological order.
507
# and the tip revision was validated by get_ancestry.
508
result_set = required_revisions
510
# if we just grabbed the possibly available ids, then
511
# we only have an estimate of whats available and need to validate
512
# that against the revision records.
514
self.source._eliminate_revisions_not_present(required_revisions))
515
if limit is not None:
516
topo_ordered = self.source.get_graph().iter_topo_order(result_set)
517
result_set = set(itertools.islice(topo_ordered, limit))
518
return self.source.revision_ids_to_search_result(result_set)
521
InterRepository.register_optimiser(InterKnitRepo)