How Swarm Forge Creates and Manages Git Worktrees in the `.worktrees/` Directory
Swarm Forge automatically creates isolated Git worktrees under a hidden .worktrees/ directory for each agent role, with special handling for the master role that runs directly in the main repository checkout.
Swarm Forge uses Git worktrees to give each AI agent its own isolated working directory while sharing repository history. This architecture, implemented in the unclebob/swarm-forge repository, manages worktree lifecycle through Clojure functions in swarmforge/scripts/swarmforge.bb, handling path resolution, Git ignore management, creation, and validation.
Worktree Path Resolution
Swarm Forge builds worktree paths using the worktree-path-for-name helper function. This joins the configured worktrees-dir (.worktrees by default) with the role name.
(defn worktree-path-for-name [worktrees-dir worktree]
(fs/path worktrees-dir worktree))
This simple path construction is defined at swarmforge/scripts/swarmforge.bb lines 72–73. The function returns a java.nio.file.Path that feeds into both Git commands and tmux window configuration.
Git Ignore Configuration
Before creating any worktrees, Swarm Forge ensures Git never tracks the .worktrees/ directory. It updates two locations:
.gitignore— appends.worktrees/for general repository hygiene.git/info/exclude— adds.worktrees/to the local exclude file
(spit (str gitignore) ".swarmforge/\n.worktrees/\n")
(ensure-in-file! exclude-file ".worktrees/")
These writes happen at lines 111–120 of swarmforge/scripts/swarmforge.bb. The dual approach ensures the directory stays hidden regardless of .gitignore sharing practices.
Creating Worktrees with prepare-worktrees!
The prepare-worktrees! function orchestrates worktree creation during system startup. It iterates over every role defined in the configuration and executes git worktree add for each non-special role.
(defn prepare-worktrees! [ctx]
;; ctx contains :worktrees-dir pointing at ".worktrees"
...)
For a role named coder, the equivalent shell command is:
git worktree add .worktrees/coder origin/main
This creation logic spans lines 321–327. After successful creation, each worktree name is added to an in-memory worktrees set for duplicate detection.
Validating Worktree Assignments
Each tmux window definition may specify a worktree name. Swarm Forge validates these declarations to prevent multiple windows from accidentally sharing the same worktree.
(reject-if (and (not (special-worktree? worktree))
(contains? worktrees worktree))
...)
The validation at lines 172–179 rejects duplicate non-special worktrees. A worktree is either:
- Already registered — known from
prepare-worktrees! - Newly added — first mention triggers registration
This ensures one-to-one mapping between windows and worktree directories.
Special Handling for the master Worktree
The master worktree (and none) are special cases. Swarm Forge never creates a .worktrees/master directory. Instead, the agent works directly in the main project checkout on its current branch.
As documented in README.md lines 191–199 and swarmforge/constitution/articles/workflow.prompt lines 5–6:
"If your assigned worktree is
master, work in the main project checkout on its current branch; do not expect or create a.worktrees/<role>directory for that role."
(if (special-worktree? "master")
(println "Use main repo checkout – no worktree needed")
(create-worktree! ctx "master"))
This design lets the orchestrator or master agent operate on the primary branch without worktree overhead.
Complete Worktree Lifecycle Example
;; 1. Path resolution
(let [role "coder"
wt-path (worktree-path-for-name ".worktrees" role)]
;; 2. Git worktree creation
(shell/sh "git" "worktree" "add" wt-path "origin/main")
;; 3. Registration for duplicate detection
(swap! worktrees conj role))
;; 4. Window parsing validates the worktree reference
(parse-window-line ctx 42
"coder\tcoder\t${project}/.worktrees/coder\tcoder\tCoder\tcodex\ttask"
role-config
@worktrees)
Key Source Files
| File | Purpose |
|---|---|
swarmforge/scripts/swarmforge.bb |
Core functions: worktree-path-for-name, prepare-worktrees!, validation logic |
README.md |
User-facing documentation of worktree behavior and master exception |
swarmforge/constitution/articles/workflow.prompt |
Constitutional rule defining special worktree handling |
test/swarmforge/*.clj |
Unit tests for creation, duplicate detection, and edge cases |
Summary
- Path construction:
worktree-path-for-namejoins.worktrees/with role names - Git hygiene:
.worktrees/is added to both.gitignoreand.git/info/exclude - Creation:
prepare-worktrees!runsgit worktree addfor each non-special role - Validation: Window parsing prevents duplicate worktree assignments
- Special case:
masterruns in main checkout; no.worktrees/masterdirectory is created
Frequently Asked Questions
How does Swarm Forge prevent Git from tracking worktree directories?
Swarm Forge writes .worktrees/ to both .gitignore and .git/info/exclude during startup. This dual coverage ensures the directory remains untracked even if .gitignore is later removed or overridden, as implemented in swarmforge/scripts/swarmforge.bb lines 111–120.
What happens if two windows request the same worktree name?
The parse-window-line function rejects the configuration with an error. It maintains a worktrees set tracking all non-special worktree names, and throws if a duplicate is detected. This validation runs at lines 172–179 of the main script.
Why doesn't the master role get its own worktree directory?
The master role operates directly in the main repository checkout to simplify orchestration and avoid unnecessary Git overhead. This behavior is hardcoded as a special case in special-worktree? and documented in both the README and constitution prompt files.
Can I customize the .worktrees/ directory location?
Yes—the :worktrees-dir key in the context map controls the base directory. The default is .worktrees relative to project root, but this can be overridden in configuration before prepare-worktrees! executes.
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 →