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=('', subset, os)) -@predicate('merge(*withbranch)', safe=True) +@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='') @predicate('branchpoint()', safe=True)