fix: adopt new worktree when a project repository is moved - #42933
fix: adopt new worktree when a project repository is moved#42933jonathangn wants to merge 1 commit into
Conversation
|
This PR doesn't fully meet our contributing guidelines and PR template. What needs to be fixed:
Please edit this PR description to address the above within 2 hours, or it will be automatically closed. If you believe this was flagged incorrectly, please let a maintainer know. |
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
|
The following comment was made by an LLM, it may be inaccurate: Found potential related PRs:
I recommend checking if PR #38584 was a previous attempt at this issue or if there's overlap in the solution approach. |
|
Closing this in favor of existing work: this duplicates #38584 (same fix, same files, more thorough) and #35311 (the maintainer-preferred approach). Nothing lost — the regression tests and analysis are preserved in this branch (fix/moved-repo-worktree) and in the PR history if anyone wants to reuse them. |
Problem
When a project's repository is moved or renamed on disk (e.g. the folder is moved to a parent directory), opencode keeps using the old worktree path:
Project.fromDirectoryalways keepsexisting.worktreefor existing (non-global) projects, even when that path no longer exists. The resolved new checkout is only ever added tosandboxes, never adopted as the project's worktree.InstanceStore.bootuses the requested directory verbatim as the instance/session directory. If a client passes a stale path (as the desktop does from its persisted project state), the instance boots with a non-existent directory.The result: "New conversation" fails with
ENOENT/FileSystem.realPatherrors until the user manually edits the database. Repros happen whenever the repo root is moved up to its parent (e.g.G:/.../AlgoTrading/EA Admirals->G:/.../AlgoTrading), so the old worktree is now a dead child of the new git root.Fix
Two complementary server-side changes:
Project.fromDirectory(packages/opencode/src/project/project.ts): if the project's canonicalworktreeno longer exists on disk and the repository still resolves to a valid checkout, adopt the resolved git worktree (data.directory) as the new canonical worktree. Existing sessions rooted at the old worktree are re-pointed to the new directory, so old conversations keep working.InstanceStore.boot(packages/opencode/src/project/instance-store.ts): when the requested directory does not exist butfromDirectoryresolved it to a non-global git project, boot the instance in the resolved worktree (result.sandbox) instead of the stale path. This makes both new sessions and loading old sessions succeed even when a client passes a path that no longer exists.Tests
Project.fromDirectory with worktrees > adopts a moved checkout as the project worktree when the original is gone— moves a repo and asserts the project adopts the new worktree.InstanceStore > boots into the resolved worktree when the requested directory no longer exists— loads an instance at a non-existent child of a git root and asserts it boots into the resolved worktree.Both new tests pass; the existing
projectandinstance-storesuites pass (47/47).tsgo --noEmitandoxlintare clean on the touched files.