跳至主要内容

Git Worktree 教程:无需切换即可在多个分支上工作

一份实用的 Git worktree 教程,展示如何同时在多个分支上工作、加速评审,并避免暂存或频繁切换上下文。
· 9分钟 阅读

使用 AI 探索

您正在一个功能分支上开发,这时队友请您评审他们的 Pull Request。您可以把改动暂存、切换分支,然后指望自己还能记得刚才做到哪。或者您也可以提交未完成的工作,只为避免丢失。再比如紧急热修:生产环境挂了,而您正深入进行一次涉及半个代码库的重构。每一次这样的上下文切换都会花费 10–15 分钟的准备时间,并打断您的专注。

Git worktree 通过允许您在独立目录中同时检出多个分支来解决这一问题。与其暂存或提交未完成的工作,您只需 cd 到另一个已检出其他分支的目录。在那里完成热修并部署,然后再 cd 回到功能分支,继续上次停下的地方。

在本教程中,我将向您展示如何创建和管理 worktree,避开常见陷阱,并将其融入日常工作流。您应当已了解 Git 的分支、提交以及基础命令行操作。如果您需要先复习 Git 基础,我推荐 DataCamp 的《Git 入门》教程来覆盖要点。

什么是 Git Worktree?

Git worktree 是一个内置功能,可创建与同一仓库关联的额外工作目录。您的主工作目录是主 worktree,每个新增的 worktree 都有自己的目录,并检出自己的分支。所有这些 worktree 都连接到同一个 .git 仓库。

图示仓库架构——中心为带有 .git 文件夹的主 worktree,多个链接的 worktree 指向它。箭头标注“共享 commits/branches/refs” 与 “各 worktree 目录中的独立工作文件”

这种共享仓库架构意味着您在任一 worktree 中的提交会立即出现在共享的 Git 数据库中,其他所有 worktree 都能访问。而文件本身彼此独立——在一个 worktree 中编辑 train.py 只会影响该目录,直到您提交更改。

为什么不直接用多个终端?

您无法在同一目录下打开多个终端并同时在不同分支上工作。Git 只允许每个目录同时检出一个分支。当您在某个终端运行 git checkout feature-b 时,会改变指向该目录的所有终端中的文件。

Git worktree 为每个分支提供独立目录来解决这个问题。每个目录都完全独立,拥有自己的文件、运行进程和构建产物。切换分支就变成了 cd ../different-directory,而不是 git checkout different-branch。

Git Worktree 的前置条件

在使用 git worktree 前,请确认您的环境:

  • Git 2.5 或更高版本:运行 git --version 进行检查。Git worktree 于 2015 年发布,大多数安装均已支持
  • 已有 Git 仓库:您需要一个至少包含一个分支的仓库
  • 熟悉命令行:所有 worktree 操作都在终端中进行

检查 worktree 是否可用:

git worktree --help

如果显示帮助页面,说明您已就绪。

何时使用 git worktree

当切换分支会打断您当前工作时,Git worktree 表现很出色:

  • 代码评审:在不暂存功能分支工作的情况下测试队友的改动
  • 紧急热修:修复生产故障,同时保持您的重构不受影响
  • 并行开发:在两个彼此独立的功能上工作,无需频繁切换分支
  • 长时间运行的进程:启动一套 30 分钟的测试,同时在另一个 worktree 里继续编码

对于 10 分钟内能完成的快速任务,可跳过使用,直接用 git checkout 更简单;或者当您专注于单一工作且预计不会被打断时,也不必使用。

创建您的第一个 Worktree

理解 git worktree 的最佳方式是创建一个并亲自体验。我们将演练基础命令、探索 Git 创建的结构,并观察更改如何在各个 worktree 之间流动。

设置示例仓库

在深入使用 worktree 之前,您需要一个 Git 仓库。如果您已有包含多个分支的 Python 项目,请跳到下一节。否则,让我们快速搭建一个简单的 ML 流水线:

mkdir ml-pipeline
cd ml-pipeline
git init

创建一个 README 和一个 Python 脚本:

echo "# ML Pipeline" > README.md
echo "def load_data():" > train.py
echo "    print('Loading training data...')" >> train.py

确认文件已创建:

ls
# You should see: README.md  train.py

提交这些文件并创建一个功能分支:

git add .
git commit -m "Initial commit"
git branch feature-preprocessing

现在您有一个包含两个分支的仓库:main(您当前的分支)和 feature-preprocessing。

基础的 worktree 创建

为现有分支创建一个 worktree 只需一条命令。让我们在单独目录中检出 feature-preprocessing:

git worktree add ../ml-pipeline-preprocessing feature-preprocessing

