acelot
acelot

Reputation: 762

Ignore all files and files in subdirectories except one file

Imagine the following structure:

/a/1.txt
/a/2.txt
/a/.keep

/a/b/1.txt
/a/b/2.txt
/a/b/3.txt
/a/b/.keep

/a/b/c/1.txt
/a/b/c/2.txt
/a/b/c/3.txt
/a/b/c/4.txt
/a/b/c/.keep

/d/test.txt
/d/work.txt

I want to ignore all files in a directory except .keep files to obtain the following results:

/a/.keep

/a/b/.keep

/a/b/c/.keep

/d/test.txt
/d/work.txt

My .gitignore file that doesn't work:

/a/*
!.keep

Upvotes: 1

Views: 1026

Answers (2)

ericbn
ericbn

Reputation: 10998

Unfortunatelly, you cannot reinclude files at directories ignored by previous rules, according to the gitignore Documentation:

It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined.

So this

/a/*
!/a/**/.keep

will only reinclude /a/.keep but not the others.

You'll have to exclude each file pattern under /a explictly.

/a/**/*.txt
/a/**/.ignore
/a/**/.alsoignore

UPDATE: Or a better solution is to create the following .gitgnore at your /a subdirectory:

*.*
!.keep

(the only drawback is that this solution will also keep files with no extension)

Upvotes: 2

NoDataFound
NoDataFound

Reputation: 11979

In your case, you should use:

/a/*
!**/.keep

From the gitignore documentation:

A leading "**" followed by a slash means match in all directories. For example, "**/foo" matches file or directory "foo" anywhere, the same as pattern "foo". "**/foo/bar" matches file or directory "bar" anywhere that is directly under directory "foo".

Upvotes: 0

Related Questions