Enhanced git worktree management with bare repository support. This plugin provides convenient commands for working with git worktrees, making it easy to work on multiple branches simultaneously.
Git worktrees allow you to have multiple working directories attached to the same repository. This is particularly useful when you need to work on multiple branches at the same time without constantly switching contexts.
# Clone repository with worktree setup
gwtc https://github.com/user/repo.git
# You're now in the main/master worktree
# Create a new feature branch
gwtw feature/awesome-feature
# Work on your feature...
# Switch back to main
gwtw main# Create worktree for bug fix
gwtw bugfix/issue-123 main
# In another terminal, work on a feature
gwtw feature/new-thing main
# List all your worktrees
gwtl
# Jump between them with fuzzy finder
gwtcd# Remove finished worktrees
gwtr feature/completed-feature
# Clean up merged branches and their worktrees
gwtclean
# Clean up references to manually deleted worktrees
gwtp- No context switching: Keep your build artifacts, node_modules, and IDE state intact per branch
- Parallel work: Run tests on one branch while developing on another
- Easy comparison: Have two branches open side-by-side for easy comparison
- Cleaner workflow: No need to stash changes when switching branches
- Clone this repository into your Oh-My-Zsh custom plugins directory:
git clone https://github.com/trthomps/git-worktree-zsh-plugin.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/git-worktree- Add
git-worktreeto your plugins array in~/.zshrc:
plugins=(... git-worktree)- Restart your terminal or run:
source ~/.zshrcFor enhanced interactive selection, install fzf:
# macOS
brew install fzf
# Linux
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/installMany commands support interactive selection with fzf when no arguments are provided. Without fzf, you'll need to provide arguments manually.
To automatically update this plugin along with Oh-My-Zsh itself, consider using OhMyZsh-full-autoupdate. This tool extends Oh-My-Zsh's built-in update mechanism to also update all custom plugins and themes automatically.
Installation is simple - just add it as another custom plugin, and it will handle updates for all your custom plugins including this one.
You can configure directories to be shared across all worktrees. These directories will be stored in the repository root (next to .git) and symlinked into each worktree. This is useful for IDE configurations, build caches, or any files you want to keep synchronized across branches.
Setup:
Add the following to your ~/.zshrc before loading the plugin:
# Example: Share IDE configs and build directories
GWT_SHARED_DIRS=(.claude .idea .vscode node_modules)
plugins=(... git-worktree)How it works:
-
When you create a worktree (using
gwtc,gwta, orgwtw), the plugin automatically:- Creates the shared directories in the repository root if they don't exist
- Creates symlinks in the new worktree pointing to the shared directories
-
When you remove a worktree (using
gwtrorgwtrm), the symlinks are cleaned up automatically
Example structure:
my-repo/
├── .git/ (bare repository)
├── .claude/ (shared across all worktrees)
├── .idea/ (shared across all worktrees)
├── main/ (worktree)
│ ├── .claude -> ../.claude
│ └── .idea -> ../.idea
└── feature-branch/ (worktree)
├── .claude -> ../.claude
└── .idea -> ../.idea
Benefits:
- IDE settings and configurations stay consistent across branches
- Build caches (
node_modules,.gradle, etc.) are shared, saving disk space - Claude Code and other tool configurations don't need to be reconfigured per branch
Clone a repository as a bare repository and set up the main worktree. This is the recommended way to start using worktrees with a new repository.
Usage:
gwtc <repo-url> [directory-name]Examples:
# Clone and create worktree in directory named after repo
gwtc https://github.com/user/repo.git
# Clone and create worktree in custom directory
gwtc https://github.com/user/repo.git my-projectWhat it does:
- Clones the repository as bare into
directory-name/.git - Automatically detects the default branch (main/master)
- Creates a worktree for the default branch
- Changes to the new worktree directory
Add a new worktree for an existing or new branch.
Usage:
gwta <branch-name> [-b] [base-branch]Options:
-b: Create a new branch
Examples:
# Create worktree for existing branch
gwta feature/new-feature
# Create new branch and worktree from main
gwta feature/new-feature -b main
# Create new branch and worktree from current HEAD
gwta bugfix/issue-123 -bQuick switch or create worktree for a branch. This is a smart command that handles multiple scenarios automatically.
Usage:
gwtw [branch-name] [base-branch]Examples:
# Switch to existing worktree or create if doesn't exist
gwtw travis/plat-934-feature
# Create from specific base branch
gwtw feature/new-thing main
# Interactive branch selection (requires fzf)
gwtwWhat it does:
- If worktree exists: switches to it
- If branch exists locally: creates worktree and checks it out
- If branch exists on remote: creates worktree and tracks remote branch
- If branch doesn't exist: creates new branch from base-branch (defaults to main)
Note: If no branch is provided and fzf is installed, an interactive branch selector will appear showing both local and remote branches. You can also type a new branch name in fzf to create it.
List all worktrees with their paths and branches.
Usage:
gwtlExample output:
/path/to/repo/.git (bare)
/path/to/repo/main abc1234 [main]
/path/to/repo/feature-x def5678 [feature-x]
Interactively select and change directory to a worktree using fzf.
Usage:
gwtcdNote: This command requires fzf to be installed and always uses interactive selection.
Remove a worktree safely (fails if there are uncommitted changes).
Usage:
gwtr [worktree-path]Examples:
# Remove specific worktree
gwtr feature/old-branch
# Interactive selection (requires fzf)
gwtrNote: If no path is provided and fzf is installed, an interactive selector will appear.
Force remove a worktree, even with uncommitted changes.
Usage:
gwtrm [worktree-path]Examples:
# Force remove specific worktree
gwtrm feature/abandoned-branch
# Interactive selection (requires fzf)
gwtrmNote: If no path is provided and fzf is installed, an interactive selector will appear.
Move a worktree to a new location.
Usage:
gwtmv <source> <destination>Examples:
gwtmv feature/old-name feature/new-name
gwtmv ../old-location ../new-locationClean up stale worktree references for directories that have been manually deleted.
Usage:
gwtpLock a worktree to prevent it from being pruned or removed.
Usage:
gwtlock [worktree-path] [reason]Examples:
# Lock specific worktree with reason
gwtlock feature/important "Work in progress"
# Interactive selection (requires fzf)
gwtlockNote: If no path is provided and fzf is installed, an interactive selector will appear.
Unlock a previously locked worktree.
Usage:
gwtunlock [worktree-path]Examples:
# Unlock specific worktree
gwtunlock feature/important
# Interactive selection (requires fzf)
gwtunlockNote: If no path is provided and fzf is installed, an interactive selector will appear.
Clean up worktrees and branches that have been merged into the default branch. Automatically detects the default branch (main/master) or you can specify a target branch. Supports detection of squash merges!
Usage:
gwtclean [target-branch] [-f]Options:
-for--force: Skip confirmation and automatically clean up
Examples:
# Auto-detect default branch and clean up merged branches
gwtclean
# Clean up branches merged into specific branch
gwtclean develop
# Force cleanup without confirmation
gwtclean -f
# Clean branches merged into develop without confirmation
gwtclean develop -fWhat it does:
- Auto-detects the default branch (main/master) if not specified
- Finds branches merged into the target branch using multiple detection methods:
- Traditional merges: Branches merged with commit history preserved
- Squash merges: Detects branches mentioned in merge commit messages
- Remote-deleted branches: Branches whose remote was deleted (likely merged)
- Unpushed branches: Local-only branches (asks for separate confirmation)
- Lists worktrees associated with those merged branches
- Removes both the worktrees and deletes the local branches
- Handles branches without worktrees separately
Safety features:
- Asks for confirmation before deletion (unless
-fflag is used) - Separately confirms unpushed local branches before including them in cleanup
- Uses safe delete (
git branch -d) which prevents deletion of unmerged changes - Skips the current branch and target branch
- Properly cleans up shared directory symlinks
- Shows categorized lists of branches found (traditional, squash-merged, remote-deleted, unpushed)
Alias: gwtcl
The plugin also provides some convenient aliases:
gwt→git worktreegwtls→gwtl(list worktrees)gwtrp→gwtp(prune worktrees)gwtcl→gwtclean(clean merged branches)
MIT License - see LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
