首页
/ Gemini CLI Git Worktree 实战:为每个并行会话分配独立代码副本

Gemini CLI Git Worktree 实战:为每个并行会话分配独立代码副本

2026-09-04 19:58:43作者:冯梦姬Eddie

Gemini CLI 提供实验性的 Git Worktree 支持,让你在处理多个任务时,为每个 Gemini 会话自动创建独立的 Git worktree 工作目录——每个目录拥有独立文件和分支,但共享同一份仓库历史,从而避免不同会话的改动相互冲突。本文基于官方文档 docs/cli/git-worktrees.md,并结合 packages/core/src/services/worktreeService.tspackages/cli/src/utils/worktreeSetup.ts 等源码,完整讲解该功能的开启方式、--worktree 命令用法、会话退出策略、恢复流程与手动管理命令。

一、为什么需要 Git Worktree 并行工作

当你在同一仓库上同时推进多个任务(例如一个会话修 bug、另一个会话开发新功能)时,两个会话会读写同一份工作区:A 会话修改的文件可能被 B 会话的模型误读,未提交的改动也会互相"污染"上下文。

Git worktree 的原生能力是创建一个独立的目录(working directory),每个目录有自己的文件状态与分支,而所有 worktree 共享同一个仓库历史(.git 对象库)。Gemini CLI 在此基础上做了自动化封装:启动时自动建 worktree、自动 chdir、记录基准提交(base SHA)、退出时保留现场,把原本需要手敲多条 git worktree 命令的流程压缩成一个 --worktree 标志。

需要注意:这是处于活跃开发中的实验性功能,当前仓库 schemas/settings.schema.json 中该配置项标注为 Requires restart: yes,修改设置后需重启 CLI 才生效。

二、开启 Git Worktrees

Worktrees 默认关闭,需要显式启用。有两种方式:

方式 1:交互式设置

  1. 在 CLI 中执行 /settings 命令;
  2. 搜索 Enable Git Worktrees,将其设置为 true

方式 2:编辑 settings.json

{
  "experimental": {
    "worktrees": true
  }
}

这一配置在源码中的定义位于 packages/cli/src/config/settingsSchema.ts(第 2234-2243 行):

worktrees: {
  type: 'boolean',
  label: 'Enable Git Worktrees',
  category: 'Experimental',
  requiresRestart: true,
  default: false,
  description: 'Enable automated Git worktree management for parallel work.',
  showInDialog: true,
},

可以看到:分类为 Experimental、默认值 falserequiresRestart: true(即 /settings 中该开关标注"需要重启")。showInDialog: true 解释了为什么它会在 /settings 对话框中被搜索到。设置读取逻辑在 packages/cli/src/config/settings.ts 中通过 settings.merged.experimental.worktrees 从用户、项目等多层合并后的配置中取值。

三、使用 --worktree 启动隔离会话

启用后,使用 --worktree(简写 -w)标志创建隔离的 worktree 并在其中启动 Gemini CLI。

3.1 指定名称启动

传入的值会同时成为 worktree 目录名(位于 .gemini/worktrees/ 下)和分支名的组成部分:

gemini --worktree feature-search

3.2 随机名称启动

省略名称时,Gemini 会自动生成一个随机名称(例如 worktree-a1b2c3d4 风格的名称):

gemini --worktree

从源码可以确认命名与落盘的具体规则。packages/core/src/services/worktreeService.tssetup() 在未收到名称时,用 ISO 时间戳 + 4 位随机后缀生成名称(第 33-42 行):

if (!worktreeName) {
  const now = new Date();
  const timestamp = now
    .toISOString()
    .replace(/[:.]/g, '-')
    .replace('T', '-')
    .replace('Z', '');
  const randomSuffix = Math.random().toString(36).substring(2, 6);
  worktreeName = `${timestamp}-${randomSuffix}`;
}

随后 createWorktree()(第 121-134 行)完成三件关键事:

const worktreePath = getWorktreePath(projectRoot, name);   // <projectRoot>/.gemini/worktrees/<name>
const branchName = `worktree-${name}`;                      // 分支名 = "worktree-" + 名称

await execa('git', ['worktree', 'add', worktreePath, '-b', branchName], {
  cwd: projectRoot,
  env: getSafeGitEnv(),
});

即:目录固定位于 <项目根>/.gemini/worktrees/<名称>,分支名固定为 worktree-<名称>。这与后文手动清理命令中 git branch -D worktree-feature-search 的分支名来源一致。创建前还会先用 git rev-parse HEAD 抓取基准提交 baseSha,返回 WorktreeInfo { name, path, baseSha },供后续判断 worktree 是否产生过改动。

项目根的解析由 getProjectRootForWorktree()(第 96-115 行)完成:执行 git rev-parse --git-common-dir,取 .git 目录的父目录作为项目根;若解析失败则退化为当前工作目录。

3.2 启动流程中的防嵌套保护

CLI 入口 packages/cli/src/gemini.tsx(第 380-388 行)在启动早期就调用 setupWorktree(),并用启动性能分析器打点 setup_worktree

// If a worktree is requested and enabled, set it up early.
let worktreeInfo: WorktreeInfo | undefined;
...
worktreeInfo = await setupWorktree(requestedWorktree || undefined);

packages/cli/src/utils/worktreeSetup.ts 中有一个重要的防重入设计:

export async function setupWorktree(
  worktreeName: string | undefined,
): Promise<WorktreeInfo | undefined> {
  if (process.env['GEMINI_CLI_WORKTREE_HANDLED'] === '1') {
    return undefined;
  }
  ...
  process.chdir(worktreeInfo.path);
  process.env['GEMINI_CLI_WORKTREE_HANDLED'] = '1';
  ...
}

即:worktree 创建成功后立即 process.chdir() 切入新目录,并设置环境变量 GEMINI_CLI_WORKTREE_HANDLED=1。该守卫确保当 CLI 因内存分配等目的重新拉起自身进程时,不会在 worktree 里再嵌套创建一层 worktree。对应测试见 packages/cli/src/utils/worktreeSetup.test.ts

此外,参数校验位于 packages/cli/src/config/config.ts(第 269-270 行):如果传了 --worktreeexperimental.worktrees 未启用,会直接报错:

The --worktree flag is only available when experimental.worktrees is enabled in your settings.

-w 选项的官方描述为:"Start Gemini in a new git worktree. If no name is provided, one is generated automatically."(见 config.ts 第 313-318 行)。

注意(继承自官方文档):每个新 worktree 都是一个全新的代码副本,需要按项目规范初始化开发环境——例如运行依赖安装(npm installyarn)、配置虚拟环境,或执行项目标准构建流程。

四、退出 worktree 会话:现场完整保留

当通过 /quitCtrl+C 退出 worktree 会话时,Gemini 的退出策略是优先保证快速与安全

  • 保留 worktree 不删除:包括所有未提交改动(修改过的文件、已暂存改动、未跟踪文件)以及你在新分支上产生的任何提交;
  • 不自动删除分支:worktree 和分支都由你自行清理;
  • 打印退出指引:退出时界面会显示如何恢复工作、以及如何手动删除 worktree 的指令。

这条退出提示的实现位于 packages/cli/src/ui/components/SessionSummaryDisplay.tsx(第 39-43 行):当配置中存在 worktree 信息时,底部提示会替换为:

footer =
  `To resume work in this worktree: cd ${escapeShellArg(worktreeSettings.path, shell)} && gemini --resume ${footerSessionId}\n` +
  `To remove manually: git worktree remove ${escapeShellArg(worktreeSettings.path, shell)}`;

即输出"恢复工作"与"手动删除"两条可直接复制的命令,且路径、会话 ID 会按当前 shell(Windows 下 PowerShell、其他平台 bash)做转义。测试用例 packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx(第 199-218 行)验证了这两条提示确实渲染在退出页面上。

