Some sample queries:
hg log -r 'branch(default)'
hg log -r 'branch(default) and 1.5:: and not merge()'
hg log -r '1.3::1.5 and keyword(bug) and file("hgext/*")'
hg log -r 'sort(date("May 2008"), user)'
hg log -r '(keyword(bug) or keyword(issue)) and not ancestors(tagged())'
grammar:
expr :=
( expr )
expr infix expr
prefix expr
expr postfix
identifier
"identifier"
function ( expr )
prefix operators:
not x / ! x
:x all revisions <= x
::x ancestors of x
postfix operators:
x:: descendants of x
x: revisions >= x
infix operators:
symbol(expression)
x::y / x..y dag range
x:y existing range operator
not x
x and y / x & y
x or y / x | y / x + y
x - y -> x & !y
x,y -> argument list
function-style filters:
adds(pattern)
all() -> 0:tip
ancestor(single, single)
ancestors(set)
author(string) alias for user
branch(set)
children(set)
closed() -> changeset is closed
contains(patterns) -> revision contains pattern
date(daterange)
descendants(set)
file(pattern)
follow() -> ::.
grep(regex) like keyword but with regex
head() -> changeset is a heads
heads(set) -> members of set with no children in set
keyword(string)
limit(set, n) -> first n members of set
max(set) -> highest revision in set
merge() -> cset is a merge
modifies(pattern)
outgoing([path])
p1(set)
p2(set)
parents(set)
removes(pattern)
reverse(set)
roots(set)
sort(set[, spec])
tagged() changeset is tagged
user(string)
Command line equivalents:
-f -> ::.
-d -> date(x)
-k -> keyword(x)
-m -> merge()
-u -> user(x)
-b -> branch(x)
-P -> !::x
-l -> limit(expr, x)
--
Mathematics is the supreme nostalgia of our time.
_______________________________________________
Mercurial-devel mailing list
Mercuri...@selenic.com
http://selenic.com/mailman/listinfo/mercurial-devel
> Some sample queries:
> hg log -r 'branch(default)'
> hg log -r 'branch(default) and 1.5:: and not merge()'
> hg log -r '1.3::1.5 and keyword(bug) and file("hgext/*")'
> hg log -r 'sort(date("May 2008"), user)'
> hg log -r '(keyword(bug) or keyword(issue)) and not ancestors(tagged())'
Very nice!
Giving it a try, I stumbled upon an issue while ending a specification
with '1.5::'. Something along the lines of the following patch might help.
# HG changeset patch
# User Cédric Duval <cedri...@free.fr>
# Date 1275942295 -7200
# Node ID 1dcf7d358d91d828ded364d7fc8b47f6a86c6de1
# Parent 3d0591a661189bcb0a5e8ef3393c59ecd7e42f79
cmdutil: fix range determination when using a DAG separator
revset must be used with open DAG range specifications, otherwise
requesting eg. 'tag::' causes a range lookup between "tag" and ":",
which triggers an abandon.
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -13,6 +13,7 @@
import similar, revset
revrangesep = ':'
+dagrevrangesep = '::'
def parsealiases(cmd):
return cmd.lstrip("^").split("|")
@@ -149,8 +150,9 @@
seen, l = set(), []
for spec in revs:
- if spec and not (
- spec.startswith(revrangesep) or spec.endswith(revrangesep)):
+ if spec and (
+ spec.startswith(dagrevrangesep) or spec.endswith(dagrevrangesep) or
+ not (spec.startswith(revrangesep) or spec.endswith(revrangesep))):
m = revset.match(spec)
for r in m(repo, range(len(repo))):
if r not in seen:
This seems to break branch names with dashes in them, as in:
hg glog --rev p-root:tip
-parren
I wonder if the following diff suggests that this will not be treated
as a regression.
$ hg diff -c e581f3ac tests
diff --git a/tests/test-bookmarks b/tests/test-bookmarks
--- a/tests/test-bookmarks
+++ b/tests/test-bookmarks
@@ -82,7 +82,7 @@
hg bookmarks
echo % look up stripped bookmark name
-hg log -r 'x y'
+hg log -r '"x y"'
echo % reject bookmark name with newline
hg bookmark '
$ hg debugrevspec 'contains())'
** unknown exception encountered, details follow
** report bug details to http://mercurial.selenic.com/bts/
** or merc...@selenic.com
** Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) [GCC 4.4.3]
** Mercurial Distributed SCM (version 1.5.1+50-3f30190781a3+20100409)
** Extensions loaded:
Traceback (most recent call last):
File "./hg", line 27, in <module>
mercurial.dispatch.run()
File "/home/peo/dev/hg/dev-crew/mercurial/dispatch.py", line 16, in run
sys.exit(dispatch(sys.argv[1:]))
File "/home/peo/dev/hg/dev-crew/mercurial/dispatch.py", line 34, in dispatch
return _runcatch(u, args)
File "/home/peo/dev/hg/dev-crew/mercurial/dispatch.py", line 54, in _runcatch
return _dispatch(ui, args)
File "/home/peo/dev/hg/dev-crew/mercurial/dispatch.py", line 480, in _dispatch
return runcommand(lui, repo, cmd, fullargs, ui, options, d)
File "/home/peo/dev/hg/dev-crew/mercurial/dispatch.py", line 350, in
runcommand
ret = _runcommand(ui, options, cmd, d)
File "/home/peo/dev/hg/dev-crew/mercurial/dispatch.py", line 531, in
_runcommand
return checkargs()
File "/home/peo/dev/hg/dev-crew/mercurial/dispatch.py", line 485, in checkargs
return cmdfunc()
File "/home/peo/dev/hg/dev-crew/mercurial/dispatch.py", line 479, in <lambda>
d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
File "/home/peo/dev/hg/dev-crew/mercurial/util.py", line 408, in check
return func(*args, **kwargs)
File "/home/peo/dev/hg/dev-crew/mercurial/commands.py", line 945, in
debugrevspec
for c in func(repo, range(len(repo))):
File "/home/peo/dev/hg/dev-crew/mercurial/revset.py", line 553, in mfunc
return getset(repo, subset, tree)
File "/home/peo/dev/hg/dev-crew/mercurial/revset.py", line 109, in getset
return methods[x[0]](repo, subset, *x[1:])
File "/home/peo/dev/hg/dev-crew/mercurial/revset.py", line 154, in func
return symbols[a[1]](repo, subset, b)
File "/home/peo/dev/hg/dev-crew/mercurial/revset.py", line 281, in contains
pat = getstring(x, "file wants a pattern")
File "/home/peo/dev/hg/dev-crew/mercurial/revset.py", line 89, in getstring
if x[0] == 'string' or x[0] == 'symbol':
TypeError: 'NoneType' object is unsubscriptable
Just chatted with hstuart a bit. Ideas:
* Require spaces around operators.
* Make 'with-dash' first look up the name "with-dash". If there is no
such name, fall back on the expression 'with - dash'. To be on the
safe side, one could use spaces to force ' - ' to be an operator.
* Accept this as changed behaviour, but at least explicitly specify _
to never become an operator.
More ideas:
* Require a prefix to introduce revspecs. This could either be a
prefix that forces people to quote in bash so they get into the habit
to avoid surprises later. Suggestion is # so if people forget to
bash-quote no harm's done:
hg log -r '#tagged()'
or else something not requiring bash-quoting like surrounding /.../:
hg log -r /a..b/
hg log -r /a-b/
hg log -r my-branch
This would still trip up people with leading slashes in their branch names.
* Supporting quoting names using /.../, so we avoid the double
quoting needed in bash for "...". Optionally we could support omitting
the trailing /:
hg log -r /my-branch/
hg log -r /my-branch
hg log -r a..b
hg log -r a-b
We could, but for operators like ':,(!', that's not really what you want.
> * Make 'with-dash' first look up the name "with-dash". If there is no
> such name, fall back on the expression 'with - dash'. To be on the
> safe side, one could use spaces to force ' - ' to be an operator.
Horrors. x - y is just shorthand for "x and not y", so the simplest answer is
to just drop it.
Here are the characters that when included in a specifier will
effectively make it a query:
essential: space ( ) " ' , :
convenience: ! & | - + ..
Of these, I think - and + are both pretty problematic but I'm not too
worried about the others. So we either need to drop some of the
convenience operators or mark queries specially.
In the past, ranges have been detected by the presence of a :, which
is why : is banned in tag names. We could for instance mark queries
like this:
hg log -r '?1.5::'
but it's a little unfortunate that this cuts us off from simply typing
hg log -r 1.5::
On the other hand, these simple :: expressions are about all you can
type without needing shell quoting.
Alternately, we could make the query test something hairy like:
if ':' in x or ' ' in x or '(' in x:
but that just seems to present weird corner cases like:
hg log -r 'tip&default'
The subspace of useful expressions without '( :' is pretty small but
it isn't quite empty.
Also, right now the parser insists that any identifier not matching
[a-z09._]+ be in quotes. Quoting allows any identifier to be
specified. This ought to be made a bit more liberal.
> * Accept this as changed behaviour, but at least explicitly specify _
> to never become an operator.
On reflection, I think the current approach is too aggressive.
--
Mathematics is the supreme nostalgia of our time.
Cool! This is a killer feature.
I just naively tried to do this:
hg update 'p1(109360)'
which was rejected: presumably update doesn't accept revsets at all,
since it's nonsensical in general. But there are certainly useful
revsets with only one member. Would it be possible to make update
accept a query that evaluates to exactly one changeset, and barf
otherwise?
Greg
Yes. Haven't gotten there yet though.
--
Mathematics is the supreme nostalgia of our time.
This is actually tripping over the lack of arguments to contains and not
the extra paren.
--
Mathematics is the supreme nostalgia of our time.