fix(grep): keep the glob attached to --include so MSYS cannot expand it - #78
Merged
shauryagangrade merged 2 commits intoAug 14, 2026
Conversation
grep passed the filter as two arguments, ["--include", glob]. On Windows the
grep found on PATH is normally Git for Windows' MSYS build, and its runtime
glob-expands a bare "*" argument against the *current* directory before grep
parses it. The filter then names whatever file sorted first in the cwd, so a
search of any other directory silently reports "No matches".
That is the whole tool failing, not an edge case: with Git installed,
shutil.which("grep") finds it, so every grep call takes this path.
Reproduced directly -- cwd holding one unrelated file, searching a temp tree
that contains two matches:
--include * rc=1 matches=0 <- expansion hits the cwd
--include=* rc=0 matches=2
omitted rc=0 matches=2
Attaching the glob to the flag hides it from that expansion, and is
equivalent everywhere else. Filtering is unaffected: --include=*.py still
selects only .py files.
This is why tests/test_tools.py::test_grep and ::test_grep_ignore_case fail
on a Windows checkout of main.
Tests: the two existing greps now pass; three added. Two assert the command
shape rather than the result, because both spellings behave identically
without the MSYS runtime -- on a Linux runner a revert would otherwise stay
green. The third checks end-to-end that a glob still filters.
This was referenced Aug 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
greppassed the filter as two arguments:On Windows the
grepfound onPATHis normally Git for Windows' MSYS build, and its runtime glob-expands a bare*argument against the current directory before grep parses it. The filter then names whatever file sorted first in the cwd, so a search of any other directory silently reportsNo matches.This isn't an edge case — with Git installed,
shutil.which("grep")finds it, so everygrepcall takes this path. The tool returns "no matches" for everything.It's also why
tests/test_tools.py::test_grepand::test_grep_ignore_casefail on a Windows checkout ofmain:Reproduction
cwd holding one unrelated file, searching a temp tree containing two matches:
Fix
One character — attach the glob to the flag,
--include=<glob>. MSYS doesn't expand a token containing=, and the two spellings are equivalent to GNU grep everywhere else.I preferred this to the alternatives: omitting
--includewhenglob == "*"fixes only the default and leaves*.pymangled, and settingMSYS=noglobin the environment is a bigger hammer that affects the whole child process.Filtering is unaffected:
Tests
The two existing greps now pass. Three added:
test_grep_passes_include_as_one_argumentandtest_grep_include_defaults_to_everythingassert the command shape, not the result. This is deliberate: without the MSYS runtime both spellings behave identically, so on a Linux runner a revert to the two-argument form would otherwise stay green.test_grep_filters_by_globchecks end-to-end that a glob still selects files.Against
main(stashing onlygcode/tools.py): 5 failed, 17 passed. With the fix, the full suite is 57 passed — up from 52 passed / 2 failed.ruff checkclean.Found while looking at #63 (differential tests,
_grep_pythonvs system grep) — that issue is a good idea independently, since this class of divergence is exactly what it would catch. Happy to send it separately.