D5496: revset: add "samebranch" keyword argument to the merge revset

angel.ezquerra (Angel Ezquerra) phabricator at mercurial-scm.org
Sun Jan 6 19:03:46 UTC 2019


angel.ezquerra created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  By default all merges are shown but if "samebranch" is set to False then merges
  with the same branch (i.e. where both parents belong to the same branch) will
  be filtered out.
  
  Conversely, if "samebranch" is set to True then only merges with the same branch
  will be shown.
  
  This is useful to visualize at a high level the relationships between different
  branches and how they are merged with each other.
  
  With the addition of the merge(withbranch) idiom on a previous revision this
  could already be done in a quite complicated way, by doing something like:
  
  merge() and branch(somebranch) and not merge(somebranch)
  
  This is not very practical ano only works for a single branch. Thus this new
  option is added.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5496

AFFECTED FILES
  mercurial/revset.py

CHANGE DETAILS

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -1249,32 +1249,54 @@
         pass
     return baseset(datarepr=('<max %r, %r>', subset, os))
 
- at predicate('merge(*withbranch)', safe=True)
+ at predicate('merge(*withbranch, samebranch=True)', safe=True)
 def merge(repo, subset, x):
     """Changeset is a merge changeset
 
     All merge revisions are returned by default. If one or more "withbranch"
     names are provided only merges with those branches (i.e. whose
     second parent belongs to one of those branches) will be returned.
+
+    It is also possible to only return merges where both parents belong to
+    the same branch by specifying samebranch=True. If samebranch=False is
+    set then only merges where both parents do not belong to the same branch
+    will be returned.
     """
     # i18n: "merge" is a keyword
-    args = getargsdict(x, 'merge', '*withbranch')
+    args = getargsdict(x, 'merge', '*withbranch samebranch')
     withbranches = []
     if 'withbranch' in args:
         for el in args['withbranch']:
             # i18n: "withbranch" is a keyword
             withbranches.append(getstring(el,
                 _('withbranch argument must be a string')))
+    samebranch = None
+    if 'samebranch' in args:
+        # i18n: "samebranch" is a keyword
+        samebranch = getboolean(args['samebranch'],
+            _('samebranch argument must be a True or False'))
     cl = repo.changelog
     if withbranches:
         # basematch is a function that returns true when a revision
         # is a merge and the second parent belongs to one of the
         # selected "merge with branches"
-        matches = lambda r: (cl.parentrevs(r)[1] != -1
-                             and repo[r].p2().branch() in withbranches)
+        basematch = lambda r: (cl.parentrevs(r)[1] != -1
+                               and repo[r].p2().branch() in withbranches)
     else:
         # basematch is a function that returns true when a revision is a merge
-        matches = lambda r: cl.parentrevs(r)[1] != -1
+        basematch = lambda r: cl.parentrevs(r)[1] != -1
+    if samebranch is None:
+        matches = basematch
+    else:
+        # if samebranch was specified, build a new match function
+        # that on top of basematch checks if the parents belong (or not)
+        # to the same branch (depending on the value of samebranch)
+        def matches(r):
+            c = repo[r]
+            if not basematch(r):
+                return False
+            issamebranchmerge = c.p1().branch() == c.p2().branch()
+            return issamebranchmerge if samebranch else not issamebranchmerge
     return subset.filter(matches, condrepr='<merge>')
 
 @predicate('branchpoint()', safe=True)



To: angel.ezquerra, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list