A simple bash script that provides a streamlined interface for managing git worktrees with automatic symlink management, optional setup script integration, and semantic versioning.
# 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-authenticationCreates a worktree if needed and navigates to it.
./wt go feature-login
# Creates worktree if missing, then provides navigation guidanceCreates 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 optionsAdvanced 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:
- Checks if worktree exists - creates it using
addlogic if missing - Runs command in the worktree directory
- Returns to the original directory after command completes
- Download script to your project root:
curl -O https://raw.githubusercontent.com/tumf/wt/main/wt
chmod +x wt-
Or copy the
wtfile to your existing git repository -
Make it executable:
chmod +x wtwt can generate shell completion scripts with ./wt completions <bash|zsh|fish|powershell> . Install the output for your shell to enable subcommand and argument hints:
# 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/wtReload your shell or run source ~/.bashrc to activate.
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
fiThen restart your shell or run autoload -Uz compinit && compinit .
mkdir -p ~/.config/fish/completions
./wt completions fish > ~/.config/fish/completions/wt.fishNew shells will pick up the completion automatically.
# 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'" # onceRestart PowerShell after updating your profile.
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
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-loginWhat happens:
- Checks if branch exists - creates it if not
- Creates worktree at
~/.wt/worktrees/<project>-<name> - Creates symlink at
.wt/worktrees/<name> - Runs optional setup script if
.wt/setupexists
Safely removes a worktree and its symlink.
./wt remove feature-login
# Removes worktree and cleans up symlinkWhat happens:
- Finds the actual worktree path from the symlink
- Removes git worktree
- Removes the symlink
Lists all existing worktrees in the repository.
./wt list
# Shows all worktrees with their paths and branchesCreates a worktree if needed and navigates to it.
./wt go feature-login
# Creates worktree if missing, then provides navigation guidanceWhat happens:
- Checks if worktree exists - creates it using
addlogic if missing - Provides navigation guidance to worktree directory
- Runs setup script if creating new worktree
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:
- Checks if worktree exists - creates it using
addlogic if missing - Runs the command in the worktree directory
- Returns to the original directory after command completes
- Runs setup script if creating new worktree
Shows the current version of wt.
./wt --version
# wt version 1.0.0After 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/
wt includes a Makefile for semantic versioning and project management.
# 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# Run tests
make test
# Clean temporary files
make clean
# Install system-wide
make installhelp- Show available make targetsversion- Display current versionbump-major- Increment major versionbump-minor- Increment minor versionbump-patch- Increment patch versionbump-beta- Add beta suffixrelease- Remove beta suffix for releaseinstall- Install to /usr/local/binclean- Remove temporary filestest- Run basic tests
wt supports automatic setup scripts that run after creating a worktree.
- Create
.wt/setupin 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!"- Make it executable:
chmod +x .wt/setup- Environment Variable:
$ROOT_WORKTREE_PATHpoints to the base repository (source tree) - Automatic Execution: Runs after every
wt addorwt go(when creating new worktree) - Template Creation:
wtcreates a basic template on first use if none exists - Flexible: Customize for your project's specific needs
# Start working on a new feature
./wt add user-profile-page
cd .wt/worktrees/user-profile-page
# Develop your feature...# Quick bug fix worktree
./wt add fix-login-bug
cd .wt/worktrees/fix-login-bug
# Fix bug and create PR...# Try something risky
./wt add experimental-refactor
cd .wt/worktrees/experimental-refactor
# Experiment safely...
./wt remove experimental-refactor # Clean up when done# 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# 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'# 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-123By 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 locationThe first time you run ./wt add , it creates a template setup script. You can customize this for your project's needs.
# Check existing worktrees
./wt list
# Remove existing worktree first
./wt remove <name>
# Then add again
./wt add <name># Make sure the script is executable
chmod +x wt# Remove broken symlink manually
rm .wt/worktrees/<name>
# Then try adding again
./wt add <name>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
This is a simple utility script with semantic versioning. To contribute:
- Fork repository: https://github.com/tumf/wt
- Clone locally:
git clone https://github.com/yourusername/wt.git - Create a feature worktree:
./wt add your-feature - Make your changes
- Test thoroughly
- Submit a pull request
# 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)MIT License - feel free to use this in your projects.
If you encounter issues:
- Check that you're in a git repository
- Ensure script is executable
- Verify git worktree support:
git worktree --version - Check permissions on your
~/.wt/worktrees/directory - Check Makefile targets:
make help
Happy worktree managing! 🌳