gitignore negation patterns are not honored for directories: * + !*/ ignores the entire repo
Summary
ag does not correctly handle the common .gitignore idiom for ignoring extensionless files (POSIX binaries):
.gitignore
*
!*.*
!*/Git interprets this as "ignore everything, then un-ignore anything with a dot and all directories," so only extensionless files are ignored. ag applies the * pattern to directories before considering the !*/ negation, so every directory is treated as ignored and their contents are never searched. In practice ag returns results only from files with a dot in the repo root and silently skips the rest of the repository.
Steps to reproduce
mkdir agtest && cd agtest
printf '*\n!*.*\n!*/\n' > .gitignore
echo 'needle in text' > readme.txt
echo 'needle in binary' > mybinary
mkdir src
echo 'needle in source' > src/main.c
ag needleExpected behavior
Matches git's interpretation (verify with git init -q . && git status --porcelain --ignored, which marks only mybinary as ignored):
readme.txt:1:needle in text
src/main.c:1:needle in sourceActual behavior
readme.txt:1:needle in textsrc/main.c is never searched because the src directory is considered ignored. In a real repo this means almost all files are skipped.
Source: ggreer/the_silver_searcher