Skip to main content

02 · Worktrees

Status: ✅ Implemented · Scope: v1 · Engineering: ../spec.md

A worktree is an additional working directory attached to the same repository — e.g. __worktree__/mobile-app_worktree-feat-dark-mode is a second checkout of app/mobile-app on a feature branch. GitTreeDesk treats worktrees as first-class: they are detected, grouped, created, and removed from the UI.

How worktrees appear​

  • In the Repos view, every linked worktree is nested under its main repository — one repository node, several working trees. A worktree row shows <branch> @ <path>; the main working tree carries a main marker.
  • In the Explorer view, worktree folders look like normal folders and carry the worktree glyph; the Repos view is the primary place to work with them.
  • Worktrees outside the workspace root are hidden by default; enable "Show external worktrees" in view options to include them (greyed, absolute path shown).
  • A worktree row behaves like a repository row everywhere: badges, changes, commit box, graph, terminal — every operation (pages 03–11) works against that worktree's working tree and its branch.

Creating a worktree​

Context menu on a repository → "New Worktree…". The dialog:

FieldBehavior
Source repositoryPre-filled from the context menu
BranchNew branch (type a name) or existing branch (picker). An existing branch that is already checked out in another worktree is blocked with a clear message — Git does not allow the same branch in two worktrees.
Base refFor a new branch: the starting point (default: the repository's current HEAD).
Target pathPre-filled from the path template (below); editable. The path is created if missing.

Path template (default matches the __worktree__ convention):

{worktreeRoot}/{repo}_{branch-slug}
  • {worktreeRoot} — defaults to <workspace>/__worktree__; change it under Settings → Git → Worktree folder.
  • {branch-slug} — the branch name with / replaced by -.
  • Example: branch worktree/feat-dark-mode on repo mobile-app → __worktree__/mobile-app_worktree-feat-dark-mode.

A freshly created __worktree__ folder is automatically attached to its parent repository (and excluded from ordinary discovery noise). After creation the tree focuses the new worktree row.

Moving, removing, pruning, locking​

ActionBehavior
MoveRelocates or renames the folder (git worktree move); uncommitted changes travel with it. The dialog suggests the worktree folder, so a rename is an edit of the last path segment, and a destination that is already the worktree's own path is refused before git runs. Missing parent directories are created; a destination folder that already exists becomes the parent. Locked worktrees are refused — unlock them first — and the main checkout never offers Move.
RemoveRefuses on a dirty worktree; "Force Remove" appears with a confirmation, and a backup ref is created first (safety nets, page 06). The folder is deleted, branch untouched.
PruneCleans up worktree records whose folders are already gone (git worktree prune). Runs manually from the repo context menu, and automatically after fetch.
Lock / UnlockProtects a worktree from prune/remove (for removable drives, long-running experiments). Locked state shows on the row.

Edge cases​

  • A worktree whose folder was deleted manually still appears greyed as "prunable" until pruned.
  • A worktree checked out on a detached HEAD shows detached @ <short-sha>.
  • Worktree folders are never mistaken for separate repositories: repository identity is the shared git directory, so mobile-app and its worktrees are always one node with multiple working trees.
  • Opening a terminal or a file "in the worktree" uses that worktree's path — never the main checkout.