Skip to contentSkip to conversation

gitignore broken in git 1.7.0.1: slash checks leading dirs

PATCH In review Jiri Slaby 8 participants 19 messages Mar 5, 2010 – Jun 15, 2016 Documentation

lore
Share & tools
lore

Jiri Slaby

author
#0 lore raw

Hi,

having 'linux' line in .gitignore makes 'include/linux/vga_switcheroo.h' to be ignored though the documentation says:
***
If the pattern does not contain a slash /, git treats it as a shell glob pattern and checks for a match against the pathname without leading directories.
***

$ touch test
$ touch include/linux/vga_asdads.h
$ git ls-files -o --exclude-from=test
include/linux/vga_asdads.h
test
$ echo linux >test
$ git ls-files -o --exclude-from=test
test

This does not happen with git 1.6.

thanks,

Signature · 1 line
js
#1 lore raw
Quoted 2 lines · Jiri Slaby

having 'linux' line in .gitignore makes 'include/linux/vga_switcheroo.h' to be ignored

That's the behavior that I would expect.

Quoted 6 lines

though the documentation says:
***
If the pattern does not contain a slash /, git treats it as a shell glob pattern and checks for a match against the pathname without leading directories.
***

and this citation confirms my expectation. Note that it says "pathname", not "filename". 'include/linux' is a "pathname".

-- Hannes

author
#2 lore raw
Quoted 13 lines · Johannes Sixt
Quoted 2 lines · Jiri Slaby

having 'linux' line in .gitignore makes 'include/linux/vga_switcheroo.h' to be ignored

That's the behavior that I would expect.

Quoted 6 lines

though the documentation says:
***
If the pattern does not contain a slash /, git treats it as a shell glob pattern and checks for a match against the pathname without leading directories.
***

Quoted 2 lines

and this citation confirms my expectation. Note that it says "pathname", not "filename". 'include/linux' is a "pathname".

What are 'leading directories' then?

Signature · 1 line
js
#3 lore raw
Quoted 11 lines · Jiri Slaby
Quoted 8 lines · Johannes Sixt
Quoted 5 lines · Jiri Slaby

***
If the pattern does not contain a slash /, git treats it as a shell glob pattern and checks for a match against the pathname without leading directories.
***

and this citation confirms my expectation. Note that it says "pathname", not "filename". 'include/linux' is a "pathname".

What are 'leading directories' then?

'include/' is the leading directory of 'include/linux'.

The cited sentence says that the particular check considers only the last path component of the pathname.

-- Hannes

author
#4 lore raw
Quoted 2 lines · Johannes Sixt

The cited sentence says that the particular check considers only the last path component of the pathname.

Thinking about it, there is no way to specify a *filename* no matter where it lies? I.e. patterns such as *.o matches also a/b/test.o/test.c? Am I missing something?

Signature · 1 line
js
#5 lore raw
Quoted 3 lines · Jiri Slaby

Thinking about it, there is no way to specify a *filename* no matter where it lies? I.e. patterns such as *.o matches also a/b/test.o/test.c? Am I missing something?

Is

*.o
!*.o/

what you are looking for? The first line matches *.o anywhere, and the second matches *.o anywhere as long as it is a directory.

author
#6 lore raw
Quoted 6 lines · Jonathan Nieder
Quoted 3 lines · Jiri Slaby

Thinking about it, there is no way to specify a *filename* no matter where it lies? I.e. patterns such as *.o matches also a/b/test.o/test.c? Am I missing something?

Quoted 7 lines

Is

*.o
!*.o/

what you are looking for? The first line matches *.o anywhere, and the second matches *.o anywhere as long as it is a directory.

As I wrote above, *.o also matches against a/b/test.o/test.c, correct?

#7 lore raw

PATCH 1/1 gitignore: do not ignore include/linux/

In reply to Johannes Sixt

linux entry in .gitignore means that everything in include/linux/ gets ignored with git 1.7.

Prepend a slash to entries which are toplevel to avoid that

Cc Johannes Sixt <[email protected]>
---
 .gitignore |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)
.gitignore +10 -10
index efab0eb..fe6ebb9 100644
@@ -34,16 +34,16 @@ modules.builtin
 #
 # Top-level generic files
 #
-tags
-TAGS
-linux
-vmlinux
-vmlinuz
-System.map
-Module.markers
-Module.symvers
-!.gitignore
-!.mailmap
+/tags
+/TAGS
+/linux
+/vmlinux
+/vmlinuz
+/System.map
+/Module.markers
+/Module.symvers
+!/.gitignore
+!/.mailmap
 
 #
 # Generated include files
Signature · 1 line
1.7.0.1
#8 lore raw

Re: [PATCH 1/1] gitignore: do not ignore include/linux/

Quoted 32 lines · Jiri Slaby

linux entry in .gitignore means that everything in include/linux/ gets ignored with git 1.7.

Prepend a slash to entries which are toplevel to avoid that

Cc Johannes Sixt <[email protected]>
---
 .gitignore |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)
