sapling/tests/test-sparse-issues.t
Jun Wu 13c3e1c6eb dirstate: stop testing directories as files in ignore handling
Summary:
This is subtle.

`.hgignore`'s current behavior: if `^foo$` rule exists, then directory `foo/`
is ignored (ex. 'foo/bar' should be ignored).

However, that imposes problems for the sparse ignore matcher, which is the
"negate" of the "include" matcher. A user can write `[include]` glob patterns
like:

  a*{b*,c*/d*}/e*

The ignore matcher will be the negate of the above patterns. Then because
`a1b2` does not match `a*{b*,c*/d*}/e`, the negate matcher returns "True",
and the ignore matcher will ignore the directory. So even if file `a1b2/e3`
should be selected, the parent directory being ignored cause the file to
be ignored.

That is clearly incorrect for sparse's usecase.

I think the issue is fundementally a layer violation - it's the *matcher*'s
responsibility to check whether one of the parent directory is matched (or
ignored), not the directory walker's responsibility.

This diff fixes the walker so it uses the visitdir interface, and moves back
the directory check to hgignore matcher to maintain compatibility. For three
matchers involved in ignore handling:

- hgignore matcher: updated to do the recursive directory handling on its own
- gitignore matcher: work out of box. already consider parent directories!
- sparse matcher: want the new behavior

`test-sparse-issues.t` is now green.

With this change, the `forceincludematcher` subdir hack used in sparse is no
longer necessary. Therefore removed.

Besides, all ignore matchers can handle "visitdir" correctly. That is, if
`visitdir('x')` returns `'all'`, then `visitdir('x/y')` will also return `'all'`.
Therefore the parent directory logic in `dirstate.dirignore` becomes
unnecessary and dropped.

Reviewed By: DurhamG

Differential Revision: D10861612

fbshipit-source-id: aa0c181ae64b361b85f08b8fecfdfe6331e9a4c2
2018-12-12 22:44:17 -08:00

23 lines
304 B
Perl

$ enable sparse
$ newrepo
$ hg sparse include a/b
$ cat .hg/sparse
[include]
a/b
[exclude]
$ mkdir -p a/b b/c
$ touch a/b/c b/c/d
$ hg status
? a/b/c
More complex pattern
$ hg sparse include 'a*/b*/c'
$ mkdir -p a1/b1
$ touch a1/b1/c
$ hg status
? a/b/c
? a1/b1/c