Skip to content

fix (core): Multiple clones of same repo are different projects#35311

Open
belisoful wants to merge 13 commits into
anomalyco:devfrom
belisoful:dev
Open

fix (core): Multiple clones of same repo are different projects#35311
belisoful wants to merge 13 commits into
anomalyco:devfrom
belisoful:dev

Conversation

@belisoful

@belisoful belisoful commented Jul 4, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #17940 #19348 #29869 #29871 #29962 #29936 #29977 #30302 #31593 #31686 #31890 #32785 #32801 #33313 #33615

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

This PR changes .git/opencode from the hash of the repo name to json; with a version and UUID. This UUID per repo-clone (locally) satisfies work trees being keyed to their respective repo-clones and separating repo-clones from each other (locally).

The file is automatically upgraded if the file is not json/UUID format. The upgrade path is automatic.

The GUI touches the project on open to ensure consistency.

Changing the path (or folder name) of a repo-clone keeps the same UUID. The project stops working in the GUI... when the new moved project is opened then the session and work trees are updated. The old project (and session data) is updated to the new path; with the old project sessions updated to the new project path-location.

How did you verify your code works?

  • New unit tests to verify behavior.
  • GUI test for Open Project on already open project, regression passed.
  • GUI test for Open Project on the same repo cloned in two different locations do open in separate projects.

Screenshots / recordings

N/A

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions github-actions Bot added needs:title needs:compliance This means the issue will auto-close after 2 hours. labels Jul 4, 2026
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Hey! Your PR title Multiple clones of same repo are different projects - Fixes: #29869 doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Based on my search results, I found a related PR:

Potential Related PR:

  • PR fix(project): repair split project IDs across worktrees #14287 - fix(project): repair split project IDs across worktrees
    • This PR appears to address a similar concern about worktrees and project ID separation, which is related to the core issue of distinguishing multiple clones of the same repository as different projects.

Note: PR #29977 (fix(core): include git store hash in project ID to distinguish indepe…) also appeared in results but may be an older or related attempt at solving a similar problem.

The current PR (#35311) appears to be focused specifically on changing .git/opencode to store JSON with a version and UUID to uniquely identify repo clones, which is a different approach to solving the worktree/project separation problem that PR #14287 addresses.

@belisoful belisoful changed the title Multiple clones of same repo are different projects - Fixes: #29869 fix: Multiple clones of same repo are different projects - #29869 Jul 4, 2026
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Jul 4, 2026
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@belisoful

belisoful commented Jul 6, 2026

Copy link
Copy Markdown
Author

I did a GUI test to check that different clones of the same repo are separate "projects".
"Open Project" on an existing repo-clone brings up that repo-clone, like before.

I wanted to actually do a real test myself before submitting this PR. (Ed: Done; checked and confirmed working)

We are seeing this issue re-listed over and over.

@belisoful belisoful marked this pull request as ready for review July 6, 2026 04:32
@belisoful belisoful changed the title fix: Multiple clones of same repo are different projects - #29869 fix (projects): Multiple clones of same repo are different projects - #29869 Jul 6, 2026
@belisoful belisoful changed the title fix (projects): Multiple clones of same repo are different projects - #29869 fix (core): Multiple clones of same repo are different projects - #29869 Jul 6, 2026
@belisoful belisoful marked this pull request as draft July 6, 2026 08:43
@belisoful

Copy link
Copy Markdown
Author

The GUI side is now updated because it was keying from the repo-clone path.
Also, when a directory is moved, then re-opened, the internal session and work trees are updated to the new location.

@belisoful belisoful marked this pull request as ready for review July 6, 2026 21:58
@belisoful belisoful requested a review from Hona as a code owner July 6, 2026 21:58
@belisoful belisoful requested a review from Brendonovich as a code owner July 6, 2026 21:58
@belisoful belisoful changed the title fix (core): Multiple clones of same repo are different projects - #29869 fix (core/app): Multiple clones of same repo are different projects - #29869 Jul 6, 2026
@belisoful belisoful changed the title fix (core/app): Multiple clones of same repo are different projects - #29869 fix (core): Multiple clones of same repo are different projects - #29869 Jul 6, 2026
@belisoful belisoful changed the title fix (core): Multiple clones of same repo are different projects - #29869 fix (core): Multiple clones of same repo are different projects Jul 6, 2026
@rifqi2320

rifqi2320 commented Jul 7, 2026

Copy link
Copy Markdown

I looked through this because it is the core/server side of the repeated Desktop clone-collision reports (#29869/#32785/#33615). The UUID-in-git-common-dir approach looks like the right shape to me: separate clones get separate durable IDs, linked worktrees still share a common identity, and path moves avoid the git-store-path hash problem from #29977.

One migration edge case I think is still worth checking before merge: in migrateProjectId, all WorkspaceTable rows for the legacy shared ID are moved to the first minted project (where project_id = oldID). The later exact-directory reclaim only updates SessionTable rows (SessionTable.directory = data.directory). If a user already has the bug-era state with clone B stored as a sandbox under clone A, and there are WorkspaceTable rows whose directory belongs to clone B, opening A first appears to move those workspace rows to A's new project ID; opening B later creates B's new project ID and reclaims B's sessions, but not B's workspace rows. Since Workspace.list(project) filters by project_id, those workspaces may remain attached to the wrong clone.

Maybe the same exact-directory/under-directory repair used for sessions should also apply to WorkspaceTable rows with a non-null directory when a sibling clone is re-opened.

Local verification I could run here:

  • packages/app: bun test src/context/project-moves.test.ts passed
  • packages/opencode: bun typecheck passed
  • packages/app: bun typecheck passed

I could not run the Git-backed backend tests locally because this environment uses Snap Bun, which cannot spawn host /usr/bin/git even by absolute path (ENOENT: posix_spawn /usr/bin/git).

@belisoful

belisoful commented Jul 7, 2026

Copy link
Copy Markdown
Author

I think you are correct about the migration edge case.

The fix for the specified migration edge case will be up some time later today.

OpenCode really needs this refactor, the bug is preventing real work from being completed

@belisoful

belisoful commented Jul 8, 2026

Copy link
Copy Markdown
Author

In the bug-era merged state, migrateProjectId bulk-moves all WorkspaceTable rows for the shared legacy id to whichever clone is opened first, and the later reclaim only repaired SessionTable.

Updated

Workspace reclaim. The exact-directory adoption in fromDirectory now applies to WorkspaceTable rows with a non-null directory as well (project_id != mine AND directory = opened directory), so a sibling clone re-opened after the split takes its workspaces back along with its sessions. Covered in the merged-clones split test, which now seeds a workspace at clone B's directory and asserts it lands on B's minted project. Kept exact-match rather than under-directory: prefix matching could adopt rows belonging to a nested checkout inside the clone (repo-in-repo), and those must stay with the nested project. Exact match can't collide with a nested root.

Fixed as suggested.

Two related issues your scenario surfaced:

  1. Storage-path directory strings. The migration renames data/worktree// on disk when re-keying storage, but sessions and workspaces running inside managed worktrees reference those paths in their directory column — after the rename they would have pointed at dead paths. Migration now rewrites those strings to the new id's storage path (same helper the moved-folder re-home uses), with a test seeding a session under data/worktree//… and asserting it follows the re-key.
  2. Worktree-first contact. For workspaces whose directory is a managed-worktree path, attribution during the split isn't possible by directory (their paths live under the storage root, not under either clone), so they initially follow the first-opened clone. They do self-correct without the sibling ever being re-opened: workspace requests route by the workspace's own directory (workspace-routing.ts → RequestPlan.Local), which boots an instance whose git common dir resolves to the true clone — minting its identity if needed — and the same exact-directory reclaim re-files the row on first use. Verifying that path end-to-end exposed a pre-existing wart it would have tripped over: a repo first contacted through a linked worktree adopted the worktree path as its permanent project root (and later filed its real root as a sandbox of itself). fromDirectory now derives the project root from the git common dir (/.git → ) on worktree-first contact, with a regression test, and the two older tests that encoded first-contact-wins as expected behavior were updated accordingly.

The Agent suggests:

With that, the only residual is cosmetic and transient: a managed-worktree workspace may be listed under the sibling clone between the one-time split migration and its first use, at which point it re-files itself. I'd defer any eager per-row attribution during migration (a git resolution per workspace row, in a path every user runs once) unless someone reports that mislabel actually biting.

If you find the cosmetic and transient issue an issue, I'll fix that too. The trade off is between a git resolution per workspace row and the "cosmetic/transient" managed-worktree workspace being listed in the wrong repo-clone until first use (where it then moves to the correct project). This is a very rare condition because workspaces are currently gated behind OPENCODE_EXPERIMENTAL_WORKSPACES and not many are using it(? right?).

Thanks also for flagging the Snap Bun / posix_spawn limitation — for the record, the git-backed suites pass here: 96 tests / 0 fail across test/project/ (one platform-conditional skip), plus typecheck on packages/opencode and packages/app.

@belisoful

belisoful commented Jul 12, 2026

Copy link
Copy Markdown
Author

@rifqi2320 The PR for "Multiple clones of same repo are different projects #35311" is updated.

If you find the cosmetic/transient issue a problem, I'll fix that too. The trade off is between a git resolution per workspace row and the "cosmetic/transient" managed-worktree workspace being listed in the wrong repo-clone until first use (where it then [without notice-indication] moves to the correct project; disappearing from the project it was misfiled). This is a very rare condition because workspaces are currently gated behind OPENCODE_EXPERIMENTAL_WORKSPACES and not many are using it? no?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multiple local clones of same repo share one project identity, breaking file change tracking

2 participants