137
137
yield (revno_str, author, date_str, origin, text)
140
def reannotate(parents_lines, new_lines, new_revision_id):
140
def reannotate(parents_lines, new_lines, new_revision_id,
141
_left_matching_blocks=None):
141
142
"""Create a new annotated version from new lines and parent annotations.
143
144
:param parents_lines: List of annotated lines for all parents
144
145
:param new_lines: The un-annotated new lines
145
146
:param new_revision_id: The revision-id to associate with new lines
146
147
(will often be CURRENT_REVISION)
148
:param left_matching_blocks: a hint about which areas are common
149
between the text and its left-hand-parent. The format is
150
the SequenceMatcher.get_matching_blocks format.
148
if len(parents_lines) == 1:
149
for data in _reannotate(parents_lines[0], new_lines, new_revision_id):
152
if len(parents_lines) == 0:
153
for line in new_lines:
154
yield new_revision_id, line
155
elif len(parents_lines) == 1:
156
for data in _reannotate(parents_lines[0], new_lines, new_revision_id,
157
_left_matching_blocks):
152
reannotations = [list(_reannotate(p, new_lines, new_revision_id)) for
160
block_list = [_left_matching_blocks] + [None] * len(parents_lines)
161
reannotations = [list(_reannotate(p, new_lines, new_revision_id, b))
162
for p, b in zip(parents_lines, block_list)]
154
163
for annos in zip(*reannotations):
155
164
origins = set(a for a, l in annos)
156
165
line = annos[0][1]
162
171
yield new_revision_id, line
165
def _reannotate(parent_lines, new_lines, new_revision_id):
174
def _reannotate(parent_lines, new_lines, new_revision_id,
175
matching_blocks=None):
166
176
plain_parent_lines = [l for r, l in parent_lines]
167
177
matcher = patiencediff.PatienceSequenceMatcher(None, plain_parent_lines,
170
for i, j, n in matcher.get_matching_blocks():
180
if matching_blocks is None:
181
matching_blocks = matcher.get_matching_blocks()
182
for i, j, n in matching_blocks:
171
183
for line in new_lines[new_cur:j]:
172
184
yield new_revision_id, line
173
185
for data in parent_lines[i:i+n]: