gwt is a small Git worktree wrapper. It creates and removes worktrees, opens them in your active terminal multiplexer, and keeps worktree branches and paths predictable.
Without a supported multiplexer, gwt still creates the worktree and prints its path so you can cd into it.
I built gwt to streamline my Codex workflow: create a worktree, start Codex there, and continue working elsewhere.
Doing that manually takes several commands. Creating the same setup in lazygit requires filling in three separate fields. gwt reduces the workflow to one command.
The install recipe requires Go and just. It installs the binary to ~/bin and Fish completions to ~/.config/fish/completions.
just installMake sure ~/bin is on your PATH.
Run gwt from inside a Git repository.
Usage:
gwt add <worktree-name> [--ignored=copy|hardlink|skip] # create a worktree and attach (default: copy)
gwt remove <worktree-name> # remove a worktree and its session or workspace
gwt list # list all worktrees except the main checkout
gwt cleanup # delete dangling wt/* branches after confirmation
remove also accepts rm and r. Other short aliases are a for add, ls or l for list, and cl or c for cleanup.
New worktrees use the branch name wt/<name> and the path <repo-parent>/<repo>-<name>. A new branch starts at HEAD; if the branch already exists, gwt checks it out instead. No network fetch runs during add.
For add and remove, gwt chooses one backend per invocation in this order:
- herdr: When
HERDR_ENV=1,gwtdelegates creation toherdr worktree create. The checkout opens as a focused workspace grouped with the parent repository. - tmux via sesh: When
TMUXis set andseshis onPATH,gwtcreates the worktree and connects withsesh. - Print path: Otherwise,
gwtcreates the worktree and prints its path.
If TMUX is set but sesh is unavailable, gwt uses the print-path backend and suggests brew install sesh.
gwt remove resolves names from Git's worktree list, so it can remove detached worktrees. It closes the matching herdr workspace or tmux session but leaves the branch intact.
gwt list shows worktree names and refs in two columns. It omits the main checkout and displays detached worktrees as (detached @ <commit>).
gwt cleanup is the only command that deletes branches. It asks for confirmation before deleting dangling wt/* branches.
By default, gwt add copies Git-ignored files, such as .env and node_modules, from the main checkout into the new worktree.
Use --ignored to select a different strategy:
copycopies each ignored file. This is the default.hardlinkhardlinks regular files and falls back to copying when a hardlink cannot be created.skipleaves ignored files behind.
Create a worktree for a feature:
gwt add parsingThis creates wt/parsing from HEAD at ../gwt-parsing, copies ignored files, and then opens the worktree or prints its path.
Create a worktree without ignored files:
gwt add parsing --ignored=skipList managed worktrees:
$ gwt list
parsing wt/parsing
old-fix (detached @ dccfb99)
tmp-8 wt/tmp-8
Remove a worktree while keeping its branch:
gwt rm parsingDelete dangling wt/* branches after confirmation:
gwt cleanupThese integrations are optional. gwt add still creates a worktree when none of them are available.
- herdr provides workspace management when
HERDR_ENV=1. - tmux provides terminal sessions.
- sesh connects worktrees to tmux sessions.
- zoxide tracks worktree directories on the tmux attach path.
Use just for common development tasks:
$ just help
Available recipes:
build # Build the gwt binary
check # Run all checks
clean # Clean build artifacts
help # Show available commands
install # Install gwt to ~/bin along with fish autocomplete
lint # Run linters
test # Run tests