WorktreeManager
A Ruby gem for managing Git worktrees with ease. WorktreeManager provides a simple and intuitive interface for creating, managing, and removing Git worktrees with built-in hook support.
Features
- Easy worktree management: Create, list, and remove Git worktrees
- Branch operations: Create new branches or checkout existing ones
- Hook system: Execute custom scripts before/after worktree operations
- Conflict detection: Automatic validation to prevent path and branch conflicts
- CLI interface: Simple command-line tool for quick operations
- Ruby API: Programmatic access for integration with other tools
-
Configuration initialization: Easy setup with
wm init
command -
Branch reset: Reset worktree branches to origin/main with
wm reset
-
Help support: All commands support
--help
flag for usage information
Installation
Add this line to your application's Gemfile:
gem 'worktree_manager'
And then execute:
bundle install
Or install it yourself as:
gem install worktree_manager
Usage
Command Line Interface
WorktreeManager provides a CLI tool called wm
for managing worktrees:
# Initialize configuration file
wm init
# List all worktrees
wm list
# Create a new worktree using just a name (uses worktrees_dir)
wm add feature-branch
# Create a worktree with a relative path
wm add ../feature-branch
# Create a worktree with an absolute path
wm add /path/to/feature-branch
# Create a worktree with an existing branch
wm add feature-branch existing-branch
# Create a worktree with a new branch
wm add feature-branch -b new-feature-branch
# Remove a worktree using just a name
wm remove feature-branch
# Remove a worktree with a path
wm remove ../feature-branch
# Force operations (bypass safety checks)
wm add existing-dir -f
wm remove worktree-with-changes -f
# Track remote branches
wm add pr-154 -t origin/pr-154 # Create local pr-154 tracking origin/pr-154
wm add pr-154 origin/pr-154 # Auto-detect remote branch
wm add hotfix -t upstream/hotfix-123 # Track from different remote
# Reset worktree branch to origin/main (must be run from worktree)
wm reset # Reset current branch to origin/main
wm reset -f # Force reset (discard uncommitted changes)
# Get help for any command
wm --help # Show all commands
wm add --help # Show help for add command
wm remove -h # Short help flag also works
Working with Remote Branches
WorktreeManager makes it easy to work with remote branches:
# Method 1: Using --track (-t) option
wm add pr-154 -t origin/pr-154
# This will:
# 1. Fetch origin/pr-154
# 2. Create a new local branch 'pr-154' tracking 'origin/pr-154'
# 3. Create worktree at '../worktrees/pr-154' (or configured location)
# Method 2: Auto-detection (when branch name contains '/')
wm add pr-154 origin/pr-154
# Automatically detects that origin/pr-154 is a remote branch
# Method 3: Different local and remote names
wm add my-fix -t origin/pr-154
# Creates local branch 'my-fix' tracking 'origin/pr-154'
# Working with different remotes
wm add upstream-fix -t upstream/fix-123
wm add fork-feature -t fork/new-feature
Example workflow for Pull Request review:
# Review PR #154
wm add pr-154 -t origin/pr-154
cd ../worktrees/pr-154
# Make changes, test, etc.
# When done, remove the worktree
cd ../main-repo
wm remove pr-154
Ruby API
require 'worktree_manager'
# Create a manager instance
manager = WorktreeManager.new
# List existing worktrees
worktrees = manager.list
worktrees.each do |worktree|
puts "Path: #{worktree.path}"
puts "Branch: #{worktree.branch}"
puts "Detached: #{worktree.detached?}"
end
# Add a new worktree
worktree = manager.add("../feature-branch", "feature-branch")
# Add a worktree with a new branch
worktree = manager.add_with_new_branch("../new-feature", "new-feature-branch")
# Remove a worktree
manager.remove("../feature-branch")
# Clean up removed worktrees
manager.prune
Hook System
WorktreeManager supports hooks that execute before and after worktree operations:
Hook Types
-
pre_add
: Execute before creating a worktree -
post_add
: Execute after creating a worktree -
pre_remove
: Execute before removing a worktree -
post_remove
: Execute after removing a worktree
Configuration
Create a .worktree.yml
file in your repository root to configure WorktreeManager:
# Base directory for worktrees (default: "../")
# When you run 'wm add feature', it creates worktree at '../feature' by default
# With worktrees_dir set to "../worktrees", it creates at '../worktrees/feature'
worktrees_dir: "../worktrees"
# Main branch name for reset command (default: "main")
# Used by 'wm reset' to determine which branch to reset to
main_branch_name: "main" # or "master" for older repositories
# Hook configuration (see below)
hooks:
# ...
Worktrees Directory
The worktrees_dir
option allows you to specify a default location for your worktrees:
-
Default value:
../
(parent directory of your main repository) - Purpose: Organize all worktrees in a specific directory
-
Usage: When you use
wm add <name>
with just a name (no path), it creates the worktree in<worktrees_dir>/<name>
Example configurations:
# Keep worktrees in a sibling directory
worktrees_dir: "../worktrees"
# Keep worktrees in a subdirectory of the parent
worktrees_dir: "../../git-worktrees"
# Use absolute path
worktrees_dir: "/home/user/projects/worktrees"
Hook Configuration
Hooks allow you to execute custom scripts during worktree operations:
hooks:
# Execute before creating a worktree (runs in main repository)
pre_add:
commands:
- "echo 'Creating worktree at: $WORKTREE_PATH'"
- "echo 'Branch: $WORKTREE_BRANCH'"
stop_on_error: true # Stop if any command fails (default: true)
# Execute after creating a worktree (runs in new worktree directory)
post_add:
commands:
- "bundle install"
- "echo 'Setup complete: $WORKTREE_BRANCH'"
# Override default working directory if needed
# pwd: "$WORKTREE_MAIN" # Run in main repository instead
# Execute before removing a worktree (runs in worktree directory)
pre_remove:
commands:
- "git add -A"
- "git stash push -m 'Auto stash before removal'"
stop_on_error: false # Continue even if commands fail
# Execute after removing a worktree (runs in main repository)
post_remove:
commands:
- "echo 'Cleanup complete: $WORKTREE_PATH'"
Available Environment Variables
-
$WORKTREE_PATH
: Path where the worktree will be created/removed (relative path) -
$WORKTREE_ABSOLUTE_PATH
: Absolute path to the worktree -
$WORKTREE_BRANCH
: Branch name (if specified) -
$WORKTREE_MAIN
: Main repository path -
$WORKTREE_MANAGER_ROOT
: Main repository path (legacy, same as$WORKTREE_MAIN
) -
$WORKTREE_FORCE
: Whether force option is enabled ("true" or "") -
$WORKTREE_SUCCESS
: Whether the operation succeeded (post hooks only, "true" or "false")
Practical Hook Examples
hooks:
# Automatic development environment setup
post_add:
commands:
- "bundle install" # Install dependencies
- "yarn install" # Install JS dependencies
- "cp .env.example .env" # Copy environment variables
- "code ." # Open in VS Code
# Default pwd is the new worktree directory
# Automatic backup of work
pre_remove:
commands:
- "git add -A"
- "git stash push -m 'Auto backup: $WORKTREE_BRANCH'"
stop_on_error: false # Continue even if nothing to stash
# Notification system (run in main repository)
post_add:
commands:
- "osascript -e 'display notification \"Workspace ready: $WORKTREE_BRANCH\" with title \"WorktreeManager\"'"
pwd: "$WORKTREE_MAIN" # Run notification from main repo
# CI/CD integration
post_add:
commands:
- "gh pr create --draft --title 'WIP: $WORKTREE_BRANCH' --body 'Auto-created by worktree manager'"
pwd: "$WORKTREE_ABSOLUTE_PATH"
CLI Command Reference
All commands support help flags (--help
, -h
, -?
, --usage
) to display usage information.
wm version
Display the current installed version.
wm init
Initialize a .worktree.yml
configuration file in your repository.
Options:
-
-f, --force
: Overwrite existing configuration file
Requirements: Must be run from the main Git repository
Examples:
wm init # Create .worktree.yml from example
wm init --force # Overwrite existing .worktree.yml
wm list
List all worktrees in the current Git repository. Can be run from either the main repository or any worktree.
wm add PATH [BRANCH]
Create a new worktree.
Arguments:
-
PATH
: Path where the worktree will be created -
BRANCH
: Branch to use (optional)
Options:
-
-b, --branch BRANCH
: Create a new branch for the worktree -
-f, --force
: Force creation even if directory exists -
-v, --verbose
: Enable verbose output for debugging
Examples:
wm add ../feature-api feature/api # Use existing branch
wm add ../new-feature -b feature/new # Create new branch
wm add ../override --force # Force creation
wm remove PATH
Remove an existing worktree.
Arguments:
-
PATH
: Path of the worktree to remove
Options:
-
-f, --force
: Force removal even if worktree has changes -
-v, --verbose
: Enable verbose output for debugging
Examples:
wm remove ../feature-api # Normal removal
wm remove ../old-feature --force # Force removal
wm reset
Reset the current worktree branch to origin/main (or configured main branch).
Options:
-
-f, --force
: Force reset even if there are uncommitted changes
Requirements: Must be run from a worktree (not from the main repository)
Configuration: The target branch can be configured via main_branch_name
in .worktree.yml
Examples:
wm reset # Reset to origin/main
wm reset --force # Force reset, discarding changes
Requirements
- Ruby 3.0.0 or higher
- Git 2.5.0 or higher (for worktree support)
Development
After checking out the repo, run:
# Install dependencies
bundle install
# Run tests
bundle exec rspec
# Build gem
gem build worktree_manager.gemspec
# Install locally
gem install worktree_manager-*.gem
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/nacyot/worktree_manager.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request