When reading pattern files, we just call open(path), which is relative to the
current directory. Let's fix this by resolving the paths before attempting to
read the file.
Previously the hgignore test just called hg init in the test directory. A future
patch needs to test hgignore stuff from outside of the repo, so let's move the
entire test repo into a subdirectory.
This adds a new rule syntax that allows the user to include a pattern file, but
only have those patterns match against files underneath the subdirectory of the
pattern file.
This is useful when you have nested projects in a repository and the inner
projects wants to set up ignore rules that won't affect other projects in the
repository. It is also useful in high commit rate repositories for removing the
root .hgignore as a point of contention.
Now that the matcher supports 'include:' rules, let's change the dirstate.ignore
creation to just create a matcher with a bunch of includes. This allows us to
completely delete ignore.py.
I moved some of the syntax documentation over to readpatternfile in match.py so
we don't lose it.
This allows the matcher to understand 'include:path/to/file' style rules. The
files support the standard hgignore syntax and any rules read from the file are
included in the matcher without regard to the files location in the repository
(i.e. if the included file is in somedir/otherdir, all of it's rules will still
apply to the entire repository).
Previously these would be considered to be relative to the current working
directory. That behavior is both undocumented and doesn't really make sense.
There are two reasonable options for how to resolve relative paths:
- relative to the repo root
- relative to the config file
Resolving these files relative to the repo root matches existing behavior with
hooks. An earlier discussion about this is available at
http://mercurial.markmail.org/thread/tvu7yhzsiywgkjzl.
Thanks to Isaac Jurado <diptongo@gmail.com> for the initial patchset that
spurred the discussion.
Previously, a glob pattern of the form 'foo/**/bar' would match 'foo/a/bar' but
not 'foo/bar'. That was because the '**' in 'foo/**/bar' would be translated to
'.*', making the final regex pattern 'foo/.*/bar'. That pattern doesn't match
the string 'foo/bar'.
This is a bug because the '**/' glob matches the empty string in standard Unix
shells like bash and zsh.
Fix that by making the ending '/' optional if an empty string can be matched.
If a directory matched a regex in hgignore but the files inside the directory
did not match the regex, they would appear as deleted in hg status. This
change fixes them to appear normally in hg status.
Removing the ignore(nf) conditional here is ok because it just means we might
stat more files than we had before. My testing on a large repo shows this
causes no performance regression since the only additional files being stat'd
are the ones that are missing (i.e. status=!), which are generally rare.
Many tests didn't change back from subdirectories at the end of the tests ...
and they don't have to. The missing 'cd ..' could always be added when another
test case is added to the test file.
This change do that tests (99.5%) consistently end up in $TESTDIR where they
started, thus making it simpler to extend them or move them around.
Globbing is usually used for filenames, so on windows it is reasonable and very
convenient that glob patterns accepts '\' or '/' when the pattern specifies
'/'.
For GUI clients its sometimes important to know which files will be ignored and
which files will be important. This allows the GUI client to skipping redoing a
'hg status' when the files are ignored but have changed. (For instance, a
typical case is that the "build" directory inside some project is ignored but
files in it frequently change.)
This adds a " (glob)" marker that works like a simpler version of
(re): "*" is converted to ".*", and "?" is converted to ".".
Both special characters can be escaped using "\", and the backslash
itself can be escaped as well.
Other glob-style syntax, like "**", "[chars]", or "[!chars]", isn't
supported.
Consider this test:
$ hg glog --template '{rev}:{node|short} "{desc}"\n'
@ 2:20c4f79fd7ac "3"
|
| o 1:38f24201dcab "2"
|/
o 0:2a18120dc1c9 "1"
Because each line beginning with "|" can be compiled as a regular
expression (equivalent to ".*|"), they will match any output.
Similarly:
$ echo foo
The blank output line can be compiled as a regular expression and will
also match any output.
With this patch, none of the above output lines will be matched as
regular expressions. A line must end in " (re)" in order to be matched
as one.
Lines are still matched literally first, so the following will pass:
$ echo 'foo (re)'
foo (re)