Fix bugs with negative ignores inside an ignored parent directory

Consider a negative matching rule to "match" a parent directory of the rule, so that we will iterate into the directory when there are negative matching rules for inside the directory. When we consider individual files inside the directory, if they don't hit the negative match rule, they will still be considered ignored files if they match the parent ignore rule. Also, always allow the negative rule to match as a leading directory so files underneath it will not be ignored.

The crazy hoops we've had to jump through regarding this ignore file logic stem go back to a design decision that I considered an optimization at the time I wrote it. Unlike core Git, libgit2 iterates over the working directory explicitly and as a result, considers which ignore rules apply to files incrementally as it scans. This seemed like a lighter weight approach to me. Unfortunately, it means we have all these special cases to handle applying ignore rules to intermediate directory paths.

I think the better long term fix is to rip out all of this special logic and just stop trying to apply ignore rules to directories as we iterate and only evaluate ignore rules against actual files. This way we will only use the full matching logic and don't have to worry about how to assess a path that is a prefix of the file we actually care about.

However, as a short term fix, I think this PR will correct the immediate problems. I'll leave it to the rest of the contributors to decide if we want to merge this short term fix or if you want to hold out for the better fix of eliminating ignore tests on intermediate directory paths altogether.

Fixes #2406 and fixes #2423 and contains the commits from both those PRs with tests.