Thread (1 message) 1 message, 1 author, 2016-06-15

Re: [PATCH 1/4] Documentation/gitignore: "foo/" patterns match directories, not files under them

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:52:24

Nguyen Thai Ngoc Duy [off-list ref] writes:
2011/11/7 Jonathan Nieder [off-list ref]:
quoted
The gitignore(5) manpage says that "foo/" will match a directory foo
and paths underneath it.
If git ignores a directory, then it essentially ignores all paths
underneath it, doesn't it?
quoted
But that is completely false: as Johannes
Sixt likes to remind us, patterns with a trailing '/' match the named
directory, not files under that directory.  For example, the following
.gitignore file

       /build/
       !/build/tests/results

does not un-ignore build/tests/results since it was never ignored in
the first place; and commands like "git status" will not notice
changes to build/tests/results because git doesn't enter the (ignored)
build/ directory.
I haven't checked but I think it's because when a directory is
ignored, git just stops checking further ignore rules. So "build" _is_
ignored, too strongly that it does not care if some files may need to
be un-ignored later on.

I remember the argument was, because ignore rules are distributed
across .gitignore files, we would need to go into ignored directories
for collecting potential un-ignore rules (for example "!results" on
build/tests/.gitignore) and that just does not make much sense because
we always have to go into ignored directories.

But in your example, where we know we have negated rules, we should
follow the rules and ignore all but build/tests/results.
quoted
Correct the manual to just say that "foo/" matches the directory
"foo", and make the wording a little clearer in other ways while at
it.
I haven't not read the next patches, maybe you have mentioned this
already. We should make clear that git does not look for negated rules
once a directory is ignored.

Your example however demonstrates a bug that should be fixed in my
opinion. So maybe one or two lines under BUGS section.
quoted
Signed-off-by: Jonathan Nieder <redacted>
---
 Documentation/gitignore.txt |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index 2e7328b8..5b070bf0 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -72,12 +72,14 @@ PATTERN FORMAT
   included again.  If a negated pattern matches, this will
   override lower precedence patterns sources.

- - If the pattern ends with a slash, it is removed for the
-   purpose of the following description, but it would only find
-   a match with a directory.  In other words, `foo/` will match a
-   directory `foo` and paths underneath it, but will not match a
-   regular file or a symbolic link `foo` (this is consistent
-   with the way how pathspec works in general in git).
+ - If the pattern ends with a slash, it will only match
+   directories.  In other words, `foo/` will match a
+   directory `foo` but will not match a regular file or a
+   symbolic link `foo` (this is consistent with the way
+   pathspecs work in general in git).
Looks good.
Or just remove "In other words, ..." that is bogus. Everything before that
is correct.
quoted
++
+The trailing slash is removed before applying the remaining
+rules.
Why does the trailing slash of a rule affect the remaining rules?
Later rule makes a path with and without a slash in it work differently.
A single token "foo/" acts as if there is no trailing slash to match
any directory in the hierarchy, e.g. it matches a directory "frotz/foo".
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help