A CLI tool for managing Git worktrees with a focus on opening them in the Cursor editor.
npm install @johnlindquist/worktreeA 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
``bash`
pnpm install -g @johnlindquist/worktree
`bash`
wt new -p, --path
Options:
- : Specify a custom path for the worktree-c, --checkout
- : Create new branch if it doesn't exist and checkout automatically-i, --install
- : Package manager to use for installing dependencies (npm, pnpm, bun, etc.)-e, --editor
- : Editor to use for opening the worktree (overrides default editor)
Example:
`bash`
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 code
Dirty 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
`bash`
wt setup
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 : Specify a custom path for the worktree-c, --checkout
- : Create new branch if it doesn't exist and checkout automatically-i, --install
- : Package manager to use for installing dependencies (npm, pnpm, bun, etc.)-e, --editor
- : Editor to use for opening the worktree (overrides default editor)-t, --trust
- : Trust and run setup commands without confirmation (for CI environments)
Example:
`bash`
wt setup feature/new-feature
wt setup feature/quick-start -i pnpm
wt setup feature/ci-build --trust # Skip confirmation in CI
`bash`
wt 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 : Specify a custom path for the worktree (defaults to )-i, --install
- : Package manager to use for installing dependencies (npm, pnpm, bun, etc.)-e, --editor
- : Editor to use for opening the worktree (overrides default editor)-s, --setup
- : Run setup scripts from worktrees.json or .cursor/worktrees.json
Example:
`bashInteractive PR selection
wt pr
$3
`bash
wt open [pathOrBranch]
`Interactive Selection: Run
wt open without arguments to see a fuzzy-searchable list of worktrees.Example:
`bash
wt open # Interactive selection
wt open feature/login # Open by branch name
wt open ./path/to/worktree # Open by path
`$3
`bash
wt list
`Shows all worktrees with their status:
- Branch name or detached HEAD state
- Locked/prunable status indicators
- Main worktree marker
$3
`bash
wt remove [pathOrBranch] [options]
`Interactive Selection: Run
wt remove without arguments to select a worktree to remove.Options:
-
-f, --force: Force removal without confirmationExample:
`bash
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 remove
`$3
`bash
wt purge
`Interactive multi-select interface to remove multiple worktrees at once. The main worktree is excluded from selection.
$3
`bash
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.
$3
`bash
wt merge [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 : 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 --removeExamples:
`bash
Basic merge (fails if target worktree has uncommitted changes)
wt merge feature/loginAuto-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 --removeAuto-commit, merge, and remove in one command
wt merge feature/login --auto-commit --removeForce remove worktree even if it has uncommitted changes
wt merge feature/login --remove --force
`Default Behavior Changes:
The
wt merge command now follows these safer defaults:
1. Dirty State Check: Fails if the target worktree has uncommitted changes (use --auto-commit to override)
2. Worktree Preservation: Keeps the source worktree after merge (use --remove to clean up)This prevents the previous destructive behavior where uncommitted changes were auto-committed with generic messages and worktrees were automatically deleted.
$3
You can set a default editor to be used when creating new worktrees:
`bash
Set default editor
wt config set editor 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 entirelyGet current default editor
wt config get editorShow config file location
wt config path
`The 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.$3
You can manually set the git provider for
wt pr if auto-detection doesn't work:`bash
Set git provider
wt config set provider gh # GitHub CLI
wt config set provider glab # GitLab CLIGet current provider
wt config get provider
`$3
You can set a global directory where all worktrees will be created:
`bash
Set default worktree directory
wt config set worktreepath Examples:
wt config set worktreepath ~/worktrees # Use ~/worktrees
wt config set worktreepath /Users/me/dev/.wt # Use absolute pathGet current default worktree directory
wt config get worktreepathClear the setting (revert to sibling directory behavior)
wt config clear worktreepath
`Path Resolution Priority:
1.
--path flag (highest priority)
2. defaultWorktreePath config setting (with repo namespace)
3. 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-loginWith global path configured (
~/worktrees):
- Current directory: /Users/me/projects/myrepo
- Command: wt new feature/login
- Creates: ~/worktrees/myrepo/feature-loginBranch Name Sanitization:
Branch names with slashes are converted to dashes for directory names:
-
feature/auth → feature-auth
- hotfix/urgent-fix → hotfix-urgent-fixThis ensures uniqueness:
feature/auth and hotfix/auth create different directories.$3
You can define setup commands in one of two locations to automatically execute them when using
wt setup:1. Cursor's format:
.cursor/worktrees.json in the repository root
2. Generic format: worktrees.json in the repository rootThe 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.#### Format Options:
Option 1:
worktrees.json (recommended for new projects):
`json
{
"setup-worktree": [
"npm install",
"cp $ROOT_WORKTREE_PATH/.local.env .local.env",
"echo 'Setup complete'"
]
}
`Option 2:
.cursor/worktrees.json (Cursor's native format):
`json
[
"npm install",
"cp $ROOT_WORKTREE_PATH/.local.env .local.env",
"echo 'Setup complete'"
]
`#### Security Model
Setup commands use a trust-based security model:
- Default behavior: Commands are displayed before execution and require confirmation
- Trust mode: Use
--trust flag to skip confirmation (for CI environments)
- No blocklist: Unlike regex-based filtering, this model lets you run any legitimate command`bash
Interactive confirmation (default)
wt setup feature/newTrust mode for CI/scripts
wt setup feature/new --trust
`#### Execution Details
- Commands are executed in the new worktree directory
- The
$ROOT_WORKTREE_PATH environment 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 --install is used)$3
The CLI fully supports bare repositories, which is the most efficient workflow for heavy worktree users:
`bash
Clone as bare repository
git clone --bare git@github.com:user/repo.git repo.gitcd repo.git
Create worktrees for different branches
wt new main -p ../main
wt new feature/auth -p ../auth
wt new hotfix/urgent -p ../urgent
`Each worktree is a separate working directory, while the bare repo contains only the
.git data.Atomic Operations
All worktree creation operations are atomic with automatic rollback on failure:
1. If worktree creation succeeds but dependency installation fails, the worktree is automatically removed
2. Stashed changes are restored in the finally block, even if an error occurs
3. Failed commands are logged but don't leave the system in an inconsistent state
Requirements
- Git
- Node.js
- An editor installed and available in PATH (defaults to Cursor, can be set to
none to skip)
- For wt pr command: GitHub CLI (gh) or GitLab CLI (glab) installed and authenticatedDevelopment
`bash
Install dependencies
pnpm installBuild
pnpm buildRun tests
pnpm testRun in development mode
pnpm dev
`Testing
The project includes comprehensive test coverage:
`bash
Run all tests
pnpm testRun with coverage
pnpm test -- --coverage
``MIT