I have deeply nested files that I would like to include in source control and have git
track them.
Example is:
Projects/
.git/
StrategicProject/
SpecificProject1/
Method1/
doc/
*.tex
.gitignore
In each of the various folders there are other files/folders that I would not like to track. I only want to track, say, all of the .tex
files in Projects/StrategicProject/SpecificProject1/Method1/doc/
As of now, to accomplish this, I have in my .gitignore
file:
StrategicProject/* # ignore everything under this, exceptions below
!StrategicProject/SpecificProject1/ # don't ignore this
StrategicProject/SpecificProject1/* # ignore everything under this, exceptions below
!StrategicProject/SpecificProject1/Method1/ # don't ignore this
StrategicProject/SpecificProject1/Method1/* # ignore everything under this, exceptions below
!StrategicProject/SpecificProject1/Method1/doc/ # don't ignore this
StrategicProject/SpecificProject1/Method1/doc/* # ignore everything under this, exceptions below
!StrategicProject/SpecificProject1/Method1/doc/*.tex # don't ignore this
The above works, but is prone to error when I create a new folder structure in my working directory. It is also quite cumbersome. To track one set of .tex
files in a nested folder needs creation of 8 lines in the .gitignore
file. A fellow-SO user created an web-app to ease this specific difficult activity. See here
While that app works fine for now, it only works over the web. More generally, is there a gui app, that works offline (without having to use the internet), that can take a look at my folder structure and allows me to check/uncheck boxes (as part of its user interface) corresponding to files/folders and based on that automatically generate the appropriate .gitignore
file?
ETA:
I use VSCode's default Git interface. While that does provide option to right click on a file and add it to .gitignore
, that is not what I would like. I would like to not ignore a specific deeply nested set of files. I am open to trying out other editors for this task.
There is one useful, albeit somewhat computationally expensive, trick you can use. As you've seen, if you ignore a directory, Git never looks inside the directory, making it impossible to un-ignore files nested deeper under the directory. This generally saves Git a lot of time: git status
has to recursively look at everything in the working tree, except that every time it hits an ignored directory, it doesn't have to look at anything there. Since lstat
-ing each entity in each directory in a recursive travel of the working tree is usually the slowest part of a Git working-tree operation, bypassing some of these calls helps out a lot.
Still, you can prevent Git from bypassing directories at all by simply making sure that !*/
is the last entry in each .gitignore
file. No matter where Git is in its traversal, this last entry says if you encounter a directory, look inside it. Now you no longer need careful and explicit stuff like:
StrategicProject/*
!StrategicProject/SpecificProject1/
StrategicProject/SpecificProject1/*
!StrategicProject/SpecificProject1/Method1/
StrategicProject/SpecificProject1/Method1/*
!StrategicProject/SpecificProject1/Method1/doc/
StrategicProject/SpecificProject1/Method1/doc/*
!StrategicProject/SpecificProject1/Method1/doc/*.tex
as you can simply list files that should be ignored; Git will always be searching everywhere.
I think Git should automatically insert exceptions as needed. That is, we should be able to write:
*.o
generated-docs
!generated-docs/*.in
and Git should figure out that this "means", e.g.:
generated-docs/*
!generated-docs/*.in
That is, the fact that we've excepted something within generated-docs
means that Git should look inside generated-docs
, even though the default is to skip over files that may be found there.