CLI tool
satococoa/wtp avatar
satococoa/wtp

wtp: A Git Worktree CLI That Adds Setup Hooks and Path Rules

🌳 A powerful Git worktree CLI tool with automated setup, branch tracking, and smart navigation

629 stars23 forksGoMIT

At a glance

What is it?
wtp wraps git worktree with automatic path generation, .wtp.yml post-create hooks, and a cd command with tab completion. It is a convenience layer for people who already use worktrees and want the setup steps to stop being manual.
Who is it for?
Adopt wtp if your team already creates worktrees per branch and you are tired of retyping paths and re-running npm ci by hand; the .wtp.yml hooks are the part that earns its place. Do not adopt it if you work on Windows, since the README lists only Linux and macOS, or if you need worktrees outside the ../worktrees base_dir convention.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 170 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The path and cleanup chores wtp removes

Plain git worktree makes you spell out the destination every time. The README contrasts the two forms directly: git worktree add ../project-worktrees/feature/auth feature/auth against wtp add feature/auth. The second form derives the path from the branch name, placing feature/auth at ../worktrees/feature/auth. That is the whole pitch in one line, and it is a real annoyance if you create worktrees often, because the path you type is pure bookkeeping and any typo leaves you with a stray directory.

The second chore is branch cleanup. Removing a worktree does not remove its branch, so finished branches pile up unless you remember the second command. wtp remove --with-branch feature/auth is documented as removing both, with a guard: the branch is deleted only if it is merged, and --force-branch overrides that check. The README calls this an atomic operation. It is not atomic in the transactional sense, but it is one invocation instead of two, which is the part that matters for whether people actually do it.

The audience is narrow and specific. If you check out one branch at a time in one directory, wtp adds nothing. It pays off for people who keep several branches materialized at once: reviewing a pull request while your own branch stays checked out, running a test suite on one branch while editing another, or spinning up a fresh copy to reproduce a bug without disturbing your working tree.

How wtp resolves a branch to a worktree path

The default layout is ../worktrees relative to the project root, and the branch name becomes a subpath, so feature/auth lands at ../worktrees/feature/auth. The base_dir key under defaults in .wtp.yml changes that root. The README does not describe how collisions are handled when a directory already exists at the computed path, so treat that as unverified.

Branch lookup has a fallback the README spells out. If the branch does not exist locally, wtp looks for a remote branch and creates a local tracking branch for it. When the same branch name exists in more than one remote, wtp refuses and prints the remotes it found: the README shows the error text naming origin and upstream, then suggests creating a local branch for the remote you want with git branch --track feature/shared upstream/feature/shared before running wtp add again. Refusing is the right call here. Silently picking origin would be a guess, and a wrong guess means the worktree tracks the wrong upstream for the rest of its life.

The management surface is small. wtp list prints PATH, BRANCH and HEAD columns, with the main worktree marked @ and an asterisk. wtp cd resolves the same targets as wtp exec, so the two commands share one naming scheme: a branch name, or @ for the main worktree. wtp exec feature/auth -- go test ./... runs a command inside that worktree without changing your shell's directory, which is the useful half of cd for scripted checks.

The .wtp.yml hooks are the reason to use wtp over a shell alias

A wrapper that only shortens paths could be replaced by a shell function. The hooks are harder to replicate. Under hooks.post_create, .wtp.yml accepts three step types, and the README documents the direction of each path carefully.

copy moves a file from the main worktree into the new one. The README notes that the source may be gitignored, which is the point: .env and a .claude context file are exactly the files a new worktree lacks and exactly the files git will not restore for you. The from path is always relative to the main worktree and the to path is relative to the new worktree, and if to is omitted it defaults to from. That asymmetry is worth reading twice, because getting it backwards means copying from the wrong tree.

symlink shares a directory between the main and new worktree, with .bin as the README's example. This is the right tool for a large dependency directory you do not want duplicated per worktree, and the wrong tool for anything the new branch is supposed to modify independently, since both worktrees then point at one directory.

command runs a shell command in the new worktree. The README's example sets an env map, NODE_ENV: development, and a work_dir key, shown as ".". It recommends explicit single-step commands such as npm ci and npm run db:setup over a single aggregate target, and shows make bootstrap as the alternative. The guidance is sound: when a hook fails, a single-step command tells you which step failed.

Installing wtp and running the first worktree

Four installation routes are documented. Homebrew on macOS and Linux: brew install satococoa/tap/wtp. Go, which requires the v2 module path: go install github.com/satococoa/wtp/v2/cmd/wtp@latest. A release tarball per platform, for example wtp_Darwin_arm64.tar.gz or wtp_Linux_x86_64.tar.gz, extracted and moved to /usr/local/bin. Or a source build with go build -o wtp ./cmd/wtp. The module path carrying /v2 matches the v2.10.x release line, so a go install without it will not resolve to these versions.

