Git worktree helper that combines worktree creation, setup, and navigation into a single command.
wt add feature/login master # create worktree + cd into it
wt cd feature/login # cd into existing worktree
wt rm feature/login # remove worktree
wt ls # list worktreesClone the repo and add two lines to your ~/.zshrc (or ~/.bashrc):
export PATH="$HOME/Projects/git-wt:$PATH"
source ~/Projects/git-wt/git-wt.shThis gives you:
git wt— works as a git subcommand (via PATH auto-discovery)wt— shell function wrapper that addscdsupport foraddandcdcommands
Alternatively, use a git alias without the shell wrapper (no auto-cd):
git config --global alias.wt '!git-wt'| Command | Description |
|---|---|
wt add <branch> [source] |
Create a worktree for <branch>, optionally from [source] branch. If the branch exists only on origin, prompts to use it |
wt rm [branch] |
Remove a worktree. Without args, removes the current one |
wt cd <branch> |
cd into an existing worktree |
wt ls |
List all worktrees (git worktree list) |
wt init |
Interactively create worktree.conf.local |
wt help |
Show help |
git-wt uses two shell-sourceable config files in each project's repo root:
worktree.conf — committed project defaults:
WORKTREE_DIR=".."
WORKTREE_PREFIX="myapp"
WORKTREE_SETUP=("./setup.sh")
WORKTREE_TEARDOWN=("./teardown.sh")worktree.conf.local — personal overrides (gitignored):
WORKTREE_DIR="/home/me/worktrees"
WORKTREE_SETUP=("./setup.sh" "direnv allow")
WORKTREE_TEARDOWN=("docker compose down")The script sources worktree.conf first, then worktree.conf.local. Later values fully replace earlier ones.
| Variable | Default | Description |
|---|---|---|
WORKTREE_DIR |
.. |
Base directory for worktrees (relative to repo root) |
WORKTREE_PREFIX |
repo name | Prefix for worktree directory names |
WORKTREE_SETUP |
() |
Commands to run after creating a worktree |
WORKTREE_TEARDOWN |
() |
Commands to run before removing a worktree |
Format: <base>/<prefix>-<sanitized-branch>
Branch feature/login with prefix myapp and base ..:
../myapp-feature-login
Sanitization: / becomes -, everything lowercased.
When you wt add a branch that doesn't exist locally but exists on origin, the script prompts you:
$ wt add jirka/DMD-875/fix-autority-typo
[wt] Branch 'jirka/DMD-875/fix-autority-typo' not found locally, but exists on origin.
Use origin/jirka/DMD-875/fix-autority-typo? [Y/n]
- Y (default) — creates the worktree tracking the remote branch
- n — creates a new branch from HEAD instead
This check is skipped when you explicitly provide a [source] argument.
git-wt is a standalone bash script. When placed in PATH, git discovers it automatically as git wt (git's subcommand convention for git-<name> executables).
The wt shell function (from git-wt.sh) wraps git wt and adds directory changing — a subprocess can't change the parent shell's directory, so the function captures the path from stdout and runs cd.
All info messages go to stderr. Only the worktree path goes to stdout (as the last line), enabling the shell wrapper to capture it.
# Set up per-project config
cd ~/projects/my-app
cat > worktree.conf <<'EOF'
WORKTREE_DIR=".."
WORKTREE_PREFIX="my-app"
WORKTREE_SETUP=("npm install")
EOF
echo "worktree.conf.local" >> .gitignore
# Create a worktree (auto-creates branch, runs setup, cd's into it)
wt add feature/login master
# Work on the feature...
# List worktrees
wt ls
# Switch to another worktree
wt cd main
# Clean up
wt rm feature/loginMIT