wt

module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 12, 2026 License: MIT

README

                  █████
                 ▒▒███
 █████ ███ █████ ███████
▒▒███ ▒███▒▒███ ▒▒▒███▒
 ▒███ ▒███ ▒███   ▒███
 ▒▒███████████    ▒███ ███
  ▒▒████▒████     ▒▒█████
   ▒▒▒▒ ▒▒▒▒       ▒▒▒▒▒

taking the orkrees out of worktrees.

Git worktrees are the best way to work on multiple branches at the same time. No stashing, no context-switching, no waiting for node_modules to reinstall. Every branch gets its own directory, ready to go.

But the built-in commands make it hard to love them. Creating a worktree means juggling git worktree add, git checkout -b, and a path you have to remember. Switching between them means typing out full directory paths. Figuring out which ones still have open PRs — or which ones were merged three weeks ago and are just sitting there — means checking GitHub manually, one by one.

wt handles all of that. One command to create a worktree and branch — or wrap an existing branch in a worktree with --from. One command to switch. One command to rebase and push. A dashboard that shows PR status, CI checks, and code review right in your terminal. And when a PR merges, one command to clean everything up.

It's also just a thin layer over git. No special repo format, no lock-in. Your worktrees and branches are normal git — wt just makes them easier to manage. Remove it and everything still works.

Zero config — works out of the box with sensible defaults. PR-aware — shows GitHub status, CI checks, and reviews in your terminal. Shell-nativecd just works when you switch worktrees.

How It Works

wt new sidebar-card       # Create worktree + branch, cd into it
wt init                   # Install deps, copy .env, etc.
# ...work on your feature...
wt submit                 # Rebase onto main + push
wt list                   # See all worktrees with PR/CI/review status
# ...PR gets merged on GitHub...
wt prune                  # Clean up merged worktrees

Install

Homebrew:

brew install mvwi/tap/wt

Go:

go install github.com/mvwi/wt@latest

Binary: Download from Releases.

Shell Setup

wt needs a thin shell wrapper so it can cd into worktrees for you. Add one line to your shell config:

Fish (~/.config/fish/config.fish):

wt init-shell fish | source
wt completion fish | source

Bash (~/.bashrc):

eval "$(wt init-shell bash)"
eval "$(wt completion bash)"

Zsh (~/.zshrc):

eval "$(wt init-shell zsh)"
eval "$(wt completion zsh)"

Commands

Command Aliases Description
wt new <name> create Create worktree with feature branch
wt init Initialize worktree (deps, .env, prisma)
wt list ls Show all worktrees with PR status
wt switch [name] sw, cd, checkout, co Switch to a worktree (fzf picker if no args)
wt rebase Rebase current branch onto base branch
wt submit Rebase + push to remote
wt move <name> mv, teleport, tp Move uncommitted changes to another worktree
wt close [name] rm Close and clean up a worktree
wt rename <name> rn Rename worktree, branch, and remote
wt prune Clean up stale worktrees (merged/closed PRs)
wt open [name] Open PR in browser
wt watch Watch PR until mergeable or blocked
wt feedback [message] Open a GitHub issue for feedback

Run wt <command> --help for detailed usage of any command.

Configuration

All fields are optional — sensible defaults work out of the box. Config is layered: defaults -> global -> repo, each layer only overrides what it sets.

  • Global (~/.config/wt/config.toml): applies to all repos
  • Repo (.wt.toml in repo root): overrides global for that repo
Config reference and examples
# Base branch to create worktrees from and rebase onto.
# Default: "main". Common alternatives: "staging", "develop"
base_branch = "staging"

# Git remote name. Default: "origin"
remote = "origin"

# Prefix for new branch names: "<prefix>/<name>".
# Default: your git username's first name (e.g., "michael").
# Set to "" to disable prefixing entirely.
branch_prefix = "michael"

# Worktree directory naming: "<prefix><name>".
# Default: "wt-<repo>-" (e.g., "wt-myapp-sidebar").
# Set to customize (e.g., "wt-" for shorter names).
worktree_prefix = ""

# Days before a worktree with no open PR is flagged stale in `wt list`.
# Default: 7
stale_threshold = 14

[init]
# .env files to copy from main worktree during init.
# Default: [".env", ".env.local", ".env.development.local"]
env_files = [".env", ".env.local"]

# Override package manager auto-detection.
# Values: "pnpm", "yarn", "npm", "bun", or "" for auto-detect.
package_manager = ""

# Commands to run after init (replaces .wt-init scripts).
post_commands = [
  "npx prisma generate",
  "npx prisma db push",
]

Global Config with Per-Repo Overrides

Set everything in ~/.config/wt/config.toml — no need to commit config to repos:

# Defaults for all repos
base_branch = "main"

# Per-repo overrides (keyed by repo directory name)
[repos.platform]
base_branch = "staging"

[repos.legacy-app]
base_branch = "develop"
branch_prefix = "fix"

Precedence: defaults -> global -> global per-repo -> .wt.toml

A .wt.toml in a repo root always wins, but most users won't need one.

Settings Reference

Setting Default Effect
base_branch "main" Branch used for wt new, wt rebase, wt submit
remote "origin" Remote for fetch/push operations
branch_prefix git username New branches: <prefix>/<name>
worktree_prefix "wt-<repo>-" Directory naming: <prefix><name>
stale_threshold 7 Days before worktree flagged stale in wt list
init.env_files .env, .env.local, .env.development.local Files copied from main repo
init.package_manager auto-detect Force specific package manager
init.post_commands [] Custom init steps

Dependencies

  • git — required
  • gh (GitHub CLI) — optional, enables PR status in wt list, safety checks in wt close, and remote rename in wt rename
  • fzf — optional, enables interactive picker in wt switch

License

MIT

Directories

Path Synopsis
cmd
wt command
internal
cmd
git
ui

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL