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,13 +1260,18 @@ 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. """ cl = repo.changelog # matchfn is a function that returns true when a revision is a merge matchfn = lambda r: cl.parentrevs(r)[1] != -1 # i18n: "merge" is a keyword - args = getargsdict(x, 'merge', 'withbranch') + args = getargsdict(x, 'merge', 'withbranch samebranch') if 'withbranch' in args: withbranch = getstring(args['withbranch'], _('withbranch argument must be a string')) @@ -1277,6 +1282,24 @@ # matches the withbranch pattern (which can be a literal or a regex) matchfn = lambda r: (cl.parentrevs(r)[1] != -1 and branchmatcher(repo[r].p2().branch())) + samebranch = None + if 'samebranch' in args: + # i18n: "samebranch" is a keyword + samebranch = getboolean( + args['samebranch'], + _('samebranch argument must be a True or False')) + if samebranch is not None: + basematchfn = matchfn + # 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) diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -1743,7 +1743,7 @@ Test section lookup $ hg help revset.merge - "merge([withbranch])" + "merge([withbranch], samebranch=True)" Changeset is a merge changeset All merge revisions are returned by default. If a "withbranch" pattern @@ -1753,6 +1753,11 @@ 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. + $ hg help glossary.dag DAG The repository of changesets of a distributed version control system diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -3016,6 +3016,28 @@ (branch merge, don't forget to commit) $ hg commit -m "different branch merge 2" +test that the merge revisions can be split between those where +samebranch is True and those where it is False + $ log 'merge()' + 6 + 11 + 13 + 15 + 17 + 19 + +show merges with the same branch + $ log 'merge(samebranch=True)' + 11 + 13 + 15 + 19 + +show merges with other branches (but not the same branch) + $ log 'merge(samebranch=False)' + 6 + 17 + show merges with a particular branch $ log 'merge(.a.b.c.)' 11 @@ -3025,6 +3047,9 @@ $ log 'merge(-a-b-c-)' 6 + $ log 'merge(".a.b.c.", samebranch=False)' + 17 + show merges with multiple branches using a regex $ log 'merge("re:.a.b.c.")' 6