Automate Git Worktree Management

Overview

When working with multiple features or branches simultaneously, git worktrees provide isolated development environments without checking out different branches in the same directory. This guide covers the two companion scripts that automate the entire worktree workflow: creating workspaces, syncing environments, and installing dependencies.

Why Use Worktrees?

Problems They Solve

  • Multiple Features in Parallel: Work on feature branches without constantly switching branches in your main working directory
  • Faster Context Switching: Access different features without rebuilding dependencies
  • CI/CD Testing: Run tests on multiple branches simultaneously
  • Isolated Environments: Each worktree has its own node_modules, .env files, and build artifacts

Monorepo Considerations

In this monorepo, worktrees are especially valuable because:
  • You can run different backend services (Go, Bun) on different worktrees simultaneously
  • Frontend (SolidStart, Astro) can be tested independently
  • Each worktree gets its own .env configuration
  • Dependencies are isolated — no conflicts between feature branches

Scripts Overview

1. setup-worktree.sh — Full Setup Automation

Purpose: Create a new git worktree with automatic environment sync and optional dependency installation Location: ./scripts/setup-worktree.sh What it does:
  1. ✅ Creates a new git worktree at ../[NAME]
  2. ✅ Creates a feature branch feature/[NAME]
  3. ✅ Syncs all .env files from main repo to worktree
  4. ✅ (Optional) Installs dependencies across all backend/frontend packages

2. sync-env.sh — Environment Sync Utility

Purpose: Keep .env files synchronized across worktrees when main repo config changes Location: ./scripts/sync-env.sh What it does:
  1. ✅ Copies .env files from main repo to worktree (overwrites with latest)
  2. ✅ Detects which files have changed
  3. ✅ Optional dry-run preview before applying changes
  4. ✅ Works on current worktree or any specified path

Getting Started

Creating a New Worktree

Quick Setup (Interactive)

./scripts/setup-worktree.sh
This prompts for a worktree name and guides you through the setup.

With Name Argument

./scripts/setup-worktree.sh auth-redesign
Creates:
  • Worktree directory: ../auth-redesign/
  • Branch: feature/auth-redesign
  • Synced .env files
  • Optionally installs dependencies

Interactive Dependency Installation

When prompted, choose whether to install dependencies:
Install dependencies (bun/pnpm)? (y/n): y
If you choose yes, the script installs:
  • backend/bun (root + monolith app)
  • backend/bun/apps/monolith
  • frontend/solidstart (root + panel app)
  • frontend/solidstart/apps/panel
  • frontend/astro (root + platform app)
  • frontend/astro/apps/platform
If you choose no, you can install dependencies later:
cd ../auth-redesign
./scripts/dev.sh  # Interactive dev environment setup

Example Workflow

# 1. Create and setup worktree
./scripts/setup-worktree.sh feature-payment-flow

# 2. Navigate to worktree
cd ../feature-payment-flow

# 3. Start development servers
./scripts/dev.sh

# 4. Make changes and commit
git add .
git commit -m "feat: implement payment flow"

# 5. Push to remote
git push -u origin feature/feature-payment-flow

# 6. Create PR from GitHub

Syncing Environment Changes

Scenario: Main Repo .env Updated

When you update .env files in the main repo (e.g., new API key, database URL), sync them to your worktrees:

From Your Worktree

# Sync current worktree
./scripts/sync-env.sh

# Preview changes first (dry-run)
./scripts/sync-env.sh --dry-run

From Main Repo (for another worktree)

# Sync to specific worktree
./scripts/sync-env.sh ../my-feature-branch

# Dry-run on specific worktree
./scripts/sync-env.sh --dry-run ../my-feature-branch

Understanding Sync Output

[INFO]  Syncing .env files from /path/to/main to /path/to/worktree

[WARN]  Updating (changes detected): backend/go/.env
[OK]    Created: backend/bun/apps/monolith/.env
[OK]    Already in sync: frontend/solidstart/apps/panel/.env
[WARN]  Source not found: some/missing/.env

[OK]    Sync complete!
  Updated/Created: 2
  Already in sync: 1
  Failed/Missing: 1
  • Updating: File exists but has differences (overwrites)
  • Created: New file copied to worktree
  • Already in sync: File unchanged (skipped)
  • Source not found: Main repo doesn’t have this file

Advanced Usage

Install Dependencies Later

If you skipped dependency installation during setup:
cd ../your-worktree

# Run dev script (interactive)
./scripts/dev.sh

# Or install manually for specific packages
cd backend/bun && bun install
cd frontend/solidstart && pnpm install

Dry-Run Preview

See what would be synced without making changes:
./scripts/sync-env.sh --dry-run
Output shows what will be created, updated, or already synced:
[INFO]  DRY RUN: Previewing .env sync

[WARN]  Will overwrite (updated): backend/go/.env
[INFO]  Will create: backend/bun/apps/monolith/.env
[OK]    Already in sync: frontend/astro/apps/platform/.env.local

[INFO]  Dry run complete. Run without --dry-run to apply changes.

Multiple Worktrees Simultaneously

You can have multiple worktrees open and run different features:
# Terminal 1: Feature A
cd ../feature-auth
./scripts/dev.sh

# Terminal 2: Feature B
cd ../feature-payments
./scripts/dev.sh

# Both run independently with isolated dependencies

Sync All Worktrees at Once

If main .env changes and you have multiple worktrees:
# From main repo
for worktree in ../*; do
  if [[ -d "$worktree/.git" ]]; then
    echo "Syncing $worktree..."
    ./scripts/sync-env.sh "$worktree"
  fi
done

Troubleshooting

Branch Already Exists

[ERROR] Failed to create worktree. Check if branch or worktree already exists.
Solution: Choose a different worktree name or delete the existing branch:
git branch -d feature/old-name

Worktree Already Exists

[ERROR] Worktree already exists at: ../my-worktree
Solution: Use a different name or remove the existing worktree:
git worktree remove ../my-worktree

Dependencies Installation Fails

If bun/pnpm install fails during setup:
cd ../your-worktree/backend/bun
bun install  # Try again with more verbose output
Common causes:
  • Node version mismatch — ensure Node ≥ 22
  • Missing bun or pnpm — install globally
  • Corrupted node_modules — delete and retry

.env Files Not Syncing

Verify the source files exist in main repo:
./scripts/sync-env.sh --dry-run
Check specific file:
ls -la backend/go/.env
If missing, copy from .env.example:
cp backend/go/.env.example backend/go/.env

Environment Mappings

Both scripts sync these .env files:
SourceDestination
backend/bun/.envbackend/bun/.env
backend/go/.envbackend/go/.env
backend/bun/apps/monolith/.envbackend/bun/apps/monolith/.env
frontend/solidstart/apps/panel/.envfrontend/solidstart/apps/panel/.env
frontend/astro/.env.localfrontend/astro/.env.local
frontend/astro/apps/platform/.env.localfrontend/astro/apps/platform/.env.local

Best Practices

✅ Do

  • Use descriptive worktree names: auth-redesign, payment-flow, not feature1
  • Sync .env before starting dev: Ensures you have latest configuration
  • Use dry-run for big syncs: Preview changes before applying them
  • Clean up old worktrees: Remove completed feature branches to avoid clutter
    git worktree remove ../old-feature
    

❌ Don’t

  • Don’t commit .env files: They contain secrets and should be in .gitignore
  • Don’t manually edit .env in worktrees: They’ll be overwritten on next sync
  • Don’t skip dependency installation: You won’t be able to run dev servers
  • Don’t use spaces in worktree names: Stick to kebab-case: my-feature not my feature
  • dev.sh — Start all development servers
  • deploy.sh — Deploy services (Go backend)

Summary

TaskCommand
Create new worktree./scripts/setup-worktree.sh my-feature
Sync .env to current worktree./scripts/sync-env.sh
Preview sync changes./scripts/sync-env.sh --dry-run
Sync to specific worktree./scripts/sync-env.sh ../other-feature
Remove worktreegit worktree remove ../my-feature
List all worktreesgit worktree list