Manage git worktrees with ease
Create, list, and prune worktrees efficiently. Run commands from anywhere in your project.
# 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).
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
# If .groverc sets "branchPrefix": "safia", example: safia/quiet-meadow
# Directory remains: quiet-meadow
# branchPrefix only accepts alphanumeric characters
With tracking for a remote branch:
grove add feature-branch --track origin/feature-branch
Optional bootstrap commands from .groverc run in the new worktree:
{
"branchPrefix": "safia",
"bootstrap": {
"commands": [
{ "program": "npm", "args": ["install"] },
{ "program": "cargo", "args": ["check"] }
]
}
}
Place .groverc in the Grove project root (next to the bare clone directory).
When grove add is called without an explicit branch name, Grove generates an adjective-noun name and prepends branchPrefix to the branch name when configured. branchPrefix must be alphanumeric only (letters and numbers). The worktree directory keeps the generated base name.
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 |
Grove