diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -1249,7 +1249,7 @@ 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 @@ -1260,14 +1260,24 @@ possible to specify a regular expression by starting the pattern with "re:". This can be used to match more than one branch (e.g. "re:branch1|branch2"). + + 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') withbranch = '' if 'withbranch' in args: withbranch = getstring(args['withbranch'], _('withbranch argument must be a string')) kind, branchname, branchmatcher = stringutil.stringmatcher(withbranch) + 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 # create the function that will be used to filter the subset if withbranch: @@ -1275,14 +1285,25 @@ # is a merge and the second parent belongs to a branch that # matches the withbranch pattern (which can be a literal or a regex) if kind == 'literal': - matchfn = lambda r: (cl.parentrevs(r)[1] != -1 - and repo[r].p2().branch() == withbranch) + basematchfn = lambda r: (cl.parentrevs(r)[1] != -1 + and repo[r].p2().branch() == withbranch) else: - matchfn = lambda r: (cl.parentrevs(r)[1] != -1 - and branchmatcher(repo[r].p2().branch())) - else: - # matchfn is a function that returns true when a revision is a merge - matchfn = lambda r: cl.parentrevs(r)[1] != -1 + basematchfn = lambda r: (cl.parentrevs(r)[1] != -1 + and branchmatcher(repo[r].p2().branch())) + else: + basematchfn = lambda r: cl.parentrevs(r)[1] != -1 + if samebranch is None: + matchfn = basematchfn + 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 matchfn(r): + c = repo[r] + if not basematchfn(r): + return False + issamebranchmerge = c.p1().branch() == c.p2().branch() + return issamebranchmerge if samebranch else not issamebranchmerge return subset.filter(matchfn, condrepr='') @predicate('branchpoint()', safe=True)