Skip to content
ChatJS
Esc
navigateopen⌘Jpreview
On this page

Git Worktrees

Parallel development environments without branch switching

Problem

Switching branches interrupts your workflow. You lose editor state, need to reinstall dependencies, and can’t easily compare implementations side-by-side. Working on multiple features or reviewing PRs requires constant context switching.

Solution

Git worktrees create separate working directories for different branches, all sharing the same repository. Each worktree has its own files, node_modules, and environment—letting you work on multiple branches simultaneously.

Implementation

Setup Script

Create a setup script that initializes worktrees with dependencies and environment files:

#!/usr/bin/env bash
# Setup a worktree with .env.local and deps
# Usage: worktree-setup.sh [branch-name]
#   No args: setup current worktree
#   With arg: create worktree + setup
set -e

MAIN_REPO=$(git worktree list | head -1 | awk '{print $1}')
REPO_NAME=$(basename "$MAIN_REPO")

if [ -n "$1" ]; then
  WORKTREE_PATH="../$REPO_NAME-$1"
  git worktree add -b "$1" "$WORKTREE_PATH" 2>/dev/null || git worktree add "$WORKTREE_PATH" "$1"
  cd "$WORKTREE_PATH"
fi

cp "$MAIN_REPO/.env.local" .env.local 2>/dev/null && echo "✓ .env.local" || echo "⚠ No .env.local"
bun i
echo "✓ Ready: $(pwd)"

Make it executable:

chmod +x scripts/worktree-setup.sh

IDE Integration (Cursor)

For Cursor IDE, add automatic dependency installation when opening worktrees:

{
  "setup-worktree": ["bun install"]
}

Git Aliases

Add these to your ~/.gitconfig for faster worktree commands:

[alias]
    # List all worktrees
    wtl = worktree list

    # Add a new worktree (usage: git wta <branch-name>)
    wta = "!f() { repo=$(basename \"$(git worktree list --porcelain | sed -n '1s/^worktree //p')\"); git worktree add -b \"$1\" \"../$repo-$1\"; }; f"

    # Remove a worktree (usage: git wtr <path>)
    wtr = "!git worktree remove \"$@\" #"

    # Prune stale worktrees
    wtp = worktree prune

    # Cleanup merged branches and their worktrees
    wt-cleanup = "!f() { git fetch -p && git branch --merged ${1:-main} | grep -v \"^[* ]*${1:-main}$\" | while read branch; do wt=$(git worktree list | grep \"\\[$branch\\]\" | awk '{print $1}'); [ -n \"$wt\" ] && git worktree remove \"$wt\"; git branch -d \"$branch\"; done }; f"

Usage

Create a New Worktree

# Create worktree for a new branch
./scripts/worktree-setup.sh feature-auth

# Or use git alias
git wta feature-auth

This creates ../chatjs-feature-auth/ with:

  • Fresh checkout of the branch
  • Copied .env.local from main repo
  • Installed dependencies

Setup Existing Worktree

# In the worktree directory, run without args
./scripts/worktree-setup.sh

List Worktrees

git worktree list
# /home/user/chatjs              abc1234 [main]
# /home/user/chatjs-feature-auth def5678 [feature-auth]

Remove Worktree

# Remove worktree (keeps branch)
git worktree remove ../chatjs-feature-auth

# Force remove if there are changes
git worktree remove --force ../chatjs-feature-auth

Commands Reference

Command Description
git wta <branch> Add worktree for branch
git wtl List all worktrees
git wtr <path> Remove worktree
git wtp Prune stale worktrees
git wt-cleanup Remove merged branches and their worktrees

Was this page helpful?