perf: optimize tracked-file exclusion predicate [CLI-1411] - #698
Closed
basti-snyk wants to merge 2 commits into
Closed
perf: optimize tracked-file exclusion predicate [CLI-1411]#698basti-snyk wants to merge 2 commits into
basti-snyk wants to merge 2 commits into
Conversation
Replace eager O(entries × patterns) index scan with lazy map lookup.
- Build map[string]struct{} of all tracked files (O(n) inserts, no
regex) instead of running gitignoreMatcher.MatchesPath per entry
- Early-exit when allMatcher says not excluded — skip map lookup
- Compile 2 matchers instead of 3 (removed buggy otherMatcher)
- Replace per-file filepath.Rel with strings.TrimPrefix
Benchmark (median, flag=on vs flag=off overhead):
DefinitelyTyped (63k): wall +60%->+4%, mem +73%->+55%
cli (84k): wall +16%->-3%, mem +59%->+4%
juice-shop (129k): wall -13%-> 0%, mem +5%->-1%
trackedFileExclusionPredicate only needs tracked file names, but go-git's repo.Storer.Index() deserializes every index Entry (hash, timestamps, mode, ~160 bytes each), which adds significant memory overhead on repositories with many tracked files. Replace the go-git repo/index loading with a direct binary parser (findDotGit + readTrackedFileNames) that walks up to the .git directory and reads only file names out of the index (v2-v4, including v4 name-prefix compression), skipping every other field. matchingRepositoryRoot is unchanged; it now takes the worktree root resolved by findDotGit instead of go-git's worktree.Filesystem.Root().
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Contributor
Author
|
/describe |
|
PR Description updated to latest commit (acd46f1) |
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.
User description
Summary
.git/indexbinary directly instead of go-git's fullEntrydeserialization — reads only file names, skips hashes/timestamps/modesBenchmark (median, flag=on vs flag=off overhead)
Commits
map[string]struct{}from index names, early-exit whenallMatchersays not excluded, compile 2 matchers instead of 3.git/indexparsing — replacego-gitPlainOpenWithOptions+Storer.Index()with a lightweight binary parser that reads only file names; handles v2/v3/v4, gitlink files (submodules/worktrees)Test plan
TestFileFilter_TrackedFiles*tests pass (real git repos viagit.PlainInit)readTrackedFileNames(v2, v2 long names, v4 prefix compression)findDotGit(found, not found)make lint && make testgreenPR Type
Enhancement
Description
Replaced dependency on
go-gitfor index parsing with custom logic.Optimized tracked file exclusion predicate for performance.
Introduced utilities for finding the
.gitdirectory and parsing index files.Added comprehensive tests for new parsing and discovery utilities.
Diagram Walkthrough
flowchart LR A[FileFilter Context] --> B{Get Tracked Files}; B -- Old way --> C[go-git Index Loader]; B -- New way --> D[findDotGit + Custom Index Parser]; C --> E[All Index Entries Loaded]; D --> F[Only Tracked File Names Parsed]; E --> G[Filter Logic (go-git-dependent)]; F --> H[Filter Logic (custom, performant)];File Walkthrough
file_filter.go
Custom Git index parsing and optimized exclusion predicate.pkg/utils/file_filter.go
go-gitdependency for index operations..git/indexfiles to read onlyfile names.
findDotGitfunction to locate the.gitdirectory and its parentworktree root.
trackedFileExclusionPredicateto use the custom-parsedtracked file names directly, improving performance.
file_filter_test.go
Tests for Git index parsing and .git discovery.pkg/utils/file_filter_test.go
gitIndexV2Entry,gitIndexV4Entry,buildGitIndex) for constructing Git index files for testing.readTrackedFileNames, covering indexversions (v2, v4) and prefix compression.
findDotGitfunction, including scenarioswhere the directory is not found.