ripgrep
ripgrep copied to clipboard
Inconsistent behavior with negation pattern in `.gitignore`
Please tick this box to confirm you have reviewed the above.
- [X] I have a different issue.
What version of ripgrep are you using?
ripgrep 13.0.0 -SIMD -AVX (compiled) +SIMD +AVX (runtime)
How did you install ripgrep?
Using nix
What operating system are you using ripgrep on?
NixOS 23.11
Describe your bug.
See below. Feels related to https://github.com/BurntSushi/ripgrep/issues/1050 but I think they're different.
What are the steps to reproduce the behavior?
Make a repo with:
.gitignore
build/
!/some_dir/build/
some_dir/build/foo
string
What is the actual behavior?
> rg -l string
some_dir/build/foo
> rg -l string some_dir
# nothing
> rg -l string some_dir/build
some_dir/build/foo
What is the expected behavior?
rg -l string some_dir
should find the file too.
Please try the latest release of ripgrep.
Oh, sorry, that appears to be fixed in 14.0
Ah nope, still a bug but it requires one more level of nesting:
ripgrep 14.1.0
features:-simd-accel,-pcre2
simd(compile):+SSE2,-SSSE3,-AVX2
simd(runtime):+SSE2,+SSSE3,+AVX2
PCRE2 is not available in this build of ripgrep.
.gitignore
build/
!/some_dir/subdir/build/
some_dir/subdir/build/foo
string
What is the actual behavior?
> rg -l string
some_dir/subdir/build/foo
> rg -l string some_dir
# nothing
> rg -l string some_dir/subdir
some_dir/subdir/build/foo
> rg -l string some_dir/subdir/build
some_dir/subdir/build/foo
I can reproduce this with the ignore
crate directly and
use ignore::Walk;
fn main() {
for result in Walk::new("./some_dir") {
match result {
Ok(entry) => println!("{}", entry.path().display()),
Err(err) => println!("ERROR: {}", err),
}
}
}
(with the CWD in the directory with the .gitignore
)
This is probably a duplicate of an existing bug, but they are difficult to find.
There are several open issues related to gitignore support that I don't plan on fixing until I've had a chance to rethink the ignore crate from first principles. It might happen within the next year.
I found a similar bug when using wildcards in .gitignore
. Let me know, if I should open a new issue.
Script to reproduce the bug:
#!/usr/bin/env sh
mkdir -p bug/foo/bar && cd bug
git init
echo "baz" > foo/bar/baz.txt
echo "/foo/bar/baz*.txt" > .gitignore
rg -l baz
# Output:
# rg: No files were searched, which means ripgrep probably applied a filter you didn't expect.
# Running with --debug will show why files are being skipped.
rg -l baz foo/
# Output:
# foo/bar/baz.txt
Version:
ripgrep 14.1.0
features:-simd-accel,+pcre2
simd(compile):+SSE2,-SSSE3,-AVX2
simd(runtime):+SSE2,+SSSE3,+AVX2
PCRE2 10.42 is available (JIT is available)
Actually, I just realized that the wildcard isn't even needed. The bug is reproducible with a .gitignore
containing /foo/bar/baz.txt
(see script in my previous comment).
It may be worth looking at https://github.com/Byron/gitoxide/tree/main/gix-ignore when refactoring, or somehow pulling in the logic from it as a library.