A fast, reliable, and ergonomic manager for Git worktrees with both a CLI and a TUI. Built in Rust.
Status: Planning/Design. This README defines the scope and features to be implemented before coding begins.
Git worktrees are powerful, but managing many of them across multiple repositories can get unwieldy. gwm
provides a consistent interface to create, list, update, and remove worktrees, with persistent state, discoverability, and a pleasant TUI for daily use.
- Written in Rust for speed and safety
- Persistent state of worktrees it manages
- Full CRUD operations for worktrees
- Both TUI and CLI interfaces
- Safe, transparent operations that use
git worktree
under the hood - Cross-platform (macOS, Linux, Windows)
- Durable storage of:
- Registered repositories (root path, default remote, metadata)
- Managed worktrees (path, branch/ref, HEAD, labels/tags, notes, managed vs. adopted)
- Optional user labels, tags, and notes per worktree
- Created/updated timestamps for auditing
- Storage engine: SQLite database
- Default location:
- macOS:
~/Library/Application Support/gwm/gwm.db
- Linux:
$XDG_DATA_HOME/gwm/gwm.db
or~/.local/share/gwm/gwm.db
- Windows:
%APPDATA%\gwm\gwm.db
- macOS:
- Override with
GWM_DB_PATH
environment variable
- Default location:
- Automatic schema migrations with versioning
- Import/export of state (JSON) for backup and portability
- Executes
git worktree ...
and other safegit
commands - Reads current status (clean/dirty), detached HEAD, ahead/behind counts, and branch tracking where applicable
- Reconciliation:
gwm sync
compares DB withgit worktree list
and filesystem; adopts or flags driftsgwm prune
leveragesgit worktree prune
and cleans stale state entries
- No rewriting of Git history; operations are transparent and confirm destructive actions
- Create
- Create worktree from existing branch
- Create new branch from base (e.g.,
main
) then create worktree - Optionally track remote branch
- Choose target path or use templated path patterns
- Read
- List all worktrees across repos with filters (repo, branch, status, tag)
- Show detailed info for a specific worktree (path, branch, HEAD, upstream, cleanliness, ahead/behind, labels/tags, notes)
- Search by path, label, tag, or branch
- Update
- Edit metadata (label, tags, notes)
- Retarget upstream tracking for branch (non-destructive)
- Rename label; refresh status
- Delete
- Remove worktree from Git and optionally delete its directory
- Forget (remove from gwm state only) without touching Git
- Force mode for stubborn directories (with confirmation)
- Register/unregister repositories in gwm
- Import/adopt existing worktrees from a repo
- List all registered repos
- Per-repo settings (default remote, default base branch)
-
Single binary
gwm
with subcommands -
Global flags:
--repo
,--json
,--quiet
,--yes
,--db <path>
,--git <path>
-
Representative commands (final flags may evolve):
- Repos
gwm repo add <path>
— Register a Git repositorygwm repo ls
— List registered repositoriesgwm repo rm <repo>
— Unregister a repository (does not modify Git)gwm repo import <repo>
— Adopt all existing worktrees from Git into gwm state
- Worktrees
gwm wt add <repo> <path> --branch <name> [--create-branch [--from <base>]] [--track origin/<name>]
— Create a worktreegwm wt ls [--repo <repo>] [--filter <expr>] [--status clean|dirty|detached] [--tag <tag>]
— List worktreesgwm wt show <worktree>
— Show details for a specific worktreegwm wt edit <worktree> [--label <text>] [--add-tag <tag>] [--rm-tag <tag>] [--note <text>]
— Update metadatagwm wt rm <worktree> [--delete-files|--keep-files] [--forget-only] [--force]
— Remove/forget a worktreegwm wt adopt <repo> <path>
— Adopt an existing worktree into gwm state
- Maintenance
gwm sync [--repo <repo>]
— Reconcile DB with Git and filesystemgwm prune [--repo <repo>]
— Prune stale worktrees via Git and clean stategwm doctor
— Diagnose environment and common issues
- UI
gwm tui [--repo <repo>]
— Launch the TUI
- Repos
-
Structured, parseable JSON output with
--json
-
Rich exit codes: 0 success, 1 usage error, 2 git error, 3 IO error, 4 state error, etc.
- Built with ratatui + crossterm (or equivalent)
- Layout
- Left: repositories pane (filterable)
- Center: worktrees list for selected repo (sortable by name, branch, status, recency)
- Right: details for the selected worktree (HEAD, upstream, status, notes, tags)
- Interactions
- Search/filter worktrees, fuzzy find
- Create new worktree (guided)
- Edit labels/tags/notes inline
- Remove/forget with confirmation
- Open worktree in $EDITOR or file manager
- Sync/prune commands
- Key bindings (tentative)
?
helpj/k
or↓/↑
navigate listsEnter
open detailsa
add worktreee
edit metadatad
delete (confirm)f
filter/searchr
refresh/synco
open in editorq
quit
- File:
$XDG_CONFIG_HOME/gwm/config.toml
(macOS:~/Library/Application Support/gwm/config.toml
, Windows:%APPDATA%\gwm\config.toml
) - Options (tentative)
default_base_branch = "main"
default_remote = "origin"
path_template = "{repo}/{branch}"
(for suggested worktree paths)editor = "$EDITOR"
confirm_dangerous = true
git_binary = "git"
- Environment variables override config where applicable (e.g.,
GWM_DB_PATH
,GWM_CONFIG
)
- All destructive operations require confirmation unless
--yes
is set --dry-run
available for create/remove/prune where possible- Clear error messages with suggested remediations
- Uses Git as the source of truth for on-disk state; DB is authoritative for metadata
- No network calls beyond invoking Git (e.g.,
git fetch
when requested)
- Cargo workspace with clear separation of concerns:
gwm-core
(library)- Domain models: Repository, Worktree, Tag, Note
- Persistence: SQLite via
rusqlite
; migrations; repositories pattern - Git adapter: small wrapper around invoking
git
safely - State reconciliation logic (sync/prune/import)
gwm-cli
(binary)- Argument parsing via
clap
- Human-readable and JSON output
- Argument parsing via
gwm-tui
(binary)- UI state + components using
ratatui
- Async tasks for background status refresh
- UI state + components using
- Tables
repos(repo_id TEXT PRIMARY KEY, root_path TEXT UNIQUE NOT NULL, default_remote TEXT, created_at TEXT, updated_at TEXT)
worktrees(wt_id TEXT PRIMARY KEY, repo_id TEXT NOT NULL, path TEXT UNIQUE NOT NULL, branch TEXT NULL, head_sha TEXT NULL, managed INTEGER NOT NULL DEFAULT 1, label TEXT NULL, note TEXT NULL, created_at TEXT, updated_at TEXT, last_seen_at TEXT, FOREIGN KEY(repo_id) REFERENCES repos(repo_id))
tags(tag TEXT PRIMARY KEY)
worktree_tags(wt_id TEXT NOT NULL, tag TEXT NOT NULL, PRIMARY KEY(wt_id, tag), FOREIGN KEY(wt_id) REFERENCES worktrees(wt_id), FOREIGN KEY(tag) REFERENCES tags(tag))
- Derived/ephemeral (not stored; computed on demand)
status
: clean/dirtyahead/behind
: relative to upstream if trackingdetached
: boolean
- v0.1 (MVP)
- CLI: repos add/ls/import, wt add/ls/show/rm/adopt, sync, prune, doctor
- SQLite persistence with migrations
- Basic TUI (list + details, add/remove, edit metadata)
- JSON output and robust exit codes
- v0.2
- Advanced filters/search, fuzzy finder in TUI
- Bulk operations (multi-select delete/adopt)
- Better ahead/behind visualization
- Path templates and per-repo defaults
- v0.3
- Watcher for live status updates
- Optional telemetry (opt-in) and metrics
- Plugin hook points for custom actions
- Git (2.31+ recommended; tested against recent stable versions)
- Rust stable toolchain (for building from source)
- Build all:
cargo build --workspace
- CLI:
cargo run -p gwm-cli -- <args>
- TUI:
cargo run -p gwm-tui -- [--repo <path>]
- Managing non-Git VCS
- Moving worktrees in place (unsupported by Git; recommend recreate)
- Automatic branch cleanup on remote (can be added later)
TBD (e.g., MIT or Apache-2.0). Will be finalized before the first release.
- Inspired by
git worktree
and TUI libraries (ratatui
,crossterm
)
If you have additional requirements or workflows you want optimized, please open an issue or propose changes to this plan.