Repository navigation
Conversation
git.repo.discover searches ancestors, so a plain directory that only sits under a repository ran worktree list/create/remove against that repository. Require the discovered repository root to be the requested directory so operations stay inside the caller's working directory.
|
The following comment was made by an LLM, it may be inaccurate: |
There was a problem hiding this comment.
The TUI part works. In a folder with no VCS, /worktrees is gone ("No matching commands"); on the base it opens a dialog whose new action always fails. In a git project it still opens normally. Core worktree tests (37 pass, same as base) and typechecks for core, tui and gui-extensions pass. Public API unchanged (no SDK, HTTP, plugin or config changes; core's git strategy is internal).
Two concerns, details inline:
- Regression in the web details panel.
movable()also hides the workspace menu for git-project sessions that aren't at a checkout root, e.g. a session in a monorepo subfolder. Creating, switching and returning to Local don't depend on the session's directory, so these sessions lose working actions. - Gating on
vcs === "git"in the client. Plugins can register worktree strategies (see #51672), and this hides/worktrees, including listing and deleting, for any non-git project such a plugin serves. A per-project capability from the server would be more accurate. If you keep the client-side check, consider hiding only thenewaction instead of the whole command.
Note that #55326 addresses the same issue in a narrower way (only the dialog's new action).
Related: #51672
| // Worktrees belong to a git project, and a session may manage them only from a | ||
| // checkout root. From a nested directory the menu would reach out to the | ||
| // repository above the session's working directory, so it stays a plain label. | ||
| const movable = () => |
There was a problem hiding this comment.
This hides the menu for any git-project session whose directory isn't the project root or a sandbox, e.g. a session started in repo/packages/foo. The comment's reason doesn't hold: SessionWorkspaceMenu.createWorktree creates from project.canonical, and "Local" moves to project.worktree, so neither depends on the session's directory. Those sessions currently get a working menu (new worktree, switch, back to Local) and would lose it, along with the "move" prompt below. Checking props.project.vcs === "git" alone is enough for #55215.
| name: "session.move", | ||
| category: "Session", | ||
| slash: { name: "worktrees" }, | ||
| enabled: canManageWorktrees, |
There was a problem hiding this comment.
Two things about this gate:
- It removes the whole
/worktreescommand (list, move, delete, refresh), not justnew. vcs === "git"doesn't fit plugin worktree strategies (the plugin API'sWorktreeEntry, V2: worktree created by a plugin strategy resolves to a new project when the project has no .git/.hg #51672). A project served by a plugin strategy, e.g. hg or jj, would lose access to its worktrees entirely.
Ideally the server would say whether the project's selected strategy can create worktrees. Short of that, hiding only the new action in the dialog (as #55326 does) has less impact.
The session details menu offered worktree actions for a project whose directory holds no git repository, where creating one can only fail. Offer the menu only for a git project.
357eff0 to
03d304b
Compare
|
Thanks. Both points are addressed in 03d304b:
This PR is now |
|
Ran the reproduction script from #55776 against this branch ( Part 2 — a plain directory whose parent later becomes a repository: Before this change that list showed Part 1 — a plain directory with no repository — still returns 400 over the API, which is expected: that part is the UI affordance, not the API. It is handled by the |


Issue for this PR
Closes #55776
Related to #55215
Type of change
What does this PR do?
Worktree actions are offered for a project whose directory holds no repository.
Creating one there can only fail:
POST /api/worktreereturns 400. The samestrategy also walked up to an ancestor repository, so a plain directory under a
repository ran list/create/remove against that repository.
core: the git strategy requires the discovered repository root to be therequested directory, so list/create/remove stay inside that checkout.
gui-extensions: the session details menu offers worktree actions only for agit project. Creating, switching and returning to Local all work from the
project's own checkouts, so nothing about the session's directory gates it.
The TUI half of #55215 is #55326.
How did you verify your code works?
bun typecheckinpackages/coreandpackages/gui-extensions;bun run lintexits 0.
The same core numbers come out of
dev(4397ee4) with these commitsreverted.
core skips: the shell-scan suites enumerate the shells installed on the machine
and skip the cases for the ones that are missing.
core failing (already failing on
dev):By hand: in a directory that is not a repository the session details menu has no
worktree actions; in a repository it still does.
Screenshots / recordings
Web — left: the session details menu for
nogit2, a directory that holds norepository. Right: the same panel after this change.
Checklist