name: git-worktrees description: 使用Git工作树进行隔离的并行开发。适用于开始独立功能工作、需要独立工作空间而无需切换分支,或在PR合并后清理工作树时。
Git 工作树
概述
Git 工作树创建隔离的工作区,共享同一个仓库,允许同时处理多个分支而无需切换。每个工作树是一个独立的目录,拥有自己的工作树,但它们共享相同的 .git 历史。
何时使用工作树
- 并行开发:在处理功能A时,同时让功能B构建/测试
- 代码审查:检出PR分支而不干扰当前工作
- 实验:尝试有风险的操作而不影响主要工作区
- 长期任务:在功能开发期间保持主分支可用
快速参考
| 操作 | 命令 |
|---|---|
| 列出工作树 | git worktree list |
| 创建工作树 | git worktree add <路径> -b <分支> |
| 从现有分支创建 | git worktree add <路径> <分支> |
| 移除工作树 | git worktree remove <路径> |
| 清理过时工作树 | git worktree prune |
创建工作树
新功能分支
# 创建带有新分支的工作树
git worktree add .worktrees/my-feature -b feat/my-feature
# 或指定基础分支
git worktree add .worktrees/my-feature -b feat/my-feature main
从现有分支创建
# 检出现有远程分支
git worktree add .worktrees/pr-review origin/fix-bug
# 检出现有本地分支
git worktree add .worktrees/hotfix hotfix/urgent-fix
目录结构
项目/
├── .git/ # 共享的git历史
├── .worktrees/ # 约定:将工作树放在这里
│ ├── feature-a/ # 第一个工作树
│ └── feature-b/ # 第二个工作树
└── src/ # 主要工作树文件
创建工作树后的设置
创建工作树后,通常需要:
cd .worktrees/my-feature
# 安装依赖
npm install # 或 pnpm install, yarn 等
# 复制必要的环境文件
cp ../.env .env.local
# 验证设置
npm test
安全规则
切勿未经确认移除具有未提交更改的工作树。
# 首先检查未提交更改
git -C .worktrees/my-feature status --porcelain
# 如果为空,安全移除
git worktree remove .worktrees/my-feature
# 合并后删除分支(-d 安全,如果未合并会失败)
git branch -d feat/my-feature
移除决策矩阵
| PR是否合并? | 有未提交更改? | 操作 |
|---|---|---|
| 是 | 否 | 安全移除 |
| 是 | 是 | 询问用户 - 更改将丢失 |
| 否 | 否 | 请勿移除 - 工作未保存 |
| 否 | 是 | 请勿移除 - 活跃工作 |
清理工作树
手动清理
# 1. 检查工作是否已合并(如果使用GitHub)
gh pr list --head feat/my-feature --state merged
# 2. 检查未提交更改
git -C .worktrees/my-feature status --porcelain
# 3. 移除工作树(仅当已合并或用户确认)
git worktree remove .worktrees/my-feature
# 4. 删除分支
git branch -d feat/my-feature
清理过时工作树
如果工作树目录被手动删除:
git worktree prune
常见模式
审查PR
# 从PR分支创建工作树
git fetch origin pull/123/head:pr-123
git worktree add .worktrees/pr-123 pr-123
# 审查、测试,然后清理
git worktree remove .worktrees/pr-123
git branch -D pr-123
并行功能开发
# 主要工作在项目根目录继续
# 在工作树中开始新功能
git worktree add .worktrees/new-api -b feat/new-api
# 同时处理两者
code .worktrees/new-api # 打开新VS Code窗口
故障排除
“分支已检出”
一个分支一次只能在一个工作树中检出:
# 查找分支被检出的位置
git worktree list
# 先移除该工作树,或使用不同分支
“工作树目录非空”
# 如果目录存在但不是工作树,强制添加
git worktree add --force <路径> <分支>
锁定工作树
如果工作树被锁定(防止意外移除):
# 解锁它
git worktree unlock <路径>
# 然后移除
git worktree remove <路径>