Home > Enterprise >  How to exclude from git everything except files with specific extension, recursively when some inter
How to exclude from git everything except files with specific extension, recursively when some inter

Time:10-14

I'm trying to exclude from a git repository everything except .asd files. The files may be at any level of the directory hierarchy, and any directory at any level may or may not contain dots in their name, making them look like file names in that sense.

For example:

Set up repository and some directory structure:

$ mkdir repository && cd repository && git init && touch .gitignore
$ mkdir -p foo/fooo/foooo/fooooo.srcs/fooooo bar/barr.srcs/barr/barrr foo/fooo/foooo/fooooo.cache/fooooo

Add some .asd files at various levels in the tree that we want to include:

$ touch foo/file1.asd foo/fooo/foooo/fooooo.srcs/file2.asd bar/barr.srcs/file3.asd bar/barr.srcs/barr/barrr/file4.asd foo/fooo/file5.asd

Majority of the contents of the parent directory hosting the repository is random stuff. The stuff may be files of all sorts of unknown types etc, so specifically declaring everything that should be ignored is not desirable. It is easier (or should be) to declare what we want to include. Add some random stuff:

$ touch huge.pdf asd.yo foo/fooo/foooo/fooooo.cache/foo.txt foo/fooo/foooo/fooooo.cache/fooooo/asd.sh bar/intro.pptx

With an empty .gitignore, all is included:

$ git status -u -s
?? .gitignore
?? asd.yo
?? bar/barr.srcs/barr/barrr/file4.asd
?? bar/barr.srcs/file3.asd
?? bar/intro.pptx
?? foo/file1.asd
?? foo/fooo/file5.asd
?? foo/fooo/foooo/fooooo.cache/foo.txt
?? foo/fooo/foooo/fooooo.cache/fooooo/asd.sh
?? foo/fooo/foooo/fooooo.srcs/file2.asd
?? huge.pdf

I've tried among other the following .gitignore:

*.*
!*/**/*.asd

which only includes file1.asd and file5.asd missing the other 3 .asd files that are within some directories that contain dots in their names. Trying to specifically add one of them reveals the issue:

$ git add foo/fooo/foooo/fooooo.srcs/file2.asd
The following paths are ignored by one of your .gitignore files:
foo/fooo/foooo/fooooo.srcs
Use -f if you really want to add them.

So is it even possible to only see .asd files using only .gitignore in this kind of repository structure? After all the thing pursued here is more of a ".gitinclude" thing which I guess doesn't exist. Of course I could just forget about trying to define the relevant git scope in .gitignore and instead just use git add *.asd in place of git add . but that is not so nice. E.g. VS Code's git extension stays too colorful then as it considers all the irrelevant files in git's scope too.

CodePudding user response:

To defeat Git's .gitignore directory optimization, use:

!*/

In this case you end up with this .gitignore file:

*
!*/
!*.asd

Note that this means that every git status will search every directory in your working tree, regardless of whether that ends up being pointless. So it's a bit CPU-expensive—but it will solve this specific problem.

  • Related