`codegraph index` ran extraction against the already-populated DB without clearing it first. On an unchanged tree every file's content hash still matched, so the orchestrator skipped re-inserting all of them and the run reported its delta (after - before = 0) as "0 nodes, 0 edges" — which read as if `index` had wiped the graph. `init` only ever differed because it runs on a freshly created, empty DB. Clear the existing graph before re-indexing so `index` rebuilds from scratch and reports the same complete result as a fresh `init`. `--force` keeps its role as the home-dir/root-path override; `sync` stays the incremental path. Adds an end-to-end regression test driving the built binary (init -> index), asserting the graph stays populated and the summary is never "0 nodes, 0 edges". Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
ab107b325a
commit
b49147eab0
+13
-10
@@ -602,8 +602,8 @@ program
|
||||
*/
|
||||
program
|
||||
.command('index [path]')
|
||||
.description('Index all files in the project')
|
||||
.option('-f, --force', 'Force full re-index even if already indexed')
|
||||
.description('Rebuild the full index from scratch (same result as a fresh init)')
|
||||
.option('-f, --force', 'Index even if the path looks like your home directory or a filesystem root')
|
||||
.option('-q, --quiet', 'Suppress progress output')
|
||||
.option('-v, --verbose', 'Show detailed worker lifecycle and memory info')
|
||||
.action(async (pathArg: string | undefined, options: { force?: boolean; quiet?: boolean; verbose?: boolean }) => {
|
||||
@@ -611,7 +611,7 @@ program
|
||||
|
||||
try {
|
||||
// Don't (re)index your home directory / a filesystem root (#845). --force
|
||||
// (already "force full re-index") doubles as the override.
|
||||
// doubles as the override.
|
||||
const unsafe = unsafeIndexRootReason(projectPath);
|
||||
if (unsafe && !options.force) {
|
||||
error(`Refusing to index ${projectPath} — it looks like ${unsafe}. Pass --force to override.`);
|
||||
@@ -628,8 +628,9 @@ program
|
||||
const cg = await CodeGraph.open(projectPath);
|
||||
|
||||
if (options.quiet) {
|
||||
// Quiet mode: no UI, just run
|
||||
if (options.force) cg.clear();
|
||||
// Quiet mode: no UI, just run. `index` is a full re-index, so clear the
|
||||
// existing graph and rebuild from scratch (see the note below — #874).
|
||||
cg.clear();
|
||||
const result = await cg.indexAll();
|
||||
if (!result.success) process.exit(1);
|
||||
cg.destroy();
|
||||
@@ -639,10 +640,12 @@ program
|
||||
const clack = await importESM('@clack/prompts');
|
||||
clack.intro('Indexing project');
|
||||
|
||||
if (options.force) {
|
||||
cg.clear();
|
||||
clack.log.info('Cleared existing index');
|
||||
}
|
||||
// `index` is a FULL re-index: clear the existing graph and rebuild it from
|
||||
// scratch so the result is identical to a fresh `init`. Without the clear,
|
||||
// indexAll() skips every unchanged file by its content hash and reports
|
||||
// "0 nodes, 0 edges" against the already-populated graph — which reads as
|
||||
// "index wiped my index" (#874). For fast incremental updates use `sync`.
|
||||
cg.clear();
|
||||
|
||||
let result: IndexResult;
|
||||
|
||||
@@ -890,7 +893,7 @@ program
|
||||
if (reindexRecommended) {
|
||||
const builtWith = buildInfo.version ? `v${buildInfo.version.replace(/^v/, '')}` : 'an earlier version';
|
||||
warn(`Index was built by ${builtWith}; re-index to pick up this engine's improvements.`);
|
||||
info('Run "codegraph index -f" (full rebuild) or "codegraph sync"');
|
||||
info('Run "codegraph index" (full rebuild) or "codegraph sync"');
|
||||
console.log();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user