# HG changeset patch # User Boris Feld # Date 1547817707 -3600 # Node ID b1ea90613af3dd1b58a22253678ddf68e17c85db # Parent d82dd55024e7912d43eff81d917f8a3e92315d8b revset: introduce an internal `_rev` predicate for '%d' usage In 24a1f67bb75a, we aligned "%d" behavior on "%ld" one, invalid revisions got silently ignored. However, soon after in 8aca89a694d4 and 26b0a7514f01, a side effect changed the behavior of "%ld" to no longer silently filter invalid revisions. After discussion on the mailing list, it was decided to align on the new %ld behavior: https://www.mercurial-scm.org/pipermail/mercurial-devel/2019-January/127291.html This changeset introduce a '_rev()' predicated that keep the benefit from 24a1f67bb75a while enforcing a more strict checking on the inputs. diff -r d82dd55024e7 -r b1ea90613af3 mercurial/revset.py --- a/mercurial/revset.py Fri Jan 18 16:03:37 2019 +0100 +++ b/mercurial/revset.py Fri Jan 18 14:21:47 2019 +0100 @@ -1765,6 +1765,20 @@ return baseset() return subset & baseset([l]) +@predicate('_rev(number)', safe=True) +def _rev(repo, subset, x): + # internal version of "rev(x)" that raise error if "x" is invalid + # i18n: "rev" is a keyword + l = getargs(x, 1, 1, _("rev requires one argument")) + try: + # i18n: "rev" is a keyword + l = int(getstring(l[0], _("rev requires a number"))) + except (TypeError, ValueError): + # i18n: "rev" is a keyword + raise error.ParseError(_("rev expects a number")) + repo.changelog.node(l) # check that the rev exists + return subset & baseset([l]) + @predicate('revset(set)', safe=True, takeorder=True) def revsetpredicate(repo, subset, x, order): """Strictly interpret the content as a revset. diff -r d82dd55024e7 -r b1ea90613af3 mercurial/revsetlang.py --- a/mercurial/revsetlang.py Fri Jan 18 16:03:37 2019 +0100 +++ b/mercurial/revsetlang.py Fri Jan 18 14:21:47 2019 +0100 @@ -585,7 +585,7 @@ def _formatargtype(c, arg): if c == 'd': - return 'rev(%d)' % int(arg) + return '_rev(%d)' % int(arg) elif c == 's': return _quote(arg) elif c == 'r': @@ -663,9 +663,9 @@ >>> formatspec(b'%r:: and %lr', b'10 or 11', (b"this()", b"that()")) '(10 or 11):: and ((this()) or (that()))' >>> formatspec(b'%d:: and not %d::', 10, 20) - 'rev(10):: and not rev(20)::' + '_rev(10):: and not _rev(20)::' >>> formatspec(b'%ld or %ld', [], [1]) - "_list('') or rev(1)" + "_list('') or _rev(1)" >>> formatspec(b'keyword(%s)', b'foo\\xe9') "keyword('foo\\\\xe9')" >>> b = lambda: b'default'