Skip to content

Latest commit

 

History

259 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

worktree-tool

worktree-tool logo

CI License: Apache-2.0

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.

worktree-tool showing three worktrees with clean, dirty, and ahead statuses

Install

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 support

Platform Status
macOS 26+ (Apple silicon / Intel) built, tested, and manually verified — including on macOS 27 (Xcode 27 SDK)
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.

Requirements

  • Stable Rust toolchain
  • git on your PATH
  • macOS 26 or newer: Xcode command line tools (xcode-select --install) for the Metal backend
  • Linux: the X11/xkbcommon dev packages above plus a Vulkan-capable driver stack

Usage

Run from inside any git repository — the app detects the repo from the current working directory:

cd ~/git/myrepo
cargo run --release

For step-by-step tutorials (first worktree, terminal setup, cleanup) and example workflows (hotfix mid-feature, PR review checkouts, parallel test runs), see the website.

Shortcuts

Key Action
n / cmd-n New worktree
R Manage remotes (list, add, remove)
/ 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 in the in-app editor (cmd/ctrl+enter commits)
C Commit via your $EDITOR (git's own resolution order)
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.

Working Copy

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 in the app: a multi-line editor opens pre-filled with commented hints (which never reach the message — lines starting with # are stripped, honoring core.commentChar). Enter is a newline; cmd/ctrl+enter or the Commit button commits, esc cancels and keeps your staged changes.

C instead opens your own editor exactly like git commit does, resolving it in git's 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.

Remotes

R (or the Remotes toolbar button) opens the repo's remote list: name, fetch URL, and the push URL when it differs. a adds a remote (name + URL — a name may not start with -, contain whitespace, or look like a path), d removes the selected one after a confirmation (its origin/* tracking refs go with it), and esc closes. Fetching and pushing live in the Branches section of each worktree (f fetch, u push, l pull).

Settings

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

Development

cargo build        # first build takes a few minutes (shader compilation)
cargo test         # unit + git integration tests
cargo clippy -- -D warnings

Building 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.

License

Apache-2.0 — see LICENSE.

About

A native GPUI (Rust) GUI for managing git worktrees — macOS, Linux, Windows, FreeBSD

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages