Initial commit
This commit is contained in:
666
skills/devops/git-worktree-setup/data/best-practices.md
Normal file
666
skills/devops/git-worktree-setup/data/best-practices.md
Normal file
@@ -0,0 +1,666 @@
|
||||
# Git Worktree Best Practices
|
||||
|
||||
A comprehensive guide to using git worktrees effectively for parallel development with Claude Code.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Branch Naming Conventions](#branch-naming-conventions)
|
||||
2. [Worktree Organization](#worktree-organization)
|
||||
3. [Resource Management](#resource-management)
|
||||
4. [Workflow Patterns](#workflow-patterns)
|
||||
5. [Cleanup Strategies](#cleanup-strategies)
|
||||
6. [Team Collaboration](#team-collaboration)
|
||||
7. [Performance Optimization](#performance-optimization)
|
||||
8. [Security Considerations](#security-considerations)
|
||||
|
||||
---
|
||||
|
||||
## Branch Naming Conventions
|
||||
|
||||
### Recommended Patterns
|
||||
|
||||
**Feature Branches:**
|
||||
```
|
||||
feature/descriptive-name
|
||||
feature/user-authentication
|
||||
feature/payment-integration
|
||||
feature/dashboard-redesign
|
||||
```
|
||||
|
||||
**Bugfix Branches:**
|
||||
```
|
||||
bugfix/issue-number-description
|
||||
bugfix/123-login-redirect
|
||||
bugfix/456-memory-leak
|
||||
bugfix/789-validation-error
|
||||
```
|
||||
|
||||
**Hotfix Branches:**
|
||||
```
|
||||
hotfix/critical-issue
|
||||
hotfix/security-patch
|
||||
hotfix/production-crash
|
||||
```
|
||||
|
||||
**Experimental Branches:**
|
||||
```
|
||||
experiment/idea-name
|
||||
experiment/new-architecture
|
||||
experiment/performance-test
|
||||
```
|
||||
|
||||
**Chore Branches:**
|
||||
```
|
||||
chore/dependency-updates
|
||||
chore/refactor-auth
|
||||
chore/update-docs
|
||||
```
|
||||
|
||||
### Why Good Names Matter
|
||||
|
||||
- **Clarity:** Instantly understand the purpose
|
||||
- **Organization:** Easy to group and filter
|
||||
- **Cleanup:** Identify old branches quickly
|
||||
- **Collaboration:** Team members know what's being worked on
|
||||
|
||||
### Naming Anti-Patterns
|
||||
|
||||
❌ **Avoid:**
|
||||
- Vague names: `fix`, `update`, `changes`
|
||||
- Personal names: `johns-branch`, `temp-work`
|
||||
- Dates only: `2025-09-04`, `sept-changes`
|
||||
- No context: `test`, `wip`, `tmp`
|
||||
|
||||
✅ **Use:**
|
||||
- Descriptive: `feature/oauth-integration`
|
||||
- Issue-linked: `bugfix/1234-payment-error`
|
||||
- Purpose-clear: `experiment/graphql-migration`
|
||||
|
||||
---
|
||||
|
||||
## Worktree Organization
|
||||
|
||||
### Directory Structure
|
||||
|
||||
**Recommended: Sibling Directories**
|
||||
```
|
||||
~/projects/
|
||||
├── myapp/ # Main worktree
|
||||
├── myapp-feature-auth/ # Feature worktree
|
||||
├── myapp-bugfix-login/ # Bugfix worktree
|
||||
└── myapp-experiment-ui/ # Experiment worktree
|
||||
```
|
||||
|
||||
**Alternative: Dedicated Worktrees Directory**
|
||||
```
|
||||
~/projects/
|
||||
├── myapp/ # Main worktree
|
||||
└── myapp-worktrees/ # All worktrees
|
||||
├── feature-auth/
|
||||
├── bugfix-login/
|
||||
└── experiment-ui/
|
||||
```
|
||||
|
||||
**Team Shared Setup:**
|
||||
```
|
||||
~/work/
|
||||
├── myapp/ # Main (stable)
|
||||
├── myapp-review/ # For PR reviews
|
||||
├── myapp-hotfix/ # Emergency fixes
|
||||
└── myapp-current/ # Active feature work
|
||||
```
|
||||
|
||||
### Location Best Practices
|
||||
|
||||
✅ **Do:**
|
||||
- Keep worktrees near main repo (faster operations)
|
||||
- Use consistent naming pattern
|
||||
- Group by purpose if many worktrees
|
||||
- Document custom locations in team wiki
|
||||
|
||||
❌ **Don't:**
|
||||
- Scatter worktrees across filesystem
|
||||
- Use deep nested paths (slow operations)
|
||||
- Mix worktrees with unrelated projects
|
||||
- Create worktrees inside other worktrees
|
||||
|
||||
---
|
||||
|
||||
## Resource Management
|
||||
|
||||
### Disk Space
|
||||
|
||||
**Understanding Space Usage:**
|
||||
```
|
||||
Main repository: 150 MB
|
||||
Each worktree:
|
||||
- Repository files: 150 MB
|
||||
- node_modules: 700 MB
|
||||
- Build artifacts: 50 MB
|
||||
Total: ~900 MB per worktree
|
||||
```
|
||||
|
||||
**Space Management Strategies:**
|
||||
|
||||
1. **Limit Active Worktrees**
|
||||
- Keep 3-5 active worktrees maximum
|
||||
- Clean up merged branches weekly
|
||||
- Archive instead of keeping indefinitely
|
||||
|
||||
2. **Share When Possible**
|
||||
- Use pnpm for shared node_modules
|
||||
- Enable yarn's zero-installs
|
||||
- Share build caches
|
||||
|
||||
3. **Clean Build Artifacts**
|
||||
```bash
|
||||
# Clean before removing worktree
|
||||
cd worktree-path
|
||||
npm run clean
|
||||
rm -rf dist/ build/ .next/
|
||||
```
|
||||
|
||||
4. **Monitor Disk Usage**
|
||||
```bash
|
||||
# Check worktree sizes
|
||||
du -sh ../myapp-*
|
||||
|
||||
# Find largest directories
|
||||
du -sh */ | sort -hr | head -10
|
||||
```
|
||||
|
||||
### Memory Considerations
|
||||
|
||||
**Running Multiple Claude Code Sessions:**
|
||||
- Each session: ~500MB RAM
|
||||
- 3 parallel sessions: ~1.5GB RAM
|
||||
- Keep system RAM usage < 80%
|
||||
|
||||
**Tips:**
|
||||
- Close unused sessions
|
||||
- Restart sessions periodically
|
||||
- Use `/handoff` to preserve context
|
||||
- Monitor system performance
|
||||
|
||||
### CPU Management
|
||||
|
||||
**Avoid Parallel Builds:**
|
||||
```bash
|
||||
# Bad: Running builds in all worktrees simultaneously
|
||||
cd worktree1 && npm run build &
|
||||
cd worktree2 && npm run build &
|
||||
cd worktree3 && npm run build &
|
||||
|
||||
# Good: Sequential or limited parallel
|
||||
npm run build # One at a time
|
||||
```
|
||||
|
||||
**Use Build Queues:**
|
||||
- Serialize resource-intensive operations
|
||||
- Limit concurrent processes
|
||||
- Use tools like `make -j2` for controlled parallelism
|
||||
|
||||
---
|
||||
|
||||
## Workflow Patterns
|
||||
|
||||
### Pattern 1: Feature Development
|
||||
|
||||
```
|
||||
1. Create worktree for feature
|
||||
└─ git worktree add ../myapp-feature-x -b feature-x
|
||||
|
||||
2. Develop in isolation
|
||||
└─ cd ../myapp-feature-x && claude
|
||||
|
||||
3. Test independently
|
||||
└─ npm test && npm run build
|
||||
|
||||
4. Merge when ready
|
||||
└─ git checkout main && git merge feature-x
|
||||
|
||||
5. Clean up
|
||||
└─ git worktree remove ../myapp-feature-x
|
||||
```
|
||||
|
||||
### Pattern 2: PR Review
|
||||
|
||||
```
|
||||
1. Create worktree from PR branch
|
||||
└─ git worktree add ../myapp-review pr-branch
|
||||
|
||||
2. Review code with Claude Code
|
||||
└─ cd ../myapp-review && claude
|
||||
|
||||
3. Test changes
|
||||
└─ npm install && npm test
|
||||
|
||||
4. Leave feedback
|
||||
└─ (Review in Claude Code)
|
||||
|
||||
5. Remove when done
|
||||
└─ git worktree remove ../myapp-review
|
||||
```
|
||||
|
||||
### Pattern 3: Hotfix While Developing
|
||||
|
||||
```
|
||||
Current state: Working on feature-x in worktree
|
||||
|
||||
1. Create hotfix worktree from main
|
||||
└─ git worktree add ../myapp-hotfix -b hotfix-critical
|
||||
|
||||
2. Fix issue in hotfix worktree
|
||||
└─ cd ../myapp-hotfix && claude
|
||||
|
||||
3. Test and deploy
|
||||
└─ npm test && deploy
|
||||
|
||||
4. Continue feature work
|
||||
└─ cd ../myapp-feature-x
|
||||
|
||||
5. Merge hotfix to both main and feature
|
||||
└─ git checkout feature-x && git merge main
|
||||
```
|
||||
|
||||
### Pattern 4: Integration Testing
|
||||
|
||||
```
|
||||
1. Create worktrees for all features
|
||||
└─ Batch create: feature-a, feature-b, feature-c
|
||||
|
||||
2. Test each independently
|
||||
└─ Parallel Claude Code sessions
|
||||
|
||||
3. Create integration worktree
|
||||
└─ git worktree add ../myapp-integration -b integration
|
||||
|
||||
4. Merge all features to integration
|
||||
└─ git merge feature-a feature-b feature-c
|
||||
|
||||
5. Test combined functionality
|
||||
└─ npm test && npm run e2e
|
||||
|
||||
6. Clean up all worktrees after merge
|
||||
```
|
||||
|
||||
### Pattern 5: Comparison Testing
|
||||
|
||||
```
|
||||
1. Keep main worktree as baseline
|
||||
2. Create feature worktree for new implementation
|
||||
3. Run same tests in both
|
||||
4. Compare results side-by-side
|
||||
5. Make decision based on data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cleanup Strategies
|
||||
|
||||
### Daily Cleanup
|
||||
|
||||
**Check merged branches:**
|
||||
```bash
|
||||
# List merged branches
|
||||
git branch --merged main | grep -v "main"
|
||||
|
||||
# Remove worktrees for merged branches
|
||||
for branch in $(git branch --merged main | grep -v "main"); do
|
||||
git worktree remove ../myapp-$branch 2>/dev/null || true
|
||||
git branch -d $branch
|
||||
done
|
||||
```
|
||||
|
||||
### Weekly Cleanup
|
||||
|
||||
**Review all worktrees:**
|
||||
```bash
|
||||
# List all worktrees with age
|
||||
git worktree list | while read path commit branch; do
|
||||
cd "$path"
|
||||
age=$(git log -1 --format=%ar)
|
||||
echo "$branch: last activity $age"
|
||||
done
|
||||
```
|
||||
|
||||
**Remove stale worktrees (30+ days):**
|
||||
```bash
|
||||
# Manual review first, then remove
|
||||
git worktree list | grep -v main | while read path; do
|
||||
cd "$path"
|
||||
last_commit=$(git log -1 --format=%ct)
|
||||
current_time=$(date +%s)
|
||||
days_old=$(( (current_time - last_commit) / 86400 ))
|
||||
|
||||
if [ $days_old -gt 30 ]; then
|
||||
echo "Stale: $path ($days_old days old)"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
### Automated Cleanup
|
||||
|
||||
**Git hooks for cleanup:**
|
||||
```bash
|
||||
# .git/hooks/post-merge
|
||||
#!/bin/bash
|
||||
# Auto-cleanup merged branches
|
||||
|
||||
CURRENT_BRANCH=$(git branch --show-current)
|
||||
|
||||
if [ "$CURRENT_BRANCH" = "main" ]; then
|
||||
echo "Checking for merged worktrees..."
|
||||
|
||||
git branch --merged main | grep -v "main" | while read branch; do
|
||||
# Check if worktree exists
|
||||
if git worktree list | grep -q "\\[$branch\\]"; then
|
||||
echo "Found merged worktree: $branch"
|
||||
echo "Run: git worktree remove /path/to/$branch"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
```
|
||||
|
||||
### Cleanup Checklist
|
||||
|
||||
Before removing a worktree:
|
||||
- [ ] No uncommitted changes
|
||||
- [ ] Branch merged or backed up
|
||||
- [ ] No important local files
|
||||
- [ ] Dependencies can be reinstalled
|
||||
- [ ] No running processes
|
||||
|
||||
---
|
||||
|
||||
## Team Collaboration
|
||||
|
||||
### Shared Worktree Conventions
|
||||
|
||||
**Team Standards Document:**
|
||||
```markdown
|
||||
# Worktree Standards
|
||||
|
||||
## Naming
|
||||
- Features: feature/{jira-id}-{description}
|
||||
- Bugfixes: bugfix/{issue-id}-{description}
|
||||
- Reviews: review-{pr-number}
|
||||
|
||||
## Location
|
||||
- All worktrees in ~/projects/myapp-worktrees/
|
||||
|
||||
## Lifecycle
|
||||
- Create: Before starting work
|
||||
- Update: Sync with main daily
|
||||
- Remove: Within 24h of merge
|
||||
|
||||
## Resources
|
||||
- Max 3 active worktrees per developer
|
||||
- Clean up merged branches in daily standup
|
||||
```
|
||||
|
||||
### Communication
|
||||
|
||||
**Notify team of worktrees:**
|
||||
```bash
|
||||
# In team chat
|
||||
Working on worktrees:
|
||||
- feature-auth (for AUTH-123)
|
||||
- bugfix-login (for BUG-456)
|
||||
- review-pr-789 (reviewing Sarah's PR)
|
||||
|
||||
Will clean up by EOD.
|
||||
```
|
||||
|
||||
### Shared Scripts
|
||||
|
||||
**Team cleanup script:**
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# team-worktree-status.sh
|
||||
|
||||
echo "Worktree Status for $(whoami)"
|
||||
echo "================================"
|
||||
|
||||
git worktree list | while read path commit branch; do
|
||||
cd "$path"
|
||||
status=$(git status --porcelain | wc -l)
|
||||
behind=$(git rev-list --count HEAD..origin/main 2>/dev/null || echo "N/A")
|
||||
|
||||
echo "$branch:"
|
||||
echo " Changes: $status"
|
||||
echo " Behind main: $behind"
|
||||
echo " Path: $path"
|
||||
echo ""
|
||||
done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Git Operations
|
||||
|
||||
**Fetch Once, Use Everywhere:**
|
||||
```bash
|
||||
# In main worktree
|
||||
git fetch --all
|
||||
|
||||
# All worktrees automatically have access
|
||||
# No need to fetch in each worktree
|
||||
```
|
||||
|
||||
**Shallow Clones for Reviews:**
|
||||
```bash
|
||||
# For temporary review worktrees
|
||||
git worktree add --detach ../review-pr HEAD
|
||||
cd ../review-pr
|
||||
git fetch origin pull/123/head:pr-123
|
||||
git checkout pr-123
|
||||
```
|
||||
|
||||
### Build Performance
|
||||
|
||||
**Share Build Caches:**
|
||||
```bash
|
||||
# In main repo
|
||||
export TURBO_CACHE_DIR=/shared/turbo-cache
|
||||
|
||||
# All worktrees use same cache
|
||||
# Builds are faster after first run
|
||||
```
|
||||
|
||||
**Incremental Builds:**
|
||||
```bash
|
||||
# Don't clean between branches
|
||||
npm run build # Uses previous cache
|
||||
|
||||
# Only clean when needed
|
||||
npm run clean && npm run build
|
||||
```
|
||||
|
||||
### Dependency Management
|
||||
|
||||
**pnpm (Recommended for Worktrees):**
|
||||
```bash
|
||||
# Global store, minimal duplication
|
||||
pnpm install
|
||||
|
||||
# All worktrees reference same packages
|
||||
# Saves ~80% disk space
|
||||
```
|
||||
|
||||
**npm/yarn (Standard):**
|
||||
```bash
|
||||
# Each worktree has full node_modules
|
||||
# More disk space, complete isolation
|
||||
npm install
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Environment Variables
|
||||
|
||||
**Never commit .env:**
|
||||
```bash
|
||||
# Each worktree needs own .env
|
||||
cp ../.env .env
|
||||
|
||||
# Add to .gitignore (should already be there)
|
||||
echo ".env" >> .gitignore
|
||||
```
|
||||
|
||||
**Worktree-specific configs:**
|
||||
```bash
|
||||
# Different API endpoints per worktree
|
||||
# main: production API
|
||||
# feature-x: staging API
|
||||
# experiment: local API
|
||||
|
||||
# .env in each worktree
|
||||
API_URL=https://staging.api.example.com
|
||||
```
|
||||
|
||||
### Credentials
|
||||
|
||||
**Don't share credentials between worktrees:**
|
||||
- Separate SSH keys if needed
|
||||
- Different tokens per environment
|
||||
- Revoke credentials in removed worktrees
|
||||
|
||||
**Clean credentials before removal:**
|
||||
```bash
|
||||
# Before removing worktree
|
||||
cd worktree-path
|
||||
rm -f .env .env.local
|
||||
rm -f config/credentials.json
|
||||
|
||||
# Then remove
|
||||
git worktree remove $(pwd)
|
||||
```
|
||||
|
||||
### Access Control
|
||||
|
||||
**Workspace Permissions:**
|
||||
```bash
|
||||
# Ensure proper permissions
|
||||
chmod 700 ~/projects/myapp-*
|
||||
|
||||
# No group/other access to sensitive worktrees
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced Tips
|
||||
|
||||
### Worktree Templates
|
||||
|
||||
**Quick setup script:**
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# new-worktree.sh
|
||||
|
||||
BRANCH=$1
|
||||
PATH=../myapp-$BRANCH
|
||||
|
||||
git worktree add $PATH -b $BRANCH
|
||||
cd $PATH
|
||||
cp ../.env .
|
||||
pnpm install
|
||||
code . # Open in editor
|
||||
|
||||
echo "Worktree ready: $PATH"
|
||||
```
|
||||
|
||||
### Automation
|
||||
|
||||
**Auto-sync worktrees:**
|
||||
```bash
|
||||
# cron job: daily sync
|
||||
0 9 * * * cd ~/projects/myapp && git fetch && \
|
||||
for wt in $(git worktree list | awk '{print $1}'); do \
|
||||
cd $wt && git pull --rebase 2>/dev/null; \
|
||||
done
|
||||
```
|
||||
|
||||
### Monitoring
|
||||
|
||||
**Disk space alerts:**
|
||||
```bash
|
||||
# Alert when worktrees exceed threshold
|
||||
TOTAL=$(du -sm ~/projects/myapp-* | awk '{sum+=$1} END {print sum}')
|
||||
|
||||
if [ $TOTAL -gt 10000 ]; then
|
||||
echo "Warning: Worktrees using ${TOTAL}MB"
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
# Create
|
||||
git worktree add ../myapp-branch -b branch
|
||||
|
||||
# List
|
||||
git worktree list
|
||||
|
||||
# Remove
|
||||
git worktree remove ../myapp-branch
|
||||
|
||||
# Prune orphaned
|
||||
git worktree prune
|
||||
|
||||
# Repair if corrupted
|
||||
git worktree repair
|
||||
|
||||
# Move worktree
|
||||
git worktree move old-path new-path
|
||||
|
||||
# Lock (prevent removal)
|
||||
git worktree lock path
|
||||
|
||||
# Unlock
|
||||
git worktree unlock path
|
||||
```
|
||||
|
||||
### Aliases
|
||||
|
||||
```bash
|
||||
# Add to ~/.gitconfig
|
||||
[alias]
|
||||
wt = worktree
|
||||
wtl = worktree list
|
||||
wta = "!f() { git worktree add ../$(basename $(pwd))-$1 -b $1; }; f"
|
||||
wtr = worktree remove
|
||||
wtp = worktree prune
|
||||
```
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
git wta feature-x # Creates ../myapp-feature-x
|
||||
git wtl # Lists all worktrees
|
||||
git wtr ../myapp-feature-x # Removes worktree
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
**Key Takeaways:**
|
||||
|
||||
1. **Use descriptive branch names** - Future you will thank you
|
||||
2. **Keep worktrees organized** - Consistent location pattern
|
||||
3. **Monitor disk space** - Limit active worktrees
|
||||
4. **Clean up regularly** - Don't hoard merged branches
|
||||
5. **Document team conventions** - Everyone follows same patterns
|
||||
6. **Optimize for performance** - Use pnpm, shared caches
|
||||
7. **Secure sensitive data** - Clean .env before removal
|
||||
8. **Automate repetitive tasks** - Scripts for common operations
|
||||
|
||||
**Remember:** Git worktrees are powerful tools for parallel development. Used well, they enhance productivity. Used poorly, they create chaos. Follow these best practices for worktree success!
|
||||
922
skills/devops/git-worktree-setup/data/troubleshooting.md
Normal file
922
skills/devops/git-worktree-setup/data/troubleshooting.md
Normal file
@@ -0,0 +1,922 @@
|
||||
# Git Worktree Troubleshooting Guide
|
||||
|
||||
Comprehensive troubleshooting for common git worktree issues, errors, and edge cases.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Creation Errors](#creation-errors)
|
||||
2. [Permission Issues](#permission-issues)
|
||||
3. [Corruption and Repair](#corruption-and-repair)
|
||||
4. [Branch Conflicts](#branch-conflicts)
|
||||
5. [Directory Issues](#directory-issues)
|
||||
6. [Performance Problems](#performance-problems)
|
||||
7. [Dependency Installation](#dependency-installation)
|
||||
8. [Git Operations](#git-operations)
|
||||
9. [Cleanup Issues](#cleanup-issues)
|
||||
10. [Advanced Debugging](#advanced-debugging)
|
||||
|
||||
---
|
||||
|
||||
## Creation Errors
|
||||
|
||||
### Error: "fatal: invalid reference"
|
||||
|
||||
**Full Error:**
|
||||
```
|
||||
fatal: invalid reference: feature-x
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Branch doesn't exist (typo or branch not created yet).
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Create new branch:**
|
||||
```bash
|
||||
git worktree add ../myapp-feature-x -b feature-x
|
||||
```
|
||||
|
||||
2. **Check branch name:**
|
||||
```bash
|
||||
git branch -a # List all branches
|
||||
git branch | grep feature # Search for branch
|
||||
```
|
||||
|
||||
3. **Track remote branch:**
|
||||
```bash
|
||||
git worktree add ../myapp-feature-x -b feature-x --track origin/feature-x
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "fatal: 'path' already exists"
|
||||
|
||||
**Full Error:**
|
||||
```
|
||||
fatal: '../myapp-feature-x' already exists
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Directory already exists at target path.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Remove directory:**
|
||||
```bash
|
||||
rm -rf ../myapp-feature-x
|
||||
git worktree add ../myapp-feature-x -b feature-x
|
||||
```
|
||||
|
||||
2. **Use different location:**
|
||||
```bash
|
||||
git worktree add ../myapp-feature-x-v2 -b feature-x
|
||||
```
|
||||
|
||||
3. **Check if it's a forgotten worktree:**
|
||||
```bash
|
||||
git worktree list # If not listed, safe to remove
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "fatal: 'branch' is already checked out"
|
||||
|
||||
**Full Error:**
|
||||
```
|
||||
fatal: 'feature-x' is already checked out at '/Users/connor/myapp-feature-x'
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Branch is already checked out in another worktree.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Navigate to existing worktree:**
|
||||
```bash
|
||||
git worktree list # Find existing worktree
|
||||
cd /path/to/existing/worktree
|
||||
```
|
||||
|
||||
2. **Remove existing worktree:**
|
||||
```bash
|
||||
git worktree remove /path/to/existing/worktree
|
||||
# Then create new one
|
||||
git worktree add ../myapp-feature-x feature-x
|
||||
```
|
||||
|
||||
3. **Use different branch:**
|
||||
```bash
|
||||
git worktree add ../myapp-feature-x-new -b feature-x-new
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "fatal: not a git repository"
|
||||
|
||||
**Full Error:**
|
||||
```
|
||||
fatal: not a git repository (or any of the parent directories): .git
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Not in a git repository.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Navigate to repository:**
|
||||
```bash
|
||||
cd /path/to/your/git/repo
|
||||
git worktree add ../worktree-name -b branch-name
|
||||
```
|
||||
|
||||
2. **Verify git repository:**
|
||||
```bash
|
||||
git status # Should not error
|
||||
ls -la .git # Should exist
|
||||
```
|
||||
|
||||
3. **Initialize if needed:**
|
||||
```bash
|
||||
git init # Only if starting new repo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Permission Issues
|
||||
|
||||
### Error: "Permission denied"
|
||||
|
||||
**Full Error:**
|
||||
```
|
||||
error: unable to create file: Permission denied
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Insufficient permissions to create worktree directory.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Check parent directory permissions:**
|
||||
```bash
|
||||
ls -ld $(dirname /path/to/worktree)
|
||||
```
|
||||
|
||||
2. **Fix permissions:**
|
||||
```bash
|
||||
chmod 755 /path/to/parent
|
||||
```
|
||||
|
||||
3. **Use location you own:**
|
||||
```bash
|
||||
git worktree add ~/worktrees/myapp-feature-x -b feature-x
|
||||
```
|
||||
|
||||
4. **Check disk quota:**
|
||||
```bash
|
||||
df -h # Check disk space
|
||||
quota -s # Check user quota (if applicable)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Operation not permitted"
|
||||
|
||||
**Cause:**
|
||||
macOS security restrictions or readonly filesystem.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Grant Full Disk Access:**
|
||||
- System Preferences → Security & Privacy → Privacy
|
||||
- Full Disk Access → Add Terminal/IDE
|
||||
|
||||
2. **Check filesystem mount:**
|
||||
```bash
|
||||
mount | grep "$(pwd)"
|
||||
# If shows 'ro' (readonly), remount:
|
||||
# sudo mount -uw /
|
||||
```
|
||||
|
||||
3. **Use different location:**
|
||||
```bash
|
||||
# Use home directory (always writable)
|
||||
git worktree add ~/worktrees/myapp-feature-x -b feature-x
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Corruption and Repair
|
||||
|
||||
### Error: "Worktree path doesn't exist but listed"
|
||||
|
||||
**Symptoms:**
|
||||
```
|
||||
git worktree list
|
||||
# Shows: /path/to/missing/worktree abc123 [branch]
|
||||
# But: ls /path/to/missing/worktree
|
||||
# No such file or directory
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Worktree directory manually deleted without `git worktree remove`.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Prune orphaned references:**
|
||||
```bash
|
||||
git worktree prune
|
||||
git worktree list # Verify removed
|
||||
```
|
||||
|
||||
2. **Force remove:**
|
||||
```bash
|
||||
git worktree remove --force /path/to/missing/worktree
|
||||
```
|
||||
|
||||
3. **Manual cleanup:**
|
||||
```bash
|
||||
# Check administrative files
|
||||
ls .git/worktrees/
|
||||
# Remove specific worktree directory
|
||||
rm -rf .git/worktrees/branch-name
|
||||
git worktree prune
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Corrupt worktree"
|
||||
|
||||
**Symptoms:**
|
||||
- Can't checkout files
|
||||
- Git commands fail in worktree
|
||||
- Missing .git file in worktree
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Repair worktree:**
|
||||
```bash
|
||||
git worktree repair
|
||||
```
|
||||
|
||||
2. **Check .git file:**
|
||||
```bash
|
||||
cat worktree-path/.git
|
||||
# Should show: gitdir: /path/to/main/.git/worktrees/branch
|
||||
```
|
||||
|
||||
3. **Recreate .git file:**
|
||||
```bash
|
||||
# If corrupt, recreate
|
||||
echo "gitdir: $(git rev-parse --git-dir)/worktrees/branch-name" > worktree-path/.git
|
||||
```
|
||||
|
||||
4. **Last resort - recreate worktree:**
|
||||
```bash
|
||||
# Backup any changes
|
||||
cp -r worktree-path worktree-path-backup
|
||||
|
||||
# Remove and recreate
|
||||
git worktree remove --force worktree-path
|
||||
git worktree add worktree-path branch-name
|
||||
|
||||
# Restore changes
|
||||
cp worktree-path-backup/* worktree-path/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Branch Conflicts
|
||||
|
||||
### Error: "Cannot delete branch checked out in worktree"
|
||||
|
||||
**Full Error:**
|
||||
```
|
||||
error: Cannot delete branch 'feature-x' checked out at '/path/to/worktree'
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Trying to delete branch that's checked out in a worktree.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Remove worktree first:**
|
||||
```bash
|
||||
git worktree remove /path/to/worktree
|
||||
git branch -d feature-x
|
||||
```
|
||||
|
||||
2. **Force delete (if sure):**
|
||||
```bash
|
||||
# This will remove worktree administrative files
|
||||
git worktree remove --force /path/to/worktree
|
||||
git branch -D feature-x
|
||||
```
|
||||
|
||||
3. **Switch branch in worktree:**
|
||||
```bash
|
||||
cd /path/to/worktree
|
||||
git checkout different-branch
|
||||
# Now can delete feature-x in main repo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Reference is not a tree"
|
||||
|
||||
**Full Error:**
|
||||
```
|
||||
fatal: reference is not a tree: abc123
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Commit reference doesn't exist or is corrupted.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Fetch latest:**
|
||||
```bash
|
||||
git fetch --all
|
||||
git worktree add ../worktree branch-name
|
||||
```
|
||||
|
||||
2. **Use specific commit:**
|
||||
```bash
|
||||
git worktree add ../worktree commit-hash
|
||||
```
|
||||
|
||||
3. **Check object exists:**
|
||||
```bash
|
||||
git cat-file -t abc123 # Should show 'commit'
|
||||
git fsck # Check repository health
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Directory Issues
|
||||
|
||||
### Error: "Disk quota exceeded"
|
||||
|
||||
**Full Error:**
|
||||
```
|
||||
error: unable to create file: Disk quota exceeded
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Not enough disk space or quota exceeded.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Check disk space:**
|
||||
```bash
|
||||
df -h
|
||||
du -sh /path/to/worktrees
|
||||
```
|
||||
|
||||
2. **Clean up old worktrees:**
|
||||
```bash
|
||||
git worktree list
|
||||
git worktree remove /path/to/old/worktree
|
||||
```
|
||||
|
||||
3. **Clean build artifacts:**
|
||||
```bash
|
||||
cd worktree
|
||||
rm -rf node_modules dist build .next
|
||||
npm install # Reinstall only what's needed
|
||||
```
|
||||
|
||||
4. **Use different partition:**
|
||||
```bash
|
||||
git worktree add /other/partition/worktree -b branch
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Worktree directory not empty"
|
||||
|
||||
**Symptoms:**
|
||||
Directory exists with files but not a git worktree.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Remove conflicting directory:**
|
||||
```bash
|
||||
# Backup if needed
|
||||
mv /path/to/directory /path/to/directory-backup
|
||||
|
||||
# Create worktree
|
||||
git worktree add /path/to/directory -b branch
|
||||
```
|
||||
|
||||
2. **Merge contents:**
|
||||
```bash
|
||||
# Create worktree elsewhere
|
||||
git worktree add /temp/location -b branch
|
||||
|
||||
# Copy existing files
|
||||
cp -r /path/to/directory/* /temp/location/
|
||||
|
||||
# Move worktree
|
||||
git worktree move /temp/location /path/to/directory
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Problems
|
||||
|
||||
### Problem: "Slow git operations in worktree"
|
||||
|
||||
**Symptoms:**
|
||||
- `git status` takes 10+ seconds
|
||||
- `git checkout` is very slow
|
||||
- High CPU usage
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Check filesystem performance:**
|
||||
```bash
|
||||
# Test read speed
|
||||
time cat large-file.txt > /dev/null
|
||||
|
||||
# Test write speed
|
||||
time dd if=/dev/zero of=test.img bs=1M count=1024
|
||||
```
|
||||
|
||||
2. **Disable status optimizations:**
|
||||
```bash
|
||||
# If on network drive
|
||||
git config core.fsmonitor false
|
||||
git config core.untrackedCache false
|
||||
```
|
||||
|
||||
3. **Use sparse checkout:**
|
||||
```bash
|
||||
git sparse-checkout init --cone
|
||||
git sparse-checkout set src/ tests/
|
||||
```
|
||||
|
||||
4. **Move to local disk:**
|
||||
```bash
|
||||
# Network drives are slow
|
||||
git worktree add ~/local-worktrees/feature-x -b feature-x
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Problem: "High disk usage"
|
||||
|
||||
**Symptoms:**
|
||||
- Each worktree uses 1GB+
|
||||
- Running out of disk space
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Use pnpm:**
|
||||
```bash
|
||||
npm install -g pnpm
|
||||
# pnpm uses content-addressable storage
|
||||
# Saves ~70% disk space for node_modules
|
||||
```
|
||||
|
||||
2. **Share node_modules:**
|
||||
```bash
|
||||
# In main repo
|
||||
pnpm install
|
||||
|
||||
# In worktree
|
||||
pnpm install --prefer-offline
|
||||
# Uses shared cache
|
||||
```
|
||||
|
||||
3. **Clean build artifacts:**
|
||||
```bash
|
||||
# Add to package.json
|
||||
"scripts": {
|
||||
"clean": "rm -rf dist build .next coverage"
|
||||
}
|
||||
|
||||
# Run before removing worktree
|
||||
npm run clean
|
||||
```
|
||||
|
||||
4. **Limit worktrees:**
|
||||
```bash
|
||||
# Keep only 3-4 active worktrees
|
||||
# Remove old ones regularly
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependency Installation
|
||||
|
||||
### Error: "npm install fails in worktree"
|
||||
|
||||
**Symptoms:**
|
||||
```
|
||||
npm ERR! code ENOENT
|
||||
npm ERR! syscall open
|
||||
npm ERR! path /path/to/worktree/package.json
|
||||
```
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Verify package.json exists:**
|
||||
```bash
|
||||
ls -la worktree-path/package.json
|
||||
```
|
||||
|
||||
2. **Check file permissions:**
|
||||
```bash
|
||||
chmod 644 worktree-path/package.json
|
||||
```
|
||||
|
||||
3. **Copy from main repo:**
|
||||
```bash
|
||||
cp main-repo/package.json worktree-path/
|
||||
cp main-repo/package-lock.json worktree-path/
|
||||
```
|
||||
|
||||
4. **Reinstall:**
|
||||
```bash
|
||||
cd worktree-path
|
||||
rm -rf node_modules package-lock.json
|
||||
npm install
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Lockfile conflict"
|
||||
|
||||
**Symptoms:**
|
||||
```
|
||||
npm ERR! Cannot read property 'match' of undefined
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Lockfile from different package manager or corrupted.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Match package manager:**
|
||||
```bash
|
||||
# Check main repo
|
||||
ls main-repo/*lock*
|
||||
|
||||
# If pnpm-lock.yaml:
|
||||
pnpm install
|
||||
|
||||
# If yarn.lock:
|
||||
yarn install
|
||||
|
||||
# If package-lock.json:
|
||||
npm install
|
||||
```
|
||||
|
||||
2. **Remove and regenerate:**
|
||||
```bash
|
||||
rm package-lock.json
|
||||
npm install # Creates fresh lockfile
|
||||
```
|
||||
|
||||
3. **Copy lockfile from main:**
|
||||
```bash
|
||||
cp main-repo/package-lock.json worktree/
|
||||
npm ci # Clean install from lockfile
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Git Operations
|
||||
|
||||
### Error: "Cannot merge in worktree"
|
||||
|
||||
**Symptoms:**
|
||||
```
|
||||
error: Your local changes would be overwritten by merge
|
||||
```
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Commit or stash changes:**
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "WIP: save changes"
|
||||
# Or:
|
||||
git stash push -m "WIP before merge"
|
||||
```
|
||||
|
||||
2. **Merge with strategy:**
|
||||
```bash
|
||||
git merge --no-commit --no-ff branch-name
|
||||
# Review changes, then commit
|
||||
```
|
||||
|
||||
3. **Rebase instead:**
|
||||
```bash
|
||||
git rebase main
|
||||
# Replay commits on top of main
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Detached HEAD in worktree"
|
||||
|
||||
**Symptoms:**
|
||||
```
|
||||
You are in 'detached HEAD' state
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Checked out specific commit instead of branch.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Create branch from current state:**
|
||||
```bash
|
||||
git checkout -b new-branch-name
|
||||
```
|
||||
|
||||
2. **Checkout existing branch:**
|
||||
```bash
|
||||
git checkout branch-name
|
||||
```
|
||||
|
||||
3. **Return to main branch:**
|
||||
```bash
|
||||
git checkout main
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cleanup Issues
|
||||
|
||||
### Error: "Cannot remove worktree - dirty"
|
||||
|
||||
**Full Error:**
|
||||
```
|
||||
error: repository is dirty, please commit or stash your changes
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Worktree has uncommitted changes.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Commit changes:**
|
||||
```bash
|
||||
cd worktree-path
|
||||
git add .
|
||||
git commit -m "Final changes before removal"
|
||||
git push # Push if needed
|
||||
|
||||
# Now remove
|
||||
git worktree remove $(pwd)
|
||||
```
|
||||
|
||||
2. **Stash changes:**
|
||||
```bash
|
||||
cd worktree-path
|
||||
git stash push -m "Saved before worktree removal"
|
||||
# Stash is available in main repo
|
||||
|
||||
git worktree remove $(pwd)
|
||||
```
|
||||
|
||||
3. **Force remove (lose changes):**
|
||||
```bash
|
||||
git worktree remove --force worktree-path
|
||||
# ⚠️ WARNING: All uncommitted changes lost!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Worktree locked"
|
||||
|
||||
**Full Error:**
|
||||
```
|
||||
error: 'worktree-path' is locked; use 'unlock' to override, or 'remove --force'
|
||||
```
|
||||
|
||||
**Cause:**
|
||||
Worktree manually locked to prevent removal.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Unlock and remove:**
|
||||
```bash
|
||||
git worktree unlock worktree-path
|
||||
git worktree remove worktree-path
|
||||
```
|
||||
|
||||
2. **Force remove:**
|
||||
```bash
|
||||
git worktree remove --force worktree-path
|
||||
```
|
||||
|
||||
3. **Check why locked:**
|
||||
```bash
|
||||
cat .git/worktrees/branch-name/locked
|
||||
# Shows reason for lock
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced Debugging
|
||||
|
||||
### Diagnostic Commands
|
||||
|
||||
**Check worktree health:**
|
||||
```bash
|
||||
# List all worktrees
|
||||
git worktree list
|
||||
|
||||
# Check git database
|
||||
git fsck
|
||||
|
||||
# Verify repository integrity
|
||||
git status
|
||||
git branch -vv
|
||||
|
||||
# Check worktree administrative files
|
||||
ls -la .git/worktrees/
|
||||
|
||||
# Detailed worktree info
|
||||
git worktree list --porcelain
|
||||
```
|
||||
|
||||
**Debug specific worktree:**
|
||||
```bash
|
||||
cd worktree-path
|
||||
|
||||
# Check git configuration
|
||||
git config --list --local
|
||||
|
||||
# Check remote tracking
|
||||
git branch -vv
|
||||
|
||||
# Check what's tracked
|
||||
git ls-files
|
||||
|
||||
# Check for corruption
|
||||
git fsck --full
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Enable Debug Logging
|
||||
|
||||
**Git verbose mode:**
|
||||
```bash
|
||||
GIT_TRACE=1 git worktree add ../debug -b debug
|
||||
# Shows all git commands executed
|
||||
```
|
||||
|
||||
**Trace specific operations:**
|
||||
```bash
|
||||
# Trace file operations
|
||||
GIT_TRACE_PACK_ACCESS=1 git status
|
||||
|
||||
# Trace setup
|
||||
GIT_TRACE_SETUP=1 git worktree list
|
||||
|
||||
# Trace performance
|
||||
GIT_TRACE_PERFORMANCE=1 git status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Recovery Procedures
|
||||
|
||||
**Recover deleted worktree:**
|
||||
```bash
|
||||
# If worktree removed but branch still exists
|
||||
git worktree add ../recovered branch-name
|
||||
|
||||
# If branch deleted too
|
||||
git reflog # Find commit
|
||||
git worktree add ../recovered commit-hash
|
||||
git checkout -b branch-name
|
||||
```
|
||||
|
||||
**Recover from backup:**
|
||||
```bash
|
||||
# If you have time machine / backup
|
||||
cp -r /backup/path/to/worktree /current/path/
|
||||
|
||||
# Repair git references
|
||||
git worktree repair
|
||||
```
|
||||
|
||||
**Nuclear option - start fresh:**
|
||||
```bash
|
||||
# Backup important changes
|
||||
cp -r worktree-path/src ~/backup/
|
||||
|
||||
# Remove all worktrees
|
||||
git worktree list | grep -v "$(git rev-parse --show-toplevel)" | \
|
||||
awk '{print $1}' | xargs -I{} git worktree remove --force {}
|
||||
|
||||
# Clean up administrative files
|
||||
git worktree prune
|
||||
|
||||
# Recreate from scratch
|
||||
git worktree add ../fresh-start branch-name
|
||||
|
||||
# Restore backed up changes
|
||||
cp -r ~/backup/* ../fresh-start/src/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
### Before Asking for Help
|
||||
|
||||
**Collect diagnostic information:**
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# worktree-diagnostics.sh
|
||||
|
||||
echo "=== Git Version ==="
|
||||
git --version
|
||||
|
||||
echo -e "\n=== Worktree List ==="
|
||||
git worktree list
|
||||
|
||||
echo -e "\n=== Repository Status ==="
|
||||
git status
|
||||
|
||||
echo -e "\n=== Branch Info ==="
|
||||
git branch -vv
|
||||
|
||||
echo -e "\n=== Remote Info ==="
|
||||
git remote -v
|
||||
|
||||
echo -e "\n=== Worktree Admin Files ==="
|
||||
ls -la .git/worktrees/
|
||||
|
||||
echo -e "\n=== Disk Space ==="
|
||||
df -h .
|
||||
|
||||
echo -e "\n=== File Permissions ==="
|
||||
ls -ld .git
|
||||
ls -ld .git/worktrees/
|
||||
|
||||
# Save to file
|
||||
# ./worktree-diagnostics.sh > diagnostics.txt
|
||||
```
|
||||
|
||||
### Common Support Channels
|
||||
|
||||
- **Git Documentation:** `git help worktree`
|
||||
- **GitHub Issues:** Check git/git repository
|
||||
- **Stack Overflow:** Tag: `git-worktree`
|
||||
- **Git Mailing List:** git@vger.kernel.org
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Most Common Issues
|
||||
|
||||
1. **Directory exists:** `rm -rf path && git worktree add path branch`
|
||||
2. **Branch checked out:** `git worktree remove old-path && git worktree add new-path branch`
|
||||
3. **Orphaned worktree:** `git worktree prune`
|
||||
4. **Permission denied:** `chmod 755 parent-dir`
|
||||
5. **Can't remove (dirty):** `git stash && git worktree remove path`
|
||||
|
||||
### Essential Commands
|
||||
|
||||
```bash
|
||||
# Diagnose
|
||||
git worktree list
|
||||
git fsck
|
||||
git worktree prune
|
||||
|
||||
# Repair
|
||||
git worktree repair
|
||||
git worktree unlock path
|
||||
|
||||
# Force operations (use with caution)
|
||||
git worktree remove --force path
|
||||
git branch -D branch-name
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Most git worktree issues fall into these categories:
|
||||
1. **Creation conflicts** - Directory or branch conflicts
|
||||
2. **Permission issues** - Filesystem restrictions
|
||||
3. **Corruption** - Manual deletions or crashes
|
||||
4. **Cleanup problems** - Uncommitted changes or locks
|
||||
|
||||
**General troubleshooting approach:**
|
||||
1. Read error message carefully
|
||||
2. Check `git worktree list` for current state
|
||||
3. Use `git worktree prune` to clean orphans
|
||||
4. Use `--force` flags only when necessary
|
||||
5. Document unusual issues for team
|
||||
|
||||
**Remember:** Git worktrees are just checkouts in different directories. Most git commands work the same way - when in doubt, treat it like a normal git repository!
|
||||
Reference in New Issue
Block a user