> ## Documentation Index
> Fetch the complete documentation index at: https://aicoding.cscitech.top/llms.txt
> Use this file to discover all available pages before exploring further.

# 01-Worktree并行开发

> 用 Git Worktree 为 Codex 并行任务建立隔离工作目录，掌握分支、依赖、端口、合并冲突、清理回滚与安全验收。

## 你将完成什么

Git Worktree 允许同一仓库同时拥有多个工作目录。它适合让多个 Codex 任务并行开发，也适合在保留当前半成品的同时试验另一条方案。读完本页，你应该能够：

* 解释 worktree 共享什么、隔离什么；
* 创建、查看、锁定、移动、修复和删除工作树；
* 为并行任务分配独立分支、依赖、数据和端口；
* 让 Codex 在清晰边界内并行工作；
* 合并冲突、清理环境并在出错时回滚；
* 用可复现的证据完成安全验收。

命令以 macOS、Linux 和 Git Bash 为例。PowerShell 的环境变量写法另列。Git 或 Codex 版本有差异时，先运行 `git worktree --help`、`codex --help` 和具体子命令的帮助。

> Worktree 只隔离 Git 工作文件和 Git 状态。`.env`、`node_modules`、构建缓存、数据库和端口不会自动隔离。

## 01 原理：它隔离了什么

### 工作树、分支和共享元数据

一个仓库可以有一棵主工作树和多棵附加工作树：

```text theme={null}
workspace/
├── billing/                         # main
├── billing-wt-feature-invoice/      # feat/INV-42
└── billing-wt-fix-timeout/          # fix/API-17
```

每个工作树有自己的：

* 工作文件；
* `HEAD` 和索引；
* 未提交修改；
* 当前终端、开发服务器和调试进程。

它们共享同一套：

* 提交对象和历史；
* 本地分支与远程跟踪引用；
* Git 配置和对象数据库；
* worktree 注册信息。

所以 worktree 不是重新 clone，也不是远程仓库。创建它通常很快，但每个目录的依赖和构建输出仍可能独立占用磁盘。

### 它能解决什么，不能解决什么

适合并行的任务：

* 一个任务修 API，另一个开发不相关的前端页面；
* 一个任务重构，另一个只补测试或调查 CI；
* 保留稳定主线，同时在另一份目录进行可丢弃实验。

Worktree 不会自动解决：

* 两个任务修改同一文件后的逻辑冲突；
* 共享数据库、Redis、消息队列或第三方账号的相互污染；
* 开发服务器争用同一端口；
* 被 `.gitignore` 忽略的文件缺失；
* 锁文件或数据库迁移编号冲突。

它隔离的是目录和 Git 状态，不是整个运行环境。并行前必须同时规划文件、分支、依赖、数据、端口、进程和凭据。

### 同一分支只能在一处检出

一个本地分支同一时间只能在一个工作树中被检出。假设 `feature/profile` 已在另一个目录使用：

```bash theme={null}
git -C ../project-main switch feature/profile
```

Git 会拒绝操作，并提示类似：

```text theme={null}
fatal: 'feature/profile' is already used by worktree at '.../project-feature'
```

这是保护机制，不要编辑 `.git/worktrees` 内部文件强行绕过。应当在原工作树继续工作，切换原工作树到其他分支，或完成任务交接。

只查看某个提交可以用 detached HEAD：

```bash theme={null}
git worktree add --detach ../project-review HEAD
```

这适合复现和检查，不适合作为长期开发分支。需要保留实验结果时创建新分支：

```bash theme={null}
git switch -c experiment/profile-investigation
```

## 02 创建前检查

在仓库根目录执行，先确认路径、分支和工作区：

```bash theme={null}
pwd
git rev-parse --show-toplevel
git status --short --branch
git branch --show-current
git worktree list --porcelain
git remote -v
```

确认：

1. 当前目录是目标仓库，不是部署目录或相邻项目。
2. 当前未提交修改已经提交、备份，或明确属于哪个任务。
3. 目标基线是最新的，或者你知道它落后于远程多少。
4. 新目录位于明确的父目录，不会被同步盘或清理工具误删。
5. 任务不需要生产凭据、客户数据或不可恢复的外部操作。

只更新远程跟踪引用：

```bash theme={null}
git fetch --prune origin
git log -1 --oneline main
git status --short --branch
```

`fetch` 不会覆盖工作文件。不要在有未提交修改时盲目 `pull`、`reset` 或清理。

## 03 命令：创建、查看和管理

### 创建已有分支

```bash theme={null}
git worktree add ../project-profile feature/profile
```

### 从基线创建新分支

```bash theme={null}
git worktree add -b feature/profile ../project-profile main
```

从远程基线创建：

```bash theme={null}
git worktree add -b feature/profile ../project-profile origin/main
```

创建前先 `git fetch origin`，避免使用过期的本地基线。

### 查看工作树

人读的列表：

```bash theme={null}
git worktree list
```

脚本和排障用：

```bash theme={null}
git worktree list --porcelain
```

在指定工作树查看实际修改：

```bash theme={null}
git -C ../project-profile status --short --branch
git -C ../project-profile log -3 --oneline --decorate
```

列表确认“注册关系”，`status` 才能确认“工作区是否干净”，两者不要混淆。

### 锁定、解锁和移动

移动磁盘、网络挂载或暂时离线的工作树可以锁定：

```bash theme={null}
git worktree lock --reason "外接磁盘暂时离线" ../project-profile
git worktree unlock ../project-profile
```

锁定不会停止进程，也不是权限控制。移动目录时优先让 Git 更新登记：

```bash theme={null}
git worktree move ../project-profile ../worktrees/project-profile
git worktree list
```

目录已经被外部工具移动时，确认新路径确实是原工作树后再修复：

```bash theme={null}
git worktree repair ../worktrees/project-profile
```

### 删除和清理登记

删除干净的工作树：

```bash theme={null}
git worktree remove ../project-profile
```

Git 拒绝删除含未提交修改的工作树。只有在保存差异并确认内容可以丢弃后才使用：

```bash theme={null}
git worktree remove --force ../project-profile
```

如果目录已被外部删除，只清理失效登记：

```bash theme={null}
git worktree prune --dry-run
git worktree prune
```

`prune` 不能恢复被删除的目录。先用 `--dry-run` 查看范围。

## 04 分支和提交边界

### 一个任务一条分支

```bash theme={null}
git worktree add -b feat/INV-42 ../billing-wt-feature-invoice origin/main
git worktree add -b fix/API-17 ../billing-wt-fix-timeout origin/main
```

不要让两个 Codex 线程共享一个功能分支。每个任务独立提交、独立测试，才能明确责任、回滚和 PR 范围。

提交前：

```bash theme={null}
git -C ../billing-wt-feature-invoice diff --check
git -C ../billing-wt-feature-invoice diff --stat HEAD
git -C ../billing-wt-feature-invoice status --short --branch
```

使用路径精确暂存：

```bash theme={null}
git -C ../billing-wt-feature-invoice add src/invoice tests/invoice
git -C ../billing-wt-feature-invoice commit -m "feat: add invoice page"
```

不要对边界不清的任务直接执行 `git add .`。提交后记录 SHA：

```bash theme={null}
git -C ../billing-wt-feature-invoice log -1 --oneline --decorate
```

### 锁文件和迁移文件是共享冲突点

即使两个任务修改不同源文件，也可能同时修改：

* `package-lock.json`、`pnpm-lock.yaml`、`poetry.lock`、`go.sum`；
* 导出索引和注册表；
* 数据库迁移编号；
* CI、格式化配置和导航文件。

约束任务“不要升级无关依赖”。需要改依赖时，让一个任务负责生成锁文件，其他任务基于它的结果继续。数据库迁移编号必须在集成阶段重新检查。

## 05 依赖、配置和数据

### 新 worktree 缺少什么

Git 默认只检出已跟踪文件，以下内容通常不会出现：

* `node_modules`、`.venv`、`vendor`；
* `.env`、`.env.local` 和本地密钥；
* `dist`、`.next`、`coverage`；
* SQLite、上传目录、本地缓存；
* IDE 私有设置和未跟踪脚本。

不要整目录复制主工作树的依赖和配置。原生依赖可能与分支不匹配，真实密钥也可能被带入错误任务。

### 可重复初始化

优先使用项目已有的 setup 脚本或 Codex local environment setup。示例：

```bash theme={null}
#!/usr/bin/env bash
set -euo pipefail
corepack enable
pnpm install --frozen-lockfile
pnpm run typecheck
```

setup 应满足：

* 使用锁文件安装；
* 可重复执行；
* 不打印令牌；
* 不连接生产服务；
* 任一步失败立即退出。

安全生成本地配置：

```bash theme={null}
cp .env.example .env.local
```

真实凭据使用操作系统凭据管理器、临时环境变量或最小权限测试账号。不要让 Codex 读取不需要的密钥，也不要把 `.env` 放入补丁和日志。

### 容器和数据库

为每个工作树使用独立 Compose 项目和数据卷：

```bash theme={null}
docker compose -p billing-inv42 up -d db
docker compose -p billing-inv42 down
```

不要执行不带项目名的全局 `docker compose down`，它可能停止其他工作树的服务。测试数据库、schema、Redis 和消息主题都应有任务级命名。

## 06 端口和进程隔离

### 预先分配端口

端口表示例：

| 任务     |  Web |  API | 数据库                  |
| ------ | ---: | ---: | -------------------- |
| main   | 3000 | 8000 | billing\_dev         |
| INV-42 | 3011 | 8011 | billing\_inv42\_test |
| API-17 | 3012 | 8012 | billing\_api17\_test |

启动时显式传入：

```bash theme={null}
WEB_PORT=3011 API_PORT=8011 pnpm dev
```

PowerShell：

```powershell theme={null}
$env:WEB_PORT="3011"; $env:API_PORT="8011"; pnpm dev
```

除了 Web 和 API，还要考虑 Vite、Storybook、调试器、数据库、Redis、队列和监控面板。端口应写进 Codex 任务说明。

### 启动前和启动后检查

macOS/Linux/Git Bash：

```bash theme={null}
( command -v lsof >/dev/null && lsof -nP -iTCP:3011 -sTCP:LISTEN ) || true
curl -fsS http://127.0.0.1:8011/health
```

PowerShell：

```powershell theme={null}
Get-NetTCPConnection -LocalPort 3011 -State Listen -ErrorAction SilentlyContinue
```

发现占用时先查进程所属工作树，再换端口或有序停止。不要批量杀掉所有 Node、Python 或 Java 进程。记录 PID、工作目录和日志；验收后停止进程并确认端口释放。

## 07 Codex 并行任务

### 拆分原则

适合并行的任务具有清晰文件边界、低耦合和独立验收条件。不适合并行的任务包括：都修改同一个配置或锁文件、后者依赖前者尚未提交的接口、都迁移同一张表、都使用同一测试环境。

有先后依赖时，先提交并验证前一个任务，再从它的分支创建后一个工作树。

### CLI 工作流

Codex CLI 是否有内置 worktree 参数取决于版本，不要猜：

```bash theme={null}
codex --help
codex exec --help
```

稳妥做法是先用 Git 创建，再从目标目录启动：

```bash theme={null}
cd ../billing-wt-feature-invoice
codex
```

任务提示应包括目录、分支、允许文件、禁止事项、端口和验收命令：

```text theme={null}
你现在位于 ../billing-wt-feature-invoice，分支 feat/INV-42。
目标：实现发票列表页面，只修改 src/invoice、src/routes/invoice.tsx 和对应测试。
约束：不要修改数据库迁移、依赖锁文件或 .env；不要访问生产服务。
端口：前端 3011，API 8011。
完成标准：运行 pnpm test -- invoice 和 pnpm typecheck，报告 diff、测试输出和风险。
不要 commit、push 或 merge，除非我明确授权。
```

### Desktop Worktree 模式

Codex Desktop 不同版本的入口和按钮名称可能变化，按当前界面为准。核心步骤是：

1. 在 Git 仓库中新建线程并选择 Worktree。
2. 选择起始分支或提交。
3. 写明文件范围、依赖初始化、端口和验收命令。
4. 运行后用 `git worktree list` 确认目录独立。
5. 完成后查看 diff、测试和分支，再决定交接、提交或清理。

某些版本先创建 detached HEAD。要保留改动时，在确认归属后创建分支：

```bash theme={null}
git switch -c feat/INV-42
```

Handoff 可以在 Local 与 Worktree 之间交接线程，但不会携带 `.gitignore` 文件。交接前后检查 `.env`、依赖、数据库和端口。

### 任务登记

| 工作树                          | 分支             | 任务   | Web/API   | 状态  |
| ---------------------------- | -------------- | ---- | --------- | --- |
| `billing`                    | `main`         | 集成   | 3000/8000 | 稳定  |
| `billing-wt-feature-invoice` | `feat/INV-42`  | 发票页面 | 3011/8011 | 开发中 |
| `billing-wt-fix-timeout`     | `fix/API-17`   | 超时修复 | 3012/8012 | 开发中 |
| `billing-wt-test-contract`   | detached 或检查分支 | 只读验证 | 无         | 检查  |

## 08 完整案例：两个任务并行到合并

### 1. 准备和创建

```bash theme={null}
cd /work/billing
git fetch --prune origin
git status --short --branch
git worktree list --porcelain
git worktree add -b feat/INV-42 ../billing-wt-feature-invoice origin/main
git worktree add -b fix/API-17 ../billing-wt-fix-timeout origin/main
git worktree list
```

若主工作树有半成品，先保存证据：

```bash theme={null}
git diff > /tmp/billing-main.patch
git diff --staged > /tmp/billing-main-staged.patch
git ls-files --others --exclude-standard > /tmp/billing-untracked.txt
```

### 2. 初始化和启动

```bash theme={null}
cd ../billing-wt-feature-invoice
pnpm install --frozen-lockfile
cp .env.example .env.local

cd ../billing-wt-fix-timeout
pnpm install --frozen-lockfile
cp .env.example .env.local
```

分别使用 `3011/8011` 和 `3012/8012`，并使用不同测试数据库。启动两个 Codex 会话后，给它们互不重叠的文件范围：

```text theme={null}
INV-42：只修改发票页面和测试；运行 pnpm test -- invoice、pnpm typecheck。
API-17：只修改 API 客户端、超时处理和测试；运行 pnpm test -- api、pnpm typecheck。
```

两边都要求先列计划、展示 diff、不要自动提交或推送。发现它要求修改范围外的文件时先暂停。

### 3. 独立验收和提交

```bash theme={null}
cd ../billing-wt-feature-invoice
git status --short --branch
git diff --check
git diff --stat
pnpm test -- invoice
pnpm typecheck
git add src/invoice src/routes/invoice.tsx tests/invoice
git commit -m "feat: add invoice list page"

cd ../billing-wt-fix-timeout
git status --short --branch
git diff --check
git diff --stat
pnpm test -- api
pnpm typecheck
git add src/api/client.ts src/api/timeout.ts tests/api
git commit -m "fix: handle API request timeout"
```

提交后记录：

```bash theme={null}
git log -1 --oneline --decorate
```

### 4. 集成和总验收

在主工作树：

```bash theme={null}
cd /work/billing
git status --short --branch
git switch main
git pull --ff-only origin main
git merge --no-ff feat/INV-42
git merge --no-ff fix/API-17
pnpm install --frozen-lockfile
pnpm test
pnpm typecheck
pnpm build
```

如果采用 PR，则分别推送分支，在 GitHub 审查后合并。不要使用 `git push --force`。即使两个分支各自通过，合并后也必须重新执行集成验收。

## 09 合并冲突

### 识别和保存现场

冲突常发生于路由、导出索引、锁文件、迁移、CI 和导航。开始合并后：

```bash theme={null}
git status
git diff --name-only --diff-filter=U
git diff > /tmp/merge-conflict.patch
```

不要让 Codex 在不知道基线和意图时直接“解决全部冲突”。

### 标准流程

```bash theme={null}
git switch main
git merge --no-ff feat/INV-42
```

逐个理解 `<<<<<<<`、`=======`、`>>>>>>>` 两边行为，结合测试和需求编辑。完成后：

```bash theme={null}
git add path/to/resolved-file
git diff --cached --check
git diff --cached
# 确认后提交
 git commit
```

无法安全解决时：

```bash theme={null}
git merge --abort
```

检查残留冲突标记：

```bash theme={null}
rg -n '^(<<<<<<<|=======|>>>>>>>)' .
git diff --check
```

### 让 Codex 协助分析

先只读分析：

```text theme={null}
当前把 feat/INV-42 合并到 main。请只读取冲突文件和相关测试，说明两边行为、回归风险和推荐方案。
不要编辑、提交、推送或访问外部系统。等我确认方案后再修改。
```

授权后仍要人工查看完整 diff 和测试结果。

## 10 清理、归档和恢复

### 删除前清单

确认以下事项后再删除：

* 分支已合并，或明确放弃；
* `status`、工作差异和未跟踪文件已经检查；
* 服务、容器、调试器和后台 Codex 已停止；
* 测试数据库和临时数据已清理；
* SHA、日志和测试报告已保存；
* 备份中没有真实密钥和客户数据。

检查并删除：

```bash theme={null}
git -C ../billing-wt-feature-invoice status --short --branch
git -C ../billing-wt-feature-invoice log -5 --oneline --decorate
git worktree list --porcelain
docker compose -p billing-inv42 down
git worktree remove ../billing-wt-feature-invoice
git branch -d feat/INV-42
git worktree prune --dry-run
```

未合并分支会被 `git branch -d` 拒绝。只有确认任务放弃并保存必要证据后才考虑 `git branch -D`。删除工作树不等于删除远程分支，远程分支按 PR 和团队规则处理。

### Codex Desktop 托管工作树

Desktop 可能把托管 worktree 放在 `CODEX_HOME` 下的 `worktrees` 目录，默认通常类似 `~/.codex/worktrees`。自动清理上限、快照和永久 worktree 规则以当前版本设置为准。

归档或删除前确认线程是否仍运行、是否置顶、是否有未提交改动、快照是否可恢复。快照不能替代提交、补丁和外部数据备份；不要仅凭目录名手动删除。

### 错误改动的回滚

先保存现场：

```bash theme={null}
git diff > /tmp/task.patch
git diff --staged > /tmp/task-staged.patch
git ls-files --others --exclude-standard > /tmp/task-untracked.txt
```

撤销明确文件前确认没有同事的修改：

```bash theme={null}
git restore --source=HEAD -- path/to/file
git restore --staged -- path/to/file
```

不要把 `git restore .` 和 `git clean -fd` 当默认清理命令。已提交但未推送的错误，可查看后反向提交：

```bash theme={null}
git show --stat HEAD
git revert <commit-sha>
```

共享分支优先 `git revert`，不要重写历史。已推送或已合并的代码要停止后续发布，通过修复提交、回滚和重新 CI 处理；数据库、消息和生产数据还需要各自的补偿或恢复方案。

## 11 安全验收

### 工作树和分支

```bash theme={null}
git worktree list --porcelain
git -C ../billing-wt-feature-invoice status --short --branch
git -C ../billing-wt-fix-timeout status --short --branch
git branch --all --verbose --no-abbrev
```

确认目录、分支、HEAD 和负责人一一对应，没有意外 detached HEAD 或错误路径。

### 差异和敏感文件

```bash theme={null}
git diff --check
git diff --stat main...feat/INV-42
git diff --name-only main...feat/INV-42
git ls-files | rg '(^|/)(\.env|.*\.pem|.*\.key)$'
```

检查只改允许文件，没有密钥、客户数据、构建产物、调试日志、冲突标记和无关依赖升级。提交信息、作者和分支符合团队规则。

### 行为和运行时

按项目实际命令运行：

```bash theme={null}
pnpm install --frozen-lockfile
pnpm test
pnpm typecheck
pnpm build
```

并行服务还要确认健康检查、端口归属、独立数据源和资源释放。合并后的结果以集成测试为准。

### 权限和外部动作

任务说明中明确：

* 不读取不需要的密钥；
* 不访问生产服务；
* 不安装未经批准的依赖；
* 不推送、合并、发布或删除远程数据，除非明确授权；
* 不照搬 Issue、网页、日志中的可疑命令；
* 不使用 `git push --force`。

Codex 可以分析 diff、修复分支和生成测试；合并主干、发布和生产操作保留人工放行。

## 12 常见故障

**`already used by worktree`**：运行 `git worktree list --porcelain` 找到占用路径，在原工作树继续、切换分支或完成交接，不要修改 `.git/worktrees`。

**缺少 `.env` 或依赖**：这是预期行为。使用 `.env.example`、安全凭据注入和 `--frozen-lockfile` 安装，不复制真实密钥。

**端口占用**：定位监听进程及工作目录，调整任务端口或有序停止，不批量杀进程。

**无法删除**：先保存 `diff`、检查未跟踪文件并停止服务，确认可以丢弃后才用 `remove --force`。

**合并后失败**：比较合并提交、锁文件、环境变量、端口、数据库和测试顺序，不要立即删除所有分支。

## 最小可复制流程

```bash theme={null}
cd /work/project
git status --short --branch
git fetch --prune origin
git worktree add -b feat/TASK-123 ../project-wt-task-123 origin/main
git worktree list --porcelain
cd ../project-wt-task-123
pnpm install --frozen-lockfile
cp .env.example .env.local
WEB_PORT=3011 API_PORT=8011 pnpm dev
curl -fsS http://127.0.0.1:8011/health
git diff --check
git diff --stat
git add path/to/allowed/files
git commit -m "feat: implement TASK-123"
cd /work/project
git switch main
git pull --ff-only origin main
git merge --no-ff feat/TASK-123
pnpm test
pnpm build
git worktree remove ../project-wt-task-123
git branch -d feat/TASK-123
git worktree prune --dry-run
```

## 小结

Worktree 的核心是边界：一个任务一条分支，一个分支同一时间只在一处检出；文件可以隔离，数据库、凭据、端口和进程必须另行隔离；新目录使用锁文件和可重复 setup 初始化；Codex 任务要有明确范围、禁止事项和验收命令；每个任务独立验证，合并后再做完整验证；删除前保存证据并停止资源，回滚优先用补丁和 `git revert`；合并、发布、强推和生产操作保留人工确认。

参考资料：`参考/codex/25-worktrees.md`、`参考/codex/26-git-github.md`、`参考/codex/31-speed.md`。
