Git worktree manager with automatic port allocation, file copying, and project setup
Install • Usage • Project Config • Global Config
Inspired by tree-me.
gem install bonchiAdd to your ~/.zshrc or ~/.bashrc:
source <(bonchi shellenv)This gives you auto-cd (jumps into the worktree after create/switch/pr) and tab completions.
bonchi init # Generate a .worktree.yml in the current project
bonchi create BRANCH [BASE] # Create new branch + worktree (alias for switch -c)
bonchi pr NUMBER_OR_URL # Checkout GitHub PR in worktree
bonchi switch BRANCH # Switch to branch in worktree
bonchi remove BRANCH # Remove a worktree (and merged branch)
bonchi rmf BRANCH # Force-remove a worktree (and merged branch)
bonchi rmrf BRANCH # Force-remove a worktree and branch
bonchi list # List all worktrees
bonchi setup [-- ARGS...] # Run setup in current worktree (ports, copy, pre_setup, setup cmd)
bonchi shellenv # Output shell function for auto-cd + completions
bonchi prune # Prune stale worktree admin files
bonchi version # Print version
bonchi help [COMMAND] # Describe available commands or one specific commandRun bonchi help <command> for detailed info on any command.
Worktrees are created at ~/dev/worktrees/<repo>/<branch>. Customize via global config or WORKTREE_ROOT env var (env var takes precedence).
Drop a .worktree.yml in your project root:
min_version: 0.4.0
copy:
- mise.toml
- .env.local
link:
- node_modules
- vendor/bundle
ports:
- PORT
- WEBPACK_PORT
edit:
mise.toml:
- "^PORT=.*": "PORT=$PORT"
pre_setup:
- mise trust
setup: mise exec -- bin/setup| Key | Description |
|---|---|
min_version |
Minimum bonchi version required (aborts with upgrade message if not met) |
copy |
Files copied from main worktree before setup |
link |
Files symlinked from main worktree (useful for large directories like node_modules) |
ports |
Env var names — unique ports allocated from a global pool |
edit |
Edits applied to files: replace, append, upsert — env vars ($VAR) are expanded (see below). Aliased as replace for backwards compatibility. |
pre_setup |
Commands run before the setup command (env vars are available) |
setup |
The setup command to run (default: bin/setup) |
bonchi create auto-runs setup when .worktree.yml exists. Skip with --no-setup.
If .worktree.yml exists in the linked worktree, it takes precedence over the main worktree's — useful for trying out config changes in a single worktree without touching main, or for committing a per-branch config. The main worktree's config is the fallback when no local config is present.
To pin every new worktree to its own copy of the config (full isolation, no propagation of later edits in main), add it to copy::
copy:
- .worktree.ymlDefault is to leave it out, so edits to main's .worktree.yml automatically apply to every subsequent bonchi setup run.
Use edit to modify files during setup. Three actions are available; entries run in order, so you can interleave them. Env vars ($VAR) are expanded in replacement values.
edit:
mise.toml:
# Replace — short form
- "^PORT=.*": "PORT=$PORT"
# Append a line unconditionally
- append: "FOO=bar"
# Replace if the regex matches, otherwise append — natural for env vars
- upsert: "^DATABASE_URL="
with: "DATABASE_URL=postgres:///myapp_$WORKTREE_BRANCH_SLUG"
.env.local:
# Replace — full form (with optional missing: warn, default: halt)
- match: "^DATABASE_URL=.*"
with: "DATABASE_URL=postgres:///myapp_$WORKTREE_BRANCH_SLUG"
missing: warnreplace works as an alias for edit (use one or the other, not both).
The following env vars are available in edit values and pre_setup commands:
| Variable | Example | Description |
|---|---|---|
$WORKTREE_MAIN |
/Users/me/projects/myapp |
Full path to the main worktree |
$WORKTREE_LINKED |
/Users/me/dev/worktrees/myapp/my-feature |
Full path to the linked worktree |
$WORKTREE_ROOT |
/Users/me/dev/worktrees |
Root directory for all worktrees |
$WORKTREE_BRANCH |
feat/new-login |
Branch name |
$WORKTREE_BRANCH_SLUG |
feat_new_login |
Branch name with non-alphanumeric chars replaced by _ |
$PORT, ... |
4012 |
Any port names listed under ports |
If a referenced env var is unset, setup aborts.
Settings are stored in ~/.bonchi.yml (or $XDG_CONFIG_HOME/bonchi/config.yml):
worktree_root: ~/worktrees
port_pool:
min: 4000
max: 5000| Key | Description |
|---|---|
worktree_root |
Where worktrees are created (default: ~/dev/worktrees) |
port_pool.min |
Minimum port number (default: 4000) |
port_pool.max |
Maximum port number (default: 5000) |
Stale port allocations for removed worktrees are pruned automatically.
# Setup
bin/setup # Make sure it exits with code 0
# Run tests
rake
# Run the CLI against the local working tree (from any cwd)
bin/bonchi-dev <command>bin/bonchi-dev pins BUNDLE_GEMFILE to this project, so it uses the in-progress code instead of the installed bonchi gem — handy when testing changes from another directory.
Using mise for env-vars is recommended.
- Update
lib/bonchi/version.rbbin/rake 'gem:write_version[0.5.0]' # commit&push # check CI - Tag
gem_push=no bin/rake release - Release workflow from GitHub Actions...
- ...publishes to RubyGems (with Sigstore attestation)
- ...creates git GitHub release after successful publish
- Update
version.rbfor next dev-cyclebin/rake 'gem:write_version[0.6.0.dev]'
MIT