Skip to content

tumf/wt

Repository files navigation

wt - Git Worktree Management Tool

A simple bash script that provides a streamlined interface for managing git worktrees with automatic symlink management, optional setup script integration, and semantic versioning.

🚀 Quick Start

# Clone and setup
git clone https://github.com/tumf/wt.git
cd wt
chmod +x wt

# Create your first worktree
./wt add feature-authentication

# Navigate to worktree (creates if needed)
./wt go feature-authentication

# List all worktrees
./wt list

# Remove when done
./wt remove feature-authentication

./wt go <name>

Creates a worktree if needed and navigates to it.

./wt go feature-login
# Creates worktree if missing, then provides navigation guidance

./wt run <name> [--] <command>

Creates a worktree if needed and runs a command in it. The -- (double hyphen) is an option terminator indicating "everything after this is arguments, not options to wt". It's optional for simple commands but recommended when using command flags.

./wt run feature-login git status
./wt run feature-login npm install
./wt run feature-login npm test
./wt run feature-login -- git stash -u  # -- prevents git flags from being treated as wt options

Advanced Example: Create tmux window and open Claude Code

# Run tmux commands to create a new window and open Claude Code
./wt run feature-login -- bash -c 'tmux new-window -n feature-login -c "$(pwd)" \; send-keys "cursor code ." Enter'

# Or create tmux session if it doesn't exist
./wt run feature-auth -- bash -c 'tmux new-session -d -s dev 2>/dev/null || true; tmux new-window -t dev -n feature-auth -c "$(pwd)" \; send-keys "cursor code ." Enter'

# If already inside a tmux session, use detach and create new session
# Option 1: Unset TMUX variable temporarily
TMUX= ./wt run feature-auth -- bash -c 'tmux new-session -d -s dev 2>/dev/null || true; tmux new-window -t dev -n feature-auth -c "$(pwd)" \; send-keys "cursor code ." Enter'

# Option 2: Add a new window to the current tmux session
./wt run feature-auth -- bash -c 'tmux new-window -t ${TMUX#*,} -n feature-auth -c "$(pwd)" \; send-keys "cursor code ." Enter'

What happens:

  1. Checks if worktree exists - creates it using add logic if missing
  2. Runs command in the worktree directory
  3. Returns to the original directory after command completes

📦 Installation

  1. Download script to your project root:
   curl -O https://raw.githubusercontent.com/tumf/wt/main/wt
   chmod +x wt
  1. Or copy the wt file to your existing git repository

  2. Make it executable:

   chmod +x wt

🔁 Shell Completions

wt can generate shell completion scripts with ./wt completions <bash|zsh|fish|powershell> . Install the output for your shell to enable subcommand and argument hints:

Bash

# User-level install (ensure directory exists)
mkdir -p ~/.local/share/bash-completion/completions
./wt completions bash > ~/.local/share/bash-completion/completions/wt

# System-wide alternative (requires sudo)
# sudo ./wt completions bash > /etc/bash_completion.d/wt

Reload your shell or run source ~/.bashrc to activate.

Zsh

mkdir -p ~/.zsh/completions
./wt completions zsh > ~/.zsh/completions/_wt

# Add the completions directory to your fpath once
if ! grep -q 'fpath+=(~/.zsh/completions)' ~/.zshrc; then
  echo 'fpath+=(~/.zsh/completions)' >> ~/.zshrc
fi

Then restart your shell or run autoload -Uz compinit && compinit .

Fish

mkdir -p ~/.config/fish/completions
./wt completions fish > ~/.config/fish/completions/wt.fish

New shells will pick up the completion automatically.

PowerShell (pwsh)

# Apply to the current session
./wt completions powershell | Out-String | Invoke-Expression

# Persist for future sessions (PowerShell 7+)
./wt completions powershell > "$HOME/.config/powershell/completions/wt.ps1"
Add-Content -Path "$HOME/.config/powershell/Microsoft.PowerShell_profile.ps1" -Value "& '$HOME/.config/powershell/completions/wt.ps1'"  # once

Restart PowerShell after updating your profile.

🎯 Why Use wt?

Managing git worktrees manually can be cumbersome. wt simplifies this by:

  • 🗂️ Organization: Creates worktrees in a consistent location (~/.wt/worktrees/)
  • 🔗 Symlinks: Provides easy access through project-local symlinks
  • ⚡ Automation: Handles branch creation and cleanup automatically
  • 🛠️ Setup Integration: Runs project-specific setup scripts
  • 🚫 Safety: Prevents duplicate worktrees and handles errors gracefully
  • 🔧 Version Management: Semantic versioning with Makefile

📋 Commands

./wt add <name>

Creates a new worktree for the specified branch name.

