首页 › tutorials › worktree 并行扇出批量跑任务

概述

本教程聚焦 Claude Code 的 worktree 并行扇出能力:用 claude -w 为每个任务创建一个 git worktree 隔离副本,配合 -p 无头模式让多个 Claude Code 实例同时开工,最后把成果合并回主干。它直接命中"批量任务"自动化的核心痛点——串行跑十个任务要等一下午,并行跑只要最慢那个的时间。适合已经会用 claude -p 跑单任务、想把它扩成可调度、可隔离、可合并的批量执行器的开发者与运维工程师。

前置条件


正文

第 1 步:理解 worktree 隔离为什么是并行的前提

直接在同一个目录里开两个 claude -p 跑不同任务,会撞车:两个实例都改 src/ 下的文件,后写的覆盖先写的,git 暂存区乱成一团。串行执行(一个跑完再跑下一个)能避免冲突,但十个任务就要排队,浪费时间。

git worktree 解决的就是这个矛盾:它是同一个仓库的"另一份检出",有自己独立的工作目录和分支,但共享 .git 历史和远程。把每个 Claude Code 会话关进各自的 worktree,A 在改 src/auth,B 在改 src/billing,磁盘上物理隔离,互不踩脚,而合并时又因为共享同一个 .git 而极其方便。

一句话记住核心:worktree 管文件隔离,subagent/agent team 管任务分工。本教程聚焦前者——把文件隔离做成可并行调度的批量管道。

第 2 步:用 --worktree 起跑第一个隔离会话

--worktree(短写 -w)是入口。传一个名字,Claude Code 会在仓库根下的 .claude/worktrees/<名字>/ 创建一份新检出,并在分支 worktree-<名字> 上启动会话:

claude --worktree feature-auth
# 等价于 claude -w feature-auth

预期结果:当前终端进入一个全新工作目录(实际是 .claude/worktrees/feature-auth/),分支显示为 worktree-feature-auth。这里做的任何修改都不会影响你的主检出。

在另一个终端用不同名字再开一个:

claude --worktree bugfix-123

现在你有两个物理隔离的会话,可同时干活。省略名字时 Claude 会自动生成一个(如 bright-running-fox)。

首次使用提示:第一次在某个目录用 --worktree 交互式启动前,要先在该目录跑一次 claude 接受工作区信任对话框;否则 --worktree 会报错并提示你先跑 claude。但非交互的 -p 会跳过信任检查,所以 claude -p --worktree xxx 无需此步骤——这对自动化至关重要。

常见问题:worktree 内容会以"未跟踪文件"形式出现在主检出的 git status 里。把 .claude/worktrees/ 加进 .gitignore 即可:

# .gitignore
.claude/worktrees/

第 3 步:配置基准分支与环境文件

基准分支(baseRef)。默认情况下,新 worktree 从 origin/HEAD(远程默认分支)拉取,保证起点干净。如果你想让 worktree 带上本地未推送的提交或在途的功能分支状态(比如让子代理在你的半成品上继续干活),把基准改成本地 HEAD:

// .claude/settings.json
{
  "worktree": {
    "baseRef": "head"
  }
}

该字段只接受 "fresh"(默认,从 origin/HEAD)或 "head"(从本地 HEAD),不接受任意 git ref。想从某个 PR 拉基准,直接传 PR 号:

claude --worktree "#1234"
# 会在 .claude/worktrees/pr-1234 创建,基准为 pull/1234/head

复制 gitignored 文件(.worktreeinclude)。worktree 是全新检出,主仓库里那些没纳入版本控制的文件(.env、.env.local、config/secrets.json)默认不会出现,跑测试就会因为缺配置而报错。在项目根新建 .worktreeinclude,用 .gitignore 语法声明要自动拷贝的文件:

# .worktreeinclude
.env
.env.local
config/secrets.json

规则很安全:只有同时被某模式匹配且确实被 gitignore的文件才会被复制,已跟踪文件永远不会被重复。该机制对 -w、子代理 worktree、桌面端并行会话都生效。

第 4 步:用 -p 把单 worktree 变成无人值守任务

交互式 -w 适合人盯着看,批量执行要的是无人值守。组合 -w 与 -p:

claude -w task-add-logging -p \
  "给 src/ 下所有 service 模块统一加上结构化日志,不要改公开 API" \
  --output-format json \
  > logs/task-add-logging.json

预期结果:Claude Code 静默创建 worktree、完成任务、把结构化结果(含改动摘要、token 用量)以 JSON 写入日志文件,进程退出。期间主检出完全不受影响。

关键点速记:

第 5 步:并行扇出——让 N 个 worktree 同时跑

隔离和无人值守就绪后,并行只剩编排。下面给出三种由轻到重的写法。

写法 A:bash 后台 + wait(最朴素,零依赖)

for t in add-logging fix-leak refactor-api; do
  ( claude -w "task-$t" -p "完成任务:$t" \
      --output-format json > "logs/$t.json" 2> "logs/$t.err" ) &