.gitignore +3 -10
index efab0eb..fe6ebb9 100644
@@ -34,16 +34,16 @@ modules.builtin
 #
 # Top-level generic files
 #
-tags
-TAGS
-linux
-vmlinux
-vmlinuz
-System.map
-Module.markers
-Module.symvers
-!.gitignore
-!.mailmap
+/tags
+/TAGS
+/linux

.gitignore modules.builtin · line 49

Quoted 10 lines
.gitignore +7 -0
+/vmlinux
+/vmlinuz
+/System.map
+/Module.markers
+/Module.symvers
+!/.gitignore
+!/.mailmap
 
 #
 # Generated include files

Actually you want to *not ignore* .gitignore and .mailmap (and .gitattributes which is missing here) anywhere, not only as top-level file. So .gitignore and .mailmap should not be prepended with slash.

#
# Top-level generic files
#
-tags
-TAGS
-linux
-vmlinux
-vmlinuz
-System.map
-Module.markers
-Module.symvers
+/tags
+/TAGS
+/linux
+/vmlinux
+/vmlinuz
+/System.map
+/Module.markers
+/Module.symvers
!.gitignore
!.mailmap

Signature · 3 lines
Jakub Narebski
Poland
ShadeHawk on #git
author
#9 lore raw

Re: [PATCH 1/1] gitignore: do not ignore include/linux/

Quoted 6 lines · Jakub Narebski
Quoted 2 lines

+!/.gitignore
+!/.mailmap

Actually you want to *not ignore* .gitignore and .mailmap (and .gitattributes which is missing here) anywhere, not only as top-level file. So .gitignore and .mailmap should not be prepended with slash.

<and moved out of the 'Top-level generic files' section then>

Signature · 1 line
js
#10 lore raw

Re: [PATCH 1/1] gitignore: do not ignore include/linux/

Quoted 10 lines · Jiri Slaby
Quoted 6 lines · Jakub Narebski
Quoted 2 lines

+!/.gitignore
+!/.mailmap

Actually you want to *not ignore* .gitignore and .mailmap (and .gitattributes which is missing here) anywhere, not only as top-level file. So .gitignore and .mailmap should not be prepended with slash.

<and moved out of the 'Top-level generic files' section then>

Please either revert 3b2a8c8f3c65 or merge the fixed up patch for 2.6.34-rc2, otherwise include/linux will continue to be ignored by git just like it is for 2.6.34-rc1.

#11 lore raw

Re: [PATCH 1/1] gitignore: do not ignore include/linux/

Quoted 10 lines · David Rientjes
Quoted 8 lines · Jiri Slaby
Quoted 6 lines · Jakub Narebski
Quoted 2 lines

+!/.gitignore
+!/.mailmap

Actually you want to *not ignore* .gitignore and .mailmap (and .gitattributes which is missing here) anywhere, not only as top-level file.  So .gitignore and .mailmap should not be prepended with slash.

Quoted 6 lines
Quoted 2 lines

<and moved out of the 'Top-level generic files' section then>

Please either revert 3b2a8c8f3c65 or merge the fixed up patch for 2.6.34-rc2, otherwise include/linux will continue to be ignored by git just like it is for 2.6.34-rc1.

Why not apply the patch from Jiri? Since this problem is introduced by new version of git, not that commit.

#12 lore raw

Re: [PATCH 1/1] gitignore: do not ignore include/linux/

Quoted 10 lines · Américo Wang
Quoted 10 lines
Quoted 9 lines
Quoted 6 lines
Quoted 2 lines

+!/.gitignore
+!/.mailmap

Actually you want to *not ignore* .gitignore and .mailmap (and .gitattributes which is missing here) anywhere, not only as top-level file.  So .gitignore and .mailmap should not be prepended with slash.

<and moved out of the 'Top-level generic files' section then>

Quoted 7 lines
Quoted 3 lines

Please either revert 3b2a8c8f3c65 or merge the fixed up patch for 2.6.34-rc2, otherwise include/linux will continue to be ignored by git just like it is for 2.6.34-rc1.

Why not apply the patch from Jiri? Since this problem is introduced by new version of git, not that commit.

Like I said, please either revert the commit that added "linux" to .gitignore or merge Jiri's patch. I'm not interested in engaging in a discussion about what can or cannot be merged during rc cycles, I just hope this is resolved for rc2.

#13 lore raw

Re: [PATCH 1/1] gitignore: do not ignore include/linux/

In reply to Jiri Slaby
Quoted 4 lines · Jiri Slaby

linux entry in .gitignore means that everything in include/linux/ gets ignored with git 1.7.

Prepend a slash to entries which are toplevel to avoid that

New change in git 1.7?

#14 lore raw
In reply to Johannes Sixt
Quoted 5 lines · Johannes Sixt
Quoted 2 lines · Jiri Slaby

having 'linux' line in .gitignore makes 'include/linux/vga_switcheroo.h' to be ignored

That's the behavior that I would expect.

