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/coderarchitect→ worktree created at.worktrees/architectcoordinator→ 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:
- Creates the directory
.worktrees/<name> - Establishes a dedicated branch
swarmforge-<name>tracking currentHEAD - Uses
--forceto 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.bbscript automates the entire lifecycle from path resolution through Git registration - Worktrees are created with
git worktree add --forceon dedicatedswarmforge-<name>branches - Version control exclusion is enforced in both
.gitignoreand 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →