Bare-repo Git worktree patterns for parallel agent workflows.
Important execution nuance: in some agent shell environments, a tool-level working directory is not reliably applied to child Git commands. That is not a problem with the worktree layout itself. Agents should prefer explicit command targeting such as git -C <worktree-path> ..., or git --git-dir <project>/.bare --work-tree <worktree-path> ... when operating from outside the repo.
This repository exists for one reason: make Git worktrees practical for multi-agent coding. The central recommendation is simple:
- Use one bare repository as the shared Git database.
- Use one branch per worktree.
- Use one agent per worktree.
- Never check out the same branch in multiple worktrees.
That gives you shared object storage, isolated working directories, and a layout that does not privilege one checkout as "the main repo".
The recommended structure is:
project/
.bare/
main/ or master/
feat-search/
feat-search-ui/
feat-search-api/
.bare/ is the brain. Every sibling directory is just a checkout.
This is usually better than a single normal clone that also hosts .worktrees/ because:
- every worktree is equal
- there is no "special" checkout that hosts the others
- there is nothing extra to
.gitignore - the mental model stays clean for both humans and agents
Use this pattern when several agents work on one larger feature:
mainormaster: trunkfeat/search-redesign: integration branch for the featurefeat/search-redesign-ui: agent branchfeat/search-redesign-api: agent branchfeat/search-redesign-tests: agent branch
Each agent branch starts from the feature branch, not directly from trunk.
Source the helpers:
. .\scripts\powershell\git-worktree.ps1To make the helpers available in every PowerShell session, add a dot-source line to your PowerShell profile:
$gitWorktreeHelpers = "C:\path\to\agent-git-worktrees\scripts\powershell\git-worktree.ps1"
if (Test-Path $gitWorktreeHelpers) {
. $gitWorktreeHelpers
}Create a new managed repo:
gnew https://github.com/OWNER/REPO.gitCreate a feature branch from trunk:
gwt feat/search-redesign -From mainIf your shell is at project/ or project/.bare/, gwt feat/search-redesign works too and defaults the base to the repository default branch.
Create agent branches from the feature branch:
gwt feat/search-redesign-ui -From feat/search-redesign
gwt feat/search-redesign-api -From feat/search-redesignList worktrees:
gwlRemove a clean merged worktree:
gwrm feat/search-redesign-uiWhen running from project/ or project/.bare/, pass the branch name explicitly to gwrm because there is no current checked-out worktree to infer it from.
Reset a managed repo to only the default branch worktree after confirming all other work is disposable:
gprune
gprune -ForceWithout -Force, gprune prints a dry-run summary and exits non-zero. With -Force, it removes all non-default registered worktrees, deletes removed non-default local branches where possible, resets the default branch worktree to origin/<default-branch>, cleans untracked files, prunes worktree metadata, and removes stray top-level project entries so only .bare and <default-branch> remain.
Source the helpers:
source ./scripts/bash/git-worktree.shThe command surface is the same: gnew, gwt, gwl, gwrm, gprune. Bash also accepts the documented gwt <branch> -From <base> form. In Bash or Zsh, run the destructive reset as gprune --force.
Merge agent branches into the feature branch from the feature worktree:
git -C ./feat/search-redesign merge feat/search-redesign-ui
git -C ./feat/search-redesign merge feat/search-redesign-api
git -C ./feat/search-redesign merge feat/search-redesign-testsThen merge the feature branch into trunk:
git -C ./main merge feat/search-redesignWhen an agent is not certain it is truly running inside the intended worktree, use explicit targeting:
git -C <worktree-path> status --short --branch
git -C <worktree-path> rev-parse --path-format=absolute --git-common-dir
git --git-dir <project>/.bare --work-tree <worktree-path> push origin <branch>Treat this as an execution-environment best practice, not as a reason to avoid worktrees.
If you already have a normal clone and want to move to the bare-repo layout, see docs/migration-guide.md.
For Windows/PowerShell, a migration script is included at scripts/powershell/migrate-repo-to-worktrees.ps1. It keeps a full sibling backup of the original repo before rebuilding the working layout.
- AGENTS.md: platform-neutral agent instructions
- docs/why-bare-repo-layout.md: rationale and tradeoffs
- docs/merge-and-cleanup.md: merge, cleanup, and conflict guidance
- scripts/powershell/git-worktree.ps1: PowerShell helpers
- scripts/powershell/migrate-repo-to-worktrees.ps1: migration helper
- scripts/bash/git-worktree.sh: Bash/Zsh helpers
- skills/codex/git-worktree-manager/SKILL.md: Codex skill version of this workflow
- Never share a branch across multiple worktrees.
- Keep one agent per worktree.
- Use explicit
-Frombases when creating agent branches from a feature branch. - Refuse to delete dirty worktrees unless the user explicitly wants destructive cleanup.
- Keep backups when migrating existing repositories.
- Prefer
git -C <worktree-path>over plaingit ...in agent shells where the current directory may not be what the tool claims. - Use
gprune --forceorgprune -Forceonly when the user clearly asks to discard all non-default worktrees and reset the project to the default branch only.
Run the Bash helper smoke tests on macOS or Linux with:
./tests/bash/git-worktree-helper-tests.shRun the PowerShell helper smoke tests on Windows with:
.\tests\powershell\git-worktree-helper-tests.ps1For manual verification, use a disposable local fixture and verify:
- dry-run exits non-zero and removes nothing
- forced cleanup works from the project root,
.bare, the default worktree, and a feature worktree - a missing default worktree is recreated at
project/<default-branch> - dirty non-default worktrees and external registered worktrees are removed
- stray top-level project files and folders are removed
- final output shows remaining registered worktrees, default branch status, default HEAD SHA,
origin/<default-branch>SHA, and top-level project-root contents
MIT. See LICENSE.