Skip to main content

Worktrees

A git worktree is a second checkout of the same repository on its own branch, in its own directory. Rune turns worktrees into a first-class workflow: each worktree opens as its own workspace, so you can have several branches checked out at once, each in its own directory, and work on them side by side without stashing or switching branches in place.

This makes worktrees the natural unit for parallel work on a repository. Say you are mid-change on a feature branch when an urgent fix comes in: spin up a worktree for the hotfix branch, fix and ship it there, and come back to your feature branch exactly as you left it, no stash, no dirty tree. The same isolation lets an agent churn through edits on its own branch in one worktree while you keep working on yours in another, with no collisions. When a task finishes or needs you, its workspace tab lights up so you know where to look.

The worktree commands

Rune ships three commands for managing worktrees from the command prompt:

CommandWhat it does
worktreenew <name>Create a new worktree on a new branch <name>, then open it as a workspace named <name>.
worktreeopen <name>Open an existing worktree as a workspace. The command prompt's completer lets you fuzzy-search the list of worktrees for the current workspace's repository.
worktreeremove <name>Remove a worktree. The command prompt's completer lets you fuzzy-search the same list of worktrees.

A typical session: create a worktree for a feature, work in it, then remove it when the branch is merged.

:worktreenew FEATURE-123
...
:worktreeremove FEATURE-123

worktreenew puts the checkout under Rune's data directory, in a path keyed to the originating repository, so worktrees from different repos never clash and nothing lands inside your project tree.

Under the hood: just aliases

The worktree commands are not built into Rune's core. They are ordinary aliases that compose existing commands, and they are a good showcase of how far Rune's alias and command-variable system goes. You can read them, copy them, and bend them to your own workflow.

Here is worktreenew, the most involved of the three:

command:
aliases:
worktreenew:
- '!! ROOT=$(git rev-parse --git-common-dir) && ROOT=$(cd "$ROOT/.." && pwd) || exit 1'
- '!! ROOT_HASH=$(printf %s "$ROOT" | (sha256sum 2>/dev/null || shasum -a 256) | cut -c1-4)'
- '!! ROOT_NAME=${ROOT##*/}'
- '!! WORKTREE=$RUNE_DATADIR/worktrees/$ROOT_NAME-$ROOT_HASH/$1'
- '!! git worktree add "$WORKTREE" -b $1'
- 'workspaceopen $WORKTREE'
- 'workspaceready workspacerename $1'

Every line is one step of a multi-step alias, run in order:

  • The !! steps run a shell command and wait for it. The first four compute a worktree path: they find the repository root, derive a short hash of it so the directory name is unique per repository, and assemble $RUNE_DATADIR/worktrees/<repo>-<hash>/<name>. $RUNE_DATADIR and $1 (the first alias argument) are command variables Rune expands before each step runs, and the variables a step assigns are visible to the steps that follow.
  • git worktree add "$WORKTREE" -b $1 creates the worktree and its branch.
  • workspaceopen $WORKTREE opens that directory as a new workspace.
  • workspaceready workspacerename $1 waits for the new workspace to finish loading, then renames its tab to the branch name. workspaceready exists for exactly this: it defers a command until the most recent workspaceopen is ready, instead of racing against it.

worktreeopen and worktreeremove follow the same pattern, and add a completer so the prompt can suggest existing worktree names:

command:
aliases:
worktreeremove:
command:
- "!! git worktree remove $1"
- "shaderrun embers 600ms"
completer: "! $SHELL -c 'git worktree list | tail -n +2 | cut -d\" \" -f1 | xargs -n1 basename'"

The completer is itself just a shell command whose output lines become the suggestions. Because these are plain aliases, you can change where worktrees live, add a step that runs your setup script, or open the agent automatically in the new workspace. See Command Variables for the full alias and expansion model.

Parallelizing work across worktrees

The reason worktrees pair so well with Rune is that each one is a separate workspace, and Rune is a multi-workspace environment. Open several worktrees and you can let different tasks run in each at the same time:

  • Work on two unrelated branches at once: leave your half-finished feature exactly as it is in one worktree and review a teammate's branch in another, with no stashing and no switching branches in place.
  • Run Rune Agent or a third-party agent (Claude Code, Codex, your own harness) in its own worktree, on its own branch, so its edits stay isolated from the branch you are working on.
  • Give each agent its own worktree and run several in parallel, one per task or per branch, then review and merge their branches one at a time.

Switch between worktree workspaces the same way you switch any workspace, and the worktree's branch is exactly what git sees in that directory, so commits, diffs, and status are all scoped to that branch.

Knowing when a worktree needs you

When you run work in parallel, you are not watching every workspace at once. So Rune surfaces activity from the workspaces you are not looking at.

When a notification is posted on a workspace that is not currently in focus, Rune highlights that workspace's tab in the notification's color and holds the notification open until you switch to it. The tab of the workspace that finished a build, hit an error, or needs your input lights up, and you can jump straight there without hunting through tabs. (You can tune the highlight with the workspace bar's needs_attention_attr.)

This works no matter where the notification comes from:

  • Internally, from Rune itself: a !! command that finishes in a background worktree, an auto-save warning, or anything that posts a notification.
  • From an extension, through the Rune SDK: an extension can post a notification on its workspace, and if that workspace is in the background its tab is highlighted.
  • From outside Rune, through runectl: any process running in a workspace terminal can post a notification with runectl notify <level> <message>, where <level> is error, warn, info, or success. Because Rune sets the workspace's socket in the terminal's environment, runectl finds the right workspace automatically.

That last one is what makes worktrees and external agents click together. Wire an agent's "I'm done" or "I need permission" hook to runectl notify, run it in its own worktree, and its workspace tab lights up the moment it needs you, even while you are working elsewhere. For a worked example with Claude Code, see the Claude Code guide.

See also

  • Command Variables: the alias and $VAR expansion model the worktree commands are built on.
  • Command Prompt: how commands and aliases are dispatched.
  • Rune Agent: Rune's built-in agent.
  • Claude Code: wiring a third-party agent to Rune notifications with runectl.
  • runectl and the Rune SDK: posting notifications and driving Rune from outside.
Ask Rune Agent