I have the following files & directory structure in my git project.
conf/.gitignore
conf/_conf.example
conf/conf.sh
conf/init/_init.example
conf/init/init.sh
The git ignore is written as:
# Ignore all files except the examples.
*
!.gitignore
!_conf.example
!init/_init.example
I've added the .gitignore to git. All files are ignored except for conf.sh, which resides in the same directory as the .gitignore file. My intent is not to ignore the _init.example file in the nested init directory, but my configuration is not doing this correctly.
Any ideas what I'm doing wrong?
The problem is that *
excludes the conf subdirectory so no further rules will ever be evaluated with respect to it. Then the same argument applies to the subsequent init subdirectory, and so on.
Generally, you undo *
by including back the directory to be examined, for example:
*
!conf
And depending on your version of git you may have to go on and add,
!conf/init
!conf/init/_init.example
but from my experience it is best to avoid the asterisk entirely in non-leaf .gitignore
files. Simply be specific about the files you want to exclude, recreating the directory structure where necessary, as part of your .gitignore
hierarchy.
The following is subjective: I always found it easier to have one top-level .gitignore
file in the repository, where all ignores are spelled out explicitly, coupled with simple globbing for file extensions.
Further, the recent git check-ignore
addition to git is useful to debug the more complex ignore scenarios, but, subjectively again, I prefer not to get into them to begin with.