168
168
the SequenceMatcher.get_matching_blocks format.
170
170
if len(parents_lines) == 0:
171
for line in new_lines:
172
yield new_revision_id, line
171
lines = [(new_revision_id, line) for line in new_lines]
173
172
elif len(parents_lines) == 1:
174
for data in _reannotate(parents_lines[0], new_lines, new_revision_id,
175
_left_matching_blocks):
173
lines = _reannotate(parents_lines[0], new_lines, new_revision_id,
174
_left_matching_blocks)
175
elif len(parents_lines) == 2:
176
left = _reannotate(parents_lines[0], new_lines, new_revision_id,
177
_left_matching_blocks)
178
right = _reannotate(parents_lines[1], new_lines, new_revision_id)
180
for idx in xrange(len(new_lines)):
181
if left[idx][0] == right[idx][0]:
182
# The annotations match, just return the left one
183
lines.append(left[idx])
184
elif left[idx][0] == new_revision_id:
185
# The left parent claims a new value, return the right one
186
lines.append(right[idx])
187
elif right[idx][0] == new_revision_id:
188
# The right parent claims a new value, return the left one
189
lines.append(left[idx])
191
# Both claim different origins
192
lines.append((new_revision_id, left[idx][1]))
178
block_list = [_left_matching_blocks] + [None] * len(parents_lines)
179
reannotations = [list(_reannotate(p, new_lines, new_revision_id, b))
180
for p, b in zip(parents_lines, block_list)]
194
reannotations = [_reannotate(parents_lines[0], new_lines,
195
new_revision_id, _left_matching_blocks)]
196
reannotations.extend(_reannotate(p, new_lines, new_revision_id)
197
for p in parents_lines[1:])
181
199
for annos in zip(*reannotations):
182
200
origins = set(a for a, l in annos)
184
201
if len(origins) == 1:
185
yield iter(origins).next(), line
186
elif len(origins) == 2 and new_revision_id in origins:
187
yield (x for x in origins if x != new_revision_id).next(), line
202
# All the parents agree, so just return the first one
203
lines.append(annos[0])
189
yield new_revision_id, line
206
if len(origins) == 2 and new_revision_id in origins:
207
origins.remove(new_revision_id)
208
if len(origins) == 1:
209
lines.append((origins.pop(), line))
211
lines.append((new_revision_id, line))
192
215
def _reannotate(parent_lines, new_lines, new_revision_id,
197
220
matcher = patiencediff.PatienceSequenceMatcher(None,
198
221
plain_parent_lines, new_lines)
199
222
matching_blocks = matcher.get_matching_blocks()
200
224
for i, j, n in matching_blocks:
201
225
for line in new_lines[new_cur:j]:
202
yield new_revision_id, line
203
for data in parent_lines[i:i+n]:
226
lines.append((new_revision_id, line))
227
lines.extend(parent_lines[i:i+n])