comparison mercurial/filemerge.py @ 46109:bdc2bf68f19e

mergetools: add new conflict marker format with diffs in I use 3-way conflict markers. Often when I resolve them, I manually compare one the base with one side and apply the differences to the other side. That can be hard when the conflict marker is large. This patch introduces a new type of conflict marker, which I'm hoping will make it easier to resolve conflicts. The new format uses `<<<<<<<` and `>>>>>>>` to open and close the markers, just like our existing 2-way and 3-way conflict markers. Instead of having 2 or 3 snapshots (left+right or left+base+right), it has a sequence of diffs. A diff looks like this: ``` ------- base +++++++ left a -b +c d ``` A diff that adds one side ("diff from nothing") has a `=======` header instead and does not have have `+` prefixed on its lines. A regular 3-way merge can be viewed as adding one side plus a diff between the base and the other side. It thus has two ways of being represented, depending on which side is being diffed: ``` <<<<<<< ======= left contents on left ------- base +++++++ right contents on -left +right >>>>>>> ``` or ``` <<<<<<< ------- base +++++++ left contents on -right +left ======= right contents on right >>>>>>> ``` I've made it so the new merge tool tries to pick a version that has the most common lines (no difference in the example above). I've called the new tool "mergediff" to stick to the convention of starting with "merge" if the tool tries a regular 3-way merge. The idea came from my pet VCS (placeholder name `jj`), which has support for octopus merges and other ways of ending up with merges of more than 3 versions. I wanted to be able to represent such conflicts in the working copy and therefore thought of this format (although I have not yet implemented it in my VCS). I then attended a meeting with Larry McVoy, who said BitKeeper has an option (`bk smerge -g`) for showing a similar format, which reminded me to actually attempt this in Mercurial. Differential Revision: https://phab.mercurial-scm.org/D9551
author Martin von Zweigbergk <martinvonz@google.com>
date Tue, 08 Dec 2020 16:45:13 -0800
parents 89a2afe31e82
children 3ca5ca380a34
comparison
equal deleted inserted replaced
46108:aa4dbc14f735 46109:bdc2bf68f19e
528 if not labels: 528 if not labels:
529 labels = _defaultconflictlabels 529 labels = _defaultconflictlabels
530 if len(labels) < 3: 530 if len(labels) < 3:
531 labels.append(b'base') 531 labels.append(b'base')
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
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 )
533 560
534 561
535 def _imergeauto( 562 def _imergeauto(
536 repo, 563 repo,
537 mynode, 564 mynode,