CROP
ProjectsParts Services

Git Worktree Workflow for CROP Microservices

A system for managing parallel working contexts for microservices with automatic status synchronization in Linear.

Git Worktree Workflow for CROP Microservices

A system for managing parallel working contexts for microservices with automatic status synchronization in Linear.

Problem

When working on multiple microservices simultaneously (4-6 tasks in parallel):

  • Constant branch switching interrupts context
  • node_modules get rebuilt on every checkout
  • Docker containers restart
  • IDE loses indexing and typing
  • Difficult to track task statuses in Linear

Solution

Git Worktree + CLI Automation + Linear Integration

Structure

CROP/
├── CROP-parts-services/        # Main repository (main) - DO NOT TOUCH
├── wt-search/                  # Worktrees for search service
│   ├── CT-89-fix-tests/
│   └── CT-124-add-filters/
├── wt-catalog/                 # Worktrees for catalog
│   └── CT-456-update-api/
├── wt-payment/                 # Worktrees for payment
│   └── CT-122-stripe-integration/
└── wt-user/                    # Worktrees for user service
    └── CT-789-user-profile/

Benefits:

  • Each task = separate directory
  • Separate node_modules (complete isolation)
  • Separate Docker containers
  • IDE maintains context for each task
  • Automatic status synchronization with Linear

Quick Start

1. Create worktree from Linear task

# Option A: Via Claude Code MCP (recommended)
# Claude Code automatically fetches data from Linear and creates worktree

# Option B: Manually via CLI
bun wt create CT-123

What happens automatically:

  1. Fetching task data from Linear
  2. Determining service by labels (Search backendwt-search/)
  3. Creating git branch vova-appdev/ct-123-description
  4. Creating worktree in wt-{service}/CT-123-...
  5. Installing dependencies (bun install)
  6. Copying .env file
  7. Updating status in Linear → "In Progress"

1b. Attach existing branch to Linear task

Scenario: You started work without a Linear task, then created a task and want to link everything.

# You have a branch
git checkout my-feature
# ... work ...

# Created Linear task CT-150
# Attach branch to task
bun wt attach my-feature CT-150

What happens automatically:

  1. Fetching task data CT-150 from Linear
  2. Verifying that branch my-feature exists
  3. Determining service by Linear labels
  4. Renaming branch: my-featurevova-appdev/ct-150-description
  5. Creating worktree in wt-{service}/CT-150-...
  6. Installing dependencies
  7. Copying .env
  8. Updating status in Linear → "In Progress"
  9. Tips on how to update remote branch

Important:

  • Branch must be committed (no uncommitted changes)
  • Cannot attach main or master
  • All your commits are preserved

Example output:

Attaching branch my-feature to task CT-150...
Fetching task data CT-150...
Task: Add semantic search to catalog
Labels: Search backend, AI/ML
Renaming branch: my-feature vova-appdev/ct-150-add-semantic-search-to-catalog
Branch renamed
Creating worktree: wt-search/CT-150-add-semantic-search-to-catalog
Worktree created!
Installing dependencies...
Updating status in Linear...
Done! Branch attached to CT-150
Navigate to: cd /Users/vova/Code/CROP/wt-search/CT-150-...

Don't forget to update remote branch:
git push origin --delete my-feature
cd "/Users/vova/Code/CROP/wt-search/CT-150-..." && git push -u origin vova-appdev/ct-150-...

2. View all active worktrees

bun wt list

# Output:
# Active worktrees (3):
#
#   CT-89 (search)
#     vova-appdev/ct-89-phase-1-restore-critical-test-coverage
#     /Users/vova/Code/CROP/wt-search/CT-89-phase-1-restore-critical-test-coverage
#
#   CT-122 (payment)
#     vova-appdev/ct-122-payment-service
#     /Users/vova/Code/CROP/wt-payment/CT-122-payment-service

3. Check task statuses

bun wt status

# Output:
# Active worktrees (3):
#
#   CT-89 (search)
#     In Progress
#     Phase 1: Restore critical test coverage
#     /Users/vova/Code/CROP/wt-search/CT-89-phase-1-restore-critical-test-coverage
#
#   CT-122 (payment)
#     In Review
#     Payment service
#     /Users/vova/Code/CROP/wt-payment/CT-122-payment-service

