summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
authorJames Long <[email protected]>2026-03-10 11:11:28 -0400
committerGitHub <[email protected]>2026-03-10 11:11:28 -0400
commit4c4aed5a875e44aec2856c117fa05e861fa62bb5 (patch)
treed8125e4d08698b0fa07ef734e799c92b28091acd /packages
parent5a40158abf02268e4f8fb47870fdc39272f7f697 (diff)
downloadopencode-4c4aed5a875e44aec2856c117fa05e861fa62bb5.tar.gz
opencode-4c4aed5a875e44aec2856c117fa05e861fa62bb5.zip
fix(core): make worktrees read the project id from local workspace (#16795)
Diffstat (limited to 'packages')
-rw-r--r--packages/opencode/src/project/project.ts63
-rw-r--r--packages/opencode/src/worktree/index.ts2
2 files changed, 38 insertions, 27 deletions
diff --git a/packages/opencode/src/project/project.ts b/packages/opencode/src/project/project.ts
index e1fff1a14..68cece0a5 100644
--- a/packages/opencode/src/project/project.ts
+++ b/packages/opencode/src/project/project.ts
@@ -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,
diff --git a/packages/opencode/src/worktree/index.ts b/packages/opencode/src/worktree/index.ts
index 8b5accc33..aa5613010 100644
--- a/packages/opencode/src/worktree/index.ts
+++ b/packages/opencode/src/worktree/index.ts
@@ -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 })
})
}