这会在您当前位置的上一级创建名为 ml-pipeline-preprocessing 的新目录,在其中检出 feature-preprocessing 分支,并将其链接到您现有的仓库。

Git 会确认创建结果:

Preparing worktree (checking out 'feature-preprocessing')
HEAD is now at 0a7f986 Initial commit

对于全新的工作,可以同时创建分支和 worktree:

git worktree add -b feature-visualization ../ml-pipeline-viz

-b 标志会创建一个名为 feature-visualization 的新分支,并在新 worktree 中检出它。

探索 worktree 结构

创建好 worktree 后,您的文件系统上会出现多个目录。要查看它们:

git worktree list
/Users/you/projects/ml-pipeline                  0a7f986 [main]
/Users/you/projects/ml-pipeline-preprocessing    0a7f986 [feature-preprocessing]

第一行显示您的主 worktree——包含 .git 文件夹的原始目录。第二行显示链接的 worktree。两者都会显示当前提交哈希和已检出的分支。

图片占位符:文件系统图示展示 worktree 之间的关系。主目录 ml-pipeline/ 包含带有 worktrees/ 子目录的 .git/ 文件夹。链接的 worktree ml-pipeline-preprocessing/ 包含一个 .git 文件(非文件夹),指向主 .git/。两个目录都显示其各自文件(README.md、train.py),但共享同一 Git 数据库。

每个 worktree 目录的功能就像一个完整的 Git 仓库。您可以进入其中、编辑文件、运行 git status 并进行提交。链接的 worktree 不包含完整的 .git 目录——它们有一个指向主仓库的 .git 文件。在主 .git 目录中,worktrees 文件夹存储每个链接 worktree 的元数据。

在 worktree 中工作

进入 feature-preprocessing 的 worktree 并进行一次提交:

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"

提交会正常进行:

[feature-preprocessing 7c8d4e2] Add feature preprocessing function
1 file changed, 3 insertions(+)

回到您的主 worktree 并查看提交历史:

cd ../ml-pipeline
git log --oneline --all

您会看到新的提交:

7c8d4e2 Add feature preprocessing function
0a7f986 Initial commit

注意,这个提交会立即出现在两个位置,无需任何额外命令。

Git Worktree 的使用场景

现在您已了解如何创建并在 worktree 中工作,我们来看看它们在解决实际开发问题时的应用场景。

代码评审工作流

队友需要您对他们的 PR 提出反馈。与其暂存更改并切换分支,不如为评审创建一个单独目录:

git worktree add ../ml-pipeline-review pr/update-training
cd ../ml-pipeline-review
pip install -r requirements.txt
python train_model.py --config experiments/baseline.yaml

测试更改并留下反馈。完成后:

cd ../ml-pipeline
git worktree remove ../ml-pipeline-review

您原本的工作保持不变。无需暂存,也无需切换上下文。若想了解更多高效代码评审的策略,请查看 DataCamp 的代码最佳实践指南。

紧急热修

如果没有 worktree:

  • 把重构改动存放到某处(stash 或 WIP 提交)
  • 检出主分支
  • 修复缺陷
  • 推送到生产
  • 检出功能分支
  • 恢复您的改动(取消暂存或回退 WIP 提交)
  • 重新建立您此前工作的心理上下文

并排的工作流对比。左侧“传统方法”:显示 7 个顺序步骤及箭头(stash → checkout → fix → push → checkout → unstash → 恢复上下文),耗时 15+ 分钟。右侧“使用 worktree”:显示 3 个并行框(主 worktree 继续工作、hotfix worktree 创建/修复/移除),耗时 2 分钟,配合简单的 cd 命令。

使用 worktree:

git worktree add ../ml-pipeline-hotfix main
cd ../ml-pipeline-hotfix

修复并部署:

git add src/data/validation.py
git commit -m "Fix schema validation for nullable timestamp fields"
git push origin main
cd ../ml-pipeline
git worktree remove ../ml-pipeline-hotfix

几秒钟后,您就能回到重构工作,所有文件都与离开时完全一致。

并行开发功能

您正在实现自定义指标和新的数据加载器——两个彼此独立的功能。为各自设置一个 worktree:

git worktree add -b feature-custom-metrics ../ml-pipeline-metrics
git worktree add -b feature-streaming-loader ../ml-pipeline-loader

您的文件系统现在看起来像这样:

~/projects/
 ml-pipeline/           [main] - your usual work
 ml-pipeline-metrics/   [feature-custom-metrics]
 ml-pipeline-loader/    [feature-streaming-loader]

并行运行这两个功能——各自在自己的终端中:

# 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

两个进程可同时运行,互不冲突。功能完成后,合并并移除对应的 worktree:

cd ~/projects/ml-pipeline
git merge feature-custom-metrics
git worktree remove ../ml-pipeline-metrics

管理与清理 Worktree

流程图展示 worktree 生命周期——创建 → 工作 → 提交 → 移除/修剪,含决策点:“完成工作?”、“状态干净?”、“手动删除?”

列出 worktree

查看仓库中的所有 worktree:

git worktree list
/Users/you/projects/ml-pipeline                  a3f9c81 [main]
/Users/you/projects/ml-pipeline-review           b7d4e92 [pr/data-validation]
/Users/you/projects/ml-pipeline-hotfix           a3f9c81 [hotfix/schema-bug]

每一行显示目录路径、当前提交哈希和已检出的分支。第一条始终是您的主 worktree(包含 .git 文件夹),其余为链接的 worktree。

用于脚本或快速导航时,只提取路径:

git worktree list | awk '{print $1}'

移除 worktree

完成某个 worktree 的工作后,请正确移除:

cd ~/projects/ml-pipeline
git worktree remove ../ml-pipeline-review

Git 会防止数据丢失。如果存在未提交的更改:

git worktree remove ../ml-pipeline-review
fatal: '../ml-pipeline-review' contains modified or untracked files, use --force to delete it

若确定无误,可强制移除:

git worktree remove --force ../ml-pipeline-review

如果某个 worktree 被锁定,可使用两次 --force:

git worktree remove --force --force ../ml-pipeline-locked

如果您手动删除了 worktree 目录(rm -rf 或通过文件管理器),Git 仍会在内部跟踪它。清理陈旧引用:

git worktree prune

预览将要被清理的内容:

git worktree prune --dry-run

最佳实践与常见陷阱

下面看看如何最大化发挥 worktree 的价值,以及如何避免一些常见错误。

Worktree 的组织方式

worktree 的放置位置很重要。多数开发者把它们放在主仓库的兄弟目录中:

~/projects/
 ml-pipeline/                    # main worktree
 ml-pipeline-feature-auth/       # linked worktree
 ml-pipeline-hotfix-login/       # linked worktree

这样的结构能把一切放在同一处,并让路径可预期。projectname-branchname 的命名模式能直接告诉您每个目录的内容。

也有开发者偏好使用专用文件夹:

~/projects/
 ml-pipeline/                    # main worktree
 ml-pipeline-worktrees/
   feature-auth/
   hotfix-login/

选择一种方式并始终如一地使用。像 ml-pipeline-user-authentication 这样的描述性名称能让目录自我说明;而 ml-pipeline-temp 或 ml-pipeline-2 之类的通用名会迫使您打开查看。把 worktree 当作临时性资源——为特定任务创建,用完就移除。

常见陷阱

同一分支在多个 worktree 中

Git 会阻止在两个 worktree 中检出同一分支:

git worktree add ../ml-pipeline-duplicate main
fatal: 'main' is already used by worktree at '/Users/you/projects/ml-pipeline'

这种保护是因为您可能会产生相互冲突的提交。如果您需要在两个位置拥有相同代码,请创建一个新分支。

遗忘的 worktree 与磁盘空间

每个 worktree 都会保留在文件系统中,直到您明确移除。旧的 worktree 会越积越多;项目可能会堆到 15 个以上被遗忘的 worktree,消耗数 GB 的空间。

每个 worktree 都包含仓库文件的完整副本。一个 500MB 的仓库配 5 个 worktree 就会占用 2.5GB。完成后请移除 worktree:

git worktree list
git worktree remove ../ml-pipeline-old-feature

嵌套创建 worktree

不要在另一个 worktree 的目录内再创建 worktree。Git 虽然允许这么做,但会导致混乱的目录结构,并让清理变得容易出错。

工作流优化

如果您经常创建 worktree,可以用 Shell 别名节省时间:

alias gwl='git worktree list'
alias gwa='git worktree add'
alias gwr='git worktree remove'

更复杂的设置可以写一个函数,一步创建 worktree 并配置开发环境:

wt() {
 git worktree add "../${PWD##*/}-$1" -b "$1"
 cd "../${PWD##*/}-$1"
 python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt
}

