504
507
return self.factory.lower_fulltext(KnitContent(new_lines))
506
def join(self, other, pb=None, msg=None, version_ids=None):
507
"""See VersionedFile.join."""
508
assert isinstance(other, KnitVersionedFile)
510
if version_ids is None:
511
version_ids = other.versions()
516
from bzrlib.progress import DummyProgress
519
version_ids = list(version_ids)
520
if None in version_ids:
521
version_ids.remove(None)
523
other_ancestry = set(other.get_ancestry(version_ids))
524
this_versions = set(self._index.get_versions())
525
needed_versions = other_ancestry - this_versions
526
cross_check_versions = other_ancestry.intersection(this_versions)
527
mismatched_versions = set()
528
for version in cross_check_versions:
529
# scan to include needed parents.
530
n1 = set(self.get_parents(version))
531
n2 = set(other.get_parents(version))
533
# FIXME TEST this check for cycles being introduced works
534
# the logic is we have a cycle if in our graph we are an
535
# ancestor of any of the n2 revisions.
541
parent_ancestors = other.get_ancestry(parent)
542
if version in parent_ancestors:
543
raise errors.GraphCycleError([parent, version])
544
# ensure this parent will be available later.
545
new_parents = n2.difference(n1)
546
needed_versions.update(new_parents.difference(this_versions))
547
mismatched_versions.add(version)
549
if not needed_versions and not cross_check_versions:
551
full_list = topo_sort(other._index.get_graph())
553
version_list = [i for i in full_list if (not self.has_version(i)
554
and i in needed_versions)]
557
for version_id in version_list:
558
data_pos, data_size = other._index.get_position(version_id)
559
records.append((version_id, data_pos, data_size))
562
for version_id, lines, digest \
563
in other._data.read_records_iter(records):
564
options = other._index.get_options(version_id)
565
parents = other._index.get_parents(version_id)
567
for parent in parents:
568
assert self.has_version(parent)
570
if self.factory.annotated:
571
# FIXME jrydberg: it should be possible to skip
572
# re-annotating components if we know that we are
573
# going to pull all revisions in the same order.
574
new_version_id = version_id
575
new_version_idx = self._index.num_versions()
576
if 'fulltext' in options:
577
lines = self._reannotate_fulltext(other, lines,
578
new_version_id, new_version_idx)
579
elif 'line-delta' in options:
580
lines = self._reannotate_line_delta(other, lines,
581
new_version_id, new_version_idx)
584
pb.update(self.filename, count, len(version_list))
586
pos, size = self._data.add_record(version_id, digest, lines)
587
self._index.add_version(version_id, options, pos, size, parents)
589
for version in mismatched_versions:
590
n1 = set(self.get_parents(version))
591
n2 = set(other.get_parents(version))
592
# write a combined record to our history.
593
new_parents = self.get_parents(version) + list(n2.difference(n1))
594
current_values = self._index._cache[version]
595
self._index.add_version(version,
603
509
def walk(self, version_ids):
604
510
"""See VersionedFile.walk."""
605
511
# We take the short path here, and extract all relevant texts
889
795
components[record_id] = (content, digest)
890
796
return components
799
class InterKnit(InterVersionedFile):
800
"""Optimised code paths for knit to knit operations."""
802
_matching_file_factory = staticmethod(AnnotatedKnitFactory)
805
def is_compatible(source, target):
806
"""Be compatible with knits. """
808
return (isinstance(source, KnitVersionedFile) and
809
isinstance(target, KnitVersionedFile))
810
except AttributeError:
813
def join(self, pb=None, msg=None, version_ids=None):
814
"""See InterVersionedFile.join."""
815
assert isinstance(self.source, KnitVersionedFile)
816
assert isinstance(self.target, KnitVersionedFile)
818
if version_ids is None:
819
version_ids = self.source.versions()
824
from bzrlib.progress import DummyProgress
827
version_ids = list(version_ids)
828
if None in version_ids:
829
version_ids.remove(None)
831
self.source_ancestry = set(self.source.get_ancestry(version_ids))
832
this_versions = set(self.target._index.get_versions())
833
needed_versions = self.source_ancestry - this_versions
834
cross_check_versions = self.source_ancestry.intersection(this_versions)
835
mismatched_versions = set()
836
for version in cross_check_versions:
837
# scan to include needed parents.
838
n1 = set(self.target.get_parents(version))
839
n2 = set(self.source.get_parents(version))
841
# FIXME TEST this check for cycles being introduced works
842
# the logic is we have a cycle if in our graph we are an
843
# ancestor of any of the n2 revisions.
849
parent_ancestors = self.source.get_ancestry(parent)
850
if version in parent_ancestors:
851
raise errors.GraphCycleError([parent, version])
852
# ensure this parent will be available later.
853
new_parents = n2.difference(n1)
854
needed_versions.update(new_parents.difference(this_versions))
855
mismatched_versions.add(version)
857
if not needed_versions and not cross_check_versions:
859
full_list = topo_sort(self.source._index.get_graph())
861
version_list = [i for i in full_list if (not self.target.has_version(i)
862
and i in needed_versions)]
865
for version_id in version_list:
866
data_pos, data_size = self.source._index.get_position(version_id)
867
records.append((version_id, data_pos, data_size))
870
for version_id, lines, digest \
871
in self.source._data.read_records_iter(records):
872
options = self.source._index.get_options(version_id)
873
parents = self.source._index.get_parents(version_id)
875
for parent in parents:
876
assert self.target.has_version(parent)
878
if self.target.factory.annotated:
879
# FIXME jrydberg: it should be possible to skip
880
# re-annotating components if we know that we are
881
# going to pull all revisions in the same order.
882
new_version_id = version_id
883
new_version_idx = self.target._index.num_versions()
884
if 'fulltext' in options:
885
lines = self.target._reannotate_fulltext(self.source, lines,
886
new_version_id, new_version_idx)
887
elif 'line-delta' in options:
888
lines = self.target._reannotate_line_delta(self.source, lines,
889
new_version_id, new_version_idx)
892
pb.update(self.target.filename, count, len(version_list))
894
pos, size = self.target._data.add_record(version_id, digest, lines)
895
self.target._index.add_version(version_id, options, pos, size, parents)
897
for version in mismatched_versions:
898
n1 = set(self.target.get_parents(version))
899
n2 = set(self.source.get_parents(version))
900
# write a combined record to our history.
901
new_parents = self.target.get_parents(version) + list(n2.difference(n1))
902
current_values = self.target._index._cache[version]
903
self.target._index.add_version(version,
912
InterVersionedFile.register_optimiser(InterKnit)