How two AI agents work on navbar and footer simultaneously without stepping on each other
A git worktree is a separate working directory attached to the same repository.
Each worktree has its own set of files on disk and its own branch checked out — but they all
share a single .git folder. This means commits appear instantly everywhere.
~/project/ ← Main repo (this is also a worktree) ├── .git/ ← The ONE shared repository (contains all branches, commits) ├── src/ │ ├── layout.tsx ← Shared components (both agents may touch this!) │ ├── navbar.tsx │ └── footer.tsx ├── package.json └── styles.css ← DANGER ZONE: both agents might edit this ~/project-navbar/ ← Worktree #1 for AI Agent 1 ├── .git ← This is a FILE (not folder), points to ~/project/.git ├── src/ │ ├── navbar.tsx ← Agent 1 editing this file │ └── ... └── [branch: feature/navbar] ~/project-footer/ ← Worktree #2 for AI Agent 2 ├── .git ← This is a FILE (not folder), points to ~/project/.git ├── src/ │ ├── footer.tsx ← Agent 2 editing this file │ └── ... └── [branch: feature/footer]
flowchart TD
subgraph SETUP["Setup"]
S1["main worktree\n~/project/"] --> S2["create 2 worktrees"]
S2 --> S3["~/project-navbar/\nbranch: feature/navbar"]
S2 --> S4["~/project-footer/\nbranch: feature/footer"]
end
subgraph PARALLEL["Parallel Work (agents run at same time)"]
S3 --> A1["Agent 1 edits\nsrc/navbar.tsx"]
S4 --> A2["Agent 2 edits\nsrc/footer.tsx"]
A1 --> A1c["Commits on\nfeature/navbar"]
A2 --> A2c["Commits on\nfeature/footer"]
end
subgraph MERGE["Merge (from main worktree)"]
A1c --> M1["git merge\nfeature/navbar"]
A2c --> M2["git merge\nfeature/footer"]
M1 --> M1r{"Conflict?"}
M2 --> M2r{"Conflict?"}
end
subgraph CONFLICT["Conflict Resolution"]
M1r -->|"No conflicts\n(different files)"| OK1["Clean merge"]
M2r -->|"No conflicts\n(different files)"| OK2["Clean merge"]
M1r -->|"YES\n(styles.css edited by both)"| RESOLVE["Manually resolve\nmerge conflicts\nin shared files"]
M2r -->|"YES\n(styles.css edited by both)"| RESOLVE
RESOLVE --> FINAL["Commit merge\nresolution"]
end
subgraph CLEANUP["Clean Up"]
OK1 --> RM["git worktree remove\n~/project-navbar\n~/project-footer"]
OK2 --> RM2["git branch -d\nfeature/navbar\nfeature/footer"]
end
style SETUP fill:#bd93f922,stroke:#bd93f9,stroke-width:1px
style PARALLEL fill:#50fa7b22,stroke:#50fa7b,stroke-width:1px
style MERGE fill:#8be9fd22,stroke:#8be9fd,stroke-width:1px
style CONFLICT fill:#ffb86c22,stroke:#ffb86c,stroke-width:1px
style CLEANUP fill:#6272a422,stroke:#6272a4,stroke-width:1px
flowchart LR
subgraph BEFORE["Before"]
ORIG["styles.css\n(original)"]
end
subgraph P1["Agent 1: Navbar"]
N["styles.css\n.navbar { ... }\n.nav-links { ... }"]
end
subgraph P2["Agent 2: Footer"]
F["styles.css\n.footer { ... }\n.social-icons { ... }"]
end
ORIG -->|"branch"| N
ORIG -->|"branch"| F
N -->|"merge first (clean)"| MERGED["styles.css\n.navbar { ... }\n.nav-links { ... }"]
F -->|"merge second"| CONFLICT["CONFLICT!\nGit can't auto-merge\nbecause both changed\nsame file"]
MERGED -->|"is the base now"| CONFLICT
CONFLICT --> RESOLVE["You resolve manually:\nkeep nav styles + footer styles\nthen git add + commit"]
style BEFORE fill:#6272a422,stroke:#6272a4,stroke-width:1px
style P1 fill:#50fa7b22,stroke:#50fa7b,stroke-width:1px
style P2 fill:#bd93f922,stroke:#bd93f9,stroke-width:1px
style CONFLICT fill:#ff555522,stroke:#ff5555,stroke-width:2px
style RESOLVE fill:#ffb86c22,stroke:#ffb86c,stroke-width:1px
flowchart TD
W1["1. CREATE worktrees\n(once, before agents start)"] -->|" "| C1
W1 -->|" "| C2
C1["git worktree add -b feature/navbar\n../project-navbar main"]
C2["git worktree add -b feature/footer\n../project-footer main"]
W2["2. AGENTS WORK\n(point each AI at its directory)"] -->|" "| D1
W2 -->|" "| D2
D1["AI Agent 1 → ~/project-navbar/\nworks on navbar.tsx\ncommits to feature/navbar"]
D2["AI Agent 2 → ~/project-footer/\nworks on footer.tsx\ncommits to feature/footer"]
W3["3. MERGE\n(from main project)"] -->|" "| M1_
M1_["git merge feature/navbar"]
M1_ -->|"clean (different files)"| M2_
M2_["git merge feature/footer"]
W4["4. IF CONFLICT\n(e.g. both edited styles.css)"] -->|" "| R1
R1["git shows <<<<<<< markers\nmanually fix the file\ngit add styles.css\ngit merge --continue"]
W5["5. CLEAN UP"] -->|" "| CL1
CL1["git worktree remove\n../project-navbar\n../project-footer"]
CL1 -->|" "| CL2
CL2["git branch -d\nfeature/navbar\nfeature/footer"]
style C1 fill:#8be9fd22,stroke:#8be9fd,stroke-width:1px
style C2 fill:#8be9fd22,stroke:#8be9fd,stroke-width:1px
style D1 fill:#50fa7b22,stroke:#50fa7b,stroke-width:1px
style D2 fill:#bd93f922,stroke:#bd93f9,stroke-width:1px
style M1_ fill:#ffb86c22,stroke:#ffb86c,stroke-width:1px
style M2_ fill:#ffb86c22,stroke:#ffb86c,stroke-width:1px
style R1 fill:#ff555522,stroke:#ff5555,stroke-width:1.5px
style CL1 fill:#6272a422,stroke:#6272a4,stroke-width:1px
style CL2 fill:#6272a422,stroke:#6272a4,stroke-width:1px
styles.css,
you still need to resolve the merge conflict after both are done.
navbar.tsx and Agent 2 only touches
footer.tsx, merging is automatic. If they both edit styles.css,
merge the first one, then let the second merge produce conflicts that you resolve.