I have the folder
application/ which I add to the
.gitignore. Inside the
application/ folder is the folder
application/language/gr. How can I include this folder?
I’ve tried this
with no luck.
How to exclude a folder but include specific subfolder using gitignore?
If you exclude
application/, then everything under it will always be excluded (even if some later negative exclusion pattern (“unignore”) might match something under
To do what you want, you have to “unignore” every parent directory of anything that you want to “unignore”. Usually, you end up writing rules for this situation in pairs: ignore everything in a directory, but not some certain subdirectory.
# you can skip this first one if it is not already excluded by prior patterns !application/ application/* !application/language/ application/language/* !application/language/gr/
/* is significant:
- The pattern
dir/excludes a directory named
dirand (implicitly) everything under it.
dir/, Git will never look at anything under
dir, and thus will never apply any of the “un-exclude” patterns to anything under
- The pattern
dir/*says nothing about
diritself; it just excludes everything under
dir/*, Git will process the direct contents of
dir, giving other patterns a chance to “un-exclude” some bit of the content (
gitignore.txt: clarify recursive nature of excluded directories
An optional prefix “
!” which negates the pattern; any matching file excluded by a previous pattern will become included again.
It is not possible to re-include a file if a parent directory of that file is excluded. (
*: unless certain conditions are met in git 2.8+, see below)
Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined.
Put a backslash (“
\“) in front of the first “
!” for patterns that begin with a literal “
!“, for example, “
Example to exclude everything except a specific directory
/*– without the slash, the wildcard would also exclude everything within
-------------------------------------------------------------- $ cat .gitignore # exclude everything except directory foo/bar /* !/foo /foo/* !/foo/bar --------------------------------------------------------------
In your case:
application/* !application/**/ application/language/* !application/language/**/ !application/language/gr/**
You must white-list folders first, before being able to white-list files within a given folder.
So with git 2.9+, this could have actually worked, but was ultimately reverted:
The first answer is great, but with newer versions of Git (1.8.2 or later), there is a double asterisk pattern you can leverage for a bit more shorthand solution:
# assuming the root folder you want to ignore is 'application' application/**/* # the subfolder(s) you want to track: !application/language/gr/
This way you don’t have to “unignore” parent directory of the subfolder you want to track.
With Git 2.17.0 (Not sure how early before this version. Possibly back to 1.8.2), using the
** pattern combined with excludes for each subdirectory leading up to your file(s) works. For example:
# assuming the root folder you want to ignore is 'application' application/** # Explicitly track certain content nested in the 'application' folder: !application/language/ !application/language/gr/ !application/language/gr/** # Example adding all files & folder in the 'gr' folder !application/language/gr/SomeFile.txt # Example adding specific file in the 'gr' folder
I’ve found only this actually works.
The only way I got this to work on my machine was to do it this way:
# Ignore all directories, and all sub-directories, and it's contents: */* #Now ignore all files in the current directory #(This fails to ignore files without a ".", for example #'file.txt' works, but #'file' doesn't): *.* #Only Include these specific directories and subdirectories: !wordpress/ !wordpress/*/ !wordpress/*/wp-content/ !wordpress/*/wp-content/themes/ !wordpress/*/wp-content/themes/* !wordpress/*/wp-content/themes/*/* !wordpress/*/wp-content/themes/*/*/* !wordpress/*/wp-content/themes/*/*/*/* !wordpress/*/wp-content/themes/*/*/*/*/*
Notice how you have to explicitly allow content for each level you want to include. So if I have subdirectories 5 deep under themes, I still need to spell that out.
I have found a similar case here, where in laravel by default,
.gitignore ignores all using asterix, then overrides the public directory. ( This is also the same solution as the main answer @Chris Johnsen, just a bit thinner and more concise maybe.)
* !public !.gitignore
This is not sufficient if you run into the OP scenario.
If you want to commit a specific subfolder of
public, say for e.g. in your
public/products directory you want to include files that are one subfolder deep e.g. to include
public/products/a/b.jpg they wont be detected correctly, even if you add them specifically like this
The solution is to make sure you add an entry for every path level like this to override them all.
* !.gitignore !public/ !public/*/ !public/products/ !public/products/* !public/products/*/ !public/products/*/ !public/products/*/*
Hope you learned something from this post.
Follow Programming Articles for more!