A simple shell script for managing git worktrees, designed for agentic coding workflows where multiple agents work on different branches simultaneously.
- Create worktrees in a sibling directory (
../<repo>-worktrees/) - List all worktrees with dirty state indicators
- View git status across all worktrees at once
- Safe removal with uncommitted change warnings
- Prune worktrees for merged branches
- Shell integration for seamless directory navigation
- Tab completion for bash and zsh
.worktreeincludesupport to copy untracked files (.env, config, etc.) into new worktrees
Copy wt to a directory in your PATH:
# Option A: User-local install
mkdir -p ~/.local/bin
cp wt ~/.local/bin/
chmod +x ~/.local/bin/wt
# Option B: System-wide install
sudo cp wt /usr/local/bin/
sudo chmod +x /usr/local/bin/wtMake sure ~/.local/bin is in your PATH. Add this to your ~/.zshrc if needed:
export PATH="$HOME/.local/bin:$PATH"The wt cd command needs a shell function wrapper to actually change directories. Add this to your ~/.zshrc (or ~/.bashrc for bash):
# Git worktree manager
wt() {
if [[ "$1" == "cd" && -n "$2" ]]; then
local dir
dir="$(command wt cd "$2")" && cd "$dir"
else
command wt "$@"
fi
}Tab completion lets you autocomplete worktree names when using wt cd or wt remove.
Bash - add to ~/.bashrc:
eval "$(wt completions bash)"Zsh - add to ~/.zshrc:
eval "$(wt completions zsh)"source ~/.zshrc # or: source ~/.bashrcNow you can use tab completion:
wt cd <TAB> # Lists available worktrees
wt remove <TAB> # Lists available worktrees
wt new feature <TAB> # Lists branches for base branchShow the current worktree in your prompt with a dirty indicator:
# Show "project (worktree)*" in worktree, or just current dir name otherwise
wt_prompt() {
local git_root wt_name repo_name dirty=""
git_root="$(git rev-parse --show-toplevel 2>/dev/null)"
if [[ "$git_root" == *-worktrees/* ]]; then
wt_name="$(basename "$git_root")"
repo_name="$(basename "$(dirname "$git_root")" | sed 's/-worktrees$//')"
[[ -n "$(git status --porcelain 2>/dev/null)" ]] && dirty="*"
echo "${repo_name} (${wt_name})${dirty}"
else
echo "${PWD##*/}"
fi
}Then use it in your prompt (zsh):
setopt PROMPT_SUBST
PROMPT='$(wt_prompt) $ 'Example output:
myproject (feature-auth) # clean worktree
myproject (feature-auth)* # dirty worktree
Documents # not in a worktree
wt new feature-auth # Branch from main/master
wt new bugfix-123 develop # Branch from developThis creates:
- A new branch named
feature-auth - A worktree at
../<repo>-worktrees/feature-auth/ - Copies any files matching
.worktreeincludepatterns (see below)
wt list # or: wt lsShows all worktrees with their branches, paths, and dirty status.
wt status # or: wt stDisplays git status --short output for every worktree.
wt cd feature-authChanges your current directory to that worktree (requires shell integration).
wt remove feature-auth # or: wt rm feature-auth
wt remove feature-auth -f # Force remove with uncommitted changesYou'll be prompted to delete the associated branch.
wt prune # Remove worktrees with merged branches
wt prune --dry-run # Preview what would be removedWhen creating a new worktree, you often need untracked files like .env or local config that aren't in source control. Place a .worktreeinclude file in your repo root to automatically copy these files into new worktrees.
The file uses .gitignore syntax — glob patterns, directory patterns, negation (!), and comments (#) all work:
# Environment files
.env
.env.local
# Local IDE/tool config
.claude/settings.local.json
.vscode/settings.json
# Everything in a directory
secrets/When you run wt new, any untracked files matching these patterns are copied from the main repo into the new worktree, preserving directory structure. Tracked files are skipped since git already includes them.
When you use wt in a repository, worktrees are created in a sibling directory:
~/code/
|-- myproject/ # Your main repository
| |-- .git/
| +-- ...
+-- myproject-worktrees/ # Worktrees directory (auto-created)
|-- feature-auth/ # Worktree 1
|-- feature-api/ # Worktree 2
+-- bugfix-123/ # Worktree 3
This tool is designed for workflows where multiple AI agents work on different features simultaneously:
-
Spin up a worktree per agent:
wt new agent-1-auth wt new agent-2-api wt new agent-3-tests
-
Each agent works in isolation - no merge conflicts or interference
-
Monitor progress:
wt status # See what each agent has changed -
Clean up when done:
wt prune # Remove merged worktrees
| Command | Alias | Description |
|---|---|---|
wt new <name> [base] |
Create worktree with new branch | |
wt list |
wt ls |
List all worktrees |
wt status |
wt st |
Status across all worktrees |
wt cd <name> |
Navigate to worktree | |
wt remove <name> |
wt rm |
Remove worktree |
wt prune |
Remove merged worktrees | |
wt completions [shell] |
Output shell completion script (bash/zsh) | |
wt help |
Show help | |
wt version |
Show version |
MIT