Skip to content

Latest commit

 

History

History
217 lines (160 loc) · 7 KB

File metadata and controls

217 lines (160 loc) · 7 KB

Bonchi

Bonchi

Git worktree manager with automatic port allocation, file copying, and project setup

Gem Version CI Status Downloads License

InstallUsageProject ConfigGlobal Config

Inspired by tree-me.

Install

gem install bonchi

Setup

Add to your ~/.zshrc or ~/.bashrc:

source <(bonchi shellenv)

This gives you auto-cd (jumps into the worktree after create/switch/pr) and tab completions.

Usage

  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 <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).

Project config

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.yml

Default is to leave it out, so edits to main's .worktree.yml automatically apply to every subsequent bonchi setup run.

Edit

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: warn

replace works as an alias for edit (use one or the other, not both).

Environment variables

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.

Global config

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.

Development

# 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.

Releasing

  1. Update lib/bonchi/version.rb
    bin/rake 'gem:write_version[0.5.0]'
    # commit&push
    # check CI
    
  2. Tag
    gem_push=no bin/rake release
    
  3. Release workflow from GitHub Actions...
    • ...publishes to RubyGems (with Sigstore attestation)
    • ...creates git GitHub release after successful publish
  4. Update version.rb for next dev-cycle
    bin/rake 'gem:write_version[0.6.0.dev]'
    

License

MIT