diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -815,6 +815,55 @@ contentdivergent = obsmod.getrevs(repo, 'contentdivergent') return subset & contentdivergent +@predicate('expectsize(set[, size])', safe=True, takeorder=True) +def expectrevsetsize(repo, subset, x, order, n=None): + """Abort if the revset doesn't expect given size""" + args = getargsdict(x, 'expect', 'set size') + size = args.get('size', n) + if size is not None: + try: + # size is given as integer range on expectsize(, ) + lr = getrange(size, _('expectsize requires a size range ' + 'or a positive integer')) + minsize, maxsize = [getinteger(a, + _('size range bounds must be integers')) + for a in lr] + size = (minsize, maxsize) + except error.ParseError: + # size is given as integer on expectsize(, ) + size = getinteger(size, + _('expectsize requires a size range ' + 'or a positive integer')) + except TypeError: + # size is 1 on one() + pass + if size is None or 'set' not in args: + raise error.ParseError(_('invalid set of arguments')) + rev = getset(repo, fullreposet(repo), args['set'], order=order) + if isinstance(size, tuple): + if minsize < 0 or maxsize < 0: + raise error.ParseError(_('negative size')) + if len(rev) not in range(size[0], size[1]+1): + raise error.RepoLookupError( + _('revset size mismatch.' + ' expected between %d and %d, got %d') % (size[0], + size[1], + len(rev))) + if isinstance(size, int): + if size < 0: + raise error.ParseError(_('negative size')) + if len(rev) != size: + raise error.RepoLookupError( + _('revset size mismatch.' + ' expected %d, got %d') % (size, len(rev))) + # filter rev by subset. since we'll probably want to get an ordered + # result from expectsize(), we'll have to conditionalize the + # filtering direction + if order == followorder: + return subset & rev + else: + return rev & subset + @predicate('extdata(source)', safe=False, weight=100) def extdata(repo, subset, x): """Changesets in the specified extdata source. (EXPERIMENTAL)""" @@ -1404,6 +1453,11 @@ obsoletes = obsmod.getrevs(repo, 'obsolete') return subset & obsoletes +@predicate('one(set)', safe=True, takeorder=True) +def one(repo, subset, x, order): + """An alias for expect(, 1)""" + return expectrevsetsize(repo, subset, x, order, n=1) + @predicate('only(set, [set])', safe=True) def only(repo, subset, x): """Changesets that are ancestors of the first set that are not ancestors diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -2950,3 +2950,103 @@ * set: 0 + +abort if the revset doesn't expect given size + $ hg log -r 'expectsize()' + hg: parse error: invalid set of arguments + [255] + $ hg log -r 'expectsize(0:2, a)' + hg: parse error: expectsize requires a size range or a positive integer + [255] + $ hg log -r 'expectsize(0:2, 3)' + changeset: 0:2785f51eece5 + branch: a + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 0 + + changeset: 1:d75937da8da0 + branch: b + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 1 + + changeset: 2:5ed5505e9f1c + branch: a-b-c- + user: Bob + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + + $ hg log -r 'expectsize(2:0, 3)' + changeset: 2:5ed5505e9f1c + branch: a-b-c- + user: Bob + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + changeset: 1:d75937da8da0 + branch: b + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 1 + + changeset: 0:2785f51eece5 + branch: a + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 0 + + $ hg log -r 'expectsize(0:1, 1)' + abort: revset size mismatch. expected 1, got 2! + [255] + $ hg log -r 'expectsize(0:4, -1)' + hg: parse error: negative size + [255] + $ hg log -r 'expectsize(0:2, 2:4)' + changeset: 0:2785f51eece5 + branch: a + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 0 + + changeset: 1:d75937da8da0 + branch: b + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 1 + + changeset: 2:5ed5505e9f1c + branch: a-b-c- + user: Bob + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + $ hg log -r 'expectsize(0:1, 3:5)' + abort: revset size mismatch. expected between 3 and 5, got 2! + [255] + $ hg log -r 'expectsize(0:1, -1:2)' + hg: parse error: negative size + [255] + $ hg log -r 'expectsize(0:1, 1:-2)' + hg: parse error: negative size + [255] + $ hg log -r 'expectsize(0:2, a:4)' + hg: parse error: expectsize requires a size range or a positive integer + [255] + $ hg log -r 'expectsize(0:2, 2:b)' + hg: parse error: expectsize requires a size range or a positive integer + [255] + $ hg log -r 'one()' + hg: parse error: invalid set of arguments + [255] + $ hg log -r 'one(2)' + changeset: 2:5ed5505e9f1c + branch: a-b-c- + user: Bob + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + $ hg log -r 'one(0:2)' + abort: revset size mismatch. expected 1, got 3! + [255]