前情提要
缘起:AI 并发能力与传统 Git 工作流的碰撞
接触到 git worktree 的直接原因,是在使用 Claude Code 辅助编程时遇到的文件系统层面的物理瓶颈。当试图让 AI Agent 在同一个代码项目中并行开发两个不同的需求 时,由于传统的 Git 仓库在同一时刻只能检出一个工作分支,导致多个 AI 任务无法在同一个工作目录下同时运行。为了给不同的 Agent 提供独立的物理执行环境,我找到了 git worktree 。
什么是 Git Worktree?
平时我们用 git checkout 切换分支时,文件会在同一个文件夹里变来变去。如果你正在写一个大功能,写到一半突然需要去修复一个紧急 Bug,通常只能用 git stash 把代码藏起来,或者先提交一个乱糟糟的 commit。
git worktree 是 Git 提供的一个强大的高级功能,它允许你在同一个本地 Git 仓库中,同时检出(checkout)多个不同的分支到不同的物理文件目录中。
常用命令速查
1. 添加新的工作区 语法:git worktree add <路径> <分支名>
示例 :假设你当前在 my-project 目录下,想在同级目录创建一个名为 my-project-hotfix 的文件夹,并检出 master 分支:
plain
git worktree add ../my-project-hotfix master
如果你想基于当前分支创建一个新分支并检出到新工作区,可以加上 _-b_ 参数:
plain
git worktree add -b hotfix/bug-123 ../my-project-hotfix master
2. 查看当前所有的工作区 可以列出当前仓库关联的所有物理路径及其对应的分支:
plain
git worktree list
3. 移除工作区 当你完成了紧急修复,不再需要那个目录时,可以使用命令安全移除:
plain
git worktree remove ../my-project-hotfix
(注意:移除前请确保该工作区没有未提交的更改,否则 Git 会阻止你删除。可以加 _-f_ 强制移除。)
4. 清理失效的工作区 如果你习惯直接在文件系统中"暴力"删除了工作区文件夹(右键 -> 删除),Git 的内部记录里可能还会保留它的追踪信息。运行以下命令可以清理掉这些失效的记录:
plain
git worktree prune
怎么玩(How)
首先,创建一个 Git 仓库
bash
mkdir ml-pipeline
cd ml-pipeline
git init
在这个仓库里添加 README.md 和一个 Python 文件
bash
echo "# ML Pipeline" > README.md
echo "def load_data():" > train.py
echo " print('Loading training data...')" >> train.py
commit 并且创建一个分支
bash
git add .
git commit -m "Initial commit"
git branch feature-preprocessing
现在你得到了一个有 2 个分支的 Git 仓库: main 和 feature-preprocessing 。
为现有分支创建工作树,只需一个命令:
bash
git worktree add ../ml-pipeline-preprocessing feature-preprocessing
这一步在当前位置的上一层级创建了一个名为: ml-pipeline-preprocessing 的文件夹

接下来为另一个全新的工作,同时创建一个分支和一个工作树:
bash
git worktree add -b feature-visualization ../ml-pipeline-viz
-b 的意思是创建 feature-visualization 分支并在新的工作树中检出该分支
worktree的结构:
bash
git worktree list

第一行显示你的主工作树 ------ 包含.git文件夹的原始目录。第二行显示你的链接工作树。两行都显示当前的提交哈希和已检出的分支。

每个worktree目录都有完整的Git仓库功能。你可以进入目录,编辑文件,执行 git status ,并且 commit 。但是链接的worktrees没有完整的 .git 文件夹,而是使用一个 .git 文件用来指向主仓库。在主.git目录内部,有一个worktrees文件夹,用于存储每个链接工作树的元数据。


在 worktree 中工作
接下来,可以进入 feature-preprocessing 并完成提交:
bash
cd ../ml-pipeline-preprocessing
cat >> train.py << 'EOF'
def preprocess_features(df):
"""Normalize numeric features."""
return (df - df.mean()) / df.std()
EOF
git add train.py
git commit -m "Add feature preprocessing function"

回到 main worktree 并且查看提交历史:
bash
cd ../ml-pipeline
git log --oneline --all


在 Worktree 目录中提交所有修改
bash
# 进入你的 worktree 物理目录
cd ../feature-worktree
# 确认你在 feature-A 分支上
git branch
# 暂存并提交你的所有修改
git add .
git commit -m "feat: 完成在 worktree 中的开发"
过河拆桥(清理 Worktree)
代码合并完并推送到远端后,那个额外的物理文件夹和分支就没有利用价值了。为了保持环境整洁,建议安全地删掉它们:
bash
# 1. 安全移除物理工作区(注意路径要写对)
git worktree remove ../feature-worktree
# 2. 删除已经合并完毕的本地分支
git branch -d feature-A
Git Worktree 使用案例
并行开发(Parallel feature development)
你正在实现自定义指标和一个新的数据加载器 ------ 这是两个独立的功能。为每个功能设置一个工作树:
bash
git worktree add -b feature-custom-metrics ../ml-pipeline-metrics
git worktree add -b feature-streaming-loader ../ml-pipeline-loader
现在的文件夹目录结构如下:
bash
~/projects/
ml-pipeline/ [main] - your usual work
ml-pipeline-metrics/ [feature-custom-metrics]
ml-pipeline-loader/ [feature-streaming-loader]
现在可以分别在各自的终端运行(并行)这两个功能:
bash
# Terminal 1
cd ~/projects/ml-pipeline-metrics
python experiments/evaluate_custom_metrics.py
# Terminal 2
cd ~/projects/ml-pipeline-loader
pytest tests/test_data_loader.py -v
两个进程会同时运行且不会产生冲突。当一个功能完成后,将其合并并移除工作树:
bash
cd ~/projects/ml-pipeline
git merge feature-custom-metrics
git worktree remove ../ml-pipeline-metrics