wt

module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jan 23, 2026 License: MIT

README

Logo

wt

Git worktree manager with GitHub/GitLab integration.

Table of Contents

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)
  • Tidy 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

Install

Homebrew (macOS/Linux):

brew install 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.

Usage

# Add worktree for existing branch
wt add feature-branch                 # in cwd
wt add feature-branch -d ~/Git        # in specific dir

# Add worktree with new branch
wt add -b feature-branch              # creates new branch
wt add -b feature-branch -d ~/Git     # in specific dir

# Open worktree for a GitHub PR or GitLab MR
wt pr open 123                        # PR/MR from current repo
wt pr open 123 myrepo                 # find repo by name in dir
wt pr clone 123 org/repo              # clone repo and checkout PR
wt pr open 123 -d ~/Git               # specify search directory

# Hooks (auto-run based on "on" config, or explicit)
wt add branch                         # runs hooks with on=["add"]
wt add branch --hook=vscode           # run specific hook
wt add branch --no-hook               # skip all hooks

# Prune merged worktrees
wt prune                              # in cwd (uses cached info, filters to current repo)
wt prune -r                           # fetch origin + PR status first, then prune
wt prune --global                     # prune all repos (not just current)
wt prune -d ~/Git/worktrees           # in specific dir
wt prune -n                           # dry run
wt prune -c                           # also remove clean (0 commits ahead)
wt prune --no-hook                    # skip post-removal hooks

# List worktrees
wt list                               # in cwd (filters to current repo if in one)
wt list --global                      # list all repos (not just current)
wt list -d ~/Git/worktrees
wt list --json

# List repositories
wt repos                              # list repos in repo_dir (or worktree_dir)
wt repos -d ~/Git                     # list repos in specific dir
wt repos -l backend                   # filter by label
wt repos --json

# Move worktrees to another directory
wt mv -d ~/Git/worktrees              # move all worktrees from cwd to dir
wt mv -d ~/Git --format={branch} # move and rename using format
wt mv --dry-run -d ~/Git              # preview what would be moved
wt mv -f -d ~/Git                     # force move dirty worktrees

# Configuration
wt config init                        # create ~/.config/wt/config.toml
wt config hooks                       # list configured hooks

Configuration

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

# Directory for new worktrees (must be absolute path or start with ~)
worktree_dir = "~/Git/worktrees"

# Optional: directory where repositories are stored (for -r/-l repo lookup)
# If not set, uses worktree_dir for repo scanning
# Useful when repos live in ~/Code but worktrees go to ~/Git/worktrees
repo_dir = "~/Code"

# Worktree folder naming format
# Placeholders: {repo}, {branch}, {folder}
worktree_format = "{repo}-{branch}"

[hooks.kitty]
command = "kitty @ launch --type=tab --cwd={path}"
description = "Open new kitty tab"
on = ["add"]  # auto-run for add command

[hooks.pr-review]
command = "cd {path} && npm install && code {path}"
description = "Setup PR for review"
on = ["pr"]  # auto-run when opening PRs

[hooks.cleanup]
command = "echo 'Removed {branch} from {repo}'"
description = "Log removed branches"
on = ["prune"]  # auto-run when removing worktrees

[hooks.vscode]
command = "code {path}"
description = "Open VS Code"
# no "on" - only runs via --hook=vscode
Worktree Format Placeholders
Placeholder Value
{repo} Repo name from git remote get-url origin
{branch} Branch name as provided
{folder} Folder name of the git repo on disk
Hook Options
Option Description
command Shell command to run (required)
description Human-readable description
on Commands to auto-run on: ["add", "pr", "prune", "merge", "all"] (empty = only via --hook)
Hook Placeholders
Placeholder Value
{path} Absolute worktree path
{branch} Branch name
{repo} Repo name from origin
{folder} Main repo folder name
{main-repo} Main repo path
{trigger} Command that triggered the hook (add, pr, prune, merge)
{key} Custom variable from --arg key=value
{key:-default} Custom variable with fallback if not provided
Custom Hook Variables

Pass dynamic values to hooks using --arg:

wt hook claude --arg prompt="implement feature X"
wt add -b feature --arg task="JIRA-123"

Example hook using custom variables:

[hooks.claude]
command = "kitty @ launch --cwd={path} -- claude {prompt:-help me}"
description = "Open Claude with custom prompt"

The {prompt:-help me} syntax provides a default value ("help me") when --arg prompt=... is not specified.

Clone Rules (for wt pr clone)

When cloning a repo via wt pr clone, configure which forge to use:

[clone]
forge = "github"  # or "gitlab"

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

[[clone.rules]]
pattern = "oss/*"
forge = "github"

Rules are matched in order; first match wins. Supports glob patterns with *.

Hook Examples

VS Code
[hooks.vscode]
command = "code {path}"
description = "Open worktree in VS Code"
on = ["add", "pr"]
tmux
[hooks.tmux]
command = "tmux new-window -c {path} -n {branch}"
description = "Open new tmux window in worktree"
on = ["add"]
gh dash

wt works well with gh dash for reviewing PRs. Configure a keybinding to open PRs as worktrees:

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

Combined with hooks, you get a seamless workflow: press O in gh dash to checkout the PR as a worktree and automatically open it in your editor.

Shell Completions

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

Development

make build    # build ./wt binary
make test     # run tests
make install  # install to ~/go/bin

Directories

Path Synopsis
cmd
wt command
internal
forge
Package forge provides an abstraction over git hosting services (GitHub, GitLab).
Package forge provides an abstraction over git hosting services (GitHub, GitLab).
git
resolve
Package resolve provides unified target resolution for worktree commands.
Package resolve provides unified target resolution for worktree commands.
ui

Jump to

Keyboard shortcuts

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