perf(claude.sh): expand .claudeignore with a pruning find walk #25
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "perf/claudeignore-pruning"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Each pattern was expanded with bash globstar, once per pattern. Bash
cannot prune, so every pattern re-walked the whole workspace including
the subtrees the ignore file itself hides -- on a 127k-path fixture,
99.2% of walked paths were inside node_modules/ and .git/, both listed
in .claudeignore. Matches under an already-tmpfs'd directory were
emitted as mounts too, though an empty tmpfs already hides them.
Patterns now become path-aware regexes fed to find(1), which prunes at
each matching directory. On that fixture a typical 6-pattern file goes
from 0.72s to 0.05s; node_modules/ + .git/ + '**/*.js' goes from 3.67s
and 240,027 arguments to 0.02s and 27. The old form was not merely slow:
7.36MB of argv against a 2MB ARG_MAX fails the exec outright.
Also fixes three defects in the code being replaced:
word-split and matched nothing, silently leaving the file visible.
spaces left one behind. Previously masked by the word-splitting.
Verified against the previous implementation over 800 fuzzed patterns:
the only divergence is that a pattern segment no longer reaches through
a symlinked directory, since find does not follow one. Documented in
README, pinned by a test, and the target stays hidden under its real
path. Adds tests/test_claudeignore.sh (27 tests); the feature had none.
Claude-Session: https://claude.ai/code/session_01NNo6M8YqCf7DrUDq6jBjF9
Each pattern was expanded with bash globstar, once per pattern. Bash cannot prune, so every pattern re-walked the whole workspace including the subtrees the ignore file itself hides -- on a 127k-path fixture, 99.2% of walked paths were inside node_modules/ and .git/, both listed in .claudeignore. Matches under an already-tmpfs'd directory were emitted as mounts too, though an empty tmpfs already hides them. Patterns now become path-aware regexes fed to find(1), which prunes at each matching directory. On that fixture a typical 6-pattern file goes from 0.72s to 0.05s; node_modules/ + .git/ + '**/*.js' goes from 3.67s and 240,027 arguments to 0.02s and 27. The old form was not merely slow: 7.36MB of argv against a 2MB ARG_MAX fails the exec outright. Also fixes three defects in the code being replaced: - hits=($pat) was unquoted, so a pattern containing a space was word-split and matched nothing, silently leaving the file visible. - ${pattern%%[[:space:]]} strips one character, so two trailing spaces left one behind. Previously masked by the word-splitting. - The summary counted argv entries, reporting twice the path count. Verified against the previous implementation over 800 fuzzed patterns: the only divergence is that a pattern segment no longer reaches through a symlinked directory, since find does not follow one. Documented in README, pinned by a test, and the target stays hidden under its real path. Adds tests/test_claudeignore.sh (27 tests); the feature had none. Claude-Session: https://claude.ai/code/session_01NNo6M8YqCf7DrUDq6jBjF9