wt-cli

module
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Sep 18, 2026 License: MIT

README

wt

wt creates git worktrees with your local files (env files, editor, installed deps) already in place, so switching to a new branch doesn't mean re-copying .env and waiting for npm install by hand.

$ wt new my-feature
wt: fetching origin...
wt: copied .env
wt: running pnpm install
wt: feature/my-feature  ->  ../myrepo-wt/my-feature

Why

A normal git checkout/switch reuses one working copy, so touching another branch means stashing your changes, killing whatever dev server or watcher was running, and often reinstalling dependencies if the lockfile differs. git worktree avoids that by giving you a second working directory on the same .git — but setting one up by hand still means manually copying .env files and rerunning the install step every time. wt automates that part, so spinning up a parallel checkout is a single command instead of a five-step ritual.

Reach for it when you need two working states of the repo alive at the same time, not when you're just switching between them one after another:

  • Reviewing a PR without shelving your own work. wt new review-pr-123 origin/pr-branch — deps and env already in place, your current branch untouched.
  • A hotfix while mid-feature. Uncommitted changes in progress, an urgent bug comes in — wt new hotfix instead of stashing.
  • Parallel agents/background jobs. Multiple AI coding agents or CI-style jobs working on different branches need separate directories so they don't clobber each other's files.
  • A long test/build run on one branch while you keep working in the main checkout.
  • Comparing behavior side by side — two branches running at once instead of switching back and forth.

If you just need a quick look at another branch and you'll be back in a minute, git stash + checkout (or git show) is cheaper — a worktree only pays for itself when the two states need to coexist.

Install

Homebrew (macOS/Linux, no Go required)
brew install bklimov-web/tap/wt

Installs as wt, updates with brew upgrade wt.

Go
go install github.com/bklimov-web/wt-cli/cmd/wt@latest

Or clone and build:

git clone https://github.com/bklimov-web/wt-cli
cd wt-cli
go build -o wt ./cmd/wt

Note: wt is a common name — it may collide with another binary on your PATH (some shells ship a wt alias for Windows Terminal, for example). If that happens, rename the built binary or alias it: alias wt=/path/to/wt.

Commands

Command What it does
wt init Scaffold a .wt.toml by detecting an install step (Go, Python, Java/Maven/Gradle, Rust, Ruby, PHP, .NET — when no JS lockfile) and gitignored local-config files (.env*, *.local*, *secret*)
wt new <name> [branch] Create a worktree branched off origin/<default>, copy env files, run the detected package manager's install, open it in your editor
wt ls List worktrees (branch + path)
wt rm [name] Remove a worktree and its branch, with a confirmation prompt. Interactive picker if name is omitted
wt open [name] Open a worktree in your configured editor. Interactive picker if name is omitted
wt path [name] Print a worktree's path. Interactive picker if name is omitted

Run any command inside your main checkout (or one of its worktrees) — wt resolves the main checkout automatically.

Configuration

wt reads config from two optional TOML files, merged in this order (later wins): defaults → ~/.config/wt/config.toml.wt.toml in your repo root.

# ~/.config/wt/config.toml or <repo>/.wt.toml
worktree_dir     = "../{repo}-wt"     # {repo} is replaced with the repo's dir name
branch_pattern   = "feature/{name}"   # {name} is replaced with the worktree name
editor           = "code"             # command used to open a worktree
env_files        = [".env", ".env.local"]
install_commands = []                 # override auto-detected install step

Install-manager detection is by lockfile: pnpm-lock.yamlpnpm install, yarn.lockyarn install --frozen-lockfile, bun.lockbbun install, package-lock.jsonnpm ci. No lockfile, no install.

install_commands overrides this detection with your own steps, run in order through the shell (stopping at the first failure) — handy for ecosystems with no single lockfile convention, e.g. Python:

install_commands = [
  "python -m venv .venv",
  ".venv/bin/pip install -r requirements.txt",
]
Environment overrides

These apply on top of both config files, for one-off use:

Variable Effect
WT_ENV_FILES Space-separated list, overrides env_files
WT_NO_INSTALL Skip the install step
WT_NO_CODE Skip opening the editor

Requirements

  • Git with worktree support
  • Go 1.25+ (only to build from source)

Development

git clone https://github.com/bklimov-web/wt-cli
cd wt-cli
make setup   # git hooks (auto-gofmt on commit, build/vet/test on push) + deps
make build   # go build ./...
make test    # go test ./...
make vet     # go vet ./...
make lint    # golangci-lint run (needs golangci-lint installed)
make ci      # what CI runs: gofmt check + vet + build + test -race -shuffle=on

No make? Run what it wraps directly:

git config core.hooksPath .githooks   # setup
go mod download                       # setup
go build ./...                        # build
go test ./...                         # test
go vet ./...                          # vet

License

MIT

Directories

Path Synopsis
cmd
wt command
Command wt creates git worktrees with local files and deps in place.
Command wt creates git worktrees with local files and deps in place.
internal
config
Package config resolves wt's configuration by layering defaults, the global config, the per-repo config, and one-off env var overrides.
Package config resolves wt's configuration by layering defaults, the global config, the per-repo config, and one-off env var overrides.
editor
Package editor opens a worktree directory in the configured editor.
Package editor opens a worktree directory in the configured editor.
git
Package git wraps the git plumbing commands wt shells out to.
Package git wraps the git plumbing commands wt shells out to.
installer
Package installer runs a worktree's install step: either a user-supplied list of commands, or an auto-detected JS package manager's install command based on lockfiles present.
Package installer runs a worktree's install step: either a user-supplied list of commands, or an auto-detected JS package manager's install command based on lockfiles present.
picker
Package picker provides interactive terminal prompts (selection, yes/no confirmation) shared by wt commands that fall back to a picker when the user doesn't name a worktree explicitly.
Package picker provides interactive terminal prompts (selection, yes/no confirmation) shared by wt commands that fall back to a picker when the user doesn't name a worktree explicitly.
worktree
Package worktree orchestrates creating a new git worktree: resolving paths from config templates, branching from origin's default branch, copying env files, and installing dependencies.
Package worktree orchestrates creating a new git worktree: resolving paths from config templates, branching from origin's default branch, copying env files, and installing dependencies.

Jump to

Keyboard shortcuts

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