A CLI tool for managing Git worktrees with a focus on opening them in the Cursor editor.
- Interactive TUI: Fuzzy-searchable selection when arguments are omitted
- Bare Repository Support: Works with bare repositories for optimal worktree workflows
- Atomic Operations: Automatic rollback on failure for safe worktree creation
- Stash-aware: Gracefully handles dirty worktrees with stash/pop workflow
- PR Integration: Create worktrees directly from GitHub PRs or GitLab MRs
- Setup Automation: Run setup scripts automatically with trust-based security
pnpm install -g @johnlindquist/worktreewt new <branchName> [options]Options:
-p, --path <path>: Specify a custom path for the worktree-c, --checkout: Create new branch if it doesn't exist and checkout automatically-i, --install <packageManager>: Package manager to use for installing dependencies (npm, pnpm, bun, etc.)-e, --editor <editor>: Editor to use for opening the worktree (overrides default editor)
Example:
wt new feature/login
wt new feature/chat --checkout
wt new feature/auth -p ./auth-worktree
wt new feature/deps -i pnpm
wt new feature/vscode -e codeDirty Worktree Handling: If your main worktree has uncommitted changes, you'll be prompted with options:
- Stash changes: Automatically stash before creating, restore after
- Abort: Cancel the operation
- Continue anyway: Proceed with uncommitted changes
wt setup <branchName> [options]Creates a new worktree and automatically runs setup commands from worktrees.json or .cursor/worktrees.json. This is useful for automating dependency installation, copying configuration files, or running custom setup scripts.
Options:
-p, --path <path>: Specify a custom path for the worktree-c, --checkout: Create new branch if it doesn't exist and checkout automatically-i, --install <packageManager>: Package manager to use for installing dependencies (npm, pnpm, bun, etc.)-e, --editor <editor>: Editor to use for opening the worktree (overrides default editor)-t, --trust: Trust and run setup commands without confirmation (for CI environments)
Example:
wt setup feature/new-feature
wt setup feature/quick-start -i pnpm
wt setup feature/ci-build --trust # Skip confirmation in CIwt pr [prNumber] [options]Interactive Selection: Run wt pr without a number to see a list of open PRs/MRs to choose from.
Uses the GitHub CLI (gh) or GitLab CLI (glab) to fetch the branch associated with the given Pull Request or Merge Request number directly (without switching your current branch), and creates a worktree for it.
Benefit: Your main worktree stays untouched. Commits made in the PR worktree can be pushed directly using git push to update the PR/MR.
Requires GitHub CLI (gh) or GitLab CLI (glab) to be installed and authenticated.
The tool automatically detects whether you're working with a GitHub or GitLab repository based on the remote URL.
Options:
-p, --path <path>: Specify a custom path for the worktree (defaults to<repoName>-<branchName>)-i, --install <packageManager>: Package manager to use for installing dependencies (npm, pnpm, bun, etc.)-e, --editor <editor>: Editor to use for opening the worktree (overrides default editor)-s, --setup: Run setup scripts fromworktrees.jsonor.cursor/worktrees.json
Example:
# Interactive PR selection
wt pr
# Create worktree for GitHub PR #123
wt pr 123
# Create worktree for GitLab MR #456 with deps and editor
wt pr 456 -i pnpm -e code
# Create worktree and run setup scripts
wt pr 123 --setupwt open [pathOrBranch]Interactive Selection: Run wt open without arguments to see a fuzzy-searchable list of worktrees.
Example:
wt open # Interactive selection
wt open feature/login # Open by branch name
wt open ./path/to/worktree # Open by pathwt listShows all worktrees with their status:
- Branch name or detached HEAD state
- Locked/prunable status indicators
- Main worktree marker
wt remove [pathOrBranch] [options]Interactive Selection: Run wt remove without arguments to select a worktree to remove.
Options:
-f, --force: Force removal without confirmation
Example:
wt remove # Interactive selection
wt remove feature/login # Remove by branch name
wt remove ./path/to/worktree # Remove by path
wt remove feature/old -f # Force removewt purgeInteractive multi-select interface to remove multiple worktrees at once. The main worktree is excluded from selection.
wt extract [branchName] [options]Extracts the current (or specified) branch into a separate worktree, useful when you want to continue working on a branch in isolation.
wt merge <branchName> [options]Merge a branch from its worktree into the current branch. The command has been designed with safety in mind to prevent accidental data loss.
Safety Features:
- Checks for uncommitted changes in the target worktree by default
- Requires explicit opt-in flags for destructive operations
- Preserves the source worktree after merge by default
Options:
--auto-commit: Automatically commit uncommitted changes in the target worktree before merging-m, --message <message>: Custom commit message when using--auto-commit(defaults to auto-generated message)--remove: Remove the source worktree after successful merge (opt-in destructive cleanup)-f, --force: Force removal of worktree when used with--remove
Examples:
# Basic merge (fails if target worktree has uncommitted changes)
wt merge feature/login
# Auto-commit changes with custom message, then merge
wt merge feature/login --auto-commit -m "WIP: Login implementation"
# Merge and remove the source worktree
wt merge feature/login --remove
# Auto-commit, merge, and remove in one command
wt merge feature/login --auto-commit --remove
# Force remove worktree even if it has uncommitted changes
wt merge feature/login --remove --forceDefault Behavior Changes:
The wt merge command now follows these safer defaults:
- Dirty State Check: Fails if the target worktree has uncommitted changes (use
--auto-committo override) - Worktree Preservation: Keeps the source worktree after merge (use
--removeto clean up)
This prevents the previous destructive behavior where uncommitted changes were auto-committed with generic messages and worktrees were automatically deleted.
You can set a default editor to be used when creating new worktrees:
# Set default editor
wt config set editor <editorName>
# Examples:
wt config set editor code # Use VS Code
wt config set editor webstorm # Use WebStorm
wt config set editor cursor # Use Cursor (default)
wt config set editor none # Skip opening editor entirely
# Get current default editor
wt config get editor
# Show config file location
wt config pathThe default editor will be used when creating new worktrees unless overridden with the -e flag.
Setting the editor to none will skip opening any editor after creating a worktree, which is useful for CI/CD pipelines or scripts.
You can manually set the git provider for wt pr if auto-detection doesn't work:
# Set git provider
wt config set provider gh # GitHub CLI
wt config set provider glab # GitLab CLI
# Get current provider
wt config get providerYou can set a global directory where all worktrees will be created:
# Set default worktree directory
wt config set worktreepath <path>
# Examples:
wt config set worktreepath ~/worktrees # Use ~/worktrees
wt config set worktreepath /Users/me/dev/.wt # Use absolute path
# Get current default worktree directory
wt config get worktreepath
# Clear the setting (revert to sibling directory behavior)
wt config clear worktreepathPath Resolution Priority:
--pathflag (highest priority)defaultWorktreePathconfig setting (with repo namespace)- Sibling directory behavior (default fallback)
Path Collision Prevention:
When using a global worktree directory, paths are automatically namespaced by repository name to prevent collisions:
Without global path configured (default):
- Current directory:
/Users/me/projects/myrepo - Command:
wt new feature/login - Creates:
/Users/me/projects/myrepo-feature-login
With global path configured (~/worktrees):
- Current directory:
/Users/me/projects/myrepo - Command:
wt new feature/login - Creates:
~/worktrees/myrepo/feature-login
Branch Name Sanitization:
Branch names with slashes are converted to dashes for directory names:
feature/auth→feature-authhotfix/urgent-fix→hotfix-urgent-fix
This ensures uniqueness: feature/auth and hotfix/auth create different directories.
You can define setup commands in one of two locations to automatically execute them when using wt setup:
- Cursor's format:
.cursor/worktrees.jsonin the repository root - Generic format:
worktrees.jsonin the repository root
The tool checks for .cursor/worktrees.json first, then falls back to worktrees.json.
Note: Setup scripts only run when using the wt setup command. The wt new command will not execute setup scripts.
Option 1: worktrees.json (recommended for new projects):
{
"setup-worktree": [
"npm install",
"cp $ROOT_WORKTREE_PATH/.local.env .local.env",
"echo 'Setup complete'"
]
}Option 2: .cursor/worktrees.json (Cursor's native format):
[
"npm install",
"cp $ROOT_WORKTREE_PATH/.local.env .local.env",
"echo 'Setup complete'"
]Setup commands use a trust-based security model:
- Default behavior: Commands are displayed before execution and require confirmation
- Trust mode: Use
--trustflag to skip confirmation (for CI environments) - No blocklist: Unlike regex-based filtering, this model lets you run any legitimate command
# Interactive confirmation (default)
wt setup feature/new
# Trust mode for CI/scripts
wt setup feature/new --trust- Commands are executed in the new worktree directory
- The
$ROOT_WORKTREE_PATHenvironment variable is available, pointing to the main repository root - Commands run with shell execution, so complex commands and piping are supported
- If a command fails, the error is logged, but setup continues with the next command
- The setup runs after worktree creation but before dependency installation (if
--installis used)
The CLI fully supports bare repositories, which is the most efficient workflow for heavy worktree users:
# Clone as bare repository
git clone --bare git@github.com:user/repo.git repo.git
cd repo.git
# Create worktrees for different branches
wt new main -p ../main
wt new feature/auth -p ../auth
wt new hotfix/urgent -p ../urgentEach worktree is a separate working directory, while the bare repo contains only the .git data.
All worktree creation operations are atomic with automatic rollback on failure:
- If worktree creation succeeds but dependency installation fails, the worktree is automatically removed
- Stashed changes are restored in the finally block, even if an error occurs
- Failed commands are logged but don't leave the system in an inconsistent state
- Git
- Node.js
- An editor installed and available in PATH (defaults to Cursor, can be set to
noneto skip) - For
wt prcommand: GitHub CLI (gh) or GitLab CLI (glab) installed and authenticated
# Install dependencies
pnpm install
# Build
pnpm build
# Run tests
pnpm test
# Run in development mode
pnpm devThe project includes comprehensive test coverage:
# Run all tests
pnpm test
# Run with coverage
pnpm test -- --coverageMIT