Skip to content

Instantly share code, notes, and snippets.

@ben-vargas
Last active January 29, 2026 00:12
Show Gist options
  • Select an option

  • Save ben-vargas/fd99be9bbce6d485c70442dd939f1a3d to your computer and use it in GitHub Desktop.

Select an option

Save ben-vargas/fd99be9bbce6d485c70442dd939f1a3d to your computer and use it in GitHub Desktop.
Bare Git Worktrees AGENTS.md

Git Bare Repository Worktree Workflow for Claude Code

🚨 CRITICAL: Understanding My Project Structure

I use a bare Git repository approach with Git worktrees extensively. Every subdirectory in my projects represents a different git branch as a worktree.

When you see a project like /home/code/projects/my-app/:

  • my-app/ = project container (NOT a working tree)
  • my-app/.bare/ = actual Git repository database
  • my-app/.git = pointer file directing Git commands to .bare/
  • All other subdirectories = worktrees representing different branches

Typical Directory Structure

project-name/                # Project container (NOT a working tree)
β”œβ”€β”€ .bare/                   # πŸ—„οΈ  Bare git repository (the actual Git database)
β”œβ”€β”€ .git                     # πŸ”— Pointer file directing Git commands to .bare
β”œβ”€β”€ main/                    # βœ… Worktree (branch: main)
β”œβ”€β”€ feature-auth/            # βœ… Worktree (branch: feature-auth) 
└── hotfix-security/         # βœ… Worktree (branch: hotfix-security)

⚠️ Critical: Upstream Tracking & Remote Configuration

1. Verify Remote Configuration

Before setting up worktrees, ensure your remotes are properly configured:

git remote -v  # Check existing remotes

# If no origin exists (rare but possible):
git remote add origin <your-repo-url>

# For forked repositories, also add upstream:
git remote add upstream <original-repo-url>

2. Every Worktree Needs Upstream Tracking

EVERY worktree needs upstream tracking configured! Without this, git pull and git push will fail with "no tracking information" errors.

  • When creating new branches: Use git push -u origin branch-name
  • When adding worktrees for existing remote branches: Run git branch --set-upstream-to=origin/branch-name branch-name
  • This applies to ALL worktrees, not just main!

Initial Setup (New Projects)

# Clone and setup bare repository
git clone --bare <repository-url> .bare
echo "gitdir: ./.bare" > .git
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"

# For forked repositories, add upstream remote
git remote add upstream <original-repo-url>  # Only if this is a fork

# Fetch and create main worktree
git fetch origin
git worktree add main main
cd main && git branch --set-upstream-to=origin/main main && cd ..

Daily Workflow

  1. Navigate to branch: cd main/ or cd feature-auth/
  2. Work normally within each worktree directory
  3. Create worktrees from project root: git worktree add new-feature -b new-feature
  4. Switch branches by changing directories (never use git checkout)

Essential Commands

# Worktree management (from project root)

# For NEW branches (not on remote yet):
git worktree add branch-name -b branch-name main  # Create new
cd branch-name && git push -u origin branch-name && cd ..  # Push and set upstream

# For EXISTING remote branches:
git worktree add branch-name branch-name  # Create worktree
cd branch-name && git branch --set-upstream-to=origin/branch-name branch-name && cd ..

# Other commands:
git worktree remove branch-name                   # Remove
git worktree list                                 # List all
git worktree prune                               # Clean stale refs

# Verification
pwd && git status                                # Where am I?
git worktree list                                # Show all worktrees

# Custom scripts (available globally)
wt feature-name [base-branch]                    # Quick create + navigate
wt-status                                        # Status of all worktrees

# For forked repositories - sync with upstream
git fetch upstream                               # Get latest from original repo
cd main && git merge upstream/main && cd ..      # Update main from upstream

Important Guidelines for Claude Code

βœ… DO:

  • Run git worktree list from project root to see all worktrees
  • Navigate to correct worktree directory before making changes
  • Use branch names directly as directory names
  • Run worktree management (add/remove/list) from project root

❌ DON'T:

  • Don't run git commands from project root (except worktree management)
  • Don't use git checkout - change directories instead
  • Don't assume any directory is special - all worktrees are equal

Migration from Old Worktree Setup

To convert from old "main/ manages worktrees" approach:

# 1. Backup and identify structure
cp -r my-project my-project-backup
cd my-project && ls -la

# 2. Remove existing worktrees (from main/)
cd main/
git worktree list  # See what exists
git worktree remove ../feature-branch  # Remove all except main/

# 3. Create bare structure
cd .. && git clone --bare main/.git .bare
rm -rf main/.git && echo "gitdir: ./.bare" > .git

# 4. Configure and recreate worktrees
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch origin
mv main main-old && git worktree add main main
cd main && git branch --set-upstream-to=origin/main main && cd ..
# Copy uncommitted changes from main-old to main/
rm -rf main-old

# 5. Recreate other worktrees
git worktree add feature-branch feature-branch
cd feature-branch && git branch --set-upstream-to=origin/feature-branch feature-branch && cd ..

# 6. Verify
git worktree list && wt-status

Summary

Every subdirectory is a worktree representing a different branch. Project root contains bare repository for worktree management only. Navigate between branches by changing directories. All git operations happen within worktree directories.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment