In my repository, I have scripts that generate loads of .json
files, that I want to ignore, so I have *.json
in .gitignore
. But I have one directory config
containing .json
files and I want those to be in version control. I know I can run git add -f config/*.json
, but is there any solution using only .gitignore
to override the previous rules, so that git sees these files automatically without me needing to manually run git add -f ...
?
I have tried these, but none worked:
*.json
!configs
!configs/
!configs/*
!configs/*.json
EDIT: to clarify, both .gitignore
and the configs
directory are both at the the top level of the repository. The structure looks something like this:
repo/
├─ .gitignore
├─ config/
│ ├─ keep_this_1.json
│ ├─ keep_this_2.json
├─ scripts/
│ ├─ results/
│ │ ├─ d1/
│ │ │ ├─ ignore_this.json
│ │ ├─ d2/
│ │ │ ├─ ignore_this_too.json
After seeing the update to your question post, it seems like that your exclusions, and the ones suggested in the answers, did not work due to a typo.
In fact, the original exclusion patterns refer to a configs
folder, while in your directory structure and screenshot, the interested folder appears to be actually called config
(without a trailing s
).
Since both the .gitignore
and the config
folder are on the same level, you can make the rules work with just the two following patterns:
*.json
!config/*.json
The exclusion !configs/*.json
would work only if the .gitignore
and the configs
folder are at the same directory level. In fact, quoting the Pattern Format section of the gitignore documentation:
If there is a separator at the beginning or middle (or both) of the pattern, then the pattern is relative to the directory level of the particular .gitignore file itself. Otherwise the pattern may also match at any level below the .gitignore level.
This means that if the .gitignore
file is defined in the root level of your working directory, while configs
is in a subdirectory, you need to either provide the path to configs
relatively from the .gitignore
:
*.json
!path/relative/from/gitignore/to/configs/*.json
or use the double asterisk to make the pattern match across multiple directory levels:
*.json
!**/configs/*.json
However, this second rule will exclude the json content of any configs
directory in your project. Therefore, if you need to exclude only the json files of a particular configs
folder, this exclusion won't do it. The previous rule is most likely what you need in this scenario.
Just for completeness, I've listed the behavior of each one of your exclusions to better understand what was going on:
*.json
!configs # excludes both files and directories named configs at any level below the .gitignore
!configs/ # excludes only directories named configs at any level below the .gitignore
!configs/* # excludes any content of a directory named configs at the same level of the current .gitignore
!configs/*.json # excludes any json file in a directory named configs at the same level of the current .gitignore