Searching code from the command line: ripgrep, ugrep or git grep, and which files each one sees
For assistants asked to find text in a code tree, this feature compares the three recorded search tools on the same six authored files. headlesson ran ripgrep 15.1.0, ugrep 7.8.5 and git grep 2.50.1 (Apple Git-155) on macOS: once the set of files to search was made the same, the matching file, line and text agreed, but each tool picks a different default set of files and prints a different machine format, and git grep exited 128 for a bad pattern while ripgrep and ugrep exited 2. It is a small sample, not a speed or full compatibility comparison.
Which files get searched by default
- The six authored files were .gitignore, .hidden.py, src/main.rs, src/util.py, build/out.txt and app.log, with .gitignore listing the last two. ripgrep (rg) (
app:ripgrep), ugrep (app:ugrep) and git grep (Git subcommand) (app:git-grep) were given byte-identical copies. - ripgrep (rg) (
app:ripgrep) skips ignored and hidden files by default, but applies .gitignore only inside a Git repository; in a separate authored tree used in its 2026-10-11 test, a copy without .git returned matches from ignored files, so --no-require-git was needed. - ugrep (
app:ugrep) uses .gitignore only when --ignore-files is given, and --hidden adds hidden files. - git grep (Git subcommand) (
app:git-grep) searches tracked files by default, including a tracked hidden file: 2 matches here. --untracked gave 3, --untracked --no-exclude-standard gave 5, and --no-index --exclude-standard gave 3. - Editorial advice, not tested beyond these files: state the directory and the hidden and ignore rules explicitly with ripgrep (rg) (
app:ripgrep), ugrep (app:ugrep) or git grep (Git subcommand) (app:git-grep) rather than relying on defaults, and check whether ignored or hidden files such as .env may be read before widening the search.
Observed in the tests
- With the hidden and ignore rules set to match, ripgrep (rg) (
app:ripgrep) and git grep (Git subcommand) (app:git-grep) returned the same file, line number and text for the 3-match and 5-match cases, and ripgrep (rg) (app:ripgrep) and ugrep (app:ugrep) agreed on the ordinary (2) and hidden (3) cases. Output order was not compared. - Machine output differs: ripgrep (rg) (
app:ripgrep) --json prints JSON Lines events, ugrep (app:ugrep) --json prints one JSON array of files with nested matches, and git grep (Git subcommand) (app:git-grep) was read through -n -z, which separates file, line number and text with NUL bytes and is not JSON. The sets were compared after decoding. - No match exited 1 with ripgrep (rg) (
app:ripgrep), ugrep (app:ugrep) and git grep (Git subcommand) (app:git-grep). An invalid pattern "(" exited 2 with ripgrep (rg) (app:ripgrep) and ugrep (app:ugrep) but 128 with git grep (Git subcommand) (app:git-grep), so a caller cannot treat every non-zero exit as "no match". - Each lesson passed all of its steps: ripgrep (rg) (
app:ripgrep) with the Homebrew build already installed (2026-10-11), ugrep (app:ugrep) built from pinned source with optional PCRE2, Boost Regex and compression libraries turned off, and git grep (Git subcommand) (app:git-grep) with the Git that ships with macOS and every command isolated from the user's Git configuration with env -i and configuration controls.
What was not tested
The comparison of ripgrep (rg) (app:ripgrep), ugrep (app:ugrep) and git grep (Git subcommand) (app:git-grep) used six small files. Binary files, Unicode, multiline matches, file names containing newlines, symlinks, full regex compatibility, ugrep's TUI and compressed-file search, speed and memory were not tested; ugrep (app:ugrep) was not rerun for the git grep comparison, only its saved inputs were checked byte for byte. headlesson_get with sections ["lesson","gotchas"] on each ID gives the exact commands, versions and failure conditions.
Records cited
Each line gives the record, its public page if there is one, and where its name comes from.
- ripgrep (rg) —
app:ripgrep(no public page yet; available over MCP); source: https://github.com/BurntSushi/ripgrep/blob/master/README.md (checked 2026-10-11, primary, official) - ugrep —
app:ugrep(no public page yet; available over MCP); source: https://github.com/Genivia/ugrep/blob/v7.8.5/README.md (checked 2026-10-14, primary, official) - git grep (Git subcommand) —
app:git-grep(no public page yet; available over MCP); source: https://github.com/git/git/blob/v2.50.1/Documentation/git-grep.adoc (checked 2026-10-14, primary, official)
Article source
headlesson editorial judgement (checked 2026-10-14, inferred, editorial).
Retrieve over MCP
headlesson_get id="feature:code-search" on https://mcp.headlesson.com/mcp