Patchwork [6,of,6,V2] merge: add a internal:merge3 tools

login
register
mail settings
Submitter Pierre-Yves David
Date Aug. 5, 2014, 11:30 p.m.
Message ID <e1204f7bc5ed4568c6b3.1407281446@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/5273/
State Accepted
Headers show

Comments

Pierre-Yves David - Aug. 5, 2014, 11:30 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@ens-lyon.org>
# Date 1407275925 25200
#      Tue Aug 05 14:58:45 2014 -0700
# Node ID e1204f7bc5ed4568c6b3fd29dd637c1907bc6566
# Parent  0c3bb100f3a682832b1b44b97e3402d9e1963360
merge: add a internal:merge3 tools.

This variant gives access to a feature already present in ``internal:merge``:
displaying merge base content.

In the basic merge (calling ``hg merge``) case, including more context to the
merge markers is an interesting addition.

But this extra information is the only viable option in case conflict from
grafting (, rebase, etc…).

When grafting ``source`` on ``destination``, the parent of ``source`` is
used as the ``base``. When all three changesets add content in the same
location, the marker for ``source`` will contains both ``base`` and ``source``
content. Without the content of base exposed, there is no way for the user
to discriminate content coming from ``base`` and content commit from ``source``.

Practical example (all addition are in the same place):

* ``destination`` adds ``Dest-Content``
* ``base``        adds ``Base-Content``
* ``source``      adds ``Src-Content``

Grafting ``source`` on ``destination`` will produce the following conflict:

  <<<<<<< destination
  Dest-Content
  =======
  Base-Content
  Src-Content
  >>>>>>> source

This that case there is no way to distinct ``base`` from ``source``. As a result
content from ``base`` are likely to slip in the resolution result.

However, adding the base make the situation very clear:

  <<<<<<< destination
  Dest-Content
  ||||||| base
  Base-Content
  ======= base
  Base-Content
  Src-Content
  >>>>>>> source

Once the base is added, the addition from the grafted changeset is made clear.
User can compare the content from ``base`` and ``source`` to make an enlightened
decision during merge resolution.
Matt Mackall - Aug. 5, 2014, 11:41 p.m.
On Tue, 2014-08-05 at 16:30 -0700, pierre-yves.david@ens-lyon.org wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@ens-lyon.org>
> # Date 1407275925 25200
> #      Tue Aug 05 14:58:45 2014 -0700
> # Node ID e1204f7bc5ed4568c6b3fd29dd637c1907bc6566
> # Parent  0c3bb100f3a682832b1b44b97e3402d9e1963360
> merge: add a internal:merge3 tools.

These are queued for default, thanks.

Patch

diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
--- a/mercurial/filemerge.py
+++ b/mercurial/filemerge.py
@@ -221,10 +221,25 @@  def _imerge(repo, mynode, orig, fcd, fco
 
         r = simplemerge.simplemerge(ui, a, b, c, label=labels)
         return True, r
     return False, 0
 
+@internaltool('merge3', True,
+              _("merging %s incomplete! "
+                "(edit conflicts, then use 'hg resolve --mark')\n"))
+def _imerge3(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
+    """
+    Uses the internal non-interactive simple merge algorithm for merging
+    files. It will fail if there are any conflicts and leave markers in
+    the partially merged file. Marker will have three sections, one from each
+    side of the merge and one for the base content."""
+    if not labels:
+        labels = _defaultconflictlabels
+    if len(labels) < 3:
+        labels.append('base')
+    return _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels)
+
 @internaltool('tagmerge', True,
               _("automatic tag merging of %s failed! "
                 "(use 'hg resolve --tool internal:merge' or another merge "
                 "tool of your choice)\n"))
 def _itagmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
diff --git a/tests/test-conflict.t b/tests/test-conflict.t
--- a/tests/test-conflict.t
+++ b/tests/test-conflict.t
@@ -196,5 +196,39 @@  Verify basic conflict markers
   3
   4
   5
   >>>>>>> other
   Hop we are done.
+
+internal:merge3
+
+  $ hg up -q --clean .
+
+  $ hg merge 1 --tool internal:merge3
+  merging a
+  warning: conflicts during merge.
+  merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
+  [1]
+  $ cat a
+  Small Mathematical Series.
+  <<<<<<< local
+  1
+  2
+  3
+  6
+  8
+  ||||||| base
+  One
+  Two
+  Three
+  Four
+  Five
+  =======
+  1
+  2
+  3
+  4
+  5
+  >>>>>>> other
+  Hop we are done.