A native GUI for managing git worktrees, built in Rust with GPUI (Zed's GPU-accelerated UI framework).
Website, tutorials, and examples →
Lists every worktree of a repository with its branch, status (dirty files, ahead/behind vs upstream), and offers create / remove / prune operations plus quick actions (open in terminal, show in file manager, copy path). Keyboard-first.
Prebuilt packages for every platform are attached to each GitHub Release (built by CI on native runners):
| Platform | Package |
|---|---|
| macOS (universal arm64 + x86_64) | …-macos-universal.dmg — open and drag Worktree Tool onto Applications (a plain .app zip is attached too) |
| Linux x86_64 / aarch64 | …-linux-<arch>.tar.gz — extract the binary; runtime deps are libxcb, libxkbcommon(+x11) and a Vulkan stack (standard on any desktop) |
| Windows x86_64 | …-windows-x86_64.zip — extract and run worktree-tool.exe |
| FreeBSD x86_64 | …-freebsd-x86_64.tar.gz — runtime needs libxcb/libxkbcommon from ports and LD_LIBRARY_PATH=/usr/local/lib |
The macOS build is ad-hoc signed, not notarized — on first launch Gatekeeper may ask you to confirm via right-click → Open. When launched from Finder the app starts at the path picker (there is no terminal cwd to detect); when run from a terminal it auto-detects the repository from the working directory.
To package locally: scripts/package-macos.sh 0.1.0 produces
dist/Worktree Tool.app and the zip.
| Platform | Status |
|---|---|
| macOS (Apple silicon / Intel) | built, tested, and manually verified |
| Linux (X11 / Wayland) | compiles and unit-tested via CI; rendering uses Vulkan through blade-graphics, linking needs libxcb, libxkbcommon, libxkbcommon-x11, libstdc++ |
| Windows | compiles and unit-tested via CI (MSVC toolchain) |
| FreeBSD | compiles via CI (GPUI gates its X11/Wayland backend to linux + freebsd); least-tested platform |
CI (.github/workflows/ci.yml) runs clippy, tests, and a release build on
macOS, Linux, Windows, and FreeBSD on every push once a remote is added.
For local cross-checks without target hardware:
cargo zigbuild --target x86_64-unknown-linux-gnu --lib (also
x86_64-pc-windows-gnu, x86_64-unknown-freebsd) — every crate compiles
cross-platform; only the final Linux binary link needs native X11 libraries.
- Stable Rust toolchain
giton yourPATH- macOS: Xcode command line tools (
xcode-select --install) for the Metal backend - Linux: the X11/xkbcommon dev packages above plus a Vulkan-capable driver stack
Run from inside any git repository — the app detects the repo from the current working directory:
cd ~/git/myrepo
cargo run --releaseFor step-by-step tutorials (first worktree, terminal setup, cleanup) and example workflows (hotfix mid-feature, PR review checkouts, parallel test runs), see the website.
| Key | Action |
|---|---|
n / cmd-n |
New worktree |
/ |
Focus search |
r / cmd-r |
Refresh |
up / down |
Move selection |
enter |
Open selected worktree's detail view |
t |
Open in terminal |
backspace / delete |
Remove selected worktree |
esc |
Clear search / close dialog / back to worktree list |
Detail view (per worktree):
| Key | Action |
|---|---|
1 / 2 / 3 |
Switch section: Working Copy ↔ History ↔ Branches |
up / down |
Move file selection (diff pane focused: move hunk cursor) |
tab |
Toggle file list ↔ diff pane |
s |
Stage / unstage selected file (diff pane focused: stage hovered hunk) |
S |
Stage all remaining changes |
d |
Discard selected file's changes (confirmation) |
c |
Commit staged changes via your editor |
g |
Continue the paused merge / rebase / cherry-pick / revert |
K |
Skip the current step (paused rebase / cherry-pick) |
A |
Abort the paused operation, restoring the pre-operation state |
t |
Open worktree in terminal |
r |
Refresh working copy |
esc |
Back to worktree list |
History section (2 from the detail view):
| Key | Action |
|---|---|
up / down |
Move commit selection (files pane focused: move file selection) |
tab |
Toggle commit list ↔ commit files |
y |
Copy the selected commit's full hash to the clipboard |
x |
Check out the selected commit (detached; refused while the working copy has changes) |
p |
Cherry-pick the selected commit onto this branch |
v |
Revert the selected commit (creates a revert commit) |
R |
Interactive rebase from the selected commit to HEAD — pick/drop/fixup rows in the dialog |
w |
Open a new worktree at the selected commit |
L |
Load 500 more commits |
r / t / esc |
Refresh / terminal / back — same as the Working Copy section |
Branches section (3 from the detail view):
| Key | Action |
|---|---|
up / down |
Move the cursor in the active list (branches or stashes) |
tab / s |
Toggle between the branch list and the stash list |
enter / x |
Switch to the selected branch (refused on a dirty working copy) |
m |
Merge the selected branch into the current branch |
R |
Rebase the current branch onto the selected branch |
d |
Delete the selected branch (refuses the current branch) |
n |
Create a new branch at HEAD |
M |
Rename the selected branch |
y |
Copy the selected branch name to the clipboard |
z |
Stash the working copy's changes (tracked + untracked) |
p / a |
Pop (apply + drop) / apply the selected stash |
D |
Drop the selected stash |
f |
Fetch all remotes (with prune) |
u |
Push the current branch (sets upstream on first push) |
l |
Pull the current branch (fast-forward only) |
F |
Force-push the current branch with lease — press twice to confirm |
r / t / esc |
Refresh / terminal / back — same as the Working Copy section |
Remote-tracking branches (origin/…) are listed after the locals; switching
and deleting refuse them, and merging/rebasing from them works. A conflicted
merge or rebase pauses (see Working Copy above): resolve and press g
in the Working Copy section, or A to back out.
Press enter on a worktree to drill into it. Changes are grouped into
Conflicts, Staged, Unstaged, and Untracked; the diff pane
shows the selected file's unified diff. Stage or unstage with s (all at
once with S), and discard a file's unstaged changes or an untracked file
with d — always with a confirmation. Discarding the unstaged part never
touches staged changes.
With the diff pane focused, ↑/↓ move a cursor between the file's hunks
and s stages just the hovered hunk (git apply --cached — the worktree
file is never touched). Binary and untracked files stage whole-file only.
Press c to write a commit: the app opens your editor exactly like
git commit does, resolving it in git's own order — $GIT_EDITOR,
core.editor, $VISUAL, $EDITOR, then a platform default. Save a
message to commit; empty the message to abort. Conflicted files show their
raw content — resolve them in your own editor, then press s to mark them
resolved.
A conflicted merge, rebase, cherry-pick, or revert pauses instead of
backing out: a banner names the operation (with rebase progress, e.g.
"rebasing 2/5"), and the paused state is real git state — other git
clients see it too. Resolve the files in your own editor, stage with s,
then g continues with the stored message (no editor round trip). K
skips the current step of a rebase or cherry-pick; A aborts and
restores the pre-operation state. While paused, mutating actions in the
other sections (branch switch, history checkout) refuse until you
continue or abort.
The Settings button (toolbar) lists the terminals detected on this machine; clicking one persists the choice immediately. The config file lives at an XDG path on every platform:
$XDG_CONFIG_HOME/worktree-tool/settings.toml # e.g. ~/.config/worktree-tool/settings.toml# worktree-tool settings
# terminal: one of the ids below (or unset for auto-detect)
terminal = "iterm"Terminal resolution order: settings.toml → $TERMCMD env var (app name,
Zed convention) → first detected terminal.
Report a bug (Settings → Report a bug) opens a prefilled GitHub issue
in your browser. It includes only the app version and platform — nothing
else is collected, and you review it before submitting. CLI terminals
launch with the worktree as their working directory; Windows Terminal gets an
explicit -d flag because its profiles override the inherited directory.
Supported terminals (auto-detected; the settings dialog only lists installed ones):
| Platform | Terminals, in auto-detect preference order |
|---|---|
| macOS | Terminal, iTerm2, WezTerm, Ghostty, Alacritty, Kitty, Warp, Hyper |
| Linux / BSD | xdg-terminal-exec, GNOME Terminal, Konsole, Xfce Terminal, foot, Tilix, Kitty, Ghostty, Alacritty, WezTerm, xterm |
| Windows | Windows Terminal, PowerShell (7), Windows PowerShell, Command Prompt, Alacritty, WezTerm, Ghostty |
cargo build # first build takes a few minutes (shader compilation)
cargo test # unit + git integration tests
cargo clippy -- -D warningsBuilding for any target — native or cross (Windows .exe from macOS,
Linux via Docker, FreeBSD, any Rust triplet) — is wrapped by:
scripts/build-target.sh <target> # host | macos-universal | x86_64-pc-windows-gnu | …See docs/BUILDING.md for the full per-platform guide and the measured cross-compilation matrix.
Note: text inputs accept raw key events; IME/marked-text input is not supported in v1.
Apache-2.0 — see LICENSE.
