562
563
(None, current_values[2], current_values[3]),
566
def get_data_stream(self, required_versions):
567
"""Get a data stream for the specified versions.
569
Versions may be returned in any order, not necessarily the order
572
:param required_versions: The exact set of versions to be extracted.
573
Unlike some other knit methods, this is not used to generate a
574
transitive closure, rather it is used precisely as given.
576
:returns: format_signature, list of (version, options, length, parents),
579
required_versions = set([osutils.safe_revision_id(v) for v in
581
# we don't care about inclusions, the caller cares.
582
# but we need to setup a list of records to visit.
583
for version_id in required_versions:
584
if not self.has_version(version_id):
585
raise RevisionNotPresent(version_id, self.filename)
586
# Pick the desired versions out of the index in oldest-to-newest order
588
for version_id in self.versions():
589
if version_id in required_versions:
590
version_list.append(version_id)
592
# create the list of version information for the result
593
copy_queue_records = []
595
result_version_list = []
596
for version_id in version_list:
597
options = self._index.get_options(version_id)
598
parents = self._index.get_parents_with_ghosts(version_id)
599
index_memo = self._index.get_position(version_id)
600
copy_queue_records.append((version_id, index_memo))
601
none, data_pos, data_size = index_memo
602
copy_set.add(version_id)
603
# version, options, length, parents
604
result_version_list.append((version_id, options, data_size,
607
# Read the compressed record data.
609
# From here down to the return should really be logic in the returned
610
# callable -- in a class that adapts read_records_iter_raw to read
613
for (version_id, raw_data), \
614
(version_id2, options, _, parents) in \
615
izip(self._data.read_records_iter_raw(copy_queue_records),
616
result_version_list):
617
assert version_id == version_id2, 'logic error, inconsistent results'
618
raw_datum.append(raw_data)
619
pseudo_file = StringIO(''.join(raw_datum))
622
return pseudo_file.read()
624
return pseudo_file.read(length)
625
return (self.get_format_signature(), result_version_list, read)
565
627
def _extract_blocks(self, version_id, source, target):
566
628
if self._index.get_method(version_id) != 'line-delta':
597
659
delta = self.factory.parse_line_delta(data, version_id)
598
660
return parent, sha1, noeol, delta
662
def get_format_signature(self):
663
"""See VersionedFile.get_format_signature()."""
664
if self.factory.annotated:
665
annotated_part = "annotated"
667
annotated_part = "plain"
668
return "knit-%s" % (annotated_part,)
600
670
def get_graph_with_ghosts(self):
601
671
"""See VersionedFile.get_graph_with_ghosts()."""
705
def insert_data_stream(self, (format, data_list, reader_callable)):
706
"""Insert knit records from a data stream into this knit.
708
If a version in the stream is already present in this knit, it will not
709
be inserted a second time. It will be checked for consistency with the
710
stored version however, and may cause a KnitCorrupt error to be raised
711
if the data in the stream disagrees with the already stored data.
713
:seealso: get_data_stream
715
if format != self.get_format_signature():
716
trace.mutter('incompatible format signature inserting to %r', self)
717
raise KnitDataStreamIncompatible(
718
format, self.get_format_signature())
720
for version_id, options, length, parents in data_list:
721
if self.has_version(version_id):
722
# First check: the list of parents.
723
my_parents = self.get_parents_with_ghosts(version_id)
724
if my_parents != parents:
725
# XXX: KnitCorrupt is not quite the right exception here.
728
'parents list %r from data stream does not match '
729
'already recorded parents %r for %s'
730
% (parents, my_parents, version_id))
732
# Also check the SHA-1 of the fulltext this content will
734
raw_data = reader_callable(length)
735
my_fulltext_sha1 = self.get_sha1(version_id)
736
df, rec = self._data._parse_record_header(version_id, raw_data)
737
stream_fulltext_sha1 = rec[3]
738
if my_fulltext_sha1 != stream_fulltext_sha1:
739
# Actually, we don't know if it's this knit that's corrupt,
740
# or the data stream we're trying to insert.
742
self.filename, 'sha-1 does not match %s' % version_id)
744
self._add_raw_records(
745
[(version_id, options, parents, length)],
746
reader_callable(length))
635
748
def versions(self):
636
749
"""See VersionedFile.versions."""
637
750
if 'evil' in debug.debug_flags: