Worktrees

A git worktree is a second working directory checked out from one repository. Branches share the repository’s objects; each worktree has its own files on disk, so you can have several branches checked out at once and switch between them by changing directory rather than by changing branch.

PwrGit treats worktrees as the unit of work. A repository in the sidebar expands into its worktrees, and selecting one is what loads the graph, the changes list, and the sync buttons.

Why worktrees are the unit

The practical consequence is that switching tasks does not touch your working tree. A half-finished change on one branch stays exactly where it is while you look at another; there is nothing to stash, and no rebuild triggered by files changing underneath a running process.

It also means “which branch am I on” is rarely the question. The question is which directory you are in, and the sidebar answers it.

Create a worktree

New worktree on a repository row opens a dialog asking for a branch name and whether to create as a new branch:

You can also reach this from search: picking a branch that has no worktree opens this dialog rather than selecting a row, since there is nothing to select yet.

New worktrees are created under ~/wt/<repo>/<branch>. The branch name is slugified for the directory name, so a branch with slashes in it still produces one directory.

Creating a worktree selects it. You asked for a branch because you want to work on it, so PwrGit takes you there rather than filing it away among the repository’s other worktrees.

The worktree root is not editable in Settings. It is ~/wt unless a repository’s existing layout says otherwise.

Worktrees made outside PwrGit

PwrGit lists every worktree a repository has, not only the ones it created. A worktree you added from a terminal appears wherever it lives on disk, with the same badges and the same actions.

The reverse also holds: PwrGit notices when a worktree is added or removed outside the app and refreshes the sidebar rather than showing a list that has quietly gone wrong.

Reading a worktree row

A row is the branch name, plus whichever of these apply:

Mark Meaning
n n uncommitted changes
n n commits ahead of upstream
n n commits behind upstream
merged Contained in the default branch, by git ancestry
Folder name Shown when the directory name differs from the branch name

The repository’s primary working tree — the original checkout, not a linked worktree — is marked as such, and cannot be removed.

The merged tag is detected by ancestry, which is a narrower claim than it sounds: a squash or rebase merge rewrites the commits, so the originals are not in the default branch and this tag will not appear even though the work landed. That case is covered by the merged pull request instead — see below.

There is also a quieter chip in the worktree header reading something like main +4. That is how far the default branch has moved on without this branch. It is not a sync state and pulling will not change it, which is why it never takes the warning color.

Finding prunable worktrees

The Stale lens in the sidebar answers “which of these can I delete?”. A worktree counts as safe to prune when it is:

Prunable rows are marked in the sidebar as well, so you do not have to switch lenses to notice one.

The merged-pull-request half needs a connected forge CLI. Without one, the git heuristic still works — it just cannot see the squash-merged branches. See Forges.

Remove a worktree

The menu on a worktree row has Remove worktree…, along with Copy branch name, Copy path, Reveal in Finder / Show in Explorer, and Reset to remote branch….

Removal refuses to run when the worktree has changes in it, unless you confirm you want it gone anyway. The primary working tree cannot be removed at all.

Removing from inside PwrGit is meaningfully better than deleting the directory yourself: git worktree remove also clears the administrative entry the repository keeps for that checkout. Deleting the folder by hand leaves that entry behind, and git keeps believing the worktree exists until something prunes it.

Removing a worktree does not delete its branch. The branch stays in the repository; only the checked-out directory goes.