Also the initial report made it sound as if there were a regression, but it doesn't seem to be the case; I don't see it behaving any differently among 1.7.0, 1.7.0.1, 1.6.0, 1.6.6, or even 1.5.4.

#15 lore raw
In reply to Johannes Sixt
Quoted 14 lines · Johannes Sixt
Quoted 2 lines · Jiri Slaby

having 'linux' line in .gitignore makes 'include/linux/vga_switcheroo.h' to be ignored

That's the behavior that I would expect.

Quoted 6 lines

though the documentation says:
***
If the pattern does not contain a slash /, git treats it as a shell glob pattern and checks for a match against the pathname without leading directories.
***

Quoted 2 lines

and this citation confirms my expectation. Note that it says "pathname", not "filename". 'include/linux' is a "pathname".

It would be more precise to say this citation does not have much to do with it. 'include/linux' contains a slash, so that paragraph does not describe what it means.

The next paragraph is more on point:

· Otherwise, git treats the pattern as a shell glob suitable for
consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will not match a / in the pathname. 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".

The relevant sentence is the last one, and I can see how the length of the paragraph might be daunting. Maybe splitting it up would help?

· Otherwise, git treats the pattern as a shell glob suitable for
consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will not match a / in the pathname. For example, "Documentation/*.html" matches "Documentation/git.html" and "tools/perf/Documentation/perf-diff.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".

Not sure.

Jonathan

-- %< --
Subject: gitignore.5: Clarify that path matches are not anchored

---
 Documentation/gitignore.txt |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)
Documentation/gitignore.txt +7 -4
index 98c459d..fa15422 100644
@@ -89,10 +89,13 @@ Patterns have the following format:
    for consumption by fnmatch(3) with the FNM_PATHNAME flag:
    wildcards in the pattern will not match a / in the pathname.
    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".
+   "Documentation/git.html" and
+   "tools/perf/Documentation/perf-diff.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".
 
 An example:
 
Signature · 1 line
1.7.0
#16 lore raw
Quoted 5 lines · Jonathan Nieder
Quoted 4 lines · Johannes Sixt
Quoted 2 lines · Jiri Slaby

having 'linux' line in .gitignore makes 'include/linux/vga_switcheroo.h' to be ignored

[...]

Quoted 6 lines
Quoted 2 lines

and this citation confirms my expectation. Note that it says "pathname", not "filename". 'include/linux' is a "pathname".

It would be more precise to say this citation does not have much to do with it. 'include/linux' contains a slash, so that paragraph does not describe what it means.

Curse my quick reading. Sorry for the nonsense, please ignore.

My suggested patch still might make sense, though. :)

Jonathan

#17 lore raw
In reply to Jonathan Nieder
Quoted 6 lines · Jonathan Nieder

· Otherwise, git treats the pattern as a shell glob suitable for
consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will not match a / in the pathname. For example, "Documentation/*.html" matches "Documentation/git.html" and "tools/perf/Documentation/perf-diff.html" but not "Documentation/ppc/ppc.html".

This is not correct: When the pattern "Documentation/*.html" matches "Documentation/git.html", then it cannot match "tools/perf/Documentation/perf-diff.html". This is because patterns that contain a slash (after stripping a trailing slash) are anchored at the directory that contains the .gitignore.

Said pattern would match the latter name only if it appeared in tools/perf/.gitignore (but in this case it wouldn't match the former name, of course).

-- Hannes

#18 lore raw

PATCH 1/1 gitignore.5: Clarify matching rules

Patterns containing a / are implicitly anchored to the directory containing the relevant .gitignore file.

Patterns not containing a / are textual matches against the path name relative to the directory containing .gitignore.

---

Quoted 5 lines · Johannes Sixt

When the pattern "Documentation/*.html" matches "Documentation/git.html", then it cannot match "tools/perf/Documentation/perf-diff.html". This is because patterns that contain a slash (after stripping a trailing slash) are anchored at the directory that contains the .gitignore.

Oh! The documentation could definitely use clarification here.

Thanks.

 Documentation/gitignore.txt |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)
Documentation/gitignore.txt +9 -5
index 98c459d..e10fa88 100644
@@ -83,16 +83,20 @@ Patterns have the following format:
 
  - If the pattern does not contain a slash '/', git treats it as
    a shell glob pattern and checks for a match against the
-   pathname without leading directories.
+   pathname relative to the location of the `.gitignore` file
+   (relative to the toplevel of the work tree if not from a
+   `.gitignore` file).
 
  - Otherwise, git treats the pattern as a shell glob suitable
    for consumption by fnmatch(3) with the FNM_PATHNAME flag:
    wildcards in the pattern will not match a / in the pathname.
    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".
+   "Documentation/git.html" but not "Documentation/ppc/ppc.html"
+   or "tools/perf/Documentation/perf.html".
+
+ - A leading slash matches the beginning of the pathname.
+   For example, "/*.c" matches "cat-file.c" but not
+   "mozilla-sha1/sha1.c".
 
 An example:
 
Signature · 1 line
1.7.0