fix(sync): stop reporting git-untracked files as pending after sync (#206) (#218)

Both git fast-paths in ExtractionOrchestrator (sync and getChangedFiles)
classified every untracked (`??`) file as "added" without checking the
index. Indexing a file doesn't make git track it, so the file stayed `??`
and was re-reported as pending and re-indexed on every run: `codegraph
status` listed it under Pending Changes forever and each `sync` re-added
it, even though its symbols were already queryable.

Merge the modified + added handling into a single hash-compared loop so
untracked files get the same treatment as tracked ones: "added" only if
missing from the index, "modified" if contents changed, skipped otherwise.
The non-git fallback path already did this and is unchanged.

Closes #206. Reported by @15290391025.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Colby Mchenry
2026-05-20 12:15:54 -05:00
committed by GitHub
co-authored by Claude Opus 4.7
parent 07c093cc3f
commit a47355780b
3 changed files with 67 additions and 16 deletions
+11 -16
View File
@@ -1261,8 +1261,12 @@ export class ExtractionOrchestrator {
}
}
// Handle modified files — read + hash only these files
for (const filePath of gitChanges.modified) {
// Handle modified + added files — read + hash only these. Untracked
// (`??`) files stay untracked in git even after we index them, so they
// can't be trusted as "new": re-hash and compare against the DB exactly
// like modified files. Otherwise every sync re-indexes them and status
// reports them as pending forever. (See issue #206.)
for (const filePath of [...gitChanges.modified, ...gitChanges.added]) {
const fullPath = path.join(this.rootDir, filePath);
let content: string;
try {
@@ -1285,13 +1289,6 @@ export class ExtractionOrchestrator {
filesModified++;
}
}
// Handle added (untracked) files
for (const filePath of gitChanges.added) {
filesToIndex.push(filePath);
changedFilePaths.push(filePath);
filesAdded++;
}
} else {
// === Fallback: full scan (non-git project or git failure) ===
const currentFiles = new Set(scanDirectory(this.rootDir, this.config));
@@ -1395,8 +1392,11 @@ export class ExtractionOrchestrator {
}
}
// Modified files — read + hash only these, compare with DB
for (const filePath of gitChanges.modified) {
// Modified + added files — read + hash, compare with DB. Untracked (`??`)
// 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.)
for (const filePath of [...gitChanges.modified, ...gitChanges.added]) {
const fullPath = path.join(this.rootDir, filePath);
let content: string;
try {
@@ -1416,11 +1416,6 @@ export class ExtractionOrchestrator {
}
}
// Added (untracked) files
for (const filePath of gitChanges.added) {
added.push(filePath);
}
return { added, modified, removed };
}