[PATCH 5 of 5] graphlog: paths/-I/-X handling requires a new revset
mpm at selenic.com
Fri Feb 24 13:12:27 CST 2012
On Fri, 2012-02-24 at 16:34 +0100, Patrick Mézard wrote:
> Le 24/02/12 00:12, Matt Mackall a écrit :
> > 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))
> So "everyfile(rev, pattern)" is true if all elements of rev.files() are matched by pattern?
> If "a" and "b" are changed in "rev":
> hg log -I b -X b
> (file(b) and not everyfile(b))
> and here everyfile(b) does not include "rev" since it does not match "a", so "rev" is returned.
Yep, you're right, that won't work.
Mathematics is the supreme nostalgia of our time.
More information about the Mercurial-devel