D5813: revset: add expect to check the size of a set
navaneeth.suresh (Navaneeth Suresh)
phabricator at mercurial-scm.org
Sun Feb 3 14:28:53 UTC 2019
navaneeth.suresh created this revision.
Herald added subscribers: mercurial-devel, mjpieters.
Herald added a reviewer: hg-reviewers.
REVISION SUMMARY
`expect(<set>, <int>)` revset fails if `<set>` is not exactly `<int>` elements.
`expect(<set>, <min>, <max>)` revset fails if `<set>` is not exactly between
`<min>` and `<max>` inclusive.
`one(<set>)` alias for `expect(<set>, 1)`.
This then allows an alias for `hg next` to be `update -r one(children(.))`
with sane failure behavior, and also makes some other scripting tasks
a little less difficult.
(Summary from WeShouldDoThat[0])
REPOSITORY
rHG Mercurial
REVISION DETAIL
https://phab.mercurial-scm.org/D5813
AFFECTED FILES
mercurial/revset.py
tests/test-revset.t
CHANGE DETAILS
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,74 @@
* set:
<baseset+ [0]>
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, 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 is not of expected size
+ [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 is not of expected size
+ [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 '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 is not of size 1
+ [255]
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -815,6 +815,41 @@
contentdivergent = obsmod.getrevs(repo, 'contentdivergent')
return subset & contentdivergent
+ at 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:
+ n = getinteger(args['size'],
+ 'expect requires an integer size')
+ if n < 0:
+ raise error.ParseError(_('negative size'))
+ if len(rev) != n:
+ raise error.Abort(_('revset is not of expected size'))
+ if n==1:
+ if len(rev) != n:
+ raise error.Abort(_('revset is not of size 1'))
+ 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 is not of expected size'))
+ return rev
+
@predicate('extdata(source)', safe=False, weight=100)
def extdata(repo, subset, x):
"""Changesets in the specified extdata source. (EXPERIMENTAL)"""
@@ -1404,6 +1439,11 @@
obsoletes = obsmod.getrevs(repo, 'obsolete')
return subset & obsoletes
+ at predicate('one(set)', safe=True)
+def one(repo, subset, x):
+ """An alias for expect(<set>, 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
To: navaneeth.suresh, #hg-reviewers
Cc: mjpieters, mercurial-devel
More information about the Mercurial-devel
mailing list