##// 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 return _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels)
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 def _imergeauto(
562 def _imergeauto(
536 repo,
563 repo,
537 mynode,
564 mynode,
@@ -455,6 +455,68 b' def is_not_null(ctx):'
455 return ctx.node() != nodemod.nullid
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 def simplemerge(ui, localctx, basectx, otherctx, **opts):
520 def simplemerge(ui, localctx, basectx, otherctx, **opts):
459 """Performs the simplemerge algorithm.
521 """Performs the simplemerge algorithm.
460
522
@@ -499,9 +561,15 b' def simplemerge(ui, localctx, basectx, o'
499 extrakwargs[b'name_base'] = name_base
561 extrakwargs[b'name_base'] = name_base
500 extrakwargs[b'minimize'] = False
562 extrakwargs[b'minimize'] = False
501
563
502 lines = m3.merge_lines(
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(
503 name_a=name_a, name_b=name_b, **pycompat.strkwargs(extrakwargs)
569 name_a=name_a, name_b=name_b, **pycompat.strkwargs(extrakwargs)
504 )
570 )
571 )
572 conflicts = m3.conflicts
505
573
506 # merge flags if necessary
574 # merge flags if necessary
507 flags = localctx.flags()
575 flags = localctx.flags()
@@ -519,5 +587,5 b' def simplemerge(ui, localctx, basectx, o'
519 else:
587 else:
520 localctx.write(mergedtext, flags)
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 return 1
591 return 1
@@ -27,6 +27,13 b''
27 * The memory footprint per changeset during pull/unbundle
27 * The memory footprint per changeset during pull/unbundle
28 operations has been further reduced.
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 == New Experimental Features ==
38 == New Experimental Features ==
32
39
@@ -282,6 +282,80 b' internal:merge3'
282 >>>>>>> merge rev
282 >>>>>>> merge rev
283 Hop we are done.
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 Add some unconflicting changes on each head, to make sure we really
359 Add some unconflicting changes on each head, to make sure we really
286 are merging, unlike :local and :other
360 are merging, unlike :local and :other
287
361
@@ -2057,6 +2057,13 b' Test dynamic list of merge tools only sh'
2057 partially merged file. Marker will have three sections, one from each
2057 partially merged file. Marker will have three sections, one from each
2058 side of the merge and one for the base content.
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 ":other"
2067 ":other"
2061 Uses the other 'p2()' version of files as the merged version.
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