Thread (2 messages) flat view 2 messages, 2 authors, 2016-06-15

Re: Change in .gitignore handling: intended or bug?

From: Junio C Hamano <hidden>
Date: 2016-06-15 23:08:39

Junio C Hamano [off-list ref] writes:
We need documentation update to settle this one before 2.8 final
ships, as we seem to be seeing more and more end-user confusion on
the list.  I tried to come up with a trimmed-down example, which is
shown below, but I suspect that the code is not exactly working the
way it is described in that (1) dir/file1 is ignored and (3)
!dir/file3 entry makes difference.

Where did my example go wrong?

FYI, if I prefix '/' to all the .gitignore entries in the example, i.e.
making it

    *
    !/dir
    /dir/file2
    !/dir/file3

instead, then dir/file1 and dir/file3 do get shown as unignored.

If it is documented somewhere, then I can update the example and
declare victory (but then the text that accompanies the example
still needs to remind the readers why the leading '/' matters.
I also found that having an extra slash at the end of the
"everything underneath 'dir' directory is included", i.e.

     *
     !/dir/
     /dir/file2
     !/dir/file3

breaks it.  dir/file1 is ignored, dir/file3 isn't but the latter is
only because there is an explicit !/dir/file3.  This is contrary to
this rule in the documentation:

 - 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).

In other words, '!/dir/' does not seem to match the directory dir
and paths underneath it.

Thanks.
quoted hunk
 Documentation/gitignore.txt | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index 3ded6fd..b841233 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -150,6 +150,40 @@ excluded, the following conditions must be met:
  - The directory part in the re-include rules must be literal (i.e. no
    wildcards)
 
+A re-inclusion of a directory makes all files in the directory
+unignored.  For example, suppose you have files `.gitignore`,
+`dir/file1`, `dir/file2`, and `dir/file3`, and have the following in
+your `.gitignore`:
+
+----------------
+*
+!dir
+# dir/file1 is not mentioned in .gitignore
+dir/file2
+!dir/file3
+----------------
+
+Then:
+
+ - `.gitignore` gets ignored, because it matches the `*` at the top
+   level;
+
+ - `dir/file1` gets unignored, because `dir` marks everything
+   underneath `dir/` to be unignored unless otherwise specified;
+
+ - `dir/file2` gets ignored, because `dir/file2` is listed to be
+   ignored;
+
+ - `dir/file3` gets unignored, because `dir/file3` is listed to be
+   ignored.  Note that the entry `!dir/file3` is redundant because
+   everything underneath `dir/` is marked to be unignored already.
+
+Some earlier versions of Git treated `!dir` differently in that it
+did not cause the paths under it unignored, but this has been
+corrected to be consistent with `dir` that says "`dir` and everything
+below are ignored."
+
+
 EXAMPLES
 --------
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help