★ Worktrunk
• 825 words • 4 min
Git worktree management for parallel AI agent workflows
I stumbled upon worktrunk (wt) due to a fortunate coincidence, serendipity
at its best. I was pitching my own pancake
wt to someone, and this
person asked if I hadn’t heard of worktrunk.
If you look at its git star
history1,
you’ll notice that it became popular only at the beginning of 2026, whereas I
wrote my wt back in November
2025.
I did proper diligence at the time but couldn’t find anything resembling my
vision. Normally I prefer to reuse rather than writing from scratch.
“AI agent workflows” is a tagline that does not convince me. If anything, it actually worsens my appeal to try out the software. Seriously. Riding the wave is not helpful.
What really sold me was its usage
examples. I was able to
immediately tell that it had very similar goals to my own wt (sans AI).
Setup #
First, install worktrunk:
brew install worktrunkIt is as simple (and rusty!) as it could be:
% brew ls worktrunk
/opt/homebrew/Cellar/worktrunk/0.53.0/.crates.toml
/opt/homebrew/Cellar/worktrunk/0.53.0/.crates2.json
/opt/homebrew/Cellar/worktrunk/0.53.0/bin/wt
/opt/homebrew/Cellar/worktrunk/0.53.0/etc/bash_completion.d/wt
/opt/homebrew/Cellar/worktrunk/0.53.0/sbom.spdx.json
/opt/homebrew/Cellar/worktrunk/0.53.0/share/fish/vendor_completions.d/wt.fish
/opt/homebrew/Cellar/worktrunk/0.53.0/share/zsh/site-functions/_wtShell completion is a bonus that you’ll definitely want, as noted in a previous post:
# worktrunk: https://worktrunk.dev/
(( $+commands[wt] )) && eval "$(wt config shell init zsh)"The snippet above integrates well with my own
dotfiles; a vanilla setup that most
people should follow is, instead, wt config shell install, which will populate
your .bashrc / .zshrc accordingly with wt config shell init.
The shell integration alone makes it compelling enough to switch to wt, but
we’re not done yet.
Workflow #
It is possible to customize
wt. I value muscle memory
and the ability to easily recall commands, therefore I crafted this basic
configuration
to facilitate the migration from my own wt:
worktree-path = "{{ repo_path }}/.worktrees/{{ branch | sanitize }}"
[aliases]
add = "wt switch --create {{ args }}"
bd = "wt remove -D {{ args }}"
cd = "wt switch {{ args }}"
checkout = "wt switch {{ args }}"
cleanup = "wt step prune {{ args }}"
co = "wt switch {{ args }}"
commit = "wt step commit {{ args }}"
create = "wt switch --create {{ args }}"
del = "wt remove {{ args }}"
delete = "wt remove {{ args }}"
goto = "wt switch --no-cd {{ args }}"
ls = "wt list {{ args }}"
new = "wt switch --create {{ args }}"
prune = "wt step prune {{ args }}"
rm = "wt remove {{ args }}"
tui = "wt switch {{ args }}"
world = "wt step prune {{ args }}"
xl = "wt list {{ args }}"
[pre-start]
prek = "test -f .pre-commit-config.yaml && prek install --install-hooks || true"
[pre-merge]
prek = "test -f .pre-commit-config.yaml && prek run --from-ref \"$(git symbolic-ref --short refs/remotes/origin/HEAD)\" --to-ref HEAD || true"You can start by running wt config create and then iterating upon the newly
generated config file, which is very well documented. What a great developer
experience!
Let’s break it down.
We start with wt add <feature> (upstream: wt switch --create). This will
create a worktree:
tperrotta ~/Workspace/perrotta.dev git:master!?
% wt add myfeature
◎ Running pre-start user:prek
test -f .pre-commit-config.yaml && prek install --install-hooks || true
prek installed at `/Users/tperrotta/Workspace/perrotta.dev/.git/hooks/pre-commit`
✓ Created branch myfeature from master and worktree @ ~/Workspace/perrotta.dev/.worktrees/myfeature
39.06s user 6.26s system 251% cpu 17.984 total
tperrotta ~/Workspace/perrotta.dev/.worktrees/myfeature git:myfeature ⎇ myfeature
% git st
## myfeature...masterAt any time, we can check the current status with wt xl (upstream: wt list):
tperrotta ~/Workspace/perrotta.dev/.worktrees/myfeature git:myfeature ⎇ myfeature
% wt xl
Branch Status HEAD± main↕ Remote⇅ Path Commit Age Message
@ myfeature _ ./.worktrees/myfeature 23df7c41 50m name author explicitly
^ master !? ^| +5 -6 | . 23df7c41 50m name author explicitly
○ Showing 2 worktrees, 1 with changesWhen opening a new shell, we can easily switch to the newly created worktree
from the repo root with wt cd (upstream: wt switch):
tperrotta ~/Workspace/perrotta.dev git:master!?
% wt cd myfeature
○ Switched to worktree for myfeature @ ~/Workspace/perrotta.dev/.worktrees/myfeature
tperrotta ~/Workspace/perrotta.dev/.worktrees/myfeature git:myfeature ⎇ myfeature
%Once we are done (e.g. created/merged a pull request), we can delete the
worktree with wt bd or wt del (upstream: wt remove -D).
That’s all! The core workflow steps are quite easy to assimilate.
You’ll notice that my worktrees are created in a .worktrees directory within
the git repository root. This is due to my setting worktree-path in the config
file. The default behavior of worktrunk is to use sibling directories (e.g.
../myrepo.myfeature from the git root).
As you can see from my config file, I have also integrated prek (pre-commit) to it:
- the creation of a worktree yields
prek install - the merge of a worktree (not covered in this post) yields
prek runon the affected commits
wt has many other features; this is just the tip of the iceberg.
-
GitHub stars are a vanity metric but they are occasionally useful. ↩︎
Backlinks
- cmux (Jul 07, 2026)