« Back to Index

Git: How to ignore root file but not a sub directory of the same name

View original Gist on GitHub

Tags: #git #ignore

How to ignore root file but not a sub directory of the same name.md

Imagine you have the following tree structure:

.
├── cmd
│   └── fastly
├── fastly

You want to avoid commiting the fastly file in the root, but you’re OK with cmd/fastly being committed.

To achieve this we need to use a specific wildcard glob that at first glance appears unintuitive:

**/fastly
!cmd/fastly

What the first line does is match both ./fastly and ./cmd/fastly, while the second line allows you to negate the ./cmd/fastly.

Originally, the first line was set to fastly but it turns out if you do that, the second line will no longer work because the first line is matched anywhere in the path, and that means gitignore cannot negate files inside an an already ignored directory (which this would do, i.e. fastly isn’t ignoring the root fastly file, it’s ignoring anything that contains fastly).

The reason **/fastly didn’t immediately spring to mind for me is because I read it as matching any subdirectory containing fastly (e.g. it would match cmd/fastly), when in fact the **/ is misleading because it will match either ./ or <some-directory-name>/ and that’s why it works to match ./fastly and ./cmd/fastly and thus we can safely negate the second line of our gitignore, because we’ve not just blanket ignored every possible folder containing fastly, we have this time in fact constrained our match to include the root file.