https://github.com/eval/bonchi
A git worktree manager 🌳
https://github.com/eval/bonchi
git worktree-manager
Last synced: 4 days ago
JSON representation
A git worktree manager 🌳
- Host: GitHub
- URL: https://github.com/eval/bonchi
- Owner: eval
- License: mit
- Created: 2026-03-13T09:32:37.000Z (24 days ago)
- Default Branch: main
- Last Pushed: 2026-03-13T21:41:25.000Z (23 days ago)
- Last Synced: 2026-03-13T22:17:22.115Z (23 days ago)
- Topics: git, worktree-manager
- Language: Ruby
- Homepage:
- Size: 51.8 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
README
Bonchi
Git worktree manager with automatic port allocation, file copying, and project setup
Install •
Usage •
Project Config •
Global Config
Inspired by [tree-me](https://github.com/haacked/dotfiles/blob/main/bin/README-tree-me.md).
## Install
```sh
gem install bonchi
```
## Setup
Add to your `~/.zshrc` or `~/.bashrc`:
```sh
source <(bonchi shellenv)
```
This gives you auto-cd (jumps into the worktree after create/switch/pr) and tab completions.
## Usage
```sh
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 command
```
Run `bonchi help ` for detailed info on any command.
Worktrees are created at `~/dev/worktrees//`. Customize via global config or `WORKTREE_ROOT` env var (env var takes precedence).
## Project config
Drop a `.worktree.yml` in your project root:
```yaml
min_version: 0.4.0
copy:
- mise.toml
- .env.local
link:
- node_modules
- vendor/bundle
ports:
- PORT
- WEBPACK_PORT
replace:
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 |
| `replace` | Regex replacements in files — env vars (`$VAR`) are expanded (see below) |
| `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`.
### Replace
Use `replace` to do regex-based find-and-replace in files. Env vars (`$VAR`) are expanded in replacement values.
```yaml
replace:
# Short form
mise.toml:
- "^PORT=.*": "PORT=$PORT"
# Full form (with optional missing: warn, default: halt)
.env.local:
- match: "^DATABASE_URL=.*"
with: "DATABASE_URL=postgres:///myapp_$WORKTREE_BRANCH_SLUG"
missing: warn
```
### Environment variables
The following env vars are available in `replace` 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` |
## Global config
Settings are stored in `~/.bonchi.yml` (or `$XDG_CONFIG_HOME/bonchi/config.yml`):
```yaml
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.
## Development
```bash
# Setup
bin/setup # Make sure it exits with code 0
# Run tests
rake
```
Using [mise](https://mise.jdx.dev/) for env-vars is recommended.
### Releasing
1. Update `lib/bonchi/version.rb`
```
bin/rake 'gem:write_version[0.5.0]'
# commit&push
# check CI
```
1. Tag
```
gem_push=no bin/rake release
```
1. Release workflow from GitHub Actions...
- ...publishes to RubyGems (with Sigstore attestation)
- ...creates git GitHub release after successful publish
1. Update `version.rb` for next dev-cycle
```
bin/rake 'gem:write_version[0.6.0.dev]'
```
## License
MIT