Skip to content

fix(opencode): use git common dir for project ID cache to prevent worktree session loss#16389

Open
michaeldwan wants to merge 1 commit intoanomalyco:devfrom
michaeldwan:md/orphaned-project-ids
Open

fix(opencode): use git common dir for project ID cache to prevent worktree session loss#16389
michaeldwan wants to merge 1 commit intoanomalyco:devfrom
michaeldwan:md/orphaned-project-ids

Conversation

@michaeldwan
Copy link

Issue for this PR

Closes #12726
Closes #12103
Closes #13782
Closes #5638

Type of change

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

What does this PR do?

Sessions disappear after restarting opencode in a git worktree. Two problems:

  1. Cache location: The project ID cache (opencode file) was read/written inside the per-worktree .git path. In a worktree that's a file, not a directory, so reads and writes silently failed. Every restart recomputed the ID from scratch.

  2. Unstable ID computation: rev-list --max-parents=0 --all includes orphan branches (gh-pages, stash roots, subtree merges). The sorted first root commit can change depending on which orphan refs exist, producing a different project ID and orphaning all previous sessions.

Fix: resolve --show-toplevel and --git-common-dir before touching the cache so it lives in the shared .git directory. All worktrees (and independent clones) for the same repo now resolve the same project ID. Switched --all to HEAD so orphan branches can't shift the root commit set.

Are you affected?

Run this to check if any of your repos have fragmented project IDs (sessions split across multiple IDs for the same repo):

opencode db "SELECT worktree, count(distinct id) as project_ids, sum(sessions) as total_sessions FROM (SELECT p.id, p.worktree, count(s.id) as sessions FROM project p JOIN session s ON s.project_id = p.id GROUP BY p.id) GROUP BY worktree HAVING project_ids > 1 ORDER BY total_sessions DESC;"

No output = not affected. If you see rows, project_ids is how many fragments exist and total_sessions is how many sessions are scattered across them.

How did you verify your code works?

  • tsgo --noEmit — 0 errors
  • bun test test/project/project.test.ts — 19 pass, 0 fail
  • New tests: worktree shares project ID with main repo + cache lands in shared .git dir; separate clone of the same repo resolves the same project ID

Screenshots / recordings

No UI changes.

Checklist

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

…tree session loss

Worktrees resolve .git to a per-worktree file, so caching the project ID
there fails silently. Each restart recomputes the ID via rev-list --all,
which is unstable for repos with orphan branches (gh-pages, stash roots).
This causes sessions to become invisible after restarting opencode in a
worktree.

- Resolve --show-toplevel and --git-common-dir before reading the cache
- Store and read the project ID cache from the shared .git directory
- Switch rev-list from --all to HEAD to exclude orphan branches
- Set local git config in test fixture for reproducible test runs
@github-actions
Copy link
Contributor

github-actions bot commented Mar 6, 2026

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

Found a potential related PR:

PR #14287: "fix(project): repair split project IDs across worktrees"
#14287

Why it's related: This PR directly addresses the same issue of split/fragmented project IDs across worktrees. The current PR (16389) appears to be a more comprehensive fix that uses git-common-dir to prevent the issue at the source, while PR #14287 likely focused on repairing already-split IDs. These may be complementary solutions or one may supersede the other.

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

Labels

None yet

Projects

None yet

1 participant