156
156
def parse_fulltext(self, content, version):
157
"""Convert fulltext to internal representation
159
fulltext content is of the format
160
revid(utf8) plaintext\n
161
internal representation is of the format:
158
165
for line in content:
159
166
origin, text = line.split(' ', 1)
160
lines.append((int(origin), text))
167
lines.append((origin.decode('utf-8'), text))
161
168
return KnitContent(lines)
163
170
def parse_line_delta_iter(self, lines):
171
"""Convert a line based delta into internal representation.
173
line delta is in the form of:
174
intstart intend intcount
176
revid(utf8) newline\n
177
internal represnetation is
178
(start, end, count, [1..count tuples (revid, newline)])
165
181
header = lines.pop(0)
166
182
start, end, c = [int(n) for n in header.split(',')]
168
184
for i in range(c):
169
185
origin, text = lines.pop(0).split(' ', 1)
170
contents.append((int(origin), text))
186
contents.append((origin.decode('utf-8'), text))
171
187
yield start, end, c, contents
173
189
def parse_line_delta(self, lines, version):
174
190
return list(self.parse_line_delta_iter(lines))
176
192
def lower_fulltext(self, content):
177
return ['%d %s' % (o, t) for o, t in content._lines]
193
"""convert a fulltext content record into a serializable form.
195
see parse_fulltext which this inverts.
197
return ['%s %s' % (o.encode('utf-8'), t) for o, t in content._lines]
179
199
def lower_line_delta(self, delta):
200
"""convert a delta into a serializable form.
202
See parse_line_delta_iter which this inverts.
181
205
for start, end, c, lines in delta:
182
206
out.append('%d,%d,%d\n' % (start, end, c))
183
207
for origin, text in lines:
184
out.append('%d %s' % (origin, text))
208
out.append('%s %s' % (origin.encode('utf-8'), text))
191
215
annotated = False
193
217
def parse_fulltext(self, content, version):
218
"""This parses an unannotated fulltext.
220
Note that this is not a noop - the internal representation
221
has (versionid, line) - its just a constant versionid.
194
223
return self.make(content, version)
196
225
def parse_line_delta_iter(self, lines, version):
483
512
options.append('no-eol')
484
513
lines[-1] = lines[-1] + '\n'
486
lines = self.factory.make(lines, len(self._index))
515
lines = self.factory.make(lines, version_id) #len(self._index))
487
516
if self.factory.annotated and len(ghostless_parents) > 0:
488
517
# Merge annotations from parent texts if so is needed.
489
518
self._merge_annotations(lines, ghostless_parents)
587
616
"""See VersionedFile.annotate_iter."""
588
617
content = self._get_content(version_id)
589
618
for origin, text in content.annotate_iter():
590
yield self._index.idx_to_name(origin), text
592
621
def get_parents(self, version_id):
593
622
"""See VersionedFile.get_parents."""
617
646
self._check_versions_present(versions)
618
647
return self._index.get_ancestry_with_ghosts(versions)
620
def _reannotate_line_delta(self, other, lines, new_version_id,
622
"""Re-annotate line-delta and return new delta."""
624
for start, end, count, contents \
625
in self.factory.parse_line_delta_iter(lines):
627
for origin, line in contents:
628
old_version_id = other._index.idx_to_name(origin)
629
if old_version_id == new_version_id:
630
idx = new_version_idx
632
idx = self._index.lookup(old_version_id)
633
new_lines.append((idx, line))
634
new_delta.append((start, end, count, new_lines))
636
return self.factory.lower_line_delta(new_delta)
638
def _reannotate_fulltext(self, other, lines, new_version_id,
640
"""Re-annotate fulltext and return new version."""
641
content = self.factory.parse_fulltext(lines, new_version_idx)
643
for origin, line in content.annotate_iter():
644
old_version_id = other._index.idx_to_name(origin)
645
if old_version_id == new_version_id:
646
idx = new_version_idx
648
idx = self._index.lookup(old_version_id)
649
new_lines.append((idx, line))
651
return self.factory.lower_fulltext(KnitContent(new_lines))
653
649
#@deprecated_method(zero_eight)
654
650
def walk(self, version_ids):
655
651
"""See VersionedFile.walk."""
1091
1087
assert (self.target.has_version(parent) or not
1092
1088
self.source.has_version(parent))
1094
if self.target.factory.annotated:
1095
# FIXME jrydberg: it should be possible to skip
1096
# re-annotating components if we know that we are
1097
# going to pull all revisions in the same order.
1098
new_version_id = version_id
1099
new_version_idx = self.target._index.num_versions()
1100
if 'fulltext' in options:
1101
lines = self.target._reannotate_fulltext(self.source, lines,
1102
new_version_id, new_version_idx)
1103
elif 'line-delta' in options:
1104
lines = self.target._reannotate_line_delta(self.source, lines,
1105
new_version_id, new_version_idx)
1107
1090
count = count + 1
1108
1091
pb.update("Joining knit", count, len(version_list))