parallel-worktrees
Skill2 starsChanged 21 days agoMITView on GitHub
Get several independent tasks done at the same time: each goes to its own agent in its own git worktree and branch, with a check that no two edit the same files, then the branches merge back one at a time, testing after each. Use when the user says 'run these in parallel', 'split this across agents', 'use worktrees', 'fan out', or has several issues, features or fixes to do side by side.
- Reads credentials
- Deletes or force-pushes
- Installs packages
6 other projects use a version of this.
Adopted by
Most recently taken up by
- mqmalagris/agent-skillstheir own version, first seen Nov 5, 2026
- theexperiencecompany/gaiatheir own version, first seen Nov 3, 2026
- TheBeardedBearSAS/claude-crafttheir own version, first seen Oct 29, 2026
- rohitg00/pro-workflowtheir own version, first seen Sep 29, 2026
- chinthakat/agent-skillstheir own version, first seen Sep 21, 2026
- kiku-jw/codex-skillstheir own version, first seen Jul 28, 2026
Other versions6 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 6
- rohitg00/pro-workflow★ 2.9ksame name
- theexperiencecompany/gaia★ 325same name
- TheBeardedBearSAS/claude-craft★ 108same name
- chinthakat/agent-skills★ 0same name
- kiku-jw/codex-skills★ 0same name
- mqmalagris/agent-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository38 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- arenaSkill
- codebase-oracleSkill
- geppettoSkill
- lean-subagent-devSkill
- methodologySkill
- overnight-runSkill
- dependency-security-auditSkill
- dependency-upgradeSkill
- rule-to-hookSkill
- safe-mergeSkill
- agent-friendly-auditSkill
- architectSkill
- brainstormSkill
- engineering-principlesSkill
- grill-meSkill
- improve-codebase-architectureSkill
- sharpenSkill
- to-issuesSkill
- to-prdSkill
- handoffSkill
- instructions-auditSkill
- project-setupSkill
- retrospectiveSkill
- session-closeSkill
- which-skillSkill
- bug-fixSkill
- ci-cost-and-cadenceSkill
- evaluatorSkill
- flaky-test-huntSkill
- hillclimbSkill
- launch-readinessSkill
- migration-reviewSkill
- mutation-testSkill
- review-triageSkill
- skill-evalSkill
- tddSkill
- verify-appSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
24 rules. 0 are common, 23 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 6 edited versions we read keep these.
23
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 9
Run several agents on one repository at the same time without them overwriting each other.
- Distinctive: line 25
If you started this skill on your own, without the user typing its name or asking for what it does, first say in one or two lines what it …
- Distinctive: line 35
Run this test for each candidate piece:
- Distinctive: line 63
Serialize: run the overlapping pieces one after another, the second starting from the first's merged result.
- Distinctive: line 69
Do not parallelize when:
- Distinctive: line 81
Write the selection rule down before spawning any arm: the tests every arm must pass, a measured number and how it is measured (for example …
- Distinctive: line 114
Put worktrees outside the main checkout, in a sibling folder, or in a folder inside it that git ignores:
- Distinctive: line 136
Read the project's README or CI config to find the real install command before guessing.
- Distinctive: line 148
Put the per-worktree values in the worktree's own untracked env file and in the brief.
- Distinctive: line 180
If an agent reports it needs a file outside its scope, stop that piece and decide: give it the file (and check no other piece owns it), or …
- Very specific: line 183
Done when: every agent has reported, every piece's done-command passes in its worktree, and status shows dirty 0 for each piece (everything …
- Distinctive: line 205
Run the full suite after each merge, not once at the end.
- Distinctive: line 213
If a merge breaks the suite and the fix is not obvious, abort it (git merge --abort, or git reset --hard to the previous merge commit on …
- Distinctive: line 220
Done when: every piece is merged into the integration branch, the full suite, lint and build pass on it, and it has been merged or opened …
- Distinctive: line 225
Remove a worktree only after proving nothing in it would be lost:
- Distinctive: line 235
Run these from the main checkout, not from inside the worktree being removed.
- Distinctive: line 248
After pruning, look for leftover folders git no longer tracks (prune only removes git's records) and delete them once you have checked …
- Distinctive: line 258
Do not run two agents in the same checkout, even "just for a quick fix".
- Distinctive: line 259
Do not start pieces from different base commits without saying so in the plan.
- Distinctive: line 260
Do not let an agent edit a file another piece owns, or regenerate a shared lockfile it does not own.
- Distinctive: line 261
Do not merge all branches and run the tests once at the end.
- Distinctive: line 262
Do not remove a worktree that has uncommitted work, or delete a branch that has unmerged work (a race's losing branch included), without …
- Distinctive: line 264
Do not treat "do not touch X" in a brief as a lock on shared state.
- Distinctive: line 265
Do not copy secrets into a tracked file to save setup time.
“Common” is measured: kept by at least 6 in 10 of the 6 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Parallel worktrees
Run several agents on one repository at the same time without them overwriting each other. Each piece of work gets its own branch and its own working folder (a git worktree), and the branches come back together one at a time.
The work to split: $ARGUMENTS
Bundled files, open them when you reach their phase:
${CLAUDE_SKILL_DIR}/BRIEF-TEMPLATE.md: the brief each piece's agent receives${CLAUDE_SKILL_DIR}/TROUBLESHOOTING.md: errors and environment problems, with fixes${CLAUDE_SKILL_DIR}/worktrees.mjs:plan-checkfinds files claimed by two pieces;statusshows every worktree's branch, ahead/behind, uncommitted files and last commit (Node 20+, no dependencies)
Why worktrees and not one checkout: two agents in one folder share one index and one set of files. One agent's
git add -A commits the other's half-finished edit, a formatter run rewrites files the other is editing, and a
branch switch pulls the floor out from under everyone. A worktree shares the repository's history but has its own
files, index and checked-out branch, so none of that can happen.
If you started this skill on your own, without the user typing its name or asking for what it does, first say in one or two lines what it will do and what it will cost, and wait for a yes. A remark or a question that only matches its description is not asking for it. If the user asked for it, or the brief you are working from does, go ahead.
Phase 1: decide whether to parallelize at all
Parallel work pays only when the pieces are truly independent. Two agents editing the same file produce a merge conflict that someone must resolve with less context than either agent had; that usually costs more than running the pieces one after another.
Run this test for each candidate piece:
- List the files it will create, edit or delete, as paths or globs. Read the code to do this; do not guess from the task title.
- Name shared generated files it would touch: lockfiles (
package-lock.json,pnpm-lock.yaml,yarn.lock,poetry.lock,uv.lock,Pipfile.lock,go.sum,Cargo.lock,Gemfile.lock,composer.lock,packages.lock.json,gradle.lockfile), generated clients, snapshot files, schema dumps, migration indexes, route manifests, translation catalogues, changelogs. - Name ordering dependencies: does any piece need a function, table, endpoint or type that another piece adds?
- Name sequence numbers: migrations numbered
0007_*, version bumps, ADR numbers. Two pieces that each take "the next number" collide even though their files have different names.
Then write the plan as JSON and check it mechanically:
{ "pieces": [
{ "name": "billing-api", "files": ["services/billing/**", "docs/billing.md"] },
{ "name": "search-ui", "files": ["web/src/search/**", "web/src/routes/search.tsx"] }
] }node "${CLAUDE_SKILL_DIR}/worktrees.mjs" plan-check plan.jsonIt expands every glob against the repository's files and lists each file claimed by more than one piece, plus new paths two pieces would both create. Exit 1 means overlap. For each overlap, pick one:
- Serialize: run the overlapping pieces one after another, the second starting from the first's merged result.
- Assign an owner: one piece owns the shared file; the others must not touch it and say in their report what they need changed there. Typical for a lockfile: one piece adds every new dependency, or dependency changes wait for integration.
- Merge the pieces into one.
Do not parallelize when:
- the whole job is under an hour of work for one agent; setup and integration cost more than they save;
- the change is tightly coupled (renaming a widely used type, changing a shared interface and all its callers);
- pieces share a database schema or migration sequence and cannot be given separate numbers up front;
- you cannot state how each piece proves it is done (then you cannot integrate safely either).
A race instead of a split
The opposite shape also uses worktrees: several agents attempt the same piece and you keep one result. It fits when the right approach is unclear and a single attempt could lock in the wrong one (an algorithm, a hard fix, a design with more than one plausible shape).
- Write the selection rule down before spawning any arm: the tests every arm must pass, a measured number and how it is measured (for example the median of five benchmark runs), or a judge with a written rubric. Write down too what happens on a tie (for example, the smaller diff wins) and when no arm passes (report to the user; do not lower the bar). A rule chosen after seeing the results picks a favourite.
- In the
plan-checkJSON, list the race as one piece with the files every arm will touch. The arms claim the same files on purpose, because only one of them is merged. - Each arm still gets its own worktree, branch (
par/<batch>/<piece>-a,-b,-c), ports and databases (Phase 3) and brief. The briefs are otherwise the same, or differ only in the approach each arm is asked to try. - A race of N arms costs N times one attempt. Unless the user asked for a race, say that cost and wait for a yes before spawning, even when the user asked for parallel work.
- For a race with a blind judge (one that does not know which arm produced which result), use
arenaif it is installed. Without it, give a fresh subagent the rubric and the results with the arm names removed.
Done when plan-check exits 0, or every reported overlap has a written decision (serialize, owner, or merge),
and every ordering dependency is either removed or turned into a sequence.
Phase 2: plan the pieces
- One branch per piece, all created from the same base commit. Record it:
git rev-parse HEADon an up-to-date base branch. Pieces started from different commits make integration harder to reason about. Recordgit worktree listtoo, for the cleanup in Phase 6. - Branch names follow one pattern, for example
par/<batch>/<piece>(par/2024-billing/api). A shared prefix makes them easy to list and delete later (git branch --list 'par/2024-billing/*'). - Pre-assign anything numbered: migration numbers, ports, test database names (see Phase 3).
- Write one brief per piece from
BRIEF-TEMPLATE.md: goal, the files it owns, what it must not touch, how it proves it is done (a command that must pass), and what to report. The brief is the agent's whole world: it did not see this conversation. - Choose the integration order now (Phase 5), so foundations go first.
Done when each piece has a branch name, a brief with a done-command, and a place in the merge order.
Phase 3: set up the worktrees
Put worktrees outside the main checkout, in a sibling folder, or in a folder inside it that git ignores:
git fetch origin
BASE=$(git rev-parse origin/main) # the recorded base commit
git worktree add -b par/batch1/api ../myrepo-wt/api "$BASE"
git worktree add -b par/batch1/ui ../myrepo-wt/ui "$BASE"
# or, inside the repo: add ".worktrees/" to .gitignore first, then
git worktree add -b par/batch1/api .worktrees/api "$BASE"
git worktree listA folder inside the repository that is not ignored shows up as untracked files in the main checkout, and tools that scan the tree (test runners, linters, file watchers, search indexes) will crawl every copy. Ignore it or use a sibling folder.
Each worktree is a fresh checkout. Nothing untracked comes with it. Budget for:
- Dependencies: install per worktree with the project's own command (
npm ci,pnpm install --frozen-lockfile,uv sync,poetry install,pip install -r requirements.txtin a fresh venv,bundle install,composer install,dotnet restore,mvn -q dependency:go-offlineor./gradlew dependencies). Go and Rust share their global module and registry caches, so they cost little;node_modulesand virtualenvs are per folder. Read the project's README or CI config to find the real install command before guessing. - Environment files:
.env,.env.local,local.settings.json,appsettings.Development.jsonand similar are usually gitignored and therefore missing. Copy them explicitly. Never commit them to make this easier. - Build caches: the first build in each worktree is a cold build. Shared caches (Gradle, Cargo's registry, the
Go build cache, ccache, Turborepo or Nx remote caches) help; per-folder ones (
target/,dist/,.next/) do not. - Ports: two dev servers on port 3000 fail, or worse, one agent tests the other's server. Give each worktree its
own:
PORT=3101,3102, and the same for any second service (API, storybook, debugger). - Databases and other shared state: two test suites against one database delete each other's rows. Give each a
name:
DATABASE_URL=.../app_test_api,.../app_test_ui, a separate SQLite file, a separate Docker Compose project (COMPOSE_PROJECT_NAME=myrepo_api), a separate Redis database number or key prefix, a separate S3 or queue prefix in local emulators.
Put the per-worktree values in the worktree's own untracked env file and in the brief.
A worktree separates files, the index and the checked-out branch, nothing else. Ports, databases and other local
services, caches that are not safe to write from two processes at once, the integration branch, remotes and tags
are still shared. For each one two agents could write, give each agent its own copy (a port, a database name, a cache
folder) or put a real lock in front of it (a sequence, or a lock the tool itself takes). A line in the brief that
says "do not touch X" is not a lock: an agent that misreads it, or a tool it runs, writes anyway, and the collision
shows up later as a failure nobody can reproduce. File ownership ("Assign an owner" in Phase 1) stays the rule for
files, because every edit lands on a branch you read at integration; shared state outside the files leaves no such
trace. The integration branch, remotes and tags stay with the orchestrator. The brief's line against merging,
pushing to the base or tagging is a reminder, not the protection: after each agent reports, check them (git tag,
git log of the integration and base branches) and undo what should not be there.
Claude Code alternative. Recent Claude Code versions can create and manage worktrees themselves: claude
--worktree <name> starts a session in a new worktree, and the Agent tool accepts isolation: "worktree" so a
subagent runs in a temporary worktree that is cleaned up if it made no changes. Check the current documentation for
the exact flags and where the worktrees are placed. These remove the manual git worktree add, but not the per
worktree setup above, and not Phases 1, 2 and 5.
Done when git worktree list shows one worktree per piece (per arm, for a race) on the right branch, and in each
one the project's install step and the piece's done-command have run once (failing tests are fine at this point; a
missing dependency is not).
Phase 4: run the agents
- Launch one agent per piece with its brief and its worktree path as the working directory. Subagents: one Agent
call per piece, all in the same message so they run concurrently. Separate sessions: one terminal per worktree,
cdinto it, start the session, paste the brief. - Each agent edits, runs its checks and commits only inside its own worktree, on its own branch. It does not
push to the base branch, does not rebase other branches, and does not run
git worktreecommands. - The orchestrator (you) does not edit files in any worktree while agents run. Watch with
node "${CLAUDE_SKILL_DIR}/worktrees.mjs" status --base mainand read the reports. - If an agent reports it needs a file outside its scope, stop that piece and decide: give it the file (and check no other piece owns it), or queue the change for integration. Do not let it "just make the small edit".
Done when every agent has reported, every piece's done-command passes in its worktree, and status shows
dirty 0 for each piece (everything committed). A race's arms are the exception: an arm that fails is a result, not
work to send back. The race is done when the selection rule has picked a winner, or no arm passed and that has gone
to the user.
Phase 5: integrate
Merge one branch at a time into an integration branch, in the order chosen in Phase 2: foundations (schema, shared types, config) first, then the pieces that build on them, the riskiest last so a problem there does not block the others.
git switch -c par/batch1/integration "$BASE"
git merge --no-ff par/batch1/api
<full test suite, lint and build, with the project's own commands>
git merge --no-ff par/batch1/ui
<full test suite again>Rebasing each branch onto the integration branch before merging works too and gives linear history; pick one style and keep it for the batch.
- Run the full suite after each merge, not once at the end. Two pieces that each pass alone can break together (a renamed helper, a duplicate route, a changed default); finding which pair broke it is easy after one merge and slow after five.
- Resolve a conflict by reading both pieces' briefs and keeping both intents. Open the file, understand each side,
write the combined version, and run the tests. Do not resolve by deleting one side's lines, by taking
--oursor--theirsfor a whole file you have not read, or by line numbers from a script. - Regenerate shared generated files (lockfiles, snapshots, generated clients) with the tool that owns them after the merge instead of hand-merging their contents.
- If a merge breaks the suite and the fix is not obvious, abort it (
git merge --abort, orgit reset --hardto the previous merge commit on the integration branch only), continue with the next piece, and send the broken one back to its agent with the failure. - In a race, judge every arm that reported by the rule written in Phase 1, record each arm's result (for the report), and merge only the winning arm, in the race piece's planned place in the order. The other arms are not merged, and a losing arm is never sent back for more work.
Done when every piece is merged into the integration branch, the full suite, lint and build pass on it, and it has been merged or opened as a pull request against the base branch the way the project normally lands work.
Phase 6: clean up
Remove a worktree only after proving nothing in it would be lost:
git -C ../myrepo-wt/api status --short # must print nothing
git log --oneline par/batch1/integration..par/batch1/api # must print nothing: every commit is merged
git worktree remove ../myrepo-wt/api
git worktree prune
git branch -d par/batch1/api # -d refuses unmerged branches; that refusal is the safety check- Run these from the main checkout, not from inside the worktree being removed.
- A listing that calls a worktree clean and merged (the commands above,
worktrees.mjs status, or any audit script) is advice, not permission. Before removing one, also check that no agent or session still runs in it: every agent of the batch has reported or been stopped, and nothing has it open. On macOS and Linux, read the output oflsof +D <path>(its exit code is 1 whether or not it finds anything), and ask the user about editors and watch-mode runners, which it can miss; on Windows, ask about open terminals and editors. Ask the user before removing any worktree this batch did not create. - A race's losing arm: remove its worktree with the commands above once its status is clean (the branch keeps the
commits). Its branch is unmerged, so
git branch -drefuses it; keep it until the user says it can go, since a losing arm can hold a part worth taking. On that yes,git branch -Don that losing branch is allowed, and only there. - Otherwise, never use
git worktree remove --forceorgit branch -Dto get past a refusal. Find out what is uncommitted or unmerged first, and either commit and merge it or confirm with the user that it can go. - After pruning, look for leftover folders git no longer tracks (prune only removes git's records) and delete them once you have checked their contents. Remove per-worktree env files, databases and Docker Compose projects you created.
Done when git worktree list shows only the worktrees that existed before the batch, the batch's branches are
deleted locally (and remotely, if they were pushed), except losing race arms the user chose to keep, and no batch
database or container is left running.
Do not
- Do not run two agents in the same checkout, even "just for a quick fix".
- Do not start pieces from different base commits without saying so in the plan.
- Do not let an agent edit a file another piece owns, or regenerate a shared lockfile it does not own.
- Do not merge all branches and run the tests once at the end.
- Do not remove a worktree that has uncommitted work, or delete a branch that has unmerged work (a race's losing branch included), without the user's yes.
- Do not treat "do not touch X" in a brief as a lock on shared state; separate it or lock it.
- Do not copy secrets into a tracked file to save setup time.
Report
Parallel worktrees: <batch name>
Base commit: <sha> Integration branch: <name>
Pieces:
<name> branch <branch> worktree <path> done-command <cmd>: PASS | FAIL commits <n>
Overlaps found by plan-check: <none | list, with the decision for each>
Race: <none | piece: selection rule; each arm's result; arm kept; losing branches kept or deleted with the user's yes>
Merge order and result after each merge: <piece>: suite PASS | FAIL (<what failed, how fixed>)
Conflicts resolved: <file: how both intents were kept>
Not merged: <piece: why, what it needs>
Cleanup: worktrees removed <n>; branches deleted <list>; leftovers <none | list>Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

