# wtp turns a branch name into a worktree path, and stops at Apple Silicon

> wtp wraps git worktree with generated paths, post-create hooks, and branch cleanup. Its support matrix leaves out Intel macOS, and its newest tag is v2.10.3 from 8 March 2026.

**satococoa/wtp** — 🌳 A powerful Git worktree CLI tool with automated setup, branch tracking, and smart navigation

- Repository: https://github.com/satococoa/wtp
- Website: https://dev.to/satococoa/wtp-a-better-git-worktree-cli-tool-4i8l
- Stars: 636 · Forks: 25
- Language: Go
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/satococoa-wtp

## The macOS support list stops at Apple Silicon

The requirements are short and have a hole in them. Git 2.17 or later, for worktree support. Then two operating systems: Linux on x86_64 or ARM64, and macOS on Apple Silicon M1, M2, or M3. No Intel Mac appears anywhere, and the download instructions back that up, naming three archives, wtp_Darwin_arm64.tar.gz, wtp_Linux_x86_64.tar.gz, and wtp_Linux_arm64.tar.gz, with no x86_64 macOS build among them. A developer on an older Intel Mac is not a partial case, they are outside the matrix. The shell list carries its own condition: Bash 4 or 5.x, but only with bash-completion v2, plus Zsh, or Fish. Completion is therefore supported on three shells outright and on one specific version of a helper on the fourth, which matters because the navigation story leans on tab completion.

## Four install paths, and three of them want root

Installation offers four routes and three of them end in root. Homebrew is one command and Go is one command, both handing the binary to another tool:

```bash
brew install satococoa/tap/wtp
go install github.com/satococoa/wtp/v2/cmd/wtp@latest
```

The binary route pipes a platform tarball into tar and then moves the result with sudo into /usr/local/bin/. The from-source route does the same after go build:

```bash
git clone https://github.com/satococoa/wtp.git
cd wtp
go build -o wtp ./cmd/wtp
sudo mv wtp /usr/local/bin/  # or add to PATH
```

So on a machine where Homebrew already owns /usr/local/bin, the two manual routes are the ones that can collide with it. The two Go-aware routes also resolve versions differently: go install pins to @latest at the moment it runs, Homebrew follows the tap, and the module path itself carries a v2 segment, so release tags and import paths do not line up one to one.

## A branch name becomes a directory path

The path scheme is the core of the tool and it is easy to reason about. A branch named feature/auth becomes a worktree at ../worktrees/feature/auth, exactly the directory the equivalent raw git command would have made you type by hand. Three create forms are shown:

```bash
wtp add feature/auth
wtp add -b feature/new-feature
wtp add -b hotfix/urgent abc1234
```

The first reuses a branch that is already local and tracks the remote one if it is missing, the second creates a branch as it creates the worktree, and the third starts from a named commit. The base is configurable, since .wtp.yml sets defaults.base_dir to ../worktrees relative to the project root, so the whole layout moves with one line. Navigation reuses the same names, with wtp cd feature/auth to jump and wtp cd @ to return to the main worktree. wtp list prints PATH, BRANCH, and HEAD, marks the main worktree with @, and shows hand-added worktrees at paths such as ../project-hotfix next to the ones wtp created.

## copy hooks read from the main worktree, not from where you run wtp

One rule in the copy hook decides everything else: from is always resolved relative to the main worktree, and to is resolved relative to the worktree being created, defaulting to from when it is omitted. An absolute from needs an explicit to, and the resolution does not change depending on where you run wtp add from, so the same result comes out whether you start in the main worktree or in a sibling. That design is what lets a gitignored .env or a .claude directory be reused at all. The catch is that copy duplicates. Every new worktree gets its own physical .env, and a credential edited in the main worktree is not edited anywhere else. Anything that must stay identical across worktrees belongs in the symlink hook instead, where from and to each accept a relative or an absolute path, which is how .bin, .cache, and node_modules get shared rather than duplicated.

## Two yaml modules and a linter-sized indirect graph

