Gitignore: ignore all files in the folder hierarchy except for one specific file type

I would like to ignore all the files below and in the folder, except for a certain type of file, which may be somewhere in the folder hierarchy:

Example

/Test /Test/unknown/folder/structure/below 

Now I want to ignore all files in the Test folder and below Test , except for some css file called layout.css , for example:

 /Test/layout.css /Test/fileto.ignore /Test/another/folder/ig.nore /Test/in/a/unknown/folder/layout.css /Test/in/a/unknown/folder/ignore.me 

.gitignore should be ignored

 /Test/fileto.ignore /Test/another/folder/ig.nore /Test/in/a/unknown/folder/ignore.me 

My .gitignore file does not work:

 Test/ !layout.css 

Any suggestions?

+22
git gitignore
Oct 18 '11 at 7:16
source share
3 answers

I managed to get your example to work by placing the .gitignore file in the Test/ directory with the following contents.

 * !*/ !.gitignore !layout.css 
+24
Oct 18 '11 at 8:01
source share

To accomplish what you want, you need to use some negative exceptions.

The basic idea is that you need to exclude every parent directory of any file that you want to execute.

So, if you want to add /Test/in/a/unknown/folder/layout.css to your git repository, you will need to perform non-playing / Test /, / Test / in /, / Test / in / a /, / Test / in / a / unknown /, and / Test / in / a / unknown / folder /.

Then, when you finally end up in a directory with some ignored and uncorrected files, you will need to specify them individually as follows:

 # Fille: .gitignore !Test/ Test/* !Test/layout.css Test/fileto.ignore !Test/another/ Test/another/* !Test/another/folder/ Test/another/folder/* !Test/in/ Test/in/* !Test/in/a/ Test/in/a/* !Test/in/a/unknown/ Test/in/a/unknown/* !Test/in/a/unknown/folder/ Test/in/a/unknown/folder/ignore.me !Test/in/a/unknown/folder/layout.css 

So, when you run $ git add-all , you will see the desired results:

 $ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: .gitignore new file: Test/in/a/unknown/folder/layout.css new file: Test/layout.css 

Note. You can find an explanation of why git add-all is the best way to add files to the git repository at http://lexsheehan.blogspot.com/2014/05/git-add-update.html

+9
Feb 12 '15 at 23:13
source share

Pretty old question, but since I was struggling with this problem, even now I decided that I would share the actual solution to the problem.

The fact is, you cannot pass empty directories to Git, as if they were ignored, this rule does not apply to .gitignore .

From https://git-scm.com/docs/gitignore

The final "/ **" matches everything inside . For example, "abc / **" matches all files inside the "abc" directory, relative to a .gitignore location with infinite depth.

A slash followed by two consecutive asterisks, then a match of zero or more directories. For example, "a / ** / b" matches "a / b", "a / x / b", "a / x / y / b", etc.

** Matches everything inside - literally everything - files and directories.

This leads us to another question in gitignore docs:

Additional prefix "!" what denies the pattern; any corresponding file excluded by the previous template is included again. It is not possible to re-include the file if the parent directory of this file is excluded. Git does not list excluded directories for performance reasons, so any templates on the contained files have no effect, no matter where they are defined. Place a backslash ("\") before the first "!" for patterns that begin with the literal "!" for example, "! Important! .txt".

If the pattern ends with a slash, it is deleted for the purpose after the description, but it will only find a match for the directory. In other words, foo / will match the foo directory and the paths below it, but will not match the regular file or the foo symlink (this is consistent with the way the pathspec method works in general in Git).

Now suppose we have the following dir structure:

 /path/to/git/repo |-- .gitignore |-- /cache |-- somefile |-- README |-- /dir |-- somefile2 |-- README 

And we want to ignore all files inside the cache / except for README files.

If we specify gitignore as follows:

 /cache/** !README 

Git will ignore everything except /cache/README . Another README will not be displayed because its /cache/dir directory has been excluded with /cache/** , and !README is not even applicable to it. To solve the problem, we need to specify gitignore as follows:

 # Ignore everything inside cache/ dir /cache/** # Except for subdirectories(won't be commited anyway if there is no commited file inside) !/cache/**/ # And except for README files !README 
+6
Dec 13 '16 at 0:54
source share



All Articles