Manage git worktrees with ease

Create, list, and prune worktrees efficiently. Run commands from anywhere in your project.

terminal
# Initialize a worktree setup
$ grove init https://github.com/captainsafia/grove.git
✓ Initialized worktree setup: grove

# Add a worktree for a branch
$ grove add main
✓ Created worktree: main

# Navigate to the worktree
$ grove go main
✓ Entering worktree: main

Install

Single binary, no dependencies.

Linux (x64/arm64), macOS (x64/arm64), Windows (x64).

$ curl https://i.safia.sh/captainsafia/grove | sh

Usage

Common workflows and examples for using Grove.

Initialize a new worktree setup

Create a bare clone optimized for worktrees:

grove init https://github.com/user/repo.git

Add a new worktree

Create a worktree for a branch (creates branch if it doesn't exist):

grove add feature-branch

Or let Grove generate a default adjective-noun name:

grove add
# Example generated name: quiet-meadow

With tracking for a remote branch:

grove add feature-branch --track origin/feature-branch

Optional bootstrap commands from .groverc run in the new worktree:

{
  "bootstrap": {
    "commands": [
      { "program": "npm", "args": ["install"] },
      { "program": "cargo", "args": ["check"] }
    ]
  }
}

Place .groverc in the Grove project root (next to the bare clone directory).

Commands must be portable across Linux/macOS/Windows and use executable + args only (no shell operators like && or pipes). If one command fails, Grove continues and reports a partial bootstrap state.

Navigate to a worktree

Open a new shell session in a worktree directory:

grove go feature-branch

Navigate by partial branch name for nested branches:

grove go my-feature

Exit the shell (Ctrl+D or exit) to return to your previous directory.

List worktrees

Show all worktrees (alias: grove ls):

grove list

Show detailed information:

grove list --details

Show only dirty worktrees:

grove list --dirty

Sync with origin

Update the bare clone with the latest changes from origin:

grove sync

Sync a specific branch:

grove sync --branch develop

Prune worktrees

Preview what would be removed:

grove prune --dry-run

Remove worktrees for branches merged to main:

grove prune

Remove worktrees older than 30 days (supports human-friendly or ISO 8601 format):

grove prune --older-than 30d
# or
grove prune --older-than P30D

Use a different base branch:

grove prune --base develop

Remove a worktree

Remove a specific worktree (alias: grove rm):

grove remove feature-branch

Force removal even with uncommitted changes:

grove remove feature-branch --force

Note: Dirty worktrees require --force to remove.

Self-update

Update grove to the latest version:

grove self-update

Update to a specific version:

grove self-update v1.0.0

Update to a specific PR build (requires GitHub CLI):

grove self-update --pr 42

Commands

Command Description
grove init <git-url> Create a new worktree setup
grove add [name] Create a new worktree (name optional)
grove go <name> Navigate to a worktree
grove list (ls) [options] List all worktrees
grove sync [options] Sync the bare clone with origin
grove prune [options] Remove worktrees for merged branches
grove remove (rm) <name> Remove a specific worktree
grove self-update [version] Update grove to a specific version or PR
grove version Show version information
grove help [command] Show help information