Skip to content

fix(sync): filter git-status fast path through ignore matcher#922

Open
itxaiohanglover wants to merge 1 commit into
colbymchenry:mainfrom
itxaiohanglover:fix/sync-ignore-matcher
Open

fix(sync): filter git-status fast path through ignore matcher#922
itxaiohanglover wants to merge 1 commit into
colbymchenry:mainfrom
itxaiohanglover:fix/sync-ignore-matcher

Conversation

@itxaiohanglover

Copy link
Copy Markdown

What

Fixes #766

The incremental sync's git fast path consumed git status --porcelain output without filtering through buildDefaultIgnore, so tracked files in default-ignored dirs (node_modules/, vendor/, etc.) leaked back into the index on every sync — disagreeing with a full index --force.

The fix

Build the shared buildDefaultIgnore(this.rootDir) matcher once and continue past ignored paths in the modified+added loop. Deleted files stay unfiltered — removal is always correct for stale entries, and it lets a newly-excluded dir's old entries clean up.

Same approach suggested by @monochrome3694 in the issue, verified locally on a ~1,100-file workspace.

Testing

  • Added regression test: commits a .ts file inside node_modules/, modifies it, and verifies sync() does not index it (filesAdded: 0, filesModified: 0).
  • All 15 existing + new sync tests pass.
  • tsc --noEmit clean.

The incremental sync's git fast path consumed `git status --porcelain`
output without filtering through `buildDefaultIgnore`, so tracked files
in default-ignored dirs (node_modules/, vendor/, etc.) leaked back into
the index on every sync — disagreeing with a full `index --force`.

Build the matcher once and skip ignored paths in the modified+added
loop. Deleted files stay unfiltered (removal is always correct for
stale entries).

Closes colbymchenry#766

@psandeep02 psandeep02 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The added code appears to:
Create an ignore matcher:
TypeScript
const ig = buildDefaultIgnore(this.rootDir);
Loop through modified and added Git files:
TypeScript
for (const filePath of [...gitChanges.modified, ...gitChanges.added]) {
Skip files that match .gitignore or default ignore patterns:
TypeScript
if (ig.ignores(filePath)) continue;
Why this is useful
The comments explain the intent clearly:
Prevent tracked files inside ignored directories (such as vendor/) from being indexed.
Ensure behavior matches the same ignore rules used elsewhere (getGitVisibleFiles).
Avoid indexing files that Git reports as changed but should be ignored.
Positive points
✅ Good explanatory comments.
✅ Reuses existing ignore logic instead of creating new rules.
✅ Helps maintain consistency between file discovery and indexing.
✅ Likely fixes the issue mentioned (#766) by preventing ignored files from leaking into the index.
Things to verify
⚠️ Ensure buildDefaultIgnore(this.rootDir) is not recreated repeatedly in a hot path if this function runs frequently.
⚠️ Confirm that intentionally tracked files inside ignored directories should indeed be skipped. Some repositories commit files under directories that are normally ignored.
⚠️ Add or verify unit tests for:
Files ignored by .gitignore
Tracked files inside ignored folders
Modified files not ignored
Added files not ignored
Overall Review
Rating: 8.5/10
The change is clean, readable, and appears to solve a real edge case while keeping behavior consistent with Git visibility rules. The comments are especially helpful for future maintainers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incremental sync (git-status fast path) bypasses the ignore matcher — tracked files in excluded dirs leak back into the index

2 participants