Repository navigation
Same git remote URL produces identical project_id for different local clones → only one project visible in desktop sidebar #42315
Description
Description
Title (EN)
Same git remote URL produces identical project_id for different local clones → only one project visible in desktop sidebar
标题 (中文)
相同的 git remote URL 导致不同本地 clone 生成相同的 project_id,桌面端侧边栏只能看到一个项目
English version
Description
When two local directories are clones of the same git remote (but on different branches / versions), opencode assigns them the same project_id. As a result, the desktop client aggregates them into a single entry in the sidebar project list, and only the first-added project is usable. The second directory cannot be added/switched to as a separate project.
Environment
- opencode desktop: 1.18.18 (Windows)
- OS: Windows
Reproduction steps
- Clone the same repo into two local directories, e.g.:
/path/to/repo-branchA(branch A)/path/to/repo-branchB(branch B)
- Both have the same remote origin URL:
origin https://git.example.com/group/repo.git - Add both directories as projects in the desktop client.
- Observe the sidebar: only one project entry is shown.
Expected behavior
Both directories should be listed as separate projects (or at least be switchable), since they are different working directories with different branches.
Actual behavior
Both directories resolve to the same project_id:
<sha1 hash>
which is sha1("git-remote:git.example.com/group/repo").
The desktop sidebar deduplicates by project_id, so only the first-added project is visible.
Root cause (from source inspection)
In Project.resolve (node-4IhTfWZ9.js around line 85716), the project_id is resolved with this priority:
sha1("git-remote:" + normalizedRemoteUrl)← always wins when a remote is set- cached value in
.git/opencode - root commit hash (
git rev-list --max-parents=0 HEAD)
Since both clones share the same remote URL, step 1 produces an identical id, and the fallbacks are never reached. Even the root-commit fallback would be identical here because both clones share the same root commit.
The project_directory table already supports a many-to-one mapping (PK is (project_id, directory)), so the data layer can hold multiple directories per project. The limitation is in the UI, which aggregates by project_id only.
Why this matters
For developers who maintain multiple versions/branches of the same repo side-by-side (e.g. a maintenance branch + a development branch), this makes it impossible to manage them as separate projects in the desktop client.
Suggested improvements (any of)
- UI: Show distinct entries per
directoryeven when they share aproject_id(theproject_directorytable already supports this). - ID resolution: Incorporate the local working directory (or branch) into the
project_idas a tiebreaker when remote URLs collide, e.g.sha1("git-remote:" + remote + ":" + worktreePath)orsha1(remote + "@" + branch). - Workspace: Allow registering an existing independent clone directory as a workspace target (currently workspaces only support
git worktree-linked directories).
中文版
问题描述
当两个本地目录是同一个 git remote 的 clone(但分支/版本不同)时,opencode 会给它们分配相同的 project_id。这导致桌面端在侧边栏的项目列表里把两者聚合成一条,只能看到最先添加的那个项目,第二个目录无法作为独立项目添加/切换使用。
环境信息
- opencode 桌面端:1.18.18(Windows)
- 操作系统:Windows
复现步骤
- 把同一个仓库 clone 到两个本地目录,例如:
/path/to/repo-branchA(分支 A)/path/to/repo-branchB(分支 B)
- 两者的 remote origin URL 相同:
origin https://git.example.com/group/repo.git - 在桌面端把这两个目录都添加为项目。
- 观察侧边栏:只显示了一个项目条目。
期望行为
两个目录应作为独立项目展示(或至少可切换),因为它们是不同的工作目录、不同分支。
实际行为
两个目录解析出了相同的 project_id:
<sha1 hash>
即 sha1("git-remote:git.example.com/group/repo")。
桌面端侧边栏按 project_id 去重,因此只显示最先添加的项目。
根因(源码分析)
在 Project.resolve(node-4IhTfWZ9.js 约 85716 行)中,project_id 按以下优先级解析:
sha1("git-remote:" + 规范化后的 remote URL)← 只要设置了 remote 就一定命中.git/opencode缓存文件- root commit hash(
git rev-list --max-parents=0 HEAD)
由于两个 clone 的 remote URL 相同,第 1 步就产生相同 id,fallback 永远不会触发。即便走到 fallback,root commit 也相同(同源仓库),结果仍会一致。
project_directory 表本身已支持多目录映射(主键是 (project_id, directory) 联合主键),数据层可以容纳同一 project_id 下的多个目录。限制在 UI 层——只按 project_id 聚合展示。
为什么这很重要
对于需要并行维护同一仓库多个版本/分支的开发者(例如同时维护某个维护分支和开发另一个分支),这导致无法在桌面端把它们作为独立项目来管理。
建议改进(任选其一)
- UI:即使
project_id相同,也按directory展示不同条目(project_directory表已支持)。 - ID 解析:当 remote URL 冲突时,把本地工作目录(或分支)纳入
project_id计算,例如sha1("git-remote:" + remote + ":" + worktreePath)或sha1(remote + "@" + branch)。 - Workspace:允许把已有的独立 clone 目录注册为 workspace 目标(目前 workspace 只支持
git worktree关联的目录)。
Plugins
No response
OpenCode version
No response
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response
Activity
github-actions commentedon Aug 13, 2026
This issue might be a duplicate of existing issues. Please check:
Please review those issues and consider whether your report adds new information before continuing.
benizzio-opencode commentedon Aug 18, 2026
Confirmed on OpenCode Desktop 1.18.18 on Linux.
We had two clones at different paths with the same basename and the same
originURL. After closing clone A and selecting clone B, Desktop reopened clone A. The local database showed exactly the collision described here:Both directories resolved to the same project ID. Closing the project in the Desktop UI only removed sidebar state; it did not remove or replace the canonical
projectrow, so selecting B was normalized back to A.Our tested workaround was intentionally destructive because we no longer needed A or its OpenCode session history:
~/.local/share/opencode/opencode.dbwith SQLite's.backup, plus~/.config/ai.opencode.desktop/opencode.global.dat, the activeopencode.window.*.dat, and A's hashedopencode.workspace.*.dat.opencode.db. This cascades to its sessions, messages, permissions, and bothproject_directorymappings.serverandglobalSync.projectstate inopencode.global.dat, remove A's notification/layout/session cache entries, remove its window tab entry, and remove A's hashed workspace state file.server.projects.local[0]andlastProject.local, then restart Desktop.On restart, OpenCode recreated the same Git-derived project ID with:
There were no remaining A directory/session/cache references, and Desktop opened B normally.
Important: deleting the shared project row removes session history for that project ID, so this workaround is only appropriate when the old history can be discarded. Editing
opencode.global.datalone was not enough because the stale canonical path also lived inopencode.db.Hona commentedon Sep 2, 2026
Fixed for opencode2 launch via #46713
You can try the desktop beta here: https://github.com/anomalyco/opencode-beta