fix(core): make worktrees read the project id from local workspace (#16795)

This commit is contained in:
James Long 2026-03-10 11:11:28 -04:00 committed by GitHub
parent 5a40158abf
commit 4c4aed5a87
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 27 deletions

View File

@ -88,6 +88,12 @@ export namespace Project {
}
}
function readCachedId(dir: string) {
return Filesystem.readText(path.join(dir, "opencode"))
.then((x) => x.trim())
.catch(() => undefined)
}
export async function fromDirectory(directory: string) {
log.info("fromDirectory", { directory })
@ -101,19 +107,43 @@ export namespace Project {
const gitBinary = which("git")
// cached id calculation
let id = await Filesystem.readText(path.join(dotgit, "opencode"))
.then((x) => x.trim())
.catch(() => undefined)
let id = await readCachedId(dotgit)
if (!gitBinary) {
return {
id: id ?? "global",
worktree: sandbox,
sandbox: sandbox,
sandbox,
vcs: Info.shape.vcs.parse(Flag.OPENCODE_FAKE_VCS),
}
}
const worktree = await git(["rev-parse", "--git-common-dir"], {
cwd: sandbox,
})
.then(async (result) => {
const common = gitpath(sandbox, await result.text())
// Avoid going to parent of sandbox when git-common-dir is empty.
return common === sandbox ? sandbox : path.dirname(common)
})
.catch(() => undefined)
if (!worktree) {
return {
id: id ?? "global",
worktree: sandbox,
sandbox,
vcs: Info.shape.vcs.parse(Flag.OPENCODE_FAKE_VCS),
}
}
// In the case of a git worktree, it can't cache the id
// because `.git` is not a folder, but it always needs the
// same project id as the common dir, so we resolve it now
if (id == null) {
id = await readCachedId(path.join(worktree, ".git"))
}
// generate id from root commit
if (!id) {
const roots = await git(["rev-list", "--max-parents=0", "--all"], {
@ -132,7 +162,7 @@ export namespace Project {
return {
id: "global",
worktree: sandbox,
sandbox: sandbox,
sandbox,
vcs: Info.shape.vcs.parse(Flag.OPENCODE_FAKE_VCS),
}
}
@ -147,7 +177,7 @@ export namespace Project {
return {
id: "global",
worktree: sandbox,
sandbox: sandbox,
sandbox,
vcs: "git",
}
}
@ -161,33 +191,14 @@ export namespace Project {
if (!top) {
return {
id,
sandbox,
worktree: sandbox,
sandbox,
vcs: Info.shape.vcs.parse(Flag.OPENCODE_FAKE_VCS),
}
}
sandbox = top
const worktree = await git(["rev-parse", "--git-common-dir"], {
cwd: sandbox,
})
.then(async (result) => {
const common = gitpath(sandbox, await result.text())
// Avoid going to parent of sandbox when git-common-dir is empty.
return common === sandbox ? sandbox : path.dirname(common)
})
.catch(() => undefined)
if (!worktree) {
return {
id,
sandbox,
worktree: sandbox,
vcs: Info.shape.vcs.parse(Flag.OPENCODE_FAKE_VCS),
}
}
return {
id,
sandbox,

View File

@ -413,7 +413,7 @@ export namespace Worktree {
await runStartScripts(info.directory, { projectID, extra })
}
void start().catch((error) => {
return start().catch((error) => {
log.error("worktree start task failed", { directory: info.directory, error })
})
}