wt

module
v0.15.0 Latest Latest
Warning

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

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

README

wt

Git worktree manager with GitHub/GitLab integration.

Why wt

Git worktrees let you work on multiple branches simultaneously without stashing or switching—great for juggling a feature branch and a hotfix, or running multiple AI agent sessions in parallel.

But worktrees can pile up fast. You end up with a dozen directories, can't remember which ones are already merged, and need custom scripts to open your editor, create terminal tabs, or clean up stale checkouts.

wt solves this:

  • Hooks auto-run commands when creating/opening worktrees (open editor, spawn terminal tab)
  • Prune removes merged worktrees and shows PR/MR status so you know what's safe to delete
  • PR checkout opens pull requests in worktrees for easier code review

⚠️ Pre-1.0 Notice

This project may include breaking command & configuration changes until v1.0 is released. Once v1 is released, backwards compatibility will be maintained.

If something breaks:

  • Delete ~/.wt/prs.json (PR cache)
  • Compare your config with wt config init -s and update to match newer config format

Install

# Homebrew (macOS/Linux)
brew install --cask raphi011/tap/wt

# Go
go install github.com/raphi011/wt/cmd/wt@latest

Requires git in PATH. For GitHub repos: gh CLI. For GitLab repos: glab CLI.

Getting Started

1. Create Config
wt config init ~/Git/worktrees           # worktrees dir only
wt config init ~/Git/worktrees ~/Code    # with separate repo dir

This creates ~/.config/wt/config.toml with your worktree directory (and optionally repo directory).

2. List Worktrees
wt list -g

You're ready to go! See Scenarios below for common workflows.

Interactive Mode

For guided worktree creation, use the -i flag:

wt checkout -i

This launches a step-by-step wizard that guides you through the checkout process.

Scenarios

Starting a New Feature
# Create worktree with new branch (from origin/main)
wt checkout -b feature-login

# Create from a different base branch
wt checkout -b feature-login --base develop

# Fetch base branch before creating (ensures up-to-date base)
wt checkout -b feature-login -f

# Fetch target branch from origin before checkout
wt checkout feature-login -f

# Stash local changes and apply them to the new worktree
wt checkout -b feature-login -s

# Add a note to remember what you're working on
wt checkout -b feature-login --note "Implementing OAuth flow"

With hooks configured, your editor opens automatically:

# ~/.config/wt/config.toml
[hooks.vscode]
command = "code {worktree-dir}"
on = ["checkout"]
Reviewing a Pull Request
# Checkout PR from current repo
wt pr checkout 123

# Checkout PR from a different local repo (by name)
wt pr checkout 123 backend-api

# Clone repo you don't have locally and checkout PR
wt pr checkout 456 org/new-repo

# Specify forge type when auto-detection fails
wt pr checkout 123 --forge gitlab

View PR details or open in browser:

wt pr view               # Show PR details
wt pr view -w            # Open PR in browser
wt pr view myrepo        # View PR for specific repo

After review, merge and clean up in one command:

wt pr merge              # Uses squash by default
wt pr merge -s rebase    # Or specify strategy
wt pr merge --keep       # Merge but keep worktree
Creating a Pull Request
# Create PR for current branch
wt pr create --title "Add login feature"

# With description
wt pr create --title "Fix bug" --body "Fixes issue #123"

# Read body from file (great for templates)
wt pr create --title "Add feature" --body-file=pr.md

# Create as draft
wt pr create --title "WIP: Refactor auth" --draft

# Create and open in browser
wt pr create --title "Ready for review" -w

# By repo name (when outside worktree)
wt pr create --title "Add feature" myrepo
Cleaning Up
# See what worktrees exist
wt list

# Remove merged worktrees (uses cached PR status)
wt prune

# Refresh PR status from GitHub/GitLab first
wt prune -R

# Preview what would be removed
wt prune -d

# Verbose dry-run: see what's skipped and why
wt prune -d -v

# Clear cached PR data and re-fetch
wt prune --reset-cache

# Remove specific branch worktree
wt prune feature-login -f

# Remove worktree from specific repo
wt prune myrepo:feature-login -f
Working Across Multiple Repos

Register and label repos for batch operations:

# Register a repo (from inside the repo)
wt repo add .

# Register a repo by path
wt repo add ~/path/to/myrepo

# Clone and register a new repo
wt repo clone git@github.com:org/repo.git

# Migrate an existing repo to bare structure (for faster worktrees)
wt repo make-bare ./myrepo

# Unregister a repo
wt repo remove myrepo

# List all repos
wt repo
wt repo -l backend    # Filter by label

Label your repos for batch operations:

# Add labels to repos
cd ~/Git/backend-api && wt label add backend
cd ~/Git/auth-service && wt label add backend
cd ~/Git/web-app && wt label add frontend

# List labels
wt label list         # Labels for current repo
wt label list -g      # All labels across repos

# Clear labels from a repo
wt label clear

# Create same branch across all backend repos (using label prefix)
wt checkout -b backend:feature-auth

# Or target specific repo by name
wt checkout -b backend-api:feature-auth

# Run command across worktrees
wt exec main -- git status              # In all repos' main worktree
wt exec backend-api:main -- make test   # In specific repo's worktree
Quick Navigation

Note: To use wt cd directly (without cd $(...) wrapper), add eval "$(wt init)" to your shell config. See wt init --help for details.

# Jump to most recently accessed worktree
wt cd

# Jump to worktree by branch name
wt cd feature-auth

# Jump to worktree in specific repo (if branch exists in multiple repos)
wt cd backend-api:feature-auth

# Interactive fuzzy search
wt cd -i

# Run command in worktree
wt exec -- git status                   # In current worktree
wt exec myrepo:main -- code .
Running Hooks Manually
# Run a hook on current worktree
wt hook vscode

# Run multiple hooks
wt hook vscode kitty

# Run on specific worktree (repo:branch format)
wt hook vscode -- myrepo:feature

# Run across worktrees by label
wt hook build -- backend:main

# Pass custom variables
wt hook claude --arg prompt="implement feature X"

# Preview command without executing
wt hook vscode -d
Branch Notes
# Set a note (visible in list/prune output)
wt note set "WIP: fixing auth timeout issue"

# Get current note
wt note get

# Clear note
wt note clear

# Set note on specific worktree (repo:branch format)
wt note set "Ready for review" myrepo:feature

Configuration

Config file: ~/.config/wt/config.toml

wt config init ~/Git/worktrees           # worktrees dir only
wt config init ~/Git/worktrees ~/Code    # with separate repo dir
wt config show                           # Show effective config
wt config hooks                          # List configured hooks
Basic Settings
# Directory for new worktrees (must be absolute or start with ~)
worktree_dir = "~/Git/worktrees"

# Where repos live (for repo: lookups, defaults to worktree_dir)
repo_dir = "~/Git"

# Default sort order for list: "id", "repo", "branch", "commit"
default_sort = "id"

[checkout]
# Folder naming: {repo}, {branch}, {origin}
worktree_format = "{repo}-{branch}"

# Base ref for new branches: "remote" (default) or "local"
base_ref = "remote"

# Auto-fetch from origin before checkout (default: false)
auto_fetch = true
Hooks
[hooks.vscode]
command = "code {worktree-dir}"
description = "Open VS Code"
on = ["checkout", "pr"]  # Auto-run for these commands

[hooks.kitty]
command = "kitty @ launch --type=tab --cwd={worktree-dir}"
description = "Open new kitty tab"
on = ["checkout"]

[hooks.cleanup]
command = "echo 'Removed {branch}'"
on = ["prune"]

[hooks.claude]
command = "kitty @ launch --cwd={worktree-dir} -- claude {prompt:-help me}"
description = "Open Claude with prompt"
# No "on" = only runs via: wt hook claude --arg prompt="..."

Hook triggers: checkout, pr, prune, merge, all

Placeholders: {worktree-dir}, {repo-dir}, {branch}, {repo}, {origin}, {trigger}, {key}, {key:-default}

Forge Settings

Configure forge detection and multi-account auth for PR operations:

[forge]
default = "github"      # Default forge
default_org = "my-company"  # Default org (allows: wt pr checkout 123 repo)

[[forge.rules]]
pattern = "company/*"
type = "gitlab"

[[forge.rules]]
pattern = "work-org/*"
type = "github"
user = "work-account"  # Use specific gh account for matching repos
Merge Settings
[merge]
strategy = "squash"  # squash, rebase, or merge
Self-Hosted Instances
[hosts]
"github.mycompany.com" = "github"
"gitlab.internal.corp" = "gitlab"
Theming

Customize the interactive UI with preset themes or custom colors:

