Reificator
Why is git ignoring this file?

Here’s a quick tip if you’ve ever struggled with an excluded file or directory in git, but couldn’t find the offending line in your .gitignore file.

The Problem

I was recently working on a project in git that was vendoring its dependencies, including them in the repository for reproducible builds. I’m not generally used to working with git in this manner, and upon installing a new test runner we were unable to actually run it on the build server. It turned out the /bin folder for the test runner was being excluded.

I’ll just search .gitignore for bin!

I thought it’d be simple: a file was being ignored, so we’ll go remove that pattern from the .gitignore. But after removing several lines saying bin, Bin/, and the like, it still wasn’t being seen.

Finding the real culprit

After some quick Google-Fu, I found out that git has this built in, in the form of git check-ignore.

Check-ignore takes a path, and returns ignored files in that path. Giving it a wildcard like **/* you can check everywhere, or you can specify something like vendor/**/* or even /vendor/excluded-file to drill down to something more specific. Because I knew there were a lot of files being excluded I just piped the wildcard output to grep, but use whatever you’re comfortable with.

But in the end listing off files that are ignored doesn’t really help you if you’ve already tracked that down yourself. Really what you want to do is figure out what rule is ignoring those files, and that’s where the verbose -v flag comes in.

That gives us the following commands, just replace PATH with whatever you’re looking for.

# Piping to grep

git check-ignore -v **/* | grep PATH

# Specifying the path with various wildcards

git check-ignore -v PATH

git check-ignore -v PATH/*

git check-ignore -v PATH/**/*

git check-ignore -v **/PATH**/*

It turns out that it was the Visual Studio .gitignore provided by the Github community. Specifically they were checking for a case insensitive [Bb]in/, which didn’t show up in a find in my editor.

To be fair, I’d have found it pretty quickly just by reading from top to bottom instead of searching. The beauty of this command is that it gives some insight into how the rules actually work; it’s worth remembering and/or clipping the documentation for that alone.