rgfind
Recover the matches ripgrep silently skips.
cargo install rfrgfind is search that can account for missed results. A plain rg search can
skip gitignored, hidden, and binary files while it still exits successfully.
The rf command recovers these matches and identifies the filter that hid
each one.
The problem: a search that fails silently
By default, ripgrep skips files that .gitignore excludes, hidden files, and
binary files. That is a good default at a terminal. If a search comes up
short, you add -uu and look again.
A program cannot look again. When an agent or a script runs rg, a search
that missed most of the matches still exits 0. The caller thinks the search
succeeded. The problem gets worse when rg is chained with fd, Git history,
or structural search. No stage of the pipe can say what the whole pipeline did
not search.
What rf shows you
Take a repo with the word timeout in three places: a tracked file, a hidden
file, and a gitignored file. Plain ripgrep finds one. rf finds all three and
names the filter that hid each:
$ rf content timeout .
content 'timeout' in . [regex]: 3 file(s), 1 by default, 2 hidden by filters
default config.py
hidden .env.local
vcs_ignore cache/build.py
! IGNORE_VCS: 1 match(es) hidden by default; add -u (ignore .gitignore/.ignore rules)
! HIDDEN_SKIPPED: 1 match(es) hidden by default; add -uu (also search hidden/dotfiles)
$ 'rg' '-u' '-e' 'timeout' '--' '.'
$ 'rg' '-uu' '-e' 'timeout' '--' '.'
Each miss has a warning code and the rg command that finds it.
Commands
rf contentsearches file contents. It removes ripgrep’s default filters one layer at a time — gitignore, hidden, binary, and case — and shows which layer hid each file.rf findruns staged discovery across file names, file contents, Git history, and structural search with ast-grep. It can recover matches that were deleted from the working tree but remain in Git history.rf whytakes one pattern and one file. It tells you whether the file matches and which filter hid it from a normal search.rf doctorreports which ignore rules apply to a path.rf capabilitiesprints the command contract as JSON.
Built for programs that act on search results
Use rf when a program acts on a search result without a person watching: an
agent, a script, or a test. For interactive work, plain rg and fd are
fine.
Every rf command returns one envelope with the same seven keys. An empty
result is a success with no rows, not an error. Exit codes are typed: 0 for
success, 1 for bad input, 3 for an environment error, 5 when the files
changed during paging, and 6 for an internal error. Results page at 100 rows
with a cursor. One command’s file list can feed the next command.
How it works
rf links ripgrep’s and fd’s own Rust crates, ignore and grep, instead of
calling the rg and fd binaries. It reads each file’s filter status while it
walks the tree, so every match keeps a record of where it came from. Git and
ast-grep run as subprocesses. If either tool is absent, rf skips that stage
and reports it.
Start with rf
rf is in early development. Expect breaking changes before 1.0. It is
licensed under Apache 2.0.
cargo install rf
rf content timeout .
See the rgfind documentation for the quickstart, the JSON contract, and the agent guide.