The filtering logic of match objects cannot be reproduced with the existing
revsets as it operates at changeset files level. A changeset touching "a" and
"b" is matched by "-I a -X b" but not by "file(a) and not file(b)".
To solve this, a new internal "_matchfiles(...)" revset is introduced. It works
like "file(x)" but accepts more than one argument and its arguments are
prefixed with "p:", "i:" and "x:" to be used as patterns, include patterns or
exclude patterns respectively.
The _matchfiles revset is kept private for now:
- There are probably smarter ways to pass the arguments in a user-friendly way
- A "rev:" argument is likely appear at some point to emulate log command
behaviour with regard to filesets: they are evaluated for the parent revision
and applied everywhere instead of being reevaluated for each revision.
This will let use override the "join" value (and/or) depending on the option
considered. The option revset arity is now deduced from the revset and the
option value type, to simplify opt2revset definition.
Using "hg log -G --print-revset" prints the revset generated by graphlog and
exits. This helps debugging and writing shorter tests.
It has been suggested to handle these tests with doctests. I think the
extension approach is better because:
- It tests the actual parameter set passed to graphlog.revset(), not what we
expect it to be. 'branch' and 'only-branch' are currently distinct options
but nothing prevents fancyopts to grow a notion of option aliasing one day,
where both options would be merged before reaching the command.
- It can be used as debug output interleaved with real log calls.
v2:
- Use a test extension instead of a global deprecated new option
The grapher cannot really handled revisions if they are not emitted in
topological order. The previous 'reverse()' revset was not enough to achieve
that and was replaced by an explicit sort call for simplicity. The --limit
option is now also handled as usual with cmdutil.loglimit() instead of a
'limit' revset.
The grandparent() function was returning only the closest predecessor of a
missing parent while it must return all of them to display a correct ancestry
graph.
follow() revset really means '::.' while we want something based on the passed
argument. Also, ancestors() revset does not include the parent revisions.
Thanks for the idea and most of the implementation to Klaus Koch
Backs revisions() and filerevs() with DAG walker which can iterate through
arbitrary list of revisions instead of strict one by one iteration from start to
stop. When a gap occurs in a revisions (i.e. in file log), the next topological
parent within the revset is searched and the connection to it is printed in the
ascii graph.
File graph can draw sometimes more connections than previous version, because
graph is produced according to the revset, not according to a file's filelog.
In case the graph contains several branches where the left parent is null, the
graphs for each are printed sequentially, not in parallel as it was a case
earlier (see for example the graph for README in hg-dev).
While this situation should never under normal use, some real
life repos sometimes contain such changesets (older hg versions,
broken rebases, etc...)
hgweb was displaying an "Internal error" in this case, and graphlog
displayed a redundant branch all the way to null: it does not cost us
much to just ignore this extra parent when constructing the DAG.
When issuing `hg pull -r REV` in a repo with no common ancestor with the
remote repo, the message 'requesting all changes' is printed, even though only
the changese that are ancestors of REV are actually requested. This can be
confusing for users (see
http://www.selenic.com/pipermail/mercurial/2010-October/035508.html).
This silences the message if (and only if) the '-r' option was passed.
The glog command didn't emit header and footer from the style, as demonstrated
by "hg glog --style xml". Asciiart combined with xml markup hardly makes sense,
but header and footer might however be useful for adding for example html pre
tags around the graph.