Patchwork [3,of,4] merge: move default destination computation in a revset

login
register
mail settings
Submitter Pierre-Yves David
Date Sept. 21, 2015, 10:16 p.m.
Message ID <d515bf3d8e84ca73062b.1442873797@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/10559/
State Superseded
Headers show

Comments

Pierre-Yves David - Sept. 21, 2015, 10:16 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1442523795 25200
#      Thu Sep 17 14:03:15 2015 -0700
# Node ID d515bf3d8e84ca73062b078e2cbc35f5bba7e360
# Parent  9f0f1c86741d9fbc71e49f55ada02c47b0cec3ca
merge: move default destination computation in a revset

This is another step toward having "default" destination more clear and unified.
Yuya Nishihara - Sept. 22, 2015, 7:11 a.m.
On Mon, 21 Sep 2015 15:16:37 -0700, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1442523795 25200
> #      Thu Sep 17 14:03:15 2015 -0700
> # Node ID d515bf3d8e84ca73062b078e2cbc35f5bba7e360
> # Parent  9f0f1c86741d9fbc71e49f55ada02c47b0cec3ca
> merge: move default destination computation in a revset
> 
> This is another step toward having "default" destination more clear and unified.

> +def _mergedefaultdest(repo, subset, x):
> +    """``_mergedefaultdest()``
> +
> +    default destination for merge.
> +    # XXX: Currently private because I expect the signature to change.
> +    # XXX: - taking rev as arguments,
> +    # XXX: - bailing out in case of ambiguity vs returning all data.
> +    """

The docstring makes it appear in the revset help. We have to comment out it
or fix the help function to exclude private functions.

> +    return baseset([repo[node].rev()])

Missing "subset &" ?
_rebasedefaultdest() has it, but _mergedefaultdest() and _updatedefaultdest()
don't.
Pierre-Yves David - Sept. 22, 2015, 7:32 a.m.
On 09/22/2015 12:11 AM, Yuya Nishihara wrote:
> On Mon, 21 Sep 2015 15:16:37 -0700, Pierre-Yves David wrote:
>> # HG changeset patch
>> # User Pierre-Yves David <pierre-yves.david@fb.com>
>> # Date 1442523795 25200
>> #      Thu Sep 17 14:03:15 2015 -0700
>> # Node ID d515bf3d8e84ca73062b078e2cbc35f5bba7e360
>> # Parent  9f0f1c86741d9fbc71e49f55ada02c47b0cec3ca
>> merge: move default destination computation in a revset
>>
>> This is another step toward having "default" destination more clear and unified.
>
>> +def _mergedefaultdest(repo, subset, x):
>> +    """``_mergedefaultdest()``
>> +
>> +    default destination for merge.
>> +    # XXX: Currently private because I expect the signature to change.
>> +    # XXX: - taking rev as arguments,
>> +    # XXX: - bailing out in case of ambiguity vs returning all data.
>> +    """
>
> The docstring makes it appear in the revset help. We have to comment out it
> or fix the help function to exclude private functions.

God point, I'll use # comment instead

>
>> +    return baseset([repo[node].rev()])
>
> Missing "subset &" ?
> _rebasedefaultdest() has it, but _mergedefaultdest() and _updatedefaultdest()
> don't.

Urg, perfect catch, sending a V2, shortly.

Patch

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4766,62 +4766,12 @@  def merge(ui, repo, node=None, **opts):
         node = opts.get('rev')
 
     if node:
         node = scmutil.revsingle(repo, node).node()
 
