No release in over 3 years
A Ruby gem for managing git worktrees with ease
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 13.0
~> 3.0

Runtime

~> 1.0
~> 0.23
 Project Readme

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.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request