Why does glob pattern with double asterisk not match anything in subdirectories?

git, gitignore, glob

Solution

First, make sure you are using Git 1.8.2 or up, since that's when `**` support was introduced.

It sounds like you're trying to exclude `.keepme` files by matching `*.*`. However, since `*` matches zero or more characters, it matches the empty string in front of the period in `.keepme`, including this file as well.

Maybe you intended it to work like `out/**/?*.*`

If you'd like to match all non-dotfiles, you can use `out/**/[!.]*` which will also include filenames without periods in them, like `Makefile`.

Problem

I'm trying to write a `.gitignore` rule to exclude some files in a particular directory that has multiple levels of subdirectories. The folder structure looks something like this: ``` out ├─a │ ├─source │ │ ├─.keepme │ │ ├─183597.txt │ │ ├─271129.txt │ │ └─288833.txt │ └─parsed │ ├─.keepme │ ├─183597.csv │ ├─271129.csv │ └─288833.csv ├─b │ └─(...) (etc.) ``` I would like to keep the `.keepme` files (so that Git saves the directory structure), so I figure I'll write a rule to match anything under `out` that matches the pattern `?*.*`: ``` out/**/?*.* ``` However, this does not match any files. I thought that `**` will match any number of subdirectories; why is this not working? I'm running Git 1.8 in Bash 4.2 on a Fedora 18 VM.

Original source