A Git worktree manager for trunk-based development
worktrunk (wt) is a Git worktree manager designed for trunk-based development workflows.
It simplifies creating, switching between, and managing Git worktrees, making it easy to
work on multiple features or branches simultaneously without the overhead of stashing
or switching branches in a single working directory.
Git-style external subcommands: wt foo now runs wt-foo from PATH when foo is not a built-in, mirroring git foo → git-foo. Third-party tools can be installed and invoked as wt without touching this repo. Unrecognized commands show a git-style error with typo suggestions. Docs (#2054, thanks @pablospe for the suggestion in #2053)
{{ owner }} template variable: Expands to the GitHub/GitLab repository owner, useful for constructing URLs or paths in hook templates and worktree-path. (#2051, thanks @greggdonovan)
Typed env-var config overrides: WORKTRUNK__LIST__TIMEOUT_MS=30 and other typed overrides now work correctly. Previously, string-typed env values silently failed deserialization, wiping all user config and falling back to defaults. (#2062)
Config error attribution: Config load errors now identify the source — file errors show TOML line/column pointers, env-var errors list the offending WORKTRUNK_* variable. Previously all failures showed a generic message. (#2068)
Per-symbol atomic status rendering: The Status column in wt list and the wt switch picker now renders each symbol independently — unresolved gates show ⋯ at their position instead of fabricating defaults when the collect deadline expires. (#2067)
Hook error messages: Malformed hook command config now lists the three accepted forms (string, named table, pipeline list) with a pointer to wt hook --help, instead of an opaque serde error. (#2042)
Stale trash cleanup: wt remove now sweeps orphaned .git/wt/trash entries older than 24 hours after each removal, reclaiming space from interrupted background removals. (#2039)
Changed
wt hook exits successfully when no hooks are configured: Previously errored; now prints a warning and exits 0, so scripts and CI can invoke wt hook unconditionally. (#2056)
Hook output log layout: Log files moved from flat .git/wt/logs/{name}.log to nested {branch}/{source}/{hook-type}/{name}.log. Per-branch listing/clearing is now O(that branch). logs get --format=json paths changed to relative. Legacy flat files are swept automatically. (#2041)
Fixed
wt config show false "Not configured": When the shell init line lives in a sourced file (common with dotfile managers), config show no longer reports "Not configured" — it checks whether integration is actually active at runtime. Fixes #1306. (#2066, thanks @wouter-intveld for reporting)
Remove-then-switch hint: The hint for shadowed remote branches now uses --foreground so the chained wt remove && wt switch actually works (background removal left a placeholder directory blocking the switch). (#2040)
Conflict detection unified: The wt switch picker and wt list now both run both conflict probes (commit-level and working-tree). Previously the picker skipped the cheaper probe, leaving the fallback unreachable for clean worktrees; wt list non-full skipped the working-tree probe, missing conflicts from interrupted rebases. (#2064)
Documentation
Surfaced vars & aliases on homepage and tips-patterns, cross-linked state keys to dedicated docs, tightened hook links. (#2035, #2036, #2037, #2038)
Internal
Subcommand ordering aligned to documented policies (pipeline order for step, CRUD for state actions). (#2043, #2044)
Install worktrunk 0.36.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.36.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.36.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.36.0
────────────────────────────────────────────────┬───────────────────┬─────────────
File │Platform │Checksum
────────────────────────────────────────────────┼───────────────────┼─────────────
worktrunk-aarch64-apple-darwin.tar.xz │Apple Silicon macOS│checksum
────────────────────────────────────────────────┼───────────────────┼─────────────
worktrunk-x86_64-apple-darwin.tar.xz │Intel macOS │checksum
────────────────────────────────────────────────┼───────────────────┼─────────────
worktrunk-x86_64-pc-windows-msvc.zip │x64 Windows │checksum
────────────────────────────────────────────────┼───────────────────┼─────────────
worktrunk-aarch64-unknown-linux-musl.tar.xz │ARM64 MUSL Linux │checksum
────────────────────────────────────────────────┼───────────────────┼─────────────
worktrunk-x86_64-unknown-linux-musl.tar.xz │x64 MUSL Linux │checksum
────────────────────────────────────────────────┴───────────────────┴─────────────
Install via Cargo
cargo install worktrunk && wt config shell install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install