fix(advisor): avoid ancestor walks for child repos

This commit is contained in:
can1357
2026-06-27 01:23:19 +02:00
parent 5abe19eda1
commit 979fa4f93e
2 changed files with 25 additions and 7 deletions
@@ -88,15 +88,32 @@ function resolveDirectChildDirectorySync(cwd: string, entry: fs.Dirent): string
}
}
async function hasGitMarker(childPath: string): Promise<boolean> {
try {
const stat = await fsPromises.stat(path.join(childPath, ".git"));
return stat.isDirectory() || stat.isFile();
} catch {
return false;
}
}
function hasGitMarkerSync(childPath: string): boolean {
try {
const stat = fs.statSync(path.join(childPath, ".git"));
return stat.isDirectory() || stat.isFile();
} catch {
return false;
}
}
async function findSingleDirectChildRepo(cwd: string): Promise<ActiveRepoContext | null> {
let context: ActiveRepoContext | null = null;
for (const entry of await readDirectChildren(cwd)) {
const childPath = await resolveDirectChildDirectory(cwd, entry);
if (!childPath) continue;
const repository = await resolveRepository(childPath);
if (!repository || path.resolve(repository.repoRoot) !== path.resolve(childPath)) continue;
if (!(await hasGitMarker(childPath))) continue;
if (context) return null;
context = buildContext(cwd, repository.repoRoot);
context = buildContext(cwd, childPath);
}
return context;
}
@@ -106,10 +123,9 @@ function findSingleDirectChildRepoSync(cwd: string): ActiveRepoContext | null {
for (const entry of readDirectChildrenSync(cwd)) {
const childPath = resolveDirectChildDirectorySync(cwd, entry);
if (!childPath) continue;
const repository = resolveRepositorySync(childPath);
if (!repository || path.resolve(repository.repoRoot) !== path.resolve(childPath)) continue;
if (!hasGitMarkerSync(childPath)) continue;
if (context) return null;
context = buildContext(cwd, repository.repoRoot);
context = buildContext(cwd, childPath);
}
return context;
}
@@ -9,6 +9,8 @@ import {
resolveActiveRepoContextSync,
} from "@oh-my-pi/pi-coding-agent/utils/active-repo-context";
const itWithSymlinkPrivilege = process.platform === "win32" ? it.skip : it;
function createGitDirectory(repoRoot: string): void {
const gitDir = path.join(repoRoot, ".git");
fs.mkdirSync(gitDir, { recursive: true });
@@ -74,7 +76,7 @@ describe("resolveActiveRepoContext", () => {
await expectResolvers(cwd, expected);
});
it("treats a direct child symlink to a repository directory as that child", async () => {
itWithSymlinkPrivilege("treats a direct child symlink to a repository directory as that child", async () => {
const cwd = path.join(tempRoot, "workspace");
const targetRoot = path.join(tempRoot, "target-repo");
const repoRoot = path.join(cwd, "linked-repo");