37
37
from cStringIO import StringIO
39
39
from bzrlib.inter import InterObject
40
from bzrlib.registry import Registry
40
41
from bzrlib.symbol_versioning import *
41
42
from bzrlib.textmerge import TextMerge
45
adapter_registry = Registry()
46
adapter_registry.register_lazy(('knit-delta-gz', 'fulltext'), 'bzrlib.knit',
47
'DeltaPlainToFullText')
48
adapter_registry.register_lazy(('knit-ft-gz', 'fulltext'), 'bzrlib.knit',
50
adapter_registry.register_lazy(('knit-annotated-delta-gz', 'knit-delta-gz'),
51
'bzrlib.knit', 'DeltaAnnotatedToUnannotated')
52
adapter_registry.register_lazy(('knit-annotated-delta-gz', 'fulltext'),
53
'bzrlib.knit', 'DeltaAnnotatedToFullText')
54
adapter_registry.register_lazy(('knit-annotated-ft-gz', 'knit-ft-gz'),
55
'bzrlib.knit', 'FTAnnotatedToUnannotated')
56
adapter_registry.register_lazy(('knit-annotated-ft-gz', 'fulltext'),
57
'bzrlib.knit', 'FTAnnotatedToFullText')
60
class ContentFactory(object):
61
"""Abstract interface for insertion and retrieval from a VersionedFile.
63
:ivar sha1: None, or the sha1 of the content fulltext.
64
:ivar storage_kind: The native storage kind of this factory. One of
65
'mpdiff', 'knit-annotated-ft', 'knit-annotated-delta', 'knit-ft',
66
'knit-delta', 'fulltext', 'knit-annotated-ft-gz',
67
'knit-annotated-delta-gz', 'knit-ft-gz', 'knit-delta-gz'.
68
:ivar key: The key of this content. Each key is a tuple with a single
70
:ivar parents: A tuple of parent keys for self.key. If the object has
71
no parent information, None (as opposed to () for an empty list of
76
"""Create a ContentFactory."""
78
self.storage_kind = None
83
class AbsentContentFactory(object):
84
"""A placeholder content factory for unavailable texts.
87
:ivar storage_kind: 'absent'.
88
:ivar key: The key of this content. Each key is a tuple with a single
93
def __init__(self, key):
94
"""Create a ContentFactory."""
96
self.storage_kind = 'absent'
101
def filter_absent(record_stream):
102
"""Adapt a record stream to remove absent records."""
103
for record in record_stream:
104
if record.storage_kind != 'absent':
44
108
class VersionedFile(object):
45
109
"""Versioned text file storage.
63
127
"""Copy this versioned file to name on transport."""
64
128
raise NotImplementedError(self.copy_to)
67
"""Return a unsorted list of versions."""
68
raise NotImplementedError(self.versions)
130
def get_record_stream(self, versions, ordering, include_delta_closure):
131
"""Get a stream of records for versions.
133
:param versions: The versions to include. Each version is a tuple
135
:param ordering: Either 'unordered' or 'topological'. A topologically
136
sorted stream has compression parents strictly before their
138
:param include_delta_closure: If True then the closure across any
139
compression parents will be included (in the data content of the
140
stream, not in the emitted records). This guarantees that
141
'fulltext' can be used successfully on every record.
142
:return: An iterator of ContentFactory objects, each of which is only
143
valid until the iterator is advanced.
145
raise NotImplementedError(self.get_record_stream)
70
147
@deprecated_method(one_four)
71
148
def has_ghost(self, version_id):
76
153
"""Returns whether version is present."""
77
154
raise NotImplementedError(self.has_version)
156
def insert_record_stream(self, stream):
157
"""Insert a record stream into this versioned file.
159
:param stream: A stream of records to insert.
161
:seealso VersionedFile.get_record_stream:
163
raise NotImplementedError
79
165
def add_lines(self, version_id, parents, lines, parent_texts=None,
80
166
left_matching_blocks=None, nostore_sha=None, random_id=False,
81
167
check_content=True):
519
606
return PlanWeaveMerge(plan, a_marker, b_marker).merge_lines()[0]
609
class RecordingVersionedFileDecorator(object):
610
"""A minimal versioned file that records calls made on it.
612
Only enough methods have been added to support tests using it to date.
614
:ivar calls: A list of the calls made; can be reset at any time by
618
def __init__(self, backing_vf):
619
"""Create a RecordingVersionedFileDecorator decorating backing_vf.
621
:param backing_vf: The versioned file to answer all methods.
623
self._backing_vf = backing_vf
626
def get_lines(self, version_ids):
627
self.calls.append(("get_lines", version_ids))
628
return self._backing_vf.get_lines(version_ids)
522
631
class _PlanMergeVersionedFile(object):
523
632
"""A VersionedFile for uncommitted and committed texts.