源码中已有的自动清理能力

值得说明的是,核心层已经实现了改动检测与条件清理逻辑。packages/core/src/services/worktreeService.ts 中:

  • hasWorktreeChanges(dirPath, baseSha)(第 151-184 行):先用 git status --porcelain 检查未提交改动,再比较当前 HEAD 是否偏离基准 SHA;若任何 git 命令失败则保守地视为有改动("assume the worktree is dirty to be safe"),防止误删用户工作;
  • maybeCleanup(info)(第 62-84 行):当 worktree 无任何改动时,自动执行 git worktree remove --forcegit branch -D 删除分支,有改动则保留并记录调试日志。

从源码结构看,maybeCleanup 的调用方目前主要见于 packages/core/src/services/worktreeService.test.ts 的单元测试(第 271-304 行);在 CLI 退出路径上,当前版本遵循文档所述"不自动删除"的策略。也就是说,条件自动清理能力已在核心层具备并有测试覆盖,属于该实验性功能的演进方向。

五、恢复 worktree 中的会话

worktree 被完整保留后,恢复工作只需进入对应目录并用 --resume 加上会话 ID 启动:

cd .gemini/worktrees/feature-search
gemini --resume <session_id>

会话 ID 即退出提示中 gemini --resume 后面的参数(与退出页打印的完全一致)。更多会话管理细节可参考 docs/cli/session-management.md

六、手动管理 Git Worktrees

如果你希望完全控制 worktree 的位置与分支命名,或需要清理被保留下来的 worktree,可以直接使用 Git 命令:

清理被保留的 worktree(分支名遵循 worktree-<名称> 约定):

git worktree remove .gemini/worktrees/feature-search --force
git branch -D worktree-feature-search

手动创建 worktree(放到任意目录、使用任意分支名,然后在该目录启动 gemini):

git worktree add ../project-feature-search -b feature-search
cd ../project-feature-search && gemini

手动创建时的一个细节:CLI 侧的 WorktreeService 内部还带有 isGeminiWorktree()(worktreeService.ts 第 136-149 行),通过 realpath 比对判断某目录是否位于 <项目根>/.gemini/worktrees/ 之下——只有 Gemini 托管的 worktree 才走其自动管理逻辑,你手动放在别处的 worktree 完全不受干预。另外,所有 git 子进程都通过 getSafeGitEnv()packages/core/src/utils/gitUtils.ts)构造安全的环境变量执行,避免宿主机 git 配置异常影响 worktree 操作。

七、小结与相关资源

  • 开启/settings 中设置 Enable Git Worktrees = true,或 settings.json 写入 {"experimental": {"worktrees": true}}(Experimental 分类,默认关闭,修改后需重启);
  • 启动gemini --worktree <名称>gemini --worktree(自动生成随机名称),目录落在 .gemini/worktrees/<名称>,分支为 worktree-<名称>
  • 退出:worktree 与分支完整保留,界面打印 cd ... && gemini --resume <id>git worktree remove ... 两条后续指令;
  • 清理git worktree remove <路径> --force + git branch -D worktree-<名称>

延伸阅读与代码入口:

内容 路径
官方文档 docs/cli/git-worktrees.md
Worktree 核心服务(创建/改动检测/清理) packages/core/src/services/worktreeService.ts
核心服务单元测试 packages/core/src/services/worktreeService.test.ts
CLI 启动期 worktree 装配 packages/cli/src/utils/worktreeSetup.ts
配置项定义 packages/cli/src/config/settingsSchema.ts
命令行参数解析与校验 packages/cli/src/config/config.ts
退出提示(恢复/清理指令) packages/cli/src/ui/components/SessionSummaryDisplay.tsx
设置参考 docs/cli/settings.md
会话管理 docs/cli/session-management.md
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
903
1.82 K
docsdocs
暂无描述
Markdown
888
5.78 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.51 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.17 K
341