./wt add feature-login
# Creates new branch 'feature-login' and worktree at ~/.wt/worktrees/project-feature-login
# Creates symlink .wt/worktrees/feature-login -> ~/.wt/worktrees/project-feature-login

What happens:

  1. Checks if branch exists - creates it if not
  2. Creates worktree at ~/.wt/worktrees/<project>-<name>
  3. Creates symlink at .wt/worktrees/<name>
  4. Runs optional setup script if .wt/setup exists

./wt remove <name>

Safely removes a worktree and its symlink.

./wt remove feature-login
# Removes worktree and cleans up symlink

What happens:

  1. Finds the actual worktree path from the symlink
  2. Removes git worktree
  3. Removes the symlink

./wt list

Lists all existing worktrees in the repository.

./wt list
# Shows all worktrees with their paths and branches

./wt go <name>

Creates a worktree if needed and navigates to it.

./wt go feature-login
# Creates worktree if missing, then provides navigation guidance

What happens:

  1. Checks if worktree exists - creates it using add logic if missing
  2. Provides navigation guidance to worktree directory
  3. Runs setup script if creating new worktree

./wt run <name> [--] <command>

Creates a worktree if needed and runs a command in it. The -- (double hyphen) is an option terminator that tells the shell "everything after this is arguments, not options to wt". It's optional for simple commands but recommended when your command has flags that might be confused with wt options.

# Simple commands without -- delimiter
./wt run feature-login git status
./wt run feature-login npm install

# Commands with flags - use -- delimiter to avoid confusion
./wt run feature-login -- git stash -u
./wt run feature-login -- npm run test -- --watch
./wt run bugfix-123 -- make test VERBOSE=1

# Create tmux window and open Claude Code in the worktree from tmux session
 tmux new-window -c "$(pwd)" "./wt run refactor -- claude 'refactor the code'" 

What happens:

  1. Checks if worktree exists - creates it using add logic if missing
  2. Runs the command in the worktree directory
  3. Returns to the original directory after command completes
  4. Runs setup script if creating new worktree

./wt version

Shows the current version of wt.

./wt --version
# wt version 1.0.0

🏗️ Directory Structure

After using wt , your project will look like this:

your-project/
├── wt                          # The management script
├── Makefile                    # Version management and development tasks
├── README.md                    # This documentation
└── .wt/                        # Created on first use
    ├── .gitignore              # Ignores worktrees directory
    ├── setup                   # Optional setup script (template)
    └── worktrees/              # Symlinks to actual worktrees
        ├── feature-auth        # -> ~/.wt/worktrees/your-project-feature-auth
        ├── bugfix-123          # -> ~/.wt/worktrees/your-project-bugfix-123
        └── experimental        # -> ~/.wt/worktrees/your-project-experimental

Actual worktrees are stored in:

~/.wt/worktrees/
├── your-project-feature-auth/
├── your-project-bugfix-123/
└── your-project-experimental/

🔧 Version Management

wt includes a Makefile for semantic versioning and project management.

Version Commands

# Show current version
make version
./wt --version

# Bump versions
make bump-patch    # 1.0.0 -> 1.0.1
make bump-minor    # 1.0.1 -> 1.1.0
make bump-major    # 1.1.0 -> 2.0.0
make bump-beta     # 1.1.0 -> 1.1.0-beta
make release       # 1.1.0-beta -> 1.1.0

Development Commands

# Run tests
make test

# Clean temporary files
make clean

# Install system-wide
make install

Available Targets

  • help - Show available make targets
  • version - Display current version
  • bump-major - Increment major version
  • bump-minor - Increment minor version
  • bump-patch - Increment patch version
  • bump-beta - Add beta suffix
  • release - Remove beta suffix for release
  • install - Install to /usr/local/bin
  • clean - Remove temporary files
  • test - Run basic tests

🔧 Setup Script Integration

wt supports automatic setup scripts that run after creating a worktree.

Creating a Setup Script

  1. Create .wt/setup in your project root:
   #!/bin/bash
   # $ROOT_WORKTREE_PATH contains the path to the base repository (source tree)

   echo "Setting up worktree from: $ROOT_WORKTREE_PATH"

   # Install dependencies
   # Use $ROOT_WORKTREE_PATH to reference base repo files if needed
   # Current worktree is available via PWD or other means
   npm install

   # Copy configuration files
   cp .env.example .env.local

   echo "Setup complete!"
  1. Make it executable:
   chmod +x .wt/setup

Setup Script Features

  • Environment Variable: $ROOT_WORKTREE_PATH points to the base repository (source tree)
  • Automatic Execution: Runs after every wt add or wt go (when creating new worktree)
  • Template Creation: wt creates a basic template on first use if none exists
  • Flexible: Customize for your project's specific needs

