304 elif m3.a[0].endswith(b'\r'): |
304 elif m3.a[0].endswith(b'\r'): |
305 return b'\r' |
305 return b'\r' |
306 return b'\n' |
306 return b'\n' |
307 |
307 |
308 |
308 |
309 def _minimize(merge_groups): |
309 def _minimize(a_lines, b_lines): |
310 """Trim conflict regions of lines where A and B sides match. |
310 """Trim conflict regions of lines where A and B sides match. |
311 |
311 |
312 Lines where both A and B have made the same changes at the beginning |
312 Lines where both A and B have made the same changes at the beginning |
313 or the end of each merge region are eliminated from the conflict |
313 or the end of each merge region are eliminated from the conflict |
314 region and are instead considered the same. |
314 region and are instead considered the same. |
315 """ |
315 """ |
316 for what, lines in merge_groups: |
316 alen = len(a_lines) |
317 if what != b"conflict": |
317 blen = len(b_lines) |
318 yield what, lines |
318 |
319 continue |
319 # find matches at the front |
320 base_lines, a_lines, b_lines = lines |
320 ii = 0 |
321 alen = len(a_lines) |
321 while ii < alen and ii < blen and a_lines[ii] == b_lines[ii]: |
322 blen = len(b_lines) |
322 ii += 1 |
323 |
323 startmatches = ii |
324 # find matches at the front |
324 |
325 ii = 0 |
325 # find matches at the end |
326 while ii < alen and ii < blen and a_lines[ii] == b_lines[ii]: |
326 ii = 0 |
327 ii += 1 |
327 while ii < alen and ii < blen and a_lines[-ii - 1] == b_lines[-ii - 1]: |
328 startmatches = ii |
328 ii += 1 |
329 |
329 endmatches = ii |
330 # find matches at the end |
330 |
331 ii = 0 |
331 lines_before = a_lines[:startmatches] |
332 while ii < alen and ii < blen and a_lines[-ii - 1] == b_lines[-ii - 1]: |
332 new_a_lines = a_lines[startmatches : alen - endmatches] |
333 ii += 1 |
333 new_b_lines = b_lines[startmatches : blen - endmatches] |
334 endmatches = ii |
334 lines_after = a_lines[alen - endmatches :] |
335 |
335 return lines_before, new_a_lines, new_b_lines, lines_after |
336 if startmatches > 0: |
|
337 yield b'same', a_lines[:startmatches] |
|
338 |
|
339 yield ( |
|
340 b'conflict', |
|
341 ( |
|
342 base_lines, |
|
343 a_lines[startmatches : alen - endmatches], |
|
344 b_lines[startmatches : blen - endmatches], |
|
345 ), |
|
346 ) |
|
347 |
|
348 if endmatches > 0: |
|
349 yield b'same', a_lines[alen - endmatches :] |
|
350 |
336 |
351 |
337 |
352 def render_minimized( |
338 def render_minimized( |
353 m3, |
339 m3, |
354 name_a=None, |
340 name_a=None, |
363 if name_a: |
349 if name_a: |
364 start_marker = start_marker + b' ' + name_a |
350 start_marker = start_marker + b' ' + name_a |
365 if name_b: |
351 if name_b: |
366 end_marker = end_marker + b' ' + name_b |
352 end_marker = end_marker + b' ' + name_b |
367 merge_groups = m3.merge_groups() |
353 merge_groups = m3.merge_groups() |
368 merge_groups = _minimize(merge_groups) |
|
369 lines = [] |
354 lines = [] |
370 for what, group_lines in merge_groups: |
355 for what, group_lines in merge_groups: |
371 if what == b'conflict': |
356 if what == b'conflict': |
|
357 conflicts = True |
372 base_lines, a_lines, b_lines = group_lines |
358 base_lines, a_lines, b_lines = group_lines |
373 conflicts = True |
359 minimized = _minimize(a_lines, b_lines) |
|
360 lines_before, a_lines, b_lines, lines_after = minimized |
|
361 lines.extend(lines_before) |
374 lines.append(start_marker + newline) |
362 lines.append(start_marker + newline) |
375 lines.extend(a_lines) |
363 lines.extend(a_lines) |
376 lines.append(mid_marker + newline) |
364 lines.append(mid_marker + newline) |
377 lines.extend(b_lines) |
365 lines.extend(b_lines) |
378 lines.append(end_marker + newline) |
366 lines.append(end_marker + newline) |
|
367 lines.extend(lines_after) |
379 else: |
368 else: |
380 lines.extend(group_lines) |
369 lines.extend(group_lines) |
381 return lines, conflicts |
370 return lines, conflicts |
382 |
371 |
383 |
372 |