Manage git worktrees and run configurable commands from a single VS Code window.
- Create/remove git worktrees from the sidebar
- Configurable commands (output mode) and terminals (interactive mode)
- Global and per-command environment variables with template expansion
- Command dependencies with automatic resolution
- Lifecycle hooks:
beforeCreate,afterCreate,beforeDelete,afterDelete - Open worktree in new VS Code window with correct env
- Multiple concurrent commands per worktree with tree view
- Stop/close running commands from UI
Create .vscode/worktree-presets.json in your project root:
{
"variables": {
"outputPath": "/home/user/builds/myproject-output${number}",
"buildPath": "${outputPath}/build/debug",
"vcpkgPrefix": "/home/user/libs/vcpkg/installed/x64-linux"
},
"env": {
"MY_VAR": "${outputPath}",
"PROJECT_ROOT": "${wtPath}"
},
"beforeCreate": ["StashChanges"],
"afterCreate": ["Setup", "Configure"],
"beforeDelete": ["SaveState"],
"afterDelete": ["NotifyCI"],
"commands": [
{
"label": "Setup",
"command": "cp CMakeUserPresets.json ${wtPath}/",
"hidden": true
},
{
"label": "Configure",
"command": "cmake -S ${wtPath} -B ${buildPath} -G Ninja"
},
{
"label": "Build",
"command": "ninja -j${cpus} install",
"cwd": "${buildPath}",
"depends": ["Configure"]
}
],
"terminals": [
{
"label": "Shell",
"command": "${SHELL}"
},
{
"label": "Claude",
"command": "claude"
},
{
"label": "Debug Server",
"command": "./run-server.sh",
"depends": ["Build"]
}
]
}| Variable | Description |
|---|---|
${wtPath} |
Worktree source directory |
${branch} |
Current branch name |
${number} |
Worktree number (1-9) |
${cpus} |
CPU count |
${SHELL} |
User's shell |
User variables in variables can reference built-in vars and each other (resolved in order).
| Section | Description |
|---|---|
variables |
User-defined variables for template expansion |
env |
Global environment variables (inherited by all commands/terminals) |
beforeCreate |
Command labels to run before worktree creation (cwd = primary repo) |
afterCreate |
Command labels to run after worktree creation (cwd = new worktree) |
beforeDelete |
Command labels to run before worktree removal (cwd = worktree, ${wtPath} available) |
afterDelete |
Command labels to run after worktree removal (cwd = primary repo) |
commands |
Output-mode commands (read-only log, stoppable) |
terminals |
Terminal-mode commands (interactive, closable) |
onCreateis still supported as an alias forafterCreate.
Hooks run sequentially and stop on first failure. Available variables differ by hook:
| Hook | ${wtPath} points to |
Worktree exists? |
|---|---|---|
beforeCreate |
future path (not yet created) | No — cwd falls back to primary repo |
afterCreate |
new worktree | Yes |
beforeDelete |
worktree being deleted | Yes |
afterDelete |
primary repo | No — cwd falls back to primary repo |
| Field | Description | Default |
|---|---|---|
label |
Display name | required |
command |
Shell command (supports ${...} variables) |
required |
cwd |
Working directory | ${wtPath} |
env |
Extra env vars (merged on top of global env) |
{} |
depends |
List of command labels that must complete first | [] |
hidden |
Hide from QuickPick (still available for hooks and depends) |
false |
When a command or terminal has depends, the extension checks if those commands have completed successfully in the current session. If not, they are run automatically before the main command.
The extension adds a window button on each secondary worktree that opens it in a new VS Code window with the global env applied. For this to work, your shell startup files (.zshenv, .bashrc) should use conditional defaults:
export MY_VAR=${MY_VAR:-default_value}This way, env vars set by the extension won't be overwritten by shell startup.
npm install
npx @vscode/vsce package
code --install-extension worktree-manager-*.vsixThen reload VS Code.
~/Projects/
myproject/ # wt1 (primary repo)
myproject2/ # wt2 (worktree)
myproject3/ # wt3 (worktree)
The extension auto-detects the primary repo via git rev-parse --git-common-dir, so it works correctly even when VS Code is opened from a secondary worktree.