4. Switch to another task

bun wt switch CT-122

# Output:
# Switching to worktree: /Users/vova/Code/CROP/wt-payment/CT-122-payment-service
# Run: cd "/Users/vova/Code/CROP/wt-payment/CT-122-payment-service"
# Or open in VS Code: code "/Users/vova/Code/CROP/wt-payment/CT-122-payment-service"

5. Work as usual

cd /Users/vova/Code/CROP/wt-search/CT-89-phase-1-restore-critical-test-coverage

# Development
bun run dev
bun test
git add .
git commit -m "fix: resolve test failures"
git push

Git hooks automatically:

  • Validate that branch contains Linear ID
  • Update status → "In Review" on first push
  • Synchronize status when switching branches

6. Complete task and delete worktree

# After merging PR
bun wt cleanup CT-89

# Output:
# Deleting worktree: /Users/vova/Code/CROP/wt-search/CT-89-phase-1-restore-critical-test-coverage
# Worktree deleted
# Delete branch vova-appdev/ct-89-...? (y/N)

Full Command List

# Creating worktree
bun wt create CT-XXX              # Create from Linear task
bun wt attach branch-name CT-XXX  # Attach existing branch to Linear

# Navigation
bun wt list                       # Show all worktrees
bun wt status                     # Show statuses from Linear
bun wt switch CT-XXX              # Switch to worktree

# Management
bun wt cleanup CT-XXX             # Delete worktree
bun wt cleanup CT-XXX --force     # Delete even with uncommitted changes
bun wt sync CT-XXX "In Review"    # Update Linear status manually

# Help
bun wt help                       # Show help

Linear Integration

Automatic Service Detection

The script determines service by Linear task labels:

Linear LabelServiceWorktree Directory
Search backendsearchwt-search/
Payment Servicepaymentwt-payment/
Catalog UXcatalogwt-catalog/
User Serviceuserwt-user/
Mediamediawt-media/

Important: Add specific labels! Generic label "Backend" won't work.

Status Synchronization

EventActionNew Status
bun wt create CT-XXXCreating worktree→ "In Progress"
git checkout ct-xxx-branchSwitching to branch→ "In Progress"
git push (first time)Pushing branch→ "In Review"
Merge PRManually in Linear→ "Done"

VS Code Integration

Open worktree as workspace

code /Users/vova/Code/CROP/wt-search/CT-89-phase-1-restore-critical-test-coverage

# Or via Fish function
wto CT-89  # wtopen

Multi-root workspace (optional)

Create .code-workspace file:

{
  "folders": [
    {
      "name": "CT-89 (Search)",
      "path": "../wt-search/CT-89-phase-1-restore-critical-test-coverage"
    },
    {
      "name": "CT-122 (Payment)",
      "path": "../wt-payment/CT-122-payment-service"
    },
    {
      "name": "Main (read-only)",
      "path": "../CROP-parts-services"
    }
  ]
}

Fish Shell Integration

Powerful integration with auto-completion and helpers is available for Fish Shell users.

Installation

cd /path/to/CROP-parts-services
fish .fish/install.fish
exec fish  # Reload shell

What Gets Installed

1. Auto-completion (Tab completions)

  • bun wt create <Tab> → Linear ID hints
  • bun wt attach <Tab> → list of local branches
  • bun wt switch <Tab> → active worktrees
  • bun wt cleanup <Tab> → active worktrees
  • bun wt sync <Tab> → active worktrees + statuses

2. Fish Functions

  • wtcd CT-XXX → quick navigation to worktree
  • wtopen CT-XXX → open worktree in VS Code
  • wtcurrent → show current worktree and status

3. Abbreviations (auto-expansion)

wtn CT-123        # → bun wt create CT-123
wta my-branch     # → bun wt attach my-branch
wtl               # → bun wt list
wts               # → bun wt status
wtc CT-123        # → bun wt cleanup CT-123
wtg CT-123        # → wtcd CT-123
wto CT-123        # → wtopen CT-123
wti               # → wtcurrent

4. Prompt Integration (optional)

Add to ~/.config/fish/functions/fish_prompt.fish:

function fish_prompt
    # ... your existing prompt ...

    # Show Linear ID in worktree
    echo -n (fish_prompt_linear)

    # ... rest of prompt ...
end

Result:

[CT-89] ~/Code/CROP/wt-search/CT-89-... $  # Yellow = In Progress
[CT-122] ~/Code/CROP/wt-payment/CT-122-... $  # Cyan = In Review

Usage Examples

# Quick worktree creation
wtn CT-150
# → bun wt create CT-150

# Navigation with one command
wtg CT-150
# Navigating to worktree: CT-150
# /Users/vova/Code/CROP/wt-search/CT-150-add-semantic-search

# Open in VS Code
wto CT-150
# Opening worktree in VS Code: CT-150

# Check current location
wti
# Current worktree: CT-150
# Service: search
# In Progress
# Add semantic search to catalog
# /Users/vova/Code/CROP/wt-search/CT-150-...

# Auto-completion works everywhere
bun wt switch <Tab>
# CT-89  CT-122  CT-150

# Abbreviations expand automatically
wtl<Space>
# → bun wt list

Fish Functions Reference

CommandWhat it doesExample
wtcd CT-XXXNavigate to worktreewtcd CT-89
wtopen CT-XXXOpen in VS Codewto CT-89 (via abbr)
wtcurrentShow current worktreewti (via abbr)
fish_prompt_linearLinear ID in promptAdd to fish_prompt

Abbreviations Reference

AbbrCommandDescription
wtnbun wt createCreate worktree
wtabun wt attachAttach branch
wtlbun wt listList worktrees
wtsbun wt statusTask statuses
wtcbun wt cleanupDelete worktree
wthbun wt helpHelp
wtgwtcdNavigate to worktree
wtowtopenOpen in VS Code
wtiwtcurrentCurrent worktree

Git Hooks

post-checkout

Trigger: Branch switching or checkout Action: Update Linear status → "In Progress" File: .husky/post-checkout

# Automatically:
# 1. Extracts Linear ID from branch name
# 2. Checks task cache
# 3. Updates status if != "In Progress"

pre-push

Trigger: git push Action: Branch validation + status update File: .husky/pre-push

# Automatically:
# 1. Checks for Linear ID in branch name
# 2. Warns if ID is missing
# 3. Updates status → "In Review" on first push

Best Practices

DO

  1. ENGLISH ONLY in Linear

    • Title: "Optimize autocomplete performance"
    • Description: "Improve input normalization..."
    • NOT: "Optimization of autocomplete"
    • Automatic check: Script bun wt create checks for Cyrillic
  2. Always create worktree via bun wt create

    • Automatic setup
    • Correct structure
    • Synchronization with Linear
  3. Keep main repository on main

    cd /path/to/CROP-parts-services
    git branch
    # * main
  4. Commit changes before switching

    git status  # Check for no uncommitted
    bun wt switch CT-XXX
  5. Use specific Linear labels

    • "Search backend"
    • NOT "Backend" (too generic)

DON'T

  1. DON'T create worktree manually

    # Bad
    git worktree add ../wt-search/my-feature
    
    # Good
    bun wt create CT-123
  2. DON'T work in main repository

    # Bad - working in main repo on feature branch
    cd /path/to/CROP-parts-services
    git checkout feature-branch
    
    # Good - working in worktree
    cd /Users/vova/Code/CROP/wt-search/CT-123-...
  3. DON'T delete worktree with uncommitted changes

    # Bad
    bun wt cleanup CT-123  # Will error
    
    # Good
    git add . && git commit
    bun wt cleanup CT-123
  4. DON'T use one worktree for different tasks

    • Each Linear task = separate worktree
    • After completing task → delete worktree

Troubleshooting

Problem: "Could not determine service"

Cause: Missing specific label in Linear

Solution:

# 1. Open task in Linear
# 2. Add label: "Search backend", "Payment Service", etc.
# 3. Retry creating worktree
bun wt create CT-XXX

Problem: "Worktree already exists"

Cause: Worktree was created earlier

Solution:

# View list
bun wt list

# Switch to existing
bun wt switch CT-XXX

# Or delete and recreate
bun wt cleanup CT-XXX
bun wt create CT-XXX

Problem: "Command failed: bun install"

Cause: Error installing dependencies in worktree

