Skip to content

grep returns no results when the workspace path contains an ignored directory name #576

Description

@Dhevenddra

Summary

grep silently returns zero matches when the workspace lives under a directory whose name is in _IGNORE_DIRS (build, dist, target, venv, node_modules, AppData, Library, and the rest). Only the ripgrep engine is affected. The pure-Python fallback is fine.

This is separate from #17. That issue is about how ripgrep's output is parsed; this one is about which files ripgrep is asked to search in the first place. I checked #123's diff and re-ran with its exact flags, and it does not change this behaviour.

Cause

grep hands ripgrep an absolute path and excludes directories with a glob per name:

for ignored in sorted(_IGNORE_DIRS):
    cmd += ["--glob", f"!**/{ignored}/**"]
cmd.append(str(base))

!**/build/** is matched against the entire absolute path, not against the part below the workspace root. So a workspace at C:\Dev\build\myproject matches its own exclusion, every file is filtered out, and rg exits 1 with no output and no error.

_py_grep filters directory names during the walk below base, so it only ever excludes descendants. The two engines disagree, which is the thing the comment above the exclusions says should not happen:

Do not rely solely on a workspace's .gitignore: the Python fallback always omits these generated/dependency directories too.

Reproduction

Measured on Windows 11, Python 3.11.9, ripgrep 15.1.0. Identical file contents in both workspaces:

from coworker.tools.search import search_tools

for p in (r"C:\Dev\build\myproject", r"C:\Dev\normal\myproject"):
    out = search_tools(p)[0](pattern="hello")
    print(p, out["engine"], out["count"])
workspace engine matches
C:\Dev\build\myproject ripgrep 0
C:\Dev\normal\myproject ripgrep 1

The only difference between the two is the name of a parent directory.

Since the cause is a glob matched against an absolute path, this is not specific to Windows. A workspace at ~/build/myproject, ~/Library/notes or anything under a dist or venv parent should behave the same way on Linux and macOS. I have only measured the Windows case, so treat the POSIX half as reasoning rather than evidence.

Why CI does not catch it

tests/test_code_tools.py::test_grep_finds_matches_and_respects_glob uses pytest's tmp_path. On Linux that resolves under /tmp, which contains no ignored name, so the test passes. On Windows tmp_path lands under %TEMP%, which sits under AppData, so the same test fails today.

One consequence worth flagging: because the cause is the search path and not the parsing, that test will still fail on Windows after #123 merges.

Suggested fix

Run ripgrep with cwd=base and pass "." as the target. ripgrep then emits workspace-relative paths, the exclusion globs match relative to the workspace, and a node_modules directory inside the workspace is still excluded correctly. _rel would resolve against base instead of the process working directory.

I have that working locally and verified it against both cases above. Happy to open a PR if you want it, and happy to leave it alone if you would rather fold it into #123.

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