The direct require block in go.mod is five modules deep. urfave/cli/v3 at 3.7.0 builds the command surface, golang.org/x/term at 0.40.0 handles the terminal, and stretchr/testify at 1.11.1 carries the tests. Then there are two yaml libraries: go.yaml.in/yaml/v3 at 3.0.4 and gopkg.in/yaml.v3 at 3.0.1, the same parser reachable under two module paths. A tool whose entire configuration is a single .wtp.yml does not obviously need both. The indirect block is the surprise. It opens with lint plugins by the dozen, from gochecknoglobals and tagalign through errname, nilnil, noinlineerr, nakedret, prealloc, forbidigo, and makezero, mixed in with real libraries like ProtonMail/go-crypto, chroma, and tabwriter. A .golangci.yml that pulls its linters in as module dependencies folds all of that into the module graph of a five-dependency CLI.

## Tags cluster in one week, then the commits stop

The release picture is a tight cluster followed by a gap. v2.10.1 landed on 3 March 2026, and v2.10.2 and v2.10.3 both landed on 8 March 2026, an hour and a half apart. The last commit to the repository is dated 30 March 2026, leaving more than six months since anything was pushed, and the repository is not archived. The practical model is a tool that finished its 2.10 line and then stopped: the binary you install comes from that window, and the workflow in the readme is the one that was current then. The packaging files match that shape. A .goreleaser.yml produces the three platform archives named above, a packaging/ directory carries the Homebrew tap, and a Taskfile.yml sits beside scripts/ for the release chores. The repository also keeps AGENTS.md, CLAUDE.md, and a .codex/ directory, so the same tool that manages your branches also expects instructions of its own.

## The safe removal flag is the one that refuses to work

Removal is where wtp stops being a thin wrapper over git. wtp remove feature/auth drops only the worktree, and wtp remove --force feature/auth does the same when the tree is dirty. The branch is a separate flag: wtp remove --with-branch feature/auth takes both, and the note on that line is the important part, because it applies only if the branch is merged. An unmerged branch needs --force-branch, shown on a line of its own as wtp remove --with-branch --force-branch with no argument at all. The readme calls this a single atomic operation, and it replaces a two-step routine where the branch delete is the half people forget, leaving an orphan behind. The trade is that the default is also the option that stops working, so the first flags most people learn are the ones that skip the merge check.

## Conclusion

wtp earns its place if you name branches after paths and keep forgetting to delete a branch after its worktree. It does not serve an Intel Mac, a Windows box, or a team that needs a release newer than the 2.10 line that shipped in the first week of March 2026. Before installing, check the platform matrix and the archive name for your architecture, decide whether your .env should be copied or symlinked into each worktree, and read the removed-branch rule carefully, since the safe flag refuses to act and the unsafe one skips the merge check entirely.

## FAQ

### What operating systems does wtp support?

Linux on x86_64 or ARM64, and macOS on Apple Silicon M1, M2, or M3. The downloadable archives are wtp_Darwin_arm64.tar.gz, wtp_Linux_x86_64.tar.gz, and wtp_Linux_arm64.tar.gz, and no Intel Mac build is offered.

### How do I install wtp on macOS or Linux?

With brew install satococoa/tap/wtp, or with go install github.com/satococoa/wtp/v2/cmd/wtp@latest. A manual route also exists: untar the platform archive and move the binary to /usr/local/bin/ with sudo, or build from source with go build -o wtp ./cmd/wtp.

### What does wtp use the .wtp.yml file for?

It holds project configuration, starting with a version field and defaults.base_dir, shown as ../worktrees relative to the project root. Its hooks.post_create list accepts copy, symlink, and command entries that run after a worktree is created.

### Does wtp remove the branch when it deletes a worktree?

Only with the flag wtp remove --with-branch, and only if the branch is already merged. Unmerged work needs wtp remove --with-branch --force-branch, which skips the merge check.

### When was the last wtp release?

v2.10.3, published on 8 March 2026, following v2.10.2 the same day and v2.10.1 on 3 March 2026. The last commit to the repository is dated 30 March 2026, and the repository is not archived.

## Sources

- [License: MIT](https://github.com/satococoa/wtp/blob/main/LICENSE)
- [Project website](https://dev.to/satococoa/wtp-a-better-git-worktree-cli-tool-4i8l)
- [README](https://github.com/satococoa/wtp/blob/main/README.md)
- [Releases](https://github.com/satococoa/wtp/releases)
- [satococoa/wtp on GitHub](https://github.com/satococoa/wtp)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/satococoa-wtp
