Skip to content

feat(worktrees): create a worktree from any ref - #75

Merged
rocketraman merged 2 commits into
masterfrom
claude/worktree-creation-ref-260a5d
Oct 27, 2026
Merged

rocketraman merged 2 commits into
masterfrom
claude/worktree-creation-ref-260a5d

Conversation

@rocketraman

Copy link
Copy Markdown
Owner

What

Adds a way to create a worktree; previously the app could only remove or prune them.

  • Entry points: a Worktree hover action on local branch rows, remote branch rows, PR rows and commit rows in the log view, plus + New worktree in the Worktrees section header. The header now renders for every git repo (as "— none" when there are no worktrees) so the first one can be made.
  • Dialog (Popup.NewWorktree): prefilled so Enter usually creates. Branch field depends on the source; folder defaults to a sibling <repo>-<branch-slug> (numbered when taken) and follows the branch name until edited; optional "open a terminal there". With no source it asks for a ref, suggests branches/tags, and shows what the text resolves to.
  • Git (WorktreeOps.add):
    • local branch → checked out as itself
    • remote branch → --track -b <name> (editable name, defaults to the short name)
    • tag/commit → --detach, or --no-track -b <name> if a branch is named
    • PR → detached tree, then gh pr checkout N inside it; the tree is removed if gh fails
  • resolve takes a typed ref in git's own order, including the short-name guess when exactly one remote has the branch.

Why the sibling default

A worktree inside the checkout shows up as untracked files and sits under the repo's file watcher (the churn WatchPolicy special-cases .claude/worktrees/ for). A sibling avoids both.

Reviewer notes

  • Never --force: refusals (branch held elsewhere, branch name taken, non-empty folder) are shown inline in the dialog, which stays open until git answers.
  • --quiet on worktree add is load-bearing: without it git's first stderr line is "Preparing worktree…", which firstError would surface instead of the actual fatal:.
  • The Prune count is now scoped to the repo on screen, since state.worktrees may belong to another repo now that the heading renders for repos with no worktrees.

Testing

  • New WorktreeCreateTest (11 tests): each source kind, refusals, resolve, refNames, defaultPath, pathProblem. Full suite 248 tests, 0 failures (from the result XML); detekt clean.
  • Exercised in a headless KWin session against a scratch repo: local branch, typed remote short name, the "branch already exists" refusal, and a tag from the log view. The PR path wasn't exercised (no GitHub remote in the fixture).

🤖 Generated with Claude Code

Until now worktrees could only be removed or pruned from the app. A
"Worktree" action on local branch, remote branch, PR and log commit
rows opens one prefilled dialog; "+ New worktree" in the Worktrees
section (now shown even when a repo has none) takes a typed ref with
suggestions.

The folder defaults to a sibling of the repo, <repo>-<branch>, so the
tree stays out of the repo's status and file watcher. A remote branch
gets a tracking local branch, a tag or commit is detached unless a
branch is named, and a PR is a detached tree that `gh pr checkout`
fills in (removed again if gh fails). git's refusals are shown in the
dialog rather than forced past; --quiet keeps the progress line from
masking them.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Raman Gupta <rocketraman@gmail.com>
@rocketraman
rocketraman force-pushed the claude/worktree-creation-ref-260a5d branch from c6525bd to f5df811 Compare October 27, 2026 21:32
The dialog called WorktreeOps.defaultPath and pathProblem directly,
which the architecture test forbids for the UI package. Both now go
through AppState, as the dialog's ref lookups already did.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Raman Gupta <rocketraman@gmail.com>
@rocketraman
rocketraman force-pushed the claude/worktree-creation-ref-260a5d branch from ff3f9c6 to 5a378c4 Compare October 27, 2026 21:47
@rocketraman
rocketraman merged commit 28ebb9f into master Oct 27, 2026
2 checks passed
@rocketraman
rocketraman deleted the claude/worktree-creation-ref-260a5d branch October 27, 2026 21:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant