67
67
Given BASE, OTHER, THIS, tries to produce a combined text
68
68
incorporating the changes from both BASE->OTHER and BASE->THIS.
69
69
All three will typically be sequences of lines."""
70
def __init__(self, base, a, b):
70
def __init__(self, base, a, b, is_cherrypick=False):
71
71
check_text_lines(base)
72
72
check_text_lines(a)
73
73
check_text_lines(b)
77
self.is_cherrypick = is_cherrypick
80
79
def merge_lines(self,
251
241
if len_a or len_b:
252
242
# try to avoid actually slicing the lists
253
equal_a = compare_range(self.a, ia, amatch,
254
self.base, iz, zmatch)
255
equal_b = compare_range(self.b, ib, bmatch,
256
self.base, iz, zmatch)
257
243
same = compare_range(self.a, ia, amatch,
258
244
self.b, ib, bmatch)
261
247
yield 'same', ia, amatch
262
elif equal_a and not equal_b:
263
yield 'b', ib, bmatch
264
elif equal_b and not equal_a:
265
yield 'a', ia, amatch
266
elif not equal_a and not equal_b:
267
yield 'conflict', iz, zmatch, ia, amatch, ib, bmatch
269
raise AssertionError("can't handle a=b=base but unmatched")
249
equal_a = compare_range(self.a, ia, amatch,
250
self.base, iz, zmatch)
251
equal_b = compare_range(self.b, ib, bmatch,
252
self.base, iz, zmatch)
253
if equal_a and not equal_b:
254
yield 'b', ib, bmatch
255
elif equal_b and not equal_a:
256
yield 'a', ia, amatch
257
elif not equal_a and not equal_b:
258
if self.is_cherrypick:
259
for node in self._refine_cherrypick_conflict(
260
iz, zmatch, ia, amatch,
264
yield 'conflict', iz, zmatch, ia, amatch, ib, bmatch
266
raise AssertionError("can't handle a=b=base but unmatched")
285
def _refine_cherrypick_conflict(self, zstart, zend, astart, aend, bstart, bend):
286
"""When cherrypicking b => a, ignore matches with b and base."""
287
# Do not emit regions which match, only regions which do not match
288
matches = bzrlib.patiencediff.PatienceSequenceMatcher(None,
289
self.base[zstart:zend], self.b[bstart:bend]).get_matching_blocks()
293
for region_iz, region_ib, region_len in matches:
294
conflict_z_len = region_iz - zzcur
295
conflict_b_len = region_ib - bbcur
296
if conflict_b_len == 0: # There are no lines in b which conflict,
301
yield ('conflict', zstart + zzcur, zstart + region_iz,
302
aend, aend, bstart + bbcur, bstart + region_ib)
304
# The first conflict gets the a-range
306
yield ('conflict', zstart + zzcur, zstart + region_iz,
307
astart, aend, bstart + bbcur, bstart + region_ib)
308
zzcur = region_iz + region_len
309
bbcur = region_ib + region_len
310
if zzcur != zend - zstart or bbcur != bend - bstart:
312
yield ('conflict', zstart + zzcur, zstart + region_iz,
313
aend, aend, bstart + bbcur, bstart + region_ib)
315
# The first conflict gets the a-range
317
yield ('conflict', zstart + zzcur, zstart + region_iz,
318
astart, aend, bstart + bbcur, bstart + region_ib)
320
yield ('conflict', zstart, zend, astart, aend, bstart, bend)
290
322
def reprocess_merge_regions(self, merge_regions):
291
323
"""Where there are conflict regions, remove the agreed lines.
318
350
if reg is not None:
323
354
def mismatch_region(next_a, region_ia, next_b, region_ib):
324
355
if next_a < region_ia or next_b < region_ib:
325
356
return 'conflict', None, None, next_a, region_ia, next_b, region_ib
328
358
def find_sync_regions(self):
329
359
"""Return a list of sync regions, where both descendents match the base.