wt switch
Switch to a worktree; create if needed.
Worktrees are addressed by branch name; paths are computed from a configurable template. Unlike git switch, this navigates between worktrees rather than changing branches in place.
Examples
wt switch feature-auth # Switch to worktree
wt switch - # Previous worktree (like cd -)
wt switch --create new-feature # Create new branch and worktree
wt switch --create hotfix --base production
wt switch pr:123 # Switch to PR #123's branchCreating a branch
The --create flag creates a new branch from the --base branch (defaults to default branch). Without --create, the branch must already exist.
Upstream tracking: Branches created with --create have no upstream tracking configured. This prevents accidental pushes to the wrong branch — for example, --base origin/main would otherwise make git push target main. Use git push -u origin <branch> to set up tracking as needed.
Without --create, switching to a remote branch (e.g., wt switch feature when only origin/feature exists) creates a local branch tracking the remote — this is the standard git behavior and is preserved.
Creating worktrees
If the branch already has a worktree, wt switch changes directories to it. Otherwise, it creates one, running hooks.
When creating a worktree, worktrunk:
- Creates worktree at configured path
- Switches to new directory
- Runs post-create hooks (blocking)
- Spawns post-start hooks (background)
wt switch feature # Existing branch → creates worktree
wt switch --create feature # New branch and worktree
wt switch --create fix --base release # New branch from release
wt switch --create temp --no-verify # Skip hooksShortcuts
| Shortcut | Meaning |
|---|---|
^ | Default branch (main/master) |
@ | Current branch/worktree |
- | Previous worktree (like cd -) |
pr:{N} | GitHub PR #N's branch |
mr:{N} | GitLab MR !N's branch |
wt switch - # Back to previous
wt switch ^ # Default branch worktree
wt switch --create fix --base=@ # Branch from current HEAD
wt switch pr:123 # PR #123's branch
wt switch mr:101 # MR !101's branchInteractive picker
When called without arguments, wt switch opens an interactive picker to browse and select worktrees with live preview. The picker requires a TTY.
Keybindings:
| Key | Action |
|---|---|
↑/↓ | Navigate worktree list |
| (type) | Filter worktrees |
Enter | Switch to selected worktree |
Alt-c | Create new worktree from query |
Alt-r | Remove selected worktree |
Esc | Cancel |
1–5 | Switch preview tab |
Alt-p | Toggle preview panel |
Ctrl-u/Ctrl-d | Scroll preview up/down |
Preview tabs (toggle with number keys):
- HEAD± — Diff of uncommitted changes
- log — Recent commits; commits already on the default branch have dimmed hashes
- main…± — Diff of changes since the merge-base with the default branch
- remote⇅ — Diff vs upstream tracking branch (ahead/behind)
- summary — LLM-generated branch summary (requires
[list] summary = trueand[commit.generation])
Pager configuration: The preview panel pipes diff output through git's pager. Override in user config:
[switch.picker]
pager = "delta --paging=never --width=$COLUMNS"
Available on Unix only (macOS, Linux). On Windows, use wt list or wt switch <branch> directly.
GitHub pull requests
The pr:<number> syntax resolves the branch for a GitHub pull request. For same-repo PRs, it switches to the branch directly. For fork PRs, it fetches refs/pull/N/head and configures pushRemote to the fork URL.
wt switch pr:101 # Checkout PR #101
Requires gh CLI to be installed and authenticated. The --create flag cannot be used with pr: syntax since the branch already exists.
Fork PRs: The local branch uses the PR's branch name directly (e.g., feature-fix), so git push works normally. If a local branch with that name already exists tracking something else, rename it first.
GitLab merge requests
The mr:<number> syntax resolves the branch for a GitLab merge request. For same-project MRs, it switches to the branch directly. For fork MRs, it fetches refs/merge-requests/N/head and configures pushRemote to the fork URL.
wt switch mr:101 # Checkout MR !101
Requires glab CLI to be installed and authenticated. The --create flag cannot be used with mr: syntax since the branch already exists.
Fork MRs: The local branch uses the MR's branch name directly, so git push works normally. If a local branch with that name already exists tracking something else, rename it first.
When wt switch fails
- Branch doesn't exist — Use
--create, or checkwt list --branches - Path occupied — Another worktree is at the target path; switch to it or remove it
- Stale directory — Use
--clobberto remove a non-worktree directory at the target path
To change which branch a worktree is on, use git switch inside that worktree.
See also
wt list— View all worktreeswt remove— Delete worktrees when donewt merge— Integrate changes back to the default branch
Command reference
wt switch - Switch to a worktree; create if needed
Usage: wt switch [OPTIONS] [BRANCH] [-- <EXECUTE_ARGS>...]
Arguments:
[BRANCH]
Branch name or shortcut
Opens interactive picker if omitted. Shortcuts: '^' (default branch),
'-' (previous), '@' (current), 'pr:{N}' (GitHub PR), 'mr:{N}' (GitLab
MR)
[EXECUTE_ARGS]...
Additional arguments for --execute command (after --)
Arguments after -- are appended to the execute command. Each argument
is expanded for templates, then POSIX shell-escaped.
Options:
--branches
Include branches without worktrees (interactive picker)
--remotes
Include remote branches (interactive picker)
-c, --create
Create a new branch
-b, --base <BASE>
Base branch
Defaults to default branch.
-x, --execute <EXECUTE>
Command to run after switch
Replaces the wt process with the command after switching, giving it
full terminal control. Useful for launching editors, AI agents, or
other interactive tools.
Supports hook template variables ({{ branch }}, {{ worktree_path }},
etc.) and filters. {{ base }} and {{ base_worktree_path }} require
--create.
Especially useful with shell aliases:
alias wsc='wt switch --create -x claude'
wsc feature-branch -- 'Fix GH #322'
Then wsc feature-branch creates the worktree and launches Claude Code.
Arguments after -- are passed to the command, so wsc feature -- 'Fix
GH #322' runs claude 'Fix GH #322', starting Claude with a prompt.
Template example: -x 'code {{ worktree_path }}' opens VS Code at the
worktree, -x 'tmux new -s {{ branch | sanitize }}' starts a tmux
session named after the branch.
-y, --yes
Skip approval prompts
--clobber
Remove stale paths at target
--no-cd
Skip directory change after switching
Hooks still run normally. Useful when hooks handle navigation (e.g.,
tmux workflows) or for CI/automation.
--no-verify
Skip hooks
-h, --help
Print help (see a summary with '-h')
Global Options:
-C <path>
Working directory for this command
--config <path>
User config file path
-v, --verbose...
Verbose output (-v: hooks, templates; -vv: debug report)