Web lists-archives.com

Re: Typo in the .gitignore docs?

On Sun, Mar 31, 2019 at 2:53 AM Dr. Adam Nielsen <info@xxxxxxxxxxxx> wrote:
> Hi everyone,
> I think there is a typo in the gitignore docs.
> Its stated on https://git-scm.com/docs/gitignore that
> >If the pattern does not contain a slash /, Git treats it as a shell
> >glob pattern and checks for a match against the pathname relative to
> >the location of the .gitignore file (relative to the toplevel of the
> >work tree if not from a .gitignore file).
> I think that maybe two things are not 100% correct. First I think it
> should be "If the pattern does contain" instead of "does not contain".
> Secondly, I think it should be mentioned that this is only true for
> slashes that are not a trailing slash.

The trailing slash is already covered in the previous paragraph as you noticed.

The "does not contain" is correct, but perhaps the wording is a bit
too easy to misunderstand. If you go back to the original version of
this document in cedb8d5d33 (Create a new manpage for the gitignore
format, and reference it elsewhere, 2007-06-02), you can see an
example of the "otherwise" part where the present of '/' will anchor
the pattern to the current directory

+   For example, "Documentation/\*.html" matches
+   "Documentation/git.html" but not
+   "Documentation/ppc/ppc.html".  A leading slash matches the
+   beginning of the pathname; for example, "/*.c" matches
+   "cat-file.c" but not "mozilla-sha1/sha1.c".

This part was later removed by me in 2e22a85e5c (gitignore.txt:
elaborate shell glob syntax, 2018-02-01). In hindsight that was a
mistake since having an example seems to help clarify the description.

So rewording this paragraph (and keep the 'does not contain' part) to
be easier to understand would be great. If you turn 'does not contain'
to 'does contain' then you would need to update the 'otherwise'
paragraph as well.

I think the part that trips people is the 'pathname' in 'checks for a
match against the pathname relative...'. I think the key point is
matching the pattern against any pathname _component_ in the path
relative to the location of .gitignore. In other words '*.c' would
match 'abc.c' component in 'def/abc.c'. 'def/ghi/abc.c' or 'abc.c'.

The following 'otherwise' paragraph perhaps could also elaborate a bit
more, that the pattern is matched against the entire path (relative to
.gitignore), not just one path component. The FNM_PATHNAME implies
that (because it would not make sense otherwise) but that's just too
hard to see.

Patches are welcome.

> You find discussions about this at
> https://github.com/git/git-scm.com/issues/1332 and at
> https://stackoverflow.com/a/41761521/2311074
> Here is my proposal for an alternative, maybe more clear version:
> >Whenever you have a string that contains a non-trailing slash "/" , its always considered from
> >the root. There is no difference between foo/bar and /foo/bar. The pattern foo/ is not
> >considered from the root, because it has no non-trailing slash "/".
> >One may match a path that does not start at the root by using "**" (see below).
> Also since we are on it, I would suggest to reduce
> >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).
> to
> >If the pattern ends with a slash, 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.
> What do you think?
> Best regards,
> Adam