devtools is a small Go CLI for managing development checkouts as Git worktrees and pairing each worktree with a tmux session.
By default it uses ~/dev as the workspace root. Set DEVTOOLS_ROOT or pass --root PATH to use a different workspace.
- Go 1.26 or newer
- Git
- tmux
- fzf, for interactive picking with
devtools pick,devtools sessions, or ambiguousdevtools switchqueries - Nix, optional, for the provided dev shell and package build
Run from this repository:
go install ./cmd/devtoolsOr build with Nix:
nix builddevtools [--root PATH] <command> [args]Commands:
devtools new <project-name>
devtools clone <repo-url> [project-name]
devtools migrate [--allow-dirty] [path]
devtools work <branch> [--from <start-point>]
devtools merge
devtools update [--all]
devtools push
devtools rebase [--onto <base>]
devtools done [worktree] [--force] [--keep-branch] [--allow-main]
devtools list
devtools status [--all]
devtools switch [path-or-query]
devtools pick
devtools sessionsCommon flow:
devtools clone git@github.com:owner/repo.git repo
cd ~/dev/repo/main
devtools work feature/example
devtools mergeclone creates a bare repository at:
<root>/<project>/.bare
and creates the default branch as a worktree at:
<root>/<project>/<branch>
Feature branches are converted to filesystem-safe worktree names, so feature/example becomes feature-example.
Creates a normal Git repository on the main branch and switches to its tmux session.
devtools new scratchClones a repository into the bare-worktree layout, creates the remote default branch worktree, and switches to its tmux session.
devtools clone git@github.com:owner/repo.git
devtools clone git@github.com:owner/repo.git custom-nameMigrates an existing checkout into the managed layout. Checkouts with tracked uncommitted changes are rejected unless --allow-dirty is passed. Untracked files are ignored by this check.
devtools migrate
devtools migrate ~/src/repo --allow-dirtyCreates a new worktree for a branch in the current managed project and switches to its tmux session.
devtools work feature/api
devtools work experiment --from origin/mainWhen --from is omitted, the current checkout's HEAD is used as the start point.
Merges the current worktree branch into the main worktree, fast-forwarding when Git can, then removes the merged worktree and deletes its local branch. Both worktrees must be clean. Pass --squash to squash the branch changes into one new commit on main; Git opens your editor for the commit message.
devtools merge
devtools merge --squashFetches from origin and fast-forwards the current project's main or master worktree. The main worktree must be clean. Pass --all to update main worktrees for all managed projects under the workspace root.
devtools update
devtools update --allPushes the current branch. If the branch has no upstream, it pushes to origin and sets the upstream.
devtools pushRebases the current worktree onto the current project's main or master branch by default. The worktree must be clean. Use --onto to choose a different base ref.
devtools rebase
devtools rebase --onto origin/mainRemoves a worktree and, by default, deletes its local branch. The worktree must be clean and pushed unless --force is used.
devtools done
devtools done feature-api --keep-branch
devtools done feature-api --forceRemoving main or master requires --allow-main.
Lists discovered worktrees under the workspace root.
devtools listShows a compact dashboard with branch, clean or dirty state, ahead/behind counts, and upstream. Untracked files are ignored when computing the dirty state.
When run from inside a managed worktree, only worktrees for that project are shown. From outside a managed project, the whole workspace root is shown. Pass --all to show the whole workspace root from anywhere.
devtools status
devtools status --allSwitches to a tmux session for a worktree. The target can be an absolute path or a query matched against discovered labels.
devtools switch repo/main
devtools switch feature-apiIf no target is provided, or if a query matches multiple worktrees, fzf is used to pick one.
Always opens the interactive picker and switches to the selected worktree.
devtools pickOpens an interactive picker for active tmux sessions and switches to the selected session.
devtools sessionsEnter the Nix dev shell:
nix developRun tests:
go test ./...Run the formatter for the Nix files:
nix fmtBuild the Nix package:
nix build