Skip to content
Merged
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
8 changes: 8 additions & 0 deletions src/db/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,14 @@ export function findDbPath(customPath?: string): string {
debug(`findDbPath: stopped at git ceiling ${ceiling}`);
break;
}
// Outside a git repo, cwd is the first (and only) directory we'll check.
// Walking past it risks attaching to a stale .codegraph/ in an unrelated
// parent — e.g. /private/tmp/.codegraph/ leaking into every /tmp/foo/ run,
// or $HOME/.codegraph/ leaking into every scratch dir under $HOME.
if (!ceiling) {
debug(`findDbPath: no git ceiling, stopping at ${dir}`);
break;
}
const parent = path.dirname(dir);
if (parent === dir) break;
dir = parent;
Expand Down
27 changes: 27 additions & 0 deletions tests/unit/db.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,33 @@ describe('findDbPath with git ceiling', () => {
fs.rmSync(emptyDir, { recursive: true, force: true });
}
});

it('does not pick up stale parent .codegraph/ when no git repo exists', () => {
// Regression for the Phase 0 footgun (dogfood report 10.6): when no git
// repo wraps cwd, findDbPath used to walk all the way to `/`, latching
// onto stale .codegraph/ from unrelated parents (e.g. /private/tmp/).
const parentDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cg-stale-parent-'));
fs.mkdirSync(path.join(parentDir, '.codegraph'), { recursive: true });
fs.writeFileSync(path.join(parentDir, '.codegraph', 'graph.db'), '');
const innerDir = path.join(parentDir, 'inner');
fs.mkdirSync(innerDir, { recursive: true });
const origCwd = process.cwd;
process.cwd = () => innerDir;
_resetRepoRootCache();
execFileSyncSpy.mockImplementationOnce(() => {
throw new Error('not a git repo');
});
try {
const result = findDbPath();
// Must NOT return the stale parent's DB.
expect(result).not.toBe(path.join(parentDir, '.codegraph', 'graph.db'));
// Falls back to the default path at cwd.
expect(result).toBe(path.join(innerDir, '.codegraph', 'graph.db'));
} finally {
process.cwd = origCwd;
fs.rmSync(parentDir, { recursive: true, force: true });
}
});
});

describe('openReadonlyOrFail', () => {
Expand Down
Loading