${PWD##*/} 会提取您当前目录名。于 ml-pipeline 中运行 wt feature-logging 会创建 ml-pipeline-feature-logging,进入其中,并用依赖配置好 Python 虚拟环境。

创建 worktree 将变成一条命令:

wt feature-custom-metrics

可按您的语言栈调整:Ruby 用 bundle install,Rust 用 cargo build,Node.js 用 npm install。

您的编辑器或 IDE 无需特殊配置即可与 worktree 协同工作。每个 worktree 都只是一个目录,像打开其他项目文件夹一样打开即可。多数现代编辑器支持同时打开多个项目根目录——您可以在一个窗口中打开三个 worktree,并在侧边栏之间切换。

进阶 Worktree:AI 助力的并行开发

如果您使用 AI 编码助手,worktree 能解锁强大的并行工作流。这种做法在 2024–2025 年间在开发者与团队中愈发流行。

为不同任务创建独立的 worktree:

git worktree add -b feature-add-logging ../ml-pipeline-logging
git worktree add -b feature-optimize-preprocessing ../ml-pipeline-optim
git worktree add -b bugfix-memory-leak ../ml-pipeline-bugfix

为每个 worktree 打开一个终端面板并启动您的 AI 助手:

# Pane 1
cd ~/projects/ml-pipeline-logging
claude

# Pane 2
cd ~/projects/ml-pipeline-optim
claude

# Pane 3
cd ~/projects/ml-pipeline-bugfix
claude

每个 AI 实例在不同功能上工作,互不干扰。团队反馈称,他们能在几个小时内完成过去需要几天的工作。例如,incident.io 使用该模式并行运行 4–5 个 Claude Code agent。某次,Claude 评估一个 UI 改进需 2 小时,实际 10 分钟就完成了。

需要权衡的点:

  • Token 消耗:多个 AI 会话会消耗更多 API 额度,并可能触发频率限制
  • 搭建开销:每个 worktree 需要自己的虚拟环境和依赖
  • 认知负荷:在不同任务的多段对话间进行管理

这对大型且彼此独立的功能(各 30 分钟以上)、不触及相同文件且 API 配额充足的场景很适用。若是快速修复、强耦合功能,或接近 API 频率上限时,请勿采用。

结语

回想开头的场景——队友需要您在功能开发中途评审 PR。现在您知道解决方案了:git worktree add ../ml-pipeline-review pr/branch-name,然后 cd 即可开始评审。您的功能开发保持不变。无需暂存、无需提交未完成代码,也无需在回来时重建心理模型。两个目录、两个分支、零摩擦。

Git worktree 不会给您的工作流增加复杂度——它是在移除复杂度。每个 worktree 都只是一个检出了某个分支的目录。但这种简单性释放出了强大的能力:无需承受暂存、检出与重建心理模型的认知负担,便可在任务间即时切换。

当您需要将 worktree 与团队协作工作流(如 Pull Request 与代码评审)集成时,DataCamp 的 GitHub 基础技能路径覆盖了与分布式团队高效协作的基本实践。

Git Worktree 常见问答

我能在 GitHub Desktop、VS Code 或其他 GUI 工具中使用 Git worktree 吗?

可以。对于编辑器和 Git 图形界面工具,worktree 就是普通项目文件夹。您可以将每个 worktree 作为独立项目打开,大多数工具——包括 VS Code、IntelliJ 和 GitHub Desktop——都能无需特殊配置地处理它们。

Git worktree 与 origin 等远程仓库如何交互?

所有 worktree 共享同一个 .git 目录,因此共享相同的远程配置和获取历史。您无需在每个 worktree 中都运行 git fetch——在其中一个执行 fetch 就会更新所有的远程。分支跟踪行为与单一 worktree 设置完全相同。

如果我没有用 git worktree remove,而是手动删除了 worktree 目录,会怎样?

Git 仍会认为该 worktree 存在,并将其标记为“可修剪”。您不会破坏仓库,但 Git 命令可能会显示警告。运行 git worktree prune 清理陈旧条目,并安全移除孤立的元数据。

将 Git worktree 与大型 monorepo 或 Bazel、Pants、Nx 等构建系统一起使用是否安全?

可以,但构建产物会迅速增多。每个 worktree 都有自己的工作目录,因此缓存、虚拟环境和构建输出会被重复。在 monorepo 中,通常会配置构建工具将缓存存放在 worktree 外,以避免过度占用磁盘空间。

我能在 Git worktree 中使用子模块或稀疏检出吗

可以。子模块和稀疏检出在 worktree 中能正常工作,但您需要在每个 worktree 中分别初始化或更新它们,因为工作目录内容并不共享。底层的 Git 数据仍然共享,但检出的文件彼此独立。

Bexruz (Bex) Tuychiev

作者

Bexruz (Bex) Tuychiev

我是一名数据科学内容创作者,拥有超过 2 年的经验,并在 Medium 上拥有较大的读者群。我喜欢用略带讽刺的笔调撰写有关 AI 和机器学习的深度文章——毕竟总得想点办法让这些内容不那么枯燥。我已发表 130 多篇文章,并制作了一门 DataCamp 课程,另有一门正在筹备中。我的内容已被超过 500 万人次阅读,其中有 2 万人在 Medium 和 LinkedIn 上成为关注者。 

主题