The requirements section is the first thing to check against your machine. Git 2.17 or later. Linux on x86_64 or ARM64, or macOS on Apple Silicon (the README names M1, M2, M3). Windows is not listed, and neither is Intel macOS. Shell completion is listed for Bash 4+/5.x with bash-completion v2, Zsh, and Fish; completion is what makes wtp cd feature/auth usable, so a shell outside that list loses much of the navigation benefit.

A first session looks like this. Run wtp add feature/auth for an existing branch, or wtp add -b feature/new-feature to create one, or wtp add -b hotfix/urgent abc1234 to branch from a specific commit. Add --exec "npm test" to run a command inside the new worktree after the hooks, or --quiet to print only the created absolute path, which the README frames as script-friendly output. wtp add -b feature/test origin/main creates a branch tracking a different remote branch. Then wtp list to see what exists, wtp cd @ to return to the main worktree, and wtp remove --with-branch feature/auth when the branch is done.

Where wtp gets in the way

The path convention is the main constraint. Worktrees live under a base_dir that defaults to ../worktrees, so if your team keeps worktrees somewhere else, or wants them outside the repository's parent directory, you either set base_dir or you are fighting the tool. The README does not show whether base_dir accepts absolute paths or paths outside the parent, so that needs checking before you commit to a layout.

Platform coverage is the harder limit. No Windows entry appears in the requirements, and no Intel macOS binary is listed in the download examples. If your team is mixed, wtp is a tool only part of the team can run, which is worse than a tool nobody runs, because the .wtp.yml hooks become a setup step that only some machines honor.

The hooks themselves are a failure surface. A command hook that fails mid-way leaves a worktree that exists but is not fully set up, and the README does not describe rollback or cleanup of a partially created worktree. There is also no documented way to skip hooks on a single wtp add, so a broken hook blocks every subsequent creation until you fix .wtp.yml or remove the hook. And the README is truncated at the copy hooks section, so the full set of configuration keys is not visible in the material available here; check the repository for keys beyond version, defaults.base_dir, and hooks.post_create before assuming the schema is complete.

Alternatives and what changes if you leave wtp

The baseline is git worktree itself, which is already installed with Git 2.17 and later. It gives you add, list, remove, and prune with explicit paths and no configuration file. You lose automatic path derivation, the copy and symlink hooks, and wtp cd with completion. You keep everything else, including the ability to script it, and you gain a tool that behaves identically on every platform Git supports. If your setup steps are two commands, git worktree plus a short shell script is a smaller thing to maintain.

A different approach is a general task runner such as make or a shell script invoked after git worktree add. That keeps the setup logic in the same file your CI already reads, rather than splitting it between .wtp.yml and a Makefile. The trade-off is that the runner has no idea a worktree was just created, so the invocation stays manual or lives in a git hook. wtp's advantage is that post_create fires as part of wtp add, which means the setup cannot be forgotten. That is the actual difference: not the command syntax, but where the trigger lives.

Direnv and similar directory-based environment tools solve an adjacent problem, loading environment variables when you enter a directory. They do not create worktrees, copy gitignored files, or run dependency installation, so they complement wtp rather than replace it. If your only pain is environment variables, one of those is the smaller dependency.

Maintenance cost, licence, and what to verify before adopting

wtp is MIT licensed, which permits commercial and private use, modification, and redistribution with the licence text retained. That is a permissive baseline; it is not legal advice, and if you vendor or repackage the binary, keep the copyright notice with it.

Maintenance signals from the material are positive but limited. The repository is not archived, the last push is dated 2026-03-30, and three patch releases shipped in March 2026 (v2.10.1, v2.10.2, v2.10.3), which suggests active patch-level attention. Patch releases at that cadence can also mean frequent small fixes; the changelogs are the place to check whether any of them touched hook execution, since that is the part that can break your setup silently.

Upgrade cost is low by design. A single binary installed via Homebrew, go install, or a tarball, with no daemon and no server-side component. The thing to watch is .wtp.yml, which is per-project and versioned by the version: "1.0" key. If a future release changes the hook schema, that key is presumably where the break shows up. The README does not document a migration path for the version key, so pin the wtp version in CI if you rely on hooks there.

Before adopting, verify three things on a scratch repository. That wtp add on a branch with no local copy correctly tracks the remote you expect, especially in a repo with more than one remote. That a copy hook with from: ".env" and no to key places the file where you think it does, given the main-relative and new-relative asymmetry. And that your shell is one of Bash 4+/5.x with bash-completion v2, Zsh, or Fish, because wtp cd without completion is not much shorter than the path you were avoiding.

Editorial conclusion

Adopt wtp if your team already creates worktrees per branch and you are tired of retyping paths and re-running npm ci by hand; the .wtp.yml hooks are the part that earns its place. Do not adopt it if you work on Windows, since the README lists only Linux and macOS, or if you need worktrees outside the ../worktrees base_dir convention. Before rolling it out, verify that your Git is 2.17 or later, that your shell completion works for the commands you actually type, and that a wtp add on a scratch branch runs your post_create hooks exactly once.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. satococoa/wtp on GitHub
Community notes

Community notes