Skip to content

Order-dependent .rgignore bug with multiple explicit search roots #3320

@markusylisiurunen

Description

@markusylisiurunen

Please tick this box to confirm you have reviewed the above.

  • I have a different issue.

What version of ripgrep are you using?

ripgrep 15.1.0

features:+pcre2
simd(compile):+NEON
simd(runtime):+NEON

PCRE2 10.45 is available (JIT is available)

How did you install ripgrep?

Homebrew

What operating system are you using ripgrep on?

macOS 15.7.4

Describe your bug.

rg appears to handle .rgignore inconsistently when multiple explicit search roots are provided.

In a minimal repro with:

  • .rgignore containing beta/**/*.svg
  • alpha/a.txt containing AWS
  • beta/x.svg containing AWS

the command:

rg --files-with-matches -n 'AWS' alpha beta

incorrectly returns beta/x.svg, even though it matches the ignore rule.

If I run the same search with the roots reversed:

rg --files-with-matches -n 'AWS' beta alpha

then beta/x.svg is correctly ignored.

So the bug seems to be that .rgignore handling is order-dependent when multiple explicit search roots are passed to ripgrep.

What are the steps to reproduce the behavior?

Create this minimal repro directory:

.
├── .rgignore
├── alpha/
│   └── a.txt
└── beta/
    └── x.svg

With these contents:

.rgignore

beta/**/*.svg

alpha/a.txt

AWS

beta/x.svg

AWS

Then run these commands from that directory:

rg --files-with-matches -n 'AWS' beta
rg --files-with-matches -n 'AWS' alpha beta
rg --files-with-matches -n 'AWS' beta alpha

You can also reproduce it with this shell script:

mkdir repro && cd repro
mkdir -p alpha beta
printf 'beta/**/*.svg\n' > .rgignore
printf 'AWS\n' > alpha/a.txt
printf 'AWS\n' > beta/x.svg

rg --files-with-matches -n 'AWS' beta
rg --files-with-matches -n 'AWS' alpha beta
rg --files-with-matches -n 'AWS' beta alpha

What is the actual behavior?

The result depends on the order of the explicit search roots.

Command:

rg --files-with-matches -n 'AWS' alpha beta

Actual output:

alpha/a.txt
beta/x.svg

But beta/x.svg should be ignored by .rgignore because it matches:

beta/**/*.svg

If I swap the root order:

rg --files-with-matches -n 'AWS' beta alpha

the output changes to:

alpha/a.txt

which is what I expect.

--debug for the working order shows that ripgrep does recognize the ignore rule and ignores beta/x.svg:

rg --debug --files-with-matches -n 'AWS' beta alpha

Relevant debug output:

rg: DEBUG|ignore::walk|crates/ignore/src/walk.rs:1942: ignoring beta/x.svg: Ignore(IgnoreMatch(Gitignore(Glob { from: Some("/path/to/repro/.rgignore"), original: "beta/**/*.svg", actual: "beta/**/*.svg", is_whitelist: false, is_only_dir: false })))

So the bug appears to be that ignore handling is order-dependent when multiple explicit search roots are provided.

What is the expected behavior?

Both commands should produce the same result regardless of the order of the explicit search roots, and both should respect .rgignore.

Given this ignore rule:

beta/**/*.svg

beta/x.svg should never be searched.

So both of these commands:

rg --files-with-matches -n 'AWS' alpha beta
rg --files-with-matches -n 'AWS' beta alpha

should return:

alpha/a.txt

and should not report beta/x.svg.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions