[PATCH 5 of 5] graphlog: paths/-I/-X handling requires a new revset
Matt Mackall
mpm at selenic.com
Thu Feb 23 23:12:28 UTC 2012
On Thu, 2012-02-23 at 18:10 +0100, Patrick Mezard wrote:
> # HG changeset patch
> # User Patrick Mezard <patrick at mezard.eu>
> # Date 1330016720 -3600
> # Node ID 5a627b49b4d94a627b6e990f07f7a5544e9376bf
> # Parent 1bfc7ba8b404b650bb360d36bd41c11a80d6f5ab
> graphlog: paths/-I/-X handling requires a new revset
>
> 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)".
Interesting.
The basic logic of include/exclude works like this (match.py:74):
if include:
if exclude:
m = lambda f: im(f) and not em(f) and pm(f)
In English, a file matches if it's included AND not excluded AND matches
the base pattern (which might be "all files").
The next question is: how is this pattern matching applied to the set of
files in a changeset? The log code has this (cmdutil.py:1083):
# The slow path checks files modified in every changeset.
for i in sorted(revs):
ctx = change(i)
matches = filter(match, ctx.files())
if matches:
fncache[i] = matches
wanted.add(i)
..which considers a changeset matching if ANY individual file matches. Which gives us three cases:
-I files and -X files have no overlap -> equivalent to just -I (your original example)
-I files and -X files overlap completely -> empty set
-I files and -X files overlap partially -> complex!
But I think there's a relatively simple way to add a revset to deal with this:
everyfile(pattern) -> match changesets where ALL files match pattern
So for a case like:
hg log -I tests -X **.py
..we get:
hg log -r 'file(tests) and not everyfile("**.py")'
Cases:
cset has tests/foo.t -> matches
cset has tests/foo.t and tests/foo.py -> matches
cset has test/foo.py -> doesn't match
cset has tests/foo.t and other/foo.py -> matches
There's probably some way to show this is correct formally with
DeMorgan's rule, but I don't see an obvious notation.
Also note: multiple -I and -X patterns get ORed together, as do base
patterns, so a complex command like this:
hg log p1 p2 -I i1 -I i2 -X x1 -X x2
becomes
(file(p1) or file(p2)) and (file(i1) or file(i2)) and not (everyfile(x1)
or everyfile(x2))
--
Mathematics is the supreme nostalgia of our time.
More information about the Mercurial-devel
mailing list