Submitter | phabricator |
---|---|
Date | Jan. 13, 2019, 10:45 p.m. |
Message ID | <6297c55d3785470b4961c3604a212824@localhost.localdomain> |
Download | mbox | patch |
Permalink | /patch/37716/ |
State | Not Applicable |
Headers | show |
Comments
> -@predicate('merge(withbranch)', safe=True) > +@predicate('merge(withbranch, samebranch=True)', safe=True) `[, samebranch]` or [, samebranch=False]`. > 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: > # matchfn is a function that returns true when a revision > # 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 These conditions can be formed as followed: ``` matchfns = [lambda r: cl.parentrevs(r)[1] != -1] if withbranch: matchfns.append(lambda r: branchmatcher(repo[r].p2().branch())) if samebranch: matchfns.append(samebranchmatchfn) if len(matchfns) == 1: # fast path for common case return subset.filter(matchfn[0], ...) else: return subset.filter(lambda r: all(p(r) for p in matchfn), ...) ```
yuja added a comment. > -@predicate('merge(withbranch)', safe=True) > +@predicate('merge(withbranch, samebranch=True)', safe=True) `[, samebranch]` or [, samebranch=False]`. > 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: > # matchfn is a function that returns true when a revision > # 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 These conditions can be formed as followed: matchfns = [lambda r: cl.parentrevs(r)[1] != -1] if withbranch: matchfns.append(lambda r: branchmatcher(repo[r].p2().branch())) if samebranch: matchfns.append(samebranchmatchfn) if len(matchfns) == 1: # fast path for common case return subset.filter(matchfn[0], ...) else: return subset.filter(lambda r: all(p(r) for p in matchfn), ...) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5496 To: angel.ezquerra, #hg-reviewers Cc: yuja, mercurial-devel
Patch
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=('<max %r, %r>', 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,29 +1260,50 @@ 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: # matchfn is a function that returns true when a revision # 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='<merge>') @predicate('branchpoint()', safe=True)