Solution:

# Navigate to worktree
cd /Users/vova/Code/CROP/wt-search/CT-XXX-...

# Install manually
bun install

# Verify it works
bun test

Problem: "Linear status not updating"

Cause: Linear CLI not installed or configured

Solution:

# Install Linear CLI
npm install -g @linear/cli

# Authenticate
linear login

# Check connection
linear issue CT-XXX

# Update status manually
bun wt sync CT-XXX "In Progress"


Usage Examples

Example 1: Starting work on a new task

# 1. Create worktree from Linear
bun wt create CT-150

# Output:
# Fetching task data CT-150...
# Task: Add semantic search to catalog
# Labels: Search backend, AI/ML
# Creating worktree: wt-search/CT-150-add-semantic-search-to-catalog
# Creating new branch: vova-appdev/ct-150-add-semantic-search-to-catalog
# Worktree created!
# Installing dependencies...
# Updating status in Linear...
# Done! Navigate to: cd /Users/vova/Code/CROP/wt-search/CT-150-...

# 2. Navigate and work
cd /Users/vova/Code/CROP/wt-search/CT-150-add-semantic-search-to-catalog
code .

# 3. Development
bun run dev
# ... write code ...
bun test
git add .
git commit -m "feat: add semantic search embeddings"
git push

Example 2: Switching between tasks

# Show all tasks
bun wt status

# Output:
# Active worktrees (3):
#
#   CT-89 (search)
#     In Progress
#     Phase 1: Restore critical test coverage
#
#   CT-122 (payment)
#     In Review
#     Payment service
#
#   CT-150 (search)
#     In Progress
#     Add semantic search to catalog

# Switch to another task
bun wt switch CT-122
cd /Users/vova/Code/CROP/wt-payment/CT-122-payment-service

# Work
bun run dev

Example 3: Completion and cleanup

# After merging PR in GitHub
bun wt cleanup CT-150

# Output:
# Deleting worktree: /Users/vova/Code/CROP/wt-search/CT-150-...
# Worktree deleted
# Delete branch vova-appdev/ct-150-...? (y/N)

# Enter 'y' to delete branch
y

# Check what's left
bun wt list

Example 4: Attaching existing branch to Linear

# Scenario: Started work without Linear task
git checkout -b quick-fix-search
git commit -m "fix: resolve search timeout"
git commit -m "test: add timeout test"

# Then created task in Linear CT-160
# Attach existing branch
bun wt attach quick-fix-search CT-160

# Output:
# Attaching branch quick-fix-search to task CT-160...
# Fetching task data CT-160...
# Task: Fix search service timeout
# Labels: Search backend, Bug
# Renaming branch: quick-fix-search → vova-appdev/ct-160-fix-search-service-timeout
# Branch renamed
# Creating worktree: wt-search/CT-160-fix-search-service-timeout
# Worktree created!
# Installing dependencies...
# Done! Branch attached to CT-160
# Navigate to: cd /Users/vova/Code/CROP/wt-search/CT-160-fix-search-service-timeout
#
# Don't forget to update remote branch:
# git push origin --delete quick-fix-search
# cd "/Users/vova/Code/CROP/wt-search/CT-160-..." && git push -u origin vova-appdev/ct-160-...

# Navigate to worktree
cd /Users/vova/Code/CROP/wt-search/CT-160-fix-search-service-timeout

# Verify everything is in place
git log --oneline
# a1b2c3d test: add timeout test
# d4e5f6g fix: resolve search timeout

# Update remote
git push origin --delete quick-fix-search
git push -u origin vova-appdev/ct-160-fix-search-service-timeout

# Continue work
bun run dev

Metrics and Monitoring

Performance

  • Creating worktree: ~30 seconds (including bun install)
  • Switching between worktrees: instant (just cd)
  • Disk space: ~500MB per worktree
  • Recommended count: 4-6 active worktrees

Time Savings

ActionWithout worktreeWith worktreeSavings
Context switching2-3 min<1 sec99%
Installing dependenciesevery checkoutonce100%
Docker restartevery checkoutnever100%
IDE indexingevery checkoutonce100%

Total: ~10-15 minutes saved per task switch.


Created automatically via Claude Code Updated: 2025-11-12

On this page