🎨 Use Cases

Feature Development

# Start working on a new feature
./wt add user-profile-page
cd .wt/worktrees/user-profile-page
# Develop your feature...

Bug Fixes

# Quick bug fix worktree
./wt add fix-login-bug
cd .wt/worktrees/fix-login-bug
# Fix bug and create PR...

Experimental Changes

# Try something risky
./wt add experimental-refactor
cd .wt/worktrees/experimental-refactor
# Experiment safely...
./wt remove experimental-refactor  # Clean up when done

Parallel Development

# Work on multiple features simultaneously
./wt add feature-auth
./wt add feature-dashboard
./wt add bugfix-navigation

# List all your worktrees
./wt list

# Switch between contexts
cd .wt/worktrees/feature-auth      # Work on auth
cd .wt/worktrees/feature-dashboard # Work on dashboard

Running Commands in Worktrees

# Run tests across different worktrees (simple command, no -- needed)
./wt run feature-auth npm test
./wt run bugfix-123 make test

# Commands with flags should use -- delimiter
./wt run feature-auth -- npm test -- --watch
./wt run bugfix-123 -- make test VERBOSE=1

# Open Claude Code in tmux window for a worktree
./wt run feature-login -- bash -c 'tmux new-window -n feature-login -c "$(pwd)" \; send-keys "cursor code ." Enter'

# Create tmux session and open multiple worktrees
./wt run feature-auth -- bash -c 'tmux new-session -d -s dev 2>/dev/null || true; tmux new-window -t dev -n feature-auth -c "$(pwd)" \; send-keys "cursor code ." Enter'
./wt run feature-dashboard -- bash -c 'tmux new-window -t dev -n feature-dashboard -c "$(pwd)" \; send-keys "cursor code ." Enter'

# If already inside a tmux session (to avoid "sessions should be nested" error)
# Option 1: Temporarily unset TMUX variable
TMUX= ./wt run feature-auth -- bash -c 'tmux new-session -d -s dev 2>/dev/null || true; tmux new-window -t dev -n feature-auth -c "$(pwd)" \; send-keys "cursor code ." Enter'

# Option 2: Add window to current tmux session
./wt run feature-auth -- bash -c 'tmux new-window -t ${TMUX#*,} -n feature-auth -c "$(pwd)" \; send-keys "cursor code ." Enter'

Version Management Workflow

# Start new feature development
make bump-minor    # 1.0.0 -> 1.1.0
./wt add new-api-feature

# Prepare for release
make release         # Remove beta suffix for stable release
git tag v1.1.0
git push origin v1.1.0

# Patch release
make bump-patch      # 1.1.0 -> 1.1.1
./wt add hotfix-123

⚙️ Configuration

Default Worktree Location

By default, worktrees are created in ~/.wt/worktrees/ . You can modify this by editing the TMP_DIR variable in the wt script:

# Change this line in the wt script
TMP_DIR="${HOME}/worktrees"  # Custom location

Custom Setup Script Template

The first time you run ./wt add , it creates a template setup script. You can customize this for your project's needs.

🐛 Troubleshooting

"Worktree already exists"

# Check existing worktrees
./wt list

# Remove existing worktree first
./wt remove <name>
# Then add again
./wt add <name>

"Permission denied"

# Make sure the script is executable
chmod +x wt

"Symlink already exists"

# Remove broken symlink manually
rm .wt/worktrees/<name>
# Then try adding again
./wt add <name>

🔒 Security

The wt script:

  • Only creates worktrees in your home directory
  • Uses relative paths for symlinks
  • Doesn't require elevated permissions
  • Works with standard git worktree commands
  • Follows shell script security best practices

🤝 Contributing

This is a simple utility script with semantic versioning. To contribute:

  1. Fork repository: https://github.com/tumf/wt
  2. Clone locally: git clone https://github.com/yourusername/wt.git
  3. Create a feature worktree: ./wt add your-feature
  4. Make your changes
  5. Test thoroughly
  6. Submit a pull request

Development Workflow

# Use version management
make bump-minor    # Start new feature
./wt add new-feature
make test           # Run tests
make clean           # Clean up artifacts

# Prepare release
make release         # Remove beta suffix
git tag v$(make version)
git push origin v$(make version)

📄 License

MIT License - feel free to use this in your projects.

🆘 Support

If you encounter issues:

  1. Check that you're in a git repository
  2. Ensure script is executable
  3. Verify git worktree support: git worktree --version
  4. Check permissions on your ~/.wt/worktrees/ directory
  5. Check Makefile targets: make help

Happy worktree managing! 🌳

About

wt - Git Worktree Management Tool

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •