[PATCH] revset: add "similar" keyword

Angel Ezquerra angel.ezquerra at gmail.com
Sun Apr 1 12:21:36 UTC 2012


# HG changeset patch
# User Angel Ezquerra <angel.ezquerra at gmail.com>
# Date 1333282334 -7200
# Node ID 5027b86b02e8285493fb359367dc36f3cf481688
# Parent  b3fefbb95aad2a9b5b8e44e6fea4860d6690368b
revset: add "similar" keyword

This keyword can be used to find revisions that are "similar" to a given
revision.

A revision is similar to another if one of its fields (description, author,
files or parents) matches the corresponding value of that field on the source
revision.

By default this keyword looks for revisions that have a similar description.

Similar takes 2 arguments (the second being optional):

1.- rev: a revset represeting a _single_ revision (e.g. tip, ., p1(.), etc)
2.- [field]: an optional field to match.
  By default similar will match the description field.

Examples:

1.- Look for revisions with the same metadata (author, description and date)
as the 11th revision:

hg log -r "similar(11)"

2.- Look for revisions with the same description as the 11th revision:

hg log -r "similar(11, description)"

You do not need to type the whole 'description' word. You could also use
'descript' or 'desc' or even 'd'.

3.- Look for revisions with the same author as the current revision:

hg log -r "similar(., author)"

You could use 'user' rather than 'author' to get the same result.

4.- Look for revisions touching the same files as the the tip of the repository

hg log -r "similar(tip, files)"

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -858,6 +858,64 @@
         raise error.ParseError(_("rev expects a number"))
     return [r for r in subset if r == l]
 
+def similar(repo, subset, x):
+    """``similar(revision, field)``
+    Changesets in which a given field is the same as in the
+    selected revision.
+    Valid fields are:
+    description, author, branch, date, files, phase,
+    parents and metadata.
+    metatadata is the default. It is an special field
+    that instructs the function to look for revisions
+    matching the description, the author and the date.
+    """
+    l = getargs(x, 1, 2, _("similar takes 1 or 2 arguments"))
+
+    s = getset(repo, xrange(len(repo)), l[0])
+    if len(s) > 1:
+        raise error.ParseError(_(
+            "similar takes a single revision "
+            "as its first argument (you passed %d)") % len(s))
+    rev = s[0]
+
+    info = 'metadata'
+    if len(l) > 1:
+        info = getstring(l[1],
+            _("similar requires a string as its second argument"))
+    # the field name does not need to be complete
+    # (e.g. 'd', 'desc' and 'description' all match the decription field)
+    def matchopt(opt, value):
+        return opt.startswith(value)
+    def matchoptlist(optlist, value):
+        for opt in optlist:
+            if matchopt(opt, value):
+                return True
+        return False
+
+    if matchopt('metadata', info):
+        def getinfo(r):
+            return (repo[r].user(), repo[r].description(), repo[r].date())
+    elif matchopt('description', info):
+        getinfo = lambda r: repo[r].description()
+    elif matchoptlist(('user', 'author'), info):
+        getinfo = lambda r: repo[r].user()
+    elif matchopt('branch', info):
+        getinfo = lambda r: repo[r].branch()
+    elif matchopt('date', info):
+        getinfo = lambda r: repo[r].date()
+    elif matchopt('files', info):
+        getinfo = lambda r: repo[r].files()
+    elif matchopt('phase', info):
+        getinfo = lambda r: repo[r].phase()
+    elif matchopt('parents', info):
+        getinfo = lambda r: repo[r].parents()
+    else:
+        raise error.ParseError(
+            _("unexpected field type passed to similar: %d") % info)
+    target = getinfo(rev)
+
+    return [r for r in subset if getinfo(r) == target]
+
 def reverse(repo, subset, x):
     """``reverse(set)``
     Reverse order of set.
@@ -1019,6 +1077,7 @@
     "roots": roots,
     "sort": sort,
     "secret": secret,
+    "similar": similar,
     "tag": tag,
     "tagged": tagged,
     "user": user,



More information about the Mercurial-devel mailing list