$ git --version
git version 2.6.4
I realize this is a duplicate but the other question\'s answers have not helped.
Folder structure
tl;dr:
/dist/**/*.*
!/dist/**/README.md
!/dist/samples/*.*
Proof it works:
tree dist -a
dist
├── bar
│ └── index.html
├── baz.js
├── foo
│ └── main.js
└── samples
├── README.md
└── stuff.jpg
find dist -type f | git check-ignore --verbose --non-matching --stdin
.gitignore:1:/dist/**/*.* dist/baz.js
.gitignore:2:!/dist/samples/*.* dist/samples/stuff.jpg
.gitignore:2:!/dist/samples/*.* dist/samples/README.md
.gitignore:1:/dist/**/*.* dist/foo/main.js
.gitignore:1:/dist/**/*.* dist/bar/index.html
Like https://stackoverflow.com/a/35279076/2496472 says, the docs mention:
An optional prefix "
!
" which negates the pattern; any matching file excluded by a previous pattern will become included again. It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined.
However, the docs also say:
Two consecutive asterisks ("
**
") in patterns matched against full pathname may have special meaning:
- A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, "
a/**/b
" matches "a/b
", "a/x/b
", "a/x/y/b
" and so on.
Putting this together, the strategy is to never ignore a directory but ignore all files within a directory, and then exclude the file you want.
References: