How SwarmForge Manages Git Worktrees Under the `.worktrees/` Directory

SwarmForge treats each role in a swarm as a separate Git worktree stored in .worktrees/, using the swarmforge.bb script to automate creation, registration, and synchronization while keeping worktrees ignored from version control.

SwarmForge is a multi-agent orchestration framework by Uncle Bob that isolates different AI roles into dedicated Git worktrees. Understanding how SwarmForge manages git worktrees under the .worktrees/ directory reveals the foundation of its role-based isolation architecture.

Worktree Lifecycle Management

The entire worktree lifecycle is orchestrated through swarmforge/scripts/swarmforge.bb. This single script handles discovery, creation, Git registration, and runtime setup for every role-specific worktree.

Defining the Worktrees Root

SwarmForge establishes a central location for all worktree metadata. In swarmforge.bb at line 469, the script stores the path to the hidden worktrees directory in the runtime context:

:worktrees-dir (fs/path project-root ".worktrees")

This becomes the anchor point for all subsequent worktree operations.

Building Worktree Paths

The helper function worktree-path-for-name (lines 71-73) constructs absolute paths for any given worktree name:

(defn worktree-path-for-name [ctx name]
  (fs/path (:worktrees-dir ctx) name))

This ensures consistent path resolution across all worktree operations.

Configuration-Driven Worktree Discovery

SwarmForge parses swarmforge.conf to determine which roles receive dedicated worktrees. During configuration parsing (lines 175-183), each role entry yields a worktree name.

Roles configured with worktree names other than master or none trigger worktree creation:

window coder  codex  coder
window architect  claude  architect
window coordinator  codex  master

In this example:

  • coder → worktree created at .worktrees/coder
  • architect → worktree created at .worktrees/architect
  • coordinator → no worktree; runs in main project directory

Creating and Registering Git Worktrees

The prepare-worktrees! function (lines 251-260) executes the actual Git commands to register each worktree:

git -C /path/to/project worktree add --force -B swarmforge-coder \
    /path/to/project/.worktrees/coder HEAD

This command:

  1. Creates the directory .worktrees/<name>
  2. Establishes a dedicated branch swarmforge-<name> tracking current HEAD
  3. Uses --force to allow re-creation if the worktree already exists

Preventing Accidental Commits

SwarmForge actively prevents .worktrees/ from entering version control. The ensure-worktrees-ignored! function (lines 107-114) writes the entry to both .gitignore and Git's internal exclude file:


# Added to .gitignore and .git/info/exclude

.worktrees/

This dual protection ensures worktree metadata never appears in diffs or commits.

Synchronizing Shared Resources

After creation, sync-worktree-scripts! (lines 70-85) copies the shared swarmforge/scripts/ directory into each worktree. This allows every agent to execute helper scripts locally without cross-worktree dependencies.

Per-Worktree Runtime Isolation

The prepare-handoff-dirs! function (lines 61-64) creates isolated runtime directories inside each worktree:

(fs/create-dirs (fs/path worktree-path ".swarmforge" "handoffs" "outbox"))
(fs/create-dirs (fs/path worktree-path ".swarmforge" "handoffs" "inbox"))

This keeps handoff state completely separated between roles while maintaining a consistent structure.

Complete Context Example

After parsing configuration and preparing worktrees, the runtime context contains structured worktree metadata:

{:worktrees-dir (fs/path "/project" ".worktrees")
 :roles [{:role "coder"
          :worktree-name "coder"
          :worktree-path (fs/path "/project/.worktrees/coder")}
         {:role "coordinator"
          :worktree-name "master"
          :worktree-path (fs/path "/project")}]}

Summary

  • SwarmForge uses .worktrees/ as a hidden directory containing one subdirectory per non-master role
  • The swarmforge.bb script automates the entire lifecycle from path resolution through Git registration
  • Worktrees are created with git worktree add --force on dedicated swarmforge-<name> branches
  • Version control exclusion is enforced in both .gitignore and Git's internal exclude file
  • Shared scripts and runtime directories are synchronized into each worktree after creation

Frequently Asked Questions

What happens if a role uses "master" as its worktree name?

The role runs directly in the main project directory without creating a separate worktree. The prepare-worktrees! function explicitly skips entries where worktree-name equals "master" or "none", treating the project root as the execution context.

Can multiple roles share the same worktree?

No. Each role with a unique worktree name receives its own isolated directory under .worktrees/. The worktree-path-for-name function generates distinct paths for every name, and Git worktrees enforce that no two worktrees can point to the same path.

Why does SwarmForge use --force when adding worktrees?

The --force flag allows the script to be idempotent. If a worktree already exists from a previous run, the command recreates it cleanly rather than failing. This supports iterative development and recovery from interrupted sessions.

What files exist inside a prepared worktree?

Each worktree contains a full Git checkout at the HEAD commit, a copy of swarmforge/scripts/ for local execution, and a .swarmforge/handoffs/ subdirectory with inbox/, outbox/, public/, and archive/ folders for agent communication.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →