git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: gitignore: how to exclude a directory tree from being ignored

From
Johannes Sixt <j.sixt@viscovery.net>
Date
Oct 1, 2009, 15:25 UTC
Message-ID
<4AC4C9DB.2090907@viscovery.net>
In-Reply-To
<4AC4C125.10609@mycircuit.org>
Peter schrieb:
Show 18 quoted lines
>>> 1) I can't have just one .gitignore file in the root dir, if I want to
>>> _recursively_ inverse the exclude pattern for a sub dir tree.
>>>     
>>
>> No, it's not the inversion of the pattern, but the slash (if it is not at
>> the end) that makes the pattern non-recursive.
>>
>>   
> from the gitignore manpage:
>>> 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). <<
> 
> Doesn't this mean, that if I say:
> vendor/
> matches the directory and ( recursively ) the paths underneath it.?

The paragraph you are citing is talking about *what* the pattern matches, but it says nothing about *where* the pattern matches.

When I was saying "recursively", then I was refering to the "where" aspect, not the "what" aspect.

If you have directories
   src/bar/vendor/
   src/foo/bar/vendor/
   src/vendor/
and you have the file src/.gitignore with the single pattern
   vendor/
then it applies to recursively ("where") these directories:
   src/bar/vendor/
   src/foo/bar/vendor/
   src/vendor/
and everything ("what") below them.
But if the same src/.gitignore has only this pattern:
   bar/vendor/
then it will not match ("where") recursively and only apply to
   src/bar/vendor/
and everything ("what") below it, but will not apply to
   src/foo/bar/vendor/
Show 5 quoted lines
> And, consequently:
> !vendor/
> inverse the exclusion for vendor ( that is: include ) and everything
> that is contained in it ? ( This is obviously not the case, but this is
> what I would expect )
You should update your expectations. ;-)

You think that git starts with the .gitignore files, and somehow applies the rules that it finds to all files (perhaps recursively).

But it does not work like this; rather it is in the oppsite direction: git starts with a file name, and then checks the rules in the .gitignore files that it has available.

For example, take the path "src/vendor/foo.exe". git finds the file src/.gitignore and there it sees the pattern "*.exe". The pattern matches, and so git obeys the rule (ignores the file). But the pattern "!vendor/" does not match (because the path ends with "foo.exe", not "vendor").

Before git had seen the path "src/vendor/foo.exe", it had already seen "src/vendor". This time the pattern "!vendor/" did match (because the name is identical *and* it is a directory, as per the cited paragraph) and git obeyed the rule (which was not to ignore the directory).

-- Hannes
Previous: PeterNext: Peter
Message 6 of 7 in “gitignore: how to exclude a directory tree from being ignored”
  1. PeterOct 1, 2009
  2. Johannes SixtOct 1, 2009
  3. PeterOct 1, 2009
  4. Johannes SixtOct 1, 2009
  5. PeterOct 1, 2009
  6. Johannes SixtOct 1, 2009
  7. PeterOct 1, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.