fix(core): include git store hash in project ID to distinguish indepe…#29977
fix(core): include git store hash in project ID to distinguish indepe…#29977FQXCS wants to merge 7 commits into
Conversation
…ndent clones Previously, project ID was derived solely from the normalized git remote URL, causing independent clones of the same repository to share the same project ID and merge into a single project (with one clone becoming a sandbox). Now the ID includes a short hash of the git store path, so clones with different .git stores produce distinct project IDs while worktrees (which share the same store) continue to share the same ID.
avarayr
left a comment
There was a problem hiding this comment.
Left comments. You need to make sure tests pass. The tests are not passing
Also, for users who already merged two clones, migrateProjectId copies the old row's sandboxes onto the new-ID row, so the desktop client's rootFor keeps redirecting the second clone to the first. New adds are fixed, but already-merged state isn't. Worth a repair migration (or pruning sandboxes whose git store differs from the worktree's).
|
#35311 is a better solution. It simply puts a UUID in each repo-clone instead of a repo hash. It also uses JSON in .git/opencode instead of writing the value directly to the file. This is a much more adaptable solution and is future proof. It checks if the repo hash is formatted as a UUID, if not then OpenCode knows it needs to upgrade the project key If you use a include a hash of the git store path, the project will break upon renaming the folder. |
Previously, project ID was derived solely from the normalized git remote URL, causing independent clones of the same repository to share the same project ID and merge into a single project (with one clone becoming a sandbox). Now the ID includes a short hash of the git store path, so clones with different .git stores produce distinct project IDs while worktrees (which share the same store) continue to share the same ID.
Issue for this PR
Closes #29869
Type of change
What does this PR do?
When adding two independent clones of the same repository (different directories, different
.gitstores) in the desktop app, they were incorrectly merged into a single project — one clone became the "worktree" and the other became a "sandbox". This happened because the project ID was derived only from the normalized git remote URL (sha1("git-remote:github.com/owner/repo")), which is identical for both clones.This PR fixes the issue by including a short SHA1 hash of the git store path in the project ID calculation. The store path is the
.gitdirectory returned bygit rev-parse --git-common-dir. This means:.gitstores) → different IDs → two separate projects ✅.gitstore) → same ID → correctly merged as one project ✅Changes:
packages/core/src/util/hash.ts— addedHash.short()for a 14-char truncated SHA1 hashpackages/core/src/project.ts—remote()androot()now include|${storeHash}in the ID inputcore/test/project.test.tsandopencode/test/project/project.test.tsto reflect the new behaviorHow did you verify your code works?
Ran both test suites:
bun test test/project.test.ts(packages/core) — 10/10 passedbun test test/project/project.test.ts(packages/opencode) — 36/36 passedbun typecheckpassed for both packagesExisting tests validate that worktrees still share project IDs, while the renamed test "separate clones of the same repo should have different project IDs" confirms independent clones now produce distinct IDs.
Screenshots / recordings
No UI changes.
Checklist