Multi-Agent Git Worktree Workflow

Git worktrees let multiple agents work in parallel on the same repository without interfering with each other. Each worktree is a separate checkout backed by a shared .git database — no cloning, no extra disk for object storage.

How Worktrees Work

  • The primary repo ($REPO_ROOT) contains the .git/ directory.
  • Each worktree gets its own directory with a .git pointer file (not a directory) that references the shared database.
  • Each worktree must be on a different branch — Git enforces this.
  • Commits, branches, and refs are shared instantly across all worktrees.

Directory Layout

$REPO_ROOT/                     # Primary repo (main checkout)
├── .git/                       # Shared git database
├── icn/                        # Cargo workspace
└── ...

$REPO_ROOT/../icn-wt/           # Worktree workspace (sibling directory)
├── agent-a/                    # Worktree on feat/agent-a
│   ├── .git                    # Pointer file → $REPO_ROOT/.git/worktrees/agent-a
│   ├── icn/
│   └── ...
├── agent-b/                    # Worktree on feat/agent-b
└── agent-c/                    # Worktree on feat/agent-c

Rules

  1. One agent = one branch = one worktree. Never share a worktree between agents.
  2. Never commit to main. All work happens on feature branches.
  3. Use the root repo as a manager checkout. Keep $REPO_ROOT on a clean main and do edits/builds/tests in ../icn-wt/*.
  4. Keep one dedicated main worktree (for rebases/cherry-picks and fresh branch creation) plus feature worktrees.
  5. Isolate build output — set CARGO_TARGET_DIR per worktree (see below).

Recommended Operating Layout

  • $REPO_ROOT (manager): clean main, run git worktree commands, avoid day-to-day edits/builds.
  • ../icn-wt/main: tracked main worktree used as the branch source for new slices.
  • ../icn-wt/<pr-or-slice>: active feature worktrees for implementation and testing.

Rust Build Isolation

Each worktree has its own directory tree, so the default icn/target/ is already separate per worktree. However, if your environment sets a global CARGO_TARGET_DIR or the workspace config.toml specifies a shared build.target-dir, multiple agents will collide.

Check: if cargo metadata --format-version=1 | jq -r .target_directory returns a path outside the worktree, you need to override it:

# Force per-worktree target (only needed if a shared target is configured)
export CARGO_TARGET_DIR="$PWD/target"

Commands Reference

Create a worktree

# From primary repo root
git worktree add ../icn-wt/<agent-name> -b feat/<agent-name> origin/main

# Optional dedicated main worktree
git worktree add -B wt-main ../icn-wt/main origin/main

List worktrees

git worktree list

Remove a worktree

git worktree remove ../icn-wt/<agent-name>
# Then optionally delete the branch
git branch -d feat/<agent-name>

Prune stale worktree references

git worktree prune

Using the helper script

# Create
./scripts/worktrees.sh create <agent-name>

# List
./scripts/worktrees.sh list

# Remove
./scripts/worktrees.sh remove <agent-name>

Typical Agent Flow

# 1. Agent is assigned a worktree (already on its branch)
cd ../icn-wt/agent-a        # relative to $REPO_ROOT

# 2. Set build isolation
export CARGO_TARGET_DIR="$PWD/target"

# 3. Sync with latest main
git fetch origin
git rebase origin/main

# 4. Work — edit, build, test
cd icn
cargo build -p icn-gateway
cargo test -p icn-gateway

# 5. Commit (conventional commit format)
git add -A
git commit -m "feat(gateway): add rate limit headers"

# 6. Push and open PR
git push -u origin feat/agent-a
gh pr create --base main --title "feat(gateway): add rate limit headers"

Cleanup Checklist

When an agent's work is merged:

  • git worktree remove ../icn-wt/<agent-name> — remove the worktree
  • git branch -d feat/<agent-name> — delete the local branch
  • git push origin --delete feat/<agent-name> — delete the remote branch (if not auto-deleted by PR merge)
  • git worktree prune — clean up stale refs
  • Remove any per-worktree target/ directory if disk space is needed
  • cd ../icn-wt/main && git pull --ff-only — keep the dedicated main worktree current

Line Endings

This repo enforces LF everywhere via .gitattributes (* text=auto eol=lf). If you see phantom diffs (files showing as modified with no real content changes), the cause is usually CRLF contamination.

Prevention:

  • Windows: set git config core.autocrlf false and let .gitattributes handle normalization
  • Editors: configure to save files with LF line endings
  • If phantom diffs appear: run git add --renormalize . and commit the result