Repository navigation
fix(core): give unborn git repos their own project id - #61249
nanoscopic wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
The fix works. I ran a small throwaway test against both checkouts: on the base, two fresh git init folders both resolve to global; with this change they get separate project ids and both show up in project.list. After the first commit the id moves to the root commit, and the old directory id is reported as previous, so the sessions follow it. The project, session-create and session-projector tests pass (107), and typecheck:tsc is clean.
Public API: unchanged. No new endpoints, events or schema fields. Only the project id that git init folders with no commits resolve to changes, from global to Hash.fast("directory:" + path).
Sessions already filed under global for an unborn repo are moved over on the next resolve, since the projector always checks global. Repos that already have an id now also get the directory id as previous, which only adds one empty session lookup when a folder's worktree row is first recorded.
One concern is left inline: after the first commit, the unborn project row stays behind as a second, empty project for the same folder.
| const resolved: Resolved = { | ||
| previous, | ||
| id: id ?? ID.global, | ||
| previous: previous ?? (identity ? directoryID : undefined), |
There was a problem hiding this comment.
Sessions move from the directory id to the new id, but the directory-id project row stays. I checked: git init → resolve → first commit → resolve, then project.list returns two projects with the same canonical, the new root-commit one and the old empty one. The old row's directory still exists, so the archive sweep never removes it. On the base the leftover row was global, which the app filters out (project.id === "global"). This one isn't filtered, so every fresh repo will show up twice in the desktop project list after its first commit (similar to #61009 / #61104). Could the previous row be archived or merged once its sessions have been moved, at least when previous is this directory id?
There was a problem hiding this comment.
Good catch. Fixed in f993152: once the worktree event has moved sessions from the directory id, the superseded project row is archived (not deleted). A new test covers git init -> resolve -> first commit -> resolve and asserts the old id disappears from project.list and is listed with ime.archived. A marker-file previous is left alone; only the directory-derived id is archived.
A repository with an unborn HEAD has no remote or root commit, so Project.resolve fell back to the shared global project. Every fresh 'git init' directory then shared one session pool, and the desktop showed the first resolved directory instead of the project. Use the same directory-derived identity as markerless directories for unborn repos. When a remote or root commit appears later, expose the directory id as 'previous' so the session projector moves existing sessions onto the upgraded identity, then archive the placeholder project row so the directory is not listed twice.
81ad377 to
f993152
Compare
There was a problem hiding this comment.
The new commits fix the leftover-project concern. After the first commit, the old unborn-repo project is now archived, so the folder isn't listed twice. In my throwaway test (two git init folders, a commit in one, resolve again), project.list returns one project for that folder, the old row appears only with archived: true, and the other repo stays active. The project, session-create, session-projector and session-move tests pass (124, 1 skipped), and typecheck:tsc is clean.
Public API: unchanged. The archive uses the existing project-updated event; nothing is added or changed.
No new concerns.
|
Heads-up: the same shared- const id = previous ?? (yield* hgRoot(worktree))
...
id: id ?? ID.global,A Mercurial checkout with no cached id and no root changeset (e.g. fresh The same treatment applied here (directory-derived identity + reporting it as Independent confirmation of the approach: I reproduced the git-side collapse from real machine state (20+ unrelated directories sharing |
Issue for this PR
Closes #55133
Refs #50979
Type of change
What does this PR do?
A repository with an unborn
HEADhas no remote and no root commit, soProject.resolvefell back to the sharedglobalproject. Every freshlygit init-ed directory therefore shared one session pool, and the desktop showed the first resolved directory instead of the new project.Give unborn repositories the same directory-derived id that markerless directories already use (
Hash.fast("directory:" + path)). Unrelated fresh repositories now resolve to distinct project ids and show up as their own projects.When a remote or root commit appears later, the directory id is reported as
previous. The existingworktree.resolvedprojection moves sessions frompreviousonto the new id, then the superseded directory-id project row is archived so the same directory is not listed twice. Theglobalproject is no longer written for these directories, which also stops it from being re-pointed at whichever empty repo resolved first.How did you verify your code works?
Project.resolvecoverage: an unborn repo gets a directory-derived id, two unrelated unborn repos get different ids and both appear inproject.list, and the directory project is archived once a commit upgrades the id.previous.git initkeep their project when the repo appears, then move to the remote-derived id after the first commit and remote.packages/core:bun run script/test.ts test/project.test.ts test/session-create.test.ts test/session-projector.test.ts test/session-move.test.ts→ 124 pass, 1 skip.packages/core:bun typecheck→ no errors.bun run check→ all 35 tasks pass. Locally I had to replace the Windows checkout of thepackages/app/src/custom-elements.d.tssymlink with its target content; this clone hascore.symlinks=false, so the symlink is a text file and fails typecheck before the change too.Checklist
Added by the opencode bot (AI-generated).
Fixes #50979
Related: #61009, #57985, #61104, #59371