-    if not node and repo._activebookmark:
-        bmheads = repo.bookmarkheads(repo._activebookmark)
-        curhead = repo[repo._activebookmark].node()
-        if len(bmheads) == 2:
-            if curhead == bmheads[0]:
-                node = bmheads[1]
-            else:
-                node = bmheads[0]
-        elif len(bmheads) > 2:
-            raise util.Abort(_("multiple matching bookmarks to merge - "
-                "please merge with an explicit rev or bookmark"),
-                hint=_("run 'hg heads' to see all heads"))
-        elif len(bmheads) <= 1:
-            raise util.Abort(_("no matching bookmark to merge - "
-                "please merge with an explicit rev or bookmark"),
-                hint=_("run 'hg heads' to see all heads"))
-
-    elif not node:
-        branch = repo[None].branch()
-        bheads = repo.branchheads(branch)
-        nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
-
-        if len(nbhs) > 2:
-            raise util.Abort(_("branch '%s' has %d heads - "
-                               "please merge with an explicit rev")
-                             % (branch, len(bheads)),
-                             hint=_("run 'hg heads .' to see heads"))
-
-        parent = repo.dirstate.p1()
-        if len(nbhs) <= 1:
-            if len(bheads) > 1:
-                raise util.Abort(_("heads are bookmarked - "
-                                   "please merge with an explicit rev"),
-                                 hint=_("run 'hg heads' to see all heads"))
-            if len(repo.heads()) > 1:
-                raise util.Abort(_("branch '%s' has one head - "
-                                   "please merge with an explicit rev")
-                                 % branch,
-                                 hint=_("run 'hg heads' to see all heads"))
-            msg, hint = _('nothing to merge'), None
-            if parent != repo.lookup(branch):
-                hint = _("use 'hg update' instead")
-            raise util.Abort(msg, hint=hint)
-
-        if parent not in bheads:
-            raise util.Abort(_('working directory not at a head revision'),
-                             hint=_("use 'hg update' or merge with an "
-                                    "explicit revision"))
-        if parent == nbhs[0]:
-            node = nbhs[-1]
-        else:
-            node = nbhs[0]
+    if not node:
+        node = scmutil.revsingle(repo, '_mergedefaultdest()').node()
 
     if opts.get('preview'):
         # find nodes that are ancestors of p2 but not of p1
         p1 = repo.lookup('.')
         p2 = repo.lookup(node)
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -461,10 +461,72 @@  def func(repo, subset, a, b):
     syms = [s for (s, fn) in symbols.items() if keep(fn)]
     raise error.UnknownIdentifier(a[1], syms)
 
 # functions
 
+def _mergedefaultdest(repo, subset, x):
+    """``_mergedefaultdest()``
+
+    default destination for merge.
+    # XXX: Currently private because I expect the signature to change.
+    # XXX: - taking rev as arguments,
+    # XXX: - bailing out in case of ambiguity vs returning all data.
+    """
+    getargs(x, 0, 0, _("_mergedefaultdest takes no arguments"))
+    if repo._activebookmark:
+        bmheads = repo.bookmarkheads(repo._activebookmark)
+        curhead = repo[repo._activebookmark].node()
+        if len(bmheads) == 2:
+            if curhead == bmheads[0]:
+                node = bmheads[1]
+            else:
+                node = bmheads[0]
+        elif len(bmheads) > 2:
+            raise util.Abort(_("multiple matching bookmarks to merge - "
+                "please merge with an explicit rev or bookmark"),
+                hint=_("run 'hg heads' to see all heads"))
+        elif len(bmheads) <= 1:
+            raise util.Abort(_("no matching bookmark to merge - "
+                "please merge with an explicit rev or bookmark"),
+                hint=_("run 'hg heads' to see all heads"))
+    else:
+        branch = repo[None].branch()
+        bheads = repo.branchheads(branch)
+        nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
+
+        if len(nbhs) > 2:
+            raise util.Abort(_("branch '%s' has %d heads - "
+                               "please merge with an explicit rev")
+                             % (branch, len(bheads)),
+                             hint=_("run 'hg heads .' to see heads"))
+
+        parent = repo.dirstate.p1()
+        if len(nbhs) <= 1:
+            if len(bheads) > 1:
+                raise util.Abort(_("heads are bookmarked - "
+                                   "please merge with an explicit rev"),
+                                 hint=_("run 'hg heads' to see all heads"))
+            if len(repo.heads()) > 1:
+                raise util.Abort(_("branch '%s' has one head - "
+                                   "please merge with an explicit rev")
+                                 % branch,
+                                 hint=_("run 'hg heads' to see all heads"))
+            msg, hint = _('nothing to merge'), None
+            if parent != repo.lookup(branch):
+                hint = _("use 'hg update' instead")
+            raise util.Abort(msg, hint=hint)
+
+        if parent not in bheads:
+            raise util.Abort(_('working directory not at a head revision'),
+                             hint=_("use 'hg update' or merge with an "
+                                    "explicit revision"))
+        if parent == nbhs[0]:
+            node = nbhs[-1]
+        else:
+            node = nbhs[0]
+    return baseset([repo[node].rev()])
+
 def adds(repo, subset, x):
     """``adds(pattern)``
     Changesets that add a file matching pattern.
 
     The pattern without explicit kind like ``glob:`` is expected to be
@@ -2098,10 +2160,11 @@  def _hexlist(repo, subset, x):
     ls = [cl.rev(node.bin(r)) for r in s.split('\0')]
     s = subset
     return baseset([r for r in ls if r in s])
 
 symbols = {
+    "_mergedefaultdest": _mergedefaultdest,
     "adds": adds,
     "all": getall,
     "ancestor": ancestor,
     "ancestors": ancestors,
     "_firstancestors": _firstancestors,