diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -815,6 +815,42 @@ contentdivergent = obsmod.getrevs(repo, 'contentdivergent') return subset & contentdivergent +@predicate('expect(set[, size[, min, max]])', safe=True, takeorder=True) +def expectrevsetsize(repo, subset, x, n=None): + """Abort if the revset doesn't expect given size""" + args = getargsdict(x, 'expect', 'set size min max') + hasset = 'set' in args + hassize = 'size' in args + hasmin = 'min' in args + hasmax = 'max' in args + + if (not (hasset and hassize) and not n or + (not (hasset and hasmax and hasmin) and not n) or + (not hasset and n)): + raise error.ParseError(_('invalid set of arguments')) + rev = getset(repo, fullreposet(repo), args['set']) + if hassize or isinstance(n, int): + n = getinteger(args.get('size', ('string', str(n))), + 'expect requires an integer size') + if n < 0: + raise error.ParseError(_('negative size')) + if len(rev) != n: + raise error.Abort( + _('revset size mismatch.' + ' expected %d, got %d') % (n, len(rev))) + if hasmin and hasmax: + i = getinteger(args['min'], + 'expect requires an integer min size') + j = getinteger(args['max'], + 'expect requires an integer max size') + if i < 0 or j < 0: + raise error.ParseError(_('negative size')) + if not (len(rev) >= i and len(rev) <= j): + raise error.Abort( + _('revset size mismatch.' + ' expected between %d and %d, got %d') % (i, j, len(rev))) + return rev + @predicate('extdata(source)', safe=False, weight=100) def extdata(repo, subset, x): """Changesets in the specified extdata source. (EXPERIMENTAL)""" @@ -1404,6 +1440,11 @@ obsoletes = obsmod.getrevs(repo, 'obsolete') return subset & obsoletes +@predicate('one(set)', safe=True) +def one(repo, subset, x): + """An alias for expect(, 1)""" + return expectrevsetsize(repo, subset, x, 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,83 @@ * set: 0 + +abort if the revset doesn't expect given size + $ hg log -r 'expect()' + hg: parse error: invalid set of arguments + [255] + $ hg log -r 'expect(0:2, a)' + hg: parse error: expect requires an integer size + [255] + $ hg log -r 'expect(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 'expect(0:1, 1)' + abort: revset size mismatch. expected 1, got 2 + [255] + $ hg log -r 'expect(0:4, -1)' + hg: parse error: negative size + [255] + $ hg log -r 'expect(0:2, min=2, max=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 'expect(0:1, min=3, max=5)' + abort: revset size mismatch. expected between 3 and 5, got 2 + [255] + $ hg log -r 'expect(0:1, min=-1, max=2)' + hg: parse error: negative size + [255] + $ hg log -r 'expect(0:1, min=1, max=-2)' + hg: parse error: negative size + [255] + $ hg log -r 'expect(0:2, min=a, max=4)' + hg: parse error: expect requires an integer min size + [255] + $ hg log -r 'expect(0:2, min=2, max=b)' + hg: parse error: expect requires an integer max size + [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]