Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do .gitignore exclusion rules actually work?

Tags:

git

gitignore

People also ask

How does .gitignore work?

A . gitignore file is a plain text file where each line contains a pattern for files/directories to ignore. Generally, this is placed in the root folder of the repository, and that's what I recommend. However, you can put it in any folder in the repository and you can also have multiple .

Does Gitignore only work when committed?

Yes, unless that file was added before the . gitignore , or if it was force added.

What is the difference between Gitignore and exclude?

git/info/exclude is the same as . gitignore, just a lower precedence and not in the repository (so, not committed and shared). Neither affects already tracked files. Both affect files that are not currently tracked.

How do I override git ignore?

gitignore file, you can override a rule by adding ! in front of a filename or folder. Use * to select the files in a folder and ** to select the files in subfolders recursively.


/a/b/c/*
!foo

Seems to work for me (git 1.7.0.4 on Linux). The * is important as otherwise you're ignoring the directory itself (so git won't look inside) instead of the files within the directory (which allows for the exclusion).

Think of the exclusions as saying "but not this one" rather than "but include this" - "ignore this directory (/a/b/c/) but not this one (foo)" doesn't make much sense; "ignore all files in this directory (/a/b/c/*) but not this one (foo)" does. To quote the man page:

An optional prefix ! which negates the pattern; any matching file excluded by a previous pattern will become included again.

i.e., the file has to have been excluded already to be included again. Hope that sheds some light.


I have a similar situation, my solution was to use:

/a/**/*
!/a/**/foo

That should work for an arbitrary number of intermediate directories if I read ** correctly.


Here is another option:

*
!/a*
!/a/*
!/a/*/*
!/a/*/*/*

That would ignore every file and directory, except files/directories three levels deep within a.


this is definitely not clear from the .gitignore man page. This works:

*
!/a
!/a/b
!/a/b/c
!/a/b/c/foo

# don't forget this one
!.gitignore

As mentioned by Chris a directory is not even opened if it is excluded. So if you want to be able to ignore * but some files, you have to build the path to those files as above. For me this is convenient, because I want to do a code review on 1 file of a library and if I want to do another later I just add it, and all else is ignored.


On a more general note, git1.8.2 will include the patch (also in its v4, prompted by some Stack Overflow question) from Adam Spiers about determining which gitignore rule actually ignores your file.

See git1.8.2 release notes and the SO question "which gitignore rule is ignoring my file":
that will be the command git check-ignore.