How to get Git to ignore all files in a directory and ALSO in its subdirectories except for .conf files?
Currently I have this in my .gitignore:
!/some/dir/
/some/dir/*
!/some/dir/**/
!/some/dir/**/*.conf
So, I want to ignore all files in /some/dir/ and also its subdirectories, except for *.conf files.
But it is not ignoring any file in /some/dir/.
For example, /some/dir/somefile is not ignore, /some/dir/subdir/anotherfile is not ignore also. I just want to not ignore files like: /some/dir/subdir/file.conf.
CodePudding user response:
You may wish to tweak this in various ways, but here's the simplest thing I know of that meets your stated requirements. Create a .gitignore
file inside some/dir
that reads:
*
!*/
!*.conf
and you're all set.
Here is an example:
$ mkdir test-ignore
$ cd test-ignore
$ git init
Initialized empty Git repository in ...
$ echo test ignore rules > README
$ git add README
$ git commit -m initial
[master (root-commit) 33962fc] initial
1 file changed, 1 insertion( )
create mode 100644 README
$ mkdir -p some/dir/a some/dir/b
$ touch some/dir/file some/dir/a/a.conf some/dir/b/b.conf some/dir/a/ignored
$ cat > some/dir/.gitignore << END
> *
> !*/
> !*.conf
> END
$ git add .
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: some/dir/a/a.conf
new file: some/dir/b/b.conf
$
Explanation
*
means ignore everything (that is currently untracked, of course; tracked files cannot be ignored).!*/
means if it's a directory, don't ignore it, do search it, and being later in the file, this overrides a previous entry; of course, being searched does not make files in the directory get added, but the subdirectory does get scanned;!*.conf
means if a file's base name matches*.conf
, don't ignore it, so any files insome/dir
named that are named*.conf
, or any files in any subdirectory ofsome/dir
that are named*.conf
, are not-ignored and hence get added.
That's why some/dir/a/a.conf
did get added, but some/dir/a/ignored
did not.
(You didn't specify in text what you want to do with some/dir/somefile
and some/dir/thing.conf
so I had the same rules apply here: file
is ignored and thing.conf
is not-ignored. I think that's what you intended with !**/*.conf
.)
In general, moving a .gitignore
file "down the tree" as far as it goes will simplify it, so it's easier to put this in some/dir/.gitignore
. The general rule !*/
, close enough to the end of a .gitignore
, forces Git not to short-circuit the scanning of subdirectories found recursively. Other than these two rules (which should be obvious, but aren't always obvious at first), the rest is obvious.