##// END OF EJS Templates
mergetools: add new conflict marker format with diffs in...
Martin von Zweigbergk -
r46724:bdc2bf68 default
parent child Browse files
Show More
@@ -532,6 +532,33 b' def _imerge3(repo, mynode, orig, fcd, fc'
532 532 return _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels)
533 533
534 534
535 @internaltool(
536 b'mergediff',
537 fullmerge,
538 _(
539 b"warning: conflicts while merging %s! "
540 b"(edit, then use 'hg resolve --mark')\n"
541 ),
542 precheck=_mergecheck,
543 )
544 def _imerge_diff(
545 repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None
546 ):
547 """
548 Uses the internal non-interactive simple merge algorithm for merging
549 files. It will fail if there are any conflicts and leave markers in
550 the partially merged file. The marker will have two sections, one with the
551 content from one side of the merge, and one with a diff from the base
552 content to the content on the other side. (experimental)"""
553 if not labels:
554 labels = _defaultconflictlabels
555 if len(labels) < 3:
556 labels.append(b'base')
557 return _merge(
558 repo, mynode, orig, fcd, fco, fca, toolconf, files, labels, b'mergediff'
559 )
560
561
535 562 def _imergeauto(
536 563 repo,
537 564 mynode,
@@ -455,6 +455,68 b' def is_not_null(ctx):'
455 455 return ctx.node() != nodemod.nullid
456 456
457 457
458 def _mergediff(m3, name_a, name_b, name_base):
459 lines = []
460 conflicts = False
461 for group in m3.merge_groups():
462 if group[0] == b'conflict':
463 base_lines, a_lines, b_lines = group[1:]
464 base_text = b''.join(base_lines)
465 b_blocks = list(
466 mdiff.allblocks(
467 base_text,
468 b''.join(b_lines),
469 lines1=base_lines,
470 lines2=b_lines,
471 )
472 )
473 a_blocks = list(
474 mdiff.allblocks(
475 base_text,
476 b''.join(a_lines),
477 lines1=base_lines,
478 lines2=b_lines,
479 )
480 )
481
482 def matching_lines(blocks):
483 return sum(
484 block[1] - block[0]
485 for block, kind in blocks
486 if kind == b'='
487 )
488
489 def diff_lines(blocks, lines1, lines2):
490 for block, kind in blocks:
491 if kind == b'=':
492 for line in lines1[block[0] : block[1]]:
493 yield b' ' + line
494 else:
495 for line in lines1[block[0] : block[1]]:
496 yield b'-' + line
497 for line in lines2[block[2] : block[3]]:
498 yield b'+' + line
499
500 lines.append(b"<<<<<<<\n")
501 if matching_lines(a_blocks) < matching_lines(b_blocks):
502 lines.append(b"======= %s\n" % name_a)
503 lines.extend(a_lines)
504 lines.append(b"------- %s\n" % name_base)
505 lines.append(b"+++++++ %s\n" % name_b)
506 lines.extend(diff_lines(b_blocks, base_lines, b_lines))
507 else:
508 lines.append(b"------- %s\n" % name_base)
509 lines.append(b"+++++++ %s\n" % name_a)
510 lines.extend(diff_lines(a_blocks, base_lines, a_lines))
511 lines.append(b"======= %s\n" % name_b)
512 lines.extend(b_lines)
513 lines.append(b">>>>>>>\n")
514 conflicts = True
515 else:
516 lines.extend(group[1])
517 return lines, conflicts
518
519
458 520 def simplemerge(ui, localctx, basectx, otherctx, **opts):
459 521 """Performs the simplemerge algorithm.
460 522
@@ -499,9 +561,15 b' def simplemerge(ui, localctx, basectx, o'
499 561 extrakwargs[b'name_base'] = name_base
500 562 extrakwargs[b'minimize'] = False
501 563
502 lines = m3.merge_lines(
503 name_a=name_a, name_b=name_b, **pycompat.strkwargs(extrakwargs)
504 )
564 if mode == b'mergediff':
565 lines, conflicts = _mergediff(m3, name_a, name_b, name_base)
566 else:
567 lines = list(
568 m3.merge_lines(
569 name_a=name_a, name_b=name_b, **pycompat.strkwargs(extrakwargs)
570 )
571 )
572 conflicts = m3.conflicts
505 573
506 574 # merge flags if necessary
507 575 flags = localctx.flags()
@@ -519,5 +587,5 b' def simplemerge(ui, localctx, basectx, o'
519 587 else:
520 588 localctx.write(mergedtext, flags)
521 589
522 if m3.conflicts and not mode == b'union':
590 if conflicts and not mode == b'union':
523 591 return 1
@@ -27,6 +27,13 b''
27 27 * The memory footprint per changeset during pull/unbundle
28 28 operations has been further reduced.
29 29
30 * There is a new internal merge tool called `internal:mergediff` (can
31 be set as the value for the `merge` config in the `[ui]`
32 section). It resolves merges the same was as `internal:merge` and
33 `internal:merge3`, but it shows conflicts differently. Instead of
34 showing 2 or 3 snapshots of the conflicting pieces of code, it
35 shows one snapshot and a diff. This may be useful when at least one
36 side of the conflict is similar to the base.
30 37
31 38 == New Experimental Features ==
32 39
@@ -282,6 +282,80 b' internal:merge3'
282 282 >>>>>>> merge rev
283 283 Hop we are done.
284 284
285 internal:mergediff
286
287 $ hg co -C 1
288 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
289 $ cat << EOF > a
290 > Small Mathematical Series.
291 > 1
292 > 2
293 > 3
294 > 4
295 > 4.5
296 > 5
297 > Hop we are done.
298 > EOF
299 $ hg co -m 2 -t internal:mergediff
300 merging a
301 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
302 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
303 use 'hg resolve' to retry unresolved file merges
304 [1]
305 $ cat a
306 Small Mathematical Series.
307 1
308 2
309 3
310 <<<<<<<
311 ------- base
312 +++++++ working copy
313 4
314 +4.5
315 5
316 ======= destination
317 6
318 8
319 >>>>>>>
320 Hop we are done.
321 Test the same thing as above but modify a bit more so we instead get the working
322 copy in full and the diff from base to destination.
323 $ hg co -C 1
324 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
325 $ cat << EOF > a
326 > Small Mathematical Series.
327 > 1
328 > 2
329 > 3.5
330 > 4.5
331 > 5.5
332 > Hop we are done.
333 > EOF
334 $ hg co -m 2 -t internal:mergediff
335 merging a
336 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
337 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
338 use 'hg resolve' to retry unresolved file merges
339 [1]
340 $ cat a
341 Small Mathematical Series.
342 1
343 2
344 <<<<<<<
345 ======= working copy
346 3.5
347 4.5
348 5.5
349 ------- base
350 +++++++ destination
351 3
352 -4
353 -5
354 +6
355 +8
356 >>>>>>>
357 Hop we are done.
358
285 359 Add some unconflicting changes on each head, to make sure we really
286 360 are merging, unlike :local and :other
287 361
@@ -2057,6 +2057,13 b' Test dynamic list of merge tools only sh'
2057 2057 partially merged file. Marker will have three sections, one from each
2058 2058 side of the merge and one for the base content.
2059 2059
2060 ":mergediff"
2061 Uses the internal non-interactive simple merge algorithm for merging
2062 files. It will fail if there are any conflicts and leave markers in the
2063 partially merged file. The marker will have two sections, one with the
2064 content from one side of the merge, and one with a diff from the base
2065 content to the content on the other side. (experimental)
2066
2060 2067 ":other"
2061 2068 Uses the other 'p2()' version of files as the merged version.
2062 2069
General Comments 0
You need to be logged in to leave comments. Login now