done
wait   # 阻塞直到全部完成
echo "全部结束"

写法 B:xargs -P(带并发上限,系统自带)

-P 3 表示最多同时跑 3 个,超过的排队:

printf '%s\n' add-logging fix-leak refactor-api harden-auth \
| xargs -P 3 -I {} bash -c '
    claude -w "task-{}" -p "完成任务:{}" \
      --output-format json > "logs/{}.json" 2> "logs/{}.err" \
    && echo "OK {}" || echo "FAIL {}"
  '

写法 C:GNU parallel(功能最全,支持失败重试、结果聚合)

parallel --jobs 4 --results logs/ \
  'claude -w task-{1} -p "完成任务:{1}" --output-format json' \
  ::: add-logging fix-leak refactor-api harden-auth

parallel 会把每个任务的 stdout/stderr/exit code 分别落到 logs/ 下结构化目录,方便事后审计。

并发上限怎么定:每个 claude -p 实例都消耗 API 并发与 token。经验值从 min(4, CPU核数-2) 起步,观察限流报错再调。并行不是越大越好——撞到 API 速率限制会集体失败。

常见问题:多个实例同时读写共享的 ~/.claude 状态目录偶发竞争。把每个实例的日志严格隔离(每任务独立文件),并避免在任务里写共享文件即可。

第 6 步:合并与冲突处理

所有任务跑完后,成果在各自的 worktree-<名字> 分支上。因为共享同一个 .git,合并非常直接。先切回主检出,再逐个合并:

git checkout main
for t in add-logging fix-leak refactor-api; do
  if git merge --no-ff "worktree-task-$t" -m "merge: $t"; then
    echo "✅ 已合并 $t"
  else
    echo "⚠️  $t 冲突,已中止,留待人工"
    git merge --abort
  fi
done

冲突处理策略:

第 7 步:清理 worktree

-p 跑出来的 worktree 不自动清理,跑完一批会留下一堆。手动清理:

for t in add-logging fix-leak refactor-api; do
  git worktree remove --force ".claude/worktrees/task-$t"
  git branch -D "worktree-task-$t" 2>/dev/null || true
done

--force 用于强制删除有未提交改动的 worktree(确认不需要时才加)。运行中的 agent 会对其 worktree 执行 git worktree lock,防止并发清理误删;agent 结束后锁自动释放。

子代理与后台会话产生的 worktree 则有自动清扫机制:超过 cleanupPeriodDays(默认若干天)且无未提交改动/未跟踪文件/未推送提交的,会被自动回收;你用 --worktree 主动建的不会被这条规则动。

第 8 步(进阶):子代理 worktree 隔离与非 git VCS

子代理隔离。在自定义子代理的 frontmatter 里加一行,让该子代理每次都在独立 worktree 里跑,子代理结束后无改动则自动删除:

---
name: refactor-agent
isolation: worktree
tools: Edit, Read, Bash
---
你是一个重构专家……

或直接在会话里说"use worktrees for your agents"。这把"任务分工"(subagent)和"文件隔离"(worktree)叠加,适合一个会话内并行派发多个改不同目录的子任务。

非 git 版本控制。worktree 默认用 git。SVN/Perforce/Mercurial 等需配置 WorktreeCreate / WorktreeRemove hook 接管创建与清理逻辑。注意:一旦用 hook 接管,.worktreeinclude 不再生效,本地配置文件的复制要写进 hook 脚本里。一个 SVN 示例:

{
  "hooks": {
    "WorktreeCreate": [
      { "hooks": [ { "type": "command",
        "command": "bash -c 'NAME=$(jq -r .name); DIR=\"$HOME/.claude/worktrees/$NAME\"; svn checkout https://svn.example.com/repo/trunk \"$DIR\" >&2 && echo \"$DIR\"'"
      } ] }
    ]
  }
}

hook 从 stdin 读 worktree 名字,检出一个 SVN 工作副本,打印目录路径,Claude Code 就把它当作会话工作目录。


实战案例:一个可运行的并行批量执行器

下面这个 fanout.sh 把前面所有步骤串成一条完整管道:读任务清单 → 并行扇出(带并发上限)→ 收集结果 → 自动合并并清理、冲突保留。

任务清单 tasks.txt,每行 <名字><TAB><提示词>:

add-logging 给 src/services/ 下每个 service 加结构化日志,不动公开 API
fix-leak    修复 src/db/pool.go 里的连接泄漏,补一个测试
refactor-api    把 src/api/handlers.go 里的回调改成 async/await 风格
harden-auth 给 src/auth/ 加输入校验,拒绝空 token

执行器 fanout.sh:

#!/usr/bin/env bash
# fanout.sh — worktree 并行批量执行器
# 用法: ./fanout.sh tasks.txt
set -euo pipefail

REPO_ROOT="$(git rev-parse --show-toplevel)"
cd "$REPO_ROOT"
WORKDIR=".claude/worktrees"
MAX_PARALLEL="${MAX_PARALLEL:-3}"
TASKS_FILE="${1:-tasks.txt}"
BASE_BRANCH="${BASE_BRANCH:-main}"

mkdir -p "$WORKDIR" logs

run_one() {
  local name="$1" prompt="$2"
  if claude -w "$name" -p "$prompt" --output-format json \
       > "logs/$name.json" 2> "logs/$name.err"; then
    echo "✅ $name 完成"
  else
    echo "❌ $name 失败(见 logs/$name.err)"
  fi
}

# —— 阶段一:并行扇出 ——
mapfile -t LINES < "$TASKS_FILE"
for line in "${LINES[@]}"; do
  [ -z "$line" ] && continue
  name="${line%%$'\t'*}"; prompt="${line#*$'\t'}"
  run_one "$name" "$prompt" &
  # 限流:达到并发上限就等一个槽位空出
  while [ "$(jobs -r | wc -l)" -ge "$MAX_PARALLEL" ]; do sleep 1; done
done
wait
echo "---- 全部任务结束,开始合并 ----"

# —— 阶段二:逐个合并 ——
git checkout "$BASE_BRANCH" 2>/dev/null || git checkout -b "$BASE_BRANCH"
for line in "${LINES[@]}"; do
  [ -z "$line" ] && continue
  name="${line%%$'\t'*}"
  branch="worktree-$name"
  wt="$WORKDIR/$name"

  # 无改动直接清掉
  if git diff --quiet "HEAD" "$branch" -- 2>/dev/null; then
    echo "⏭️  $name 无改动"
    git worktree remove --force "$wt" 2>/dev/null || true
    git branch -D "$branch" 2>/dev/null || true
    continue
  fi

  if git merge --no-ff "$branch" -m "merge: $name"; then
    echo "🔗 已合并 $branch"
    git worktree remove --force "$wt" 2>/dev/null || true
    git branch -D "$branch" 2>/dev/null || true
  else
    echo "⚠️  $branch 冲突,保留 worktree 待人工处理:$wt"
    git merge --abort
  fi
done

echo "---- 完成。成功合并的改动已在 $BASE_BRANCH ----"

运行:

chmod +x fanout.sh
MAX_PARALLEL=4 ./fanout.sh tasks.txt

预期结果:屏幕滚动打印每个任务的 ✅/❌,最后打印合并结果。成功的分支并入 main 并清理 worktree;失败或冲突的 worktree 原地保留,你可在 .claude/worktrees/<名字>/ 里继续处理。logs/ 下留存每个任务的 JSON 结果与错误日志,便于审计与重跑。

扩展点:失败任务可在第二阶段加一段 claude -w "$name" -p "修复 logs/$name.err 里的错误" 做一轮自愈重试;想跨多个仓库批量操作,把 REPO_ROOT 换成遍历仓库列表的外层循环即可。


Mermaid 流程图:并行扇出→隔离执行→合并

flowchart TD
    A[tasks.txt 任务清单] --> B[逐行读取任务]
    B --> C{并行扇出<br/>MAX_PARALLEL 限流}
    C --> W1[worktree-add-logging<br/>claude -w -p]
    C --> W2[worktree-fix-leak<br/>claude -w -p]
    C --> W3[worktree-refactor-api<br/>claude -w -p]
    C --> W4[worktree-harden-auth<br/>claude -w -p]
    W1 --> R1[logs/add-logging.json]
    W2 --> R2[logs/fix-leak.json]
    W3 --> R3[logs/refactor-api.json]
    W4 --> R4[logs/harden-auth.json]
    R1 --> M[wait 全部完成]
    R2 --> M
    R3 --> M
    R4 --> M
    M --> G{逐个合并到 main}
    G -->|无冲突| K[git merge + 清理 worktree]
    G -->|有冲突| H[保留 worktree 待人工/自愈重试]
    K --> DONE([main 已包含全部改动])
    H --> DONE

延伸阅读


训练营适用性评估


参考来源

  1. Run parallel sessions with worktrees — Claude Code Docs — 官方对 --worktree、baseRef、.worktreeinclude、子代理隔离、清理规则与 WorktreeCreate/WorktreeRemove hook 的权威说明。
  2. Introduction to Git Worktrees in Claude Code — Better Stack — 三个功能并行实现的实操指南,含 worktree 管理技巧与已知问题排查。
  3. Practical Parallelism With Claude Code, Part 3: Automating Parallel — 从 tmux 手动编排到自动化并行任务分发的演进,脚本编排思路的来源。
  4. Git Worktrees + Claude Code: The 2026 Playbook — 多 agent 同仓库并行时分支冲突与 stash 混乱的成因与 worktree 解法。
  5. git-worktree(1) Manual Page — git worktree add/remove/lock/prune 完整命令参考,自定义 worktree 布局与清理的底层依据。

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入