Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions __tests__/sync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,5 +302,37 @@ describe('Sync Module', () => {
expect(result.filesRemoved).toBe(0);
expect(result.changedFilePaths).toBeUndefined();
});

it('should not index tracked files in default-ignored dirs (issue #766)', async () => {
// Create a committed file inside node_modules/ (a default-ignored dir).
// git status reports changes to tracked files even when they match
// DEFAULT_IGNORE_PATTERNS — the sync git fast path must filter them.
const nmDir = path.join(testDir, 'node_modules', 'pkg');
fs.mkdirSync(nmDir, { recursive: true });
fs.writeFileSync(
path.join(nmDir, 'index.ts'),
`export function depFunc() { return 'original'; }`
);
git('add', '-A');
git('commit', '-m', 'add dependency');

// Full index excludes node_modules/ — depFunc is NOT in the graph.
await cg.indexAll();
expect(cg.searchNodes('depFunc').length).toBe(0);

// Modify the tracked file inside node_modules/.
fs.writeFileSync(
path.join(nmDir, 'index.ts'),
`export function depFunc() { return 'modified'; }`
);

// sync() must NOT pick up the change — the file is in an ignored dir.
const result = await cg.sync();
expect(result.filesAdded).toBe(0);
expect(result.filesModified).toBe(0);

// depFunc is still not in the graph.
expect(cg.searchNodes('depFunc').length).toBe(0);
});
});
});
8 changes: 8 additions & 0 deletions src/extraction/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1810,7 +1810,15 @@ export class ExtractionOrchestrator {
// files stay untracked in git even after indexing, so they must be
// hash-compared like modified files instead of always counting as added —
// otherwise status reports them as pending forever. (See issue #206.)
//
// Filter through the same ignore matcher used by getGitVisibleFiles so
// tracked files in excluded dirs (e.g. a committed `vendor/`) don't leak
// back into the index. git status reports changes to tracked files even
// when they match DEFAULT_IGNORE_PATTERNS or a .gitignore entry. (#766)
const ig = buildDefaultIgnore(this.rootDir);
for (const filePath of [...gitChanges.modified, ...gitChanges.added]) {
if (ig.ignores(filePath)) continue;

const fullPath = path.join(this.rootDir, filePath);
let content: string;
try {
Expand Down