[theme]
# Use a preset theme
name = "dracula"  # default, dracula, nord, gruvbox, catppuccin-frappe, catppuccin-mocha

# Use nerd font symbols (requires a nerd font installed)
nerdfont = true

Override individual colors with hex codes or ANSI color numbers:

[theme]
name = "nord"       # Start with a preset
primary = "#88c0d0" # Override specific colors
accent = "#b48ead"

Available color keys: primary, accent, success, error, muted, normal, info.

Integration with gh-dash

wt works great with gh-dash. Add a keybinding to checkout PRs as worktrees:

# ~/.config/gh-dash/config.yml
keybindings:
  prs:
    - key: O
      command: wt pr checkout {{.PrNumber}} {{.RepoName}}

Press O to checkout PR → hooks auto-open your editor.

Shell Completions

# Fish
wt completion fish > ~/.config/fish/completions/wt.fish

# Bash
wt completion bash > ~/.local/share/bash-completion/completions/wt

# Zsh (add ~/.zfunc to fpath in .zshrc)
wt completion zsh > ~/.zfunc/_wt

Command Reference

Common commands have short aliases (shown in wt --help): co, ls, p, r, x.

Command Description
wt checkout Checkout worktree for branch
wt list List worktrees
wt prune Remove merged worktrees
wt repo Manage repositories
wt pr checkout Checkout PR (clones if needed)
wt pr create Create PR for current branch
wt pr view View PR details or open in browser
wt pr merge Merge PR and clean up
wt exec Run command in worktree
wt cd Print worktree/repo path
wt note Manage branch notes
wt label Manage repo labels
wt hook Run configured hook
wt config Manage configuration
wt init Output shell wrapper for cd
wt completion Generate shell completions

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

Development

make build    # Build ./wt binary
make test     # Run tests
make install  # Install to ~/go/bin

Directories

Path Synopsis
cmd
wt command
internal
cmd
Package cmd provides helpers for executing shell commands with proper error handling.
Package cmd provides helpers for executing shell commands with proper error handling.
config
Package config handles loading and validation of wt configuration.
Package config handles loading and validation of wt configuration.
forge
Package forge provides an abstraction layer for git hosting services.
Package forge provides an abstraction layer for git hosting services.
format
Package format handles worktree folder name generation and path sanitization.
Package format handles worktree folder name generation and path sanitization.
git
Package git provides git operations via shell commands.
Package git provides git operations via shell commands.
history
Package history tracks the most recently accessed worktree path.
Package history tracks the most recently accessed worktree path.
hooks
Package hooks provides post-operation hook execution with placeholder substitution.
Package hooks provides post-operation hook execution with placeholder substitution.
log
Package log provides context-aware logging for wt.
Package log provides context-aware logging for wt.
output
Package output provides context-aware output for wt.
Package output provides context-aware output for wt.
prcache
Package prcache provides PR status caching stored in ~/.wt/prs.json.
Package prcache provides PR status caching stored in ~/.wt/prs.json.
registry
Package registry manages the repo registry at ~/.wt/repos.json
Package registry manages the repo registry at ~/.wt/repos.json
resolve
Package resolve provides target resolution for worktree commands.
Package resolve provides target resolution for worktree commands.
storage
Package storage provides atomic file operations for JSON data in ~/.wt/
Package storage provides atomic file operations for JSON data in ~/.wt/
ui
Package ui provides terminal UI components for wt command output.
Package ui provides terminal UI components for wt command output.
ui/progress
Package progress provides progress indication components.
Package progress provides progress indication components.
ui/prompt
Package prompt provides simple interactive prompts.
Package prompt provides simple interactive prompts.
ui/static
Package static provides non-interactive terminal output components.
Package static provides non-interactive terminal output components.
ui/styles
Package styles provides shared lipgloss styles for UI components.
Package styles provides shared lipgloss styles for UI components.
ui/wizard/flows
Package flows provides command-specific wizard implementations.
Package flows provides command-specific wizard implementations.
ui/wizard/framework
Package framework provides the core wizard orchestration system.
Package framework provides the core wizard orchestration system.
ui/wizard/steps
Package steps provides reusable step components for wizards.
Package steps provides reusable step components for wizards.
tools
testdoc command
Package main provides a CLI tool to generate markdown documentation from Go test functions and their doc comments.
Package main provides a CLI tool to generate markdown documentation from Go test functions and their doc comments.

Jump to

Keyboard shortcuts

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