Skip to content

Instantly share code, notes, and snippets.

@ben-vargas
Last active October 16, 2025 13:27
Show Gist options
  • Save ben-vargas/fd99be9bbce6d485c70442dd939f1a3d to your computer and use it in GitHub Desktop.
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.

Clone a GitHub repository using the bare repository worktree workflow.

This command sets up a new project with the bare Git repository approach where every subdirectory represents a different Git branch as a worktree.

Usage

/worktree-clone <project-name> <github-url>

Parameters

What this command does

When invoked, perform the following steps:

  1. Parse arguments: Extract project name and GitHub URL from $ARGUMENTS
  2. Create project directory: mkdir -p <project-name>
  3. Clone bare repository: Navigate into the project directory and run:
    git clone --bare <github-url> .bare
  4. Create .git pointer: Create a file named .git with content gitdir: ./.bare
  5. Configure remote fetch: Run:
    git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
  6. Fetch from origin: git fetch origin
  7. Create main worktree: Run:
    git worktree add main main
  8. Set upstream tracking: Navigate into main/ and run:
    git branch --set-upstream-to=origin/main main
  9. Verify setup: Show the worktree list with git worktree list
  10. Display structure: Show the directory tree to confirm proper setup

Expected Result

project-name/
β”œβ”€β”€ .bare/          # Git repository database
β”œβ”€β”€ .git            # Pointer to .bare/
└── main/           # Worktree (branch: main)

Error Handling

  • If the project directory already exists, warn the user and ask if they want to proceed
  • If the GitHub URL is invalid or clone fails, report the error clearly
  • If the main branch doesn't exist, check for other default branches (master, develop)

Notes

  • All commands should be executed with proper error checking
  • Use chained commands where appropriate to minimize back-and-forth
  • Report progress and final status to the user
  • After setup, the user should navigate into <project-name>/main/ to start working

Create a new Git worktree in the current project using the bare repository worktree workflow.

This command creates a new worktree (branch) in the project root. Must be run from within a project that uses the bare repository structure.

Usage

/worktree-create <worktree-name> <base-branch>

Parameters

  • worktree-name: Name for the new worktree/branch (e.g., "feature-auth", "hotfix-login")
  • base-branch: Base branch to fork from (e.g., "main", "develop", "origin/feature-x")

What this command does

When invoked, perform the following steps:

  1. Verify project structure: Check that we're in a bare repository worktree project

    • Look for .bare/ directory or .git file pointing to .bare/
    • If not found, navigate up to find the project root
  2. Navigate to project root: Change to the directory containing .bare/

  3. Parse arguments: Extract worktree name and base branch from $ARGUMENTS

  4. Check if branch exists remotely: Run:

    git fetch origin
    git branch -r | grep "origin/<worktree-name>"
  5. Create worktree based on scenario:

    Scenario A - New branch (doesn't exist on remote):

    git worktree add <worktree-name> -b <worktree-name> <base-branch>
    cd <worktree-name> && git push -u origin <worktree-name> && cd ..

    Scenario B - Existing remote branch:

    git worktree add <worktree-name> <worktree-name>
    cd <worktree-name> && git branch --set-upstream-to=origin/<worktree-name> <worktree-name> && cd ..
  6. Verify creation: Show worktree list with git worktree list

  7. Display status: Show the new directory structure

Expected Result

After successful execution:

project-name/
β”œβ”€β”€ .bare/
β”œβ”€β”€ .git
β”œβ”€β”€ main/
β”œβ”€β”€ feature-auth/        # βœ… Newly created worktree
└── <worktree-name>/     # βœ… Your new worktree

Examples

Create a new feature branch from main:

/worktree-create feature-auth main

Create a hotfix from an existing branch:

/worktree-create hotfix-security feature-auth

Checkout an existing remote branch:

/worktree-create develop develop

Error Handling

  • If not in a bare repository project, show clear error message
  • If worktree name already exists locally, warn and ask if user wants to remove it first
  • If base branch doesn't exist, show available branches
  • If git fetch fails, report network/remote issues

Notes

  • Worktree management commands must be run from the project root (where .bare/ is located)
  • The worktree name becomes both the directory name and branch name
  • After creation, user should cd <worktree-name>/ to start working
  • Never use git checkout - always use worktrees to switch between branches
  • All worktrees need upstream tracking configured for push/pull to work
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment