Gemini CLI Git Worktree 实战:并行会话的独立工作目录指南
2026/9/5 17:42:29 网站建设 项目流程

Gemini CLI Git Worktree 实战:并行会话的独立工作目录指南

【免费下载链接】awesome-design-systems💅🏻 ⚒ A collection of awesome design systems项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-design-systems

你同时开着两个 Gemini CLI 会话处理同一个仓库:A 会话在修登录 bug,刚写入一半的未提交改动;B 会话却在开发搜索功能,把 A 改到一半的文件当基准读取,又把自己的改动写回同一份工作区。两边的修改互相污染上下文,连构建结果都不可信。Gemini CLI 的实验性功能Git Worktree就是为这类冲突设计的:它为每个会话自动分配一个独立的 Git worktree 工作目录——文件与分支各自独立、共享同一份仓库历史(worktree 可以理解为同一仓库的第二份检出,只是文件状态和分支互不干扰)。

三步跑通:如何开启 Worktrees 配置并启动隔离会话

先建立整体印象,最小可用路径只有三步;每一步的机制细节后文再拆。

第 1 步:打开实验性开关。Worktrees 默认关闭,两种开启方式:在 CLI 里执行/settings,搜索Enable Git Worktrees置为true;或直接写入settings.json

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

该配置项定义在 packages/cli/src/config/settingsSchema.ts(约 2234-2243 行):归属Experimental分类、默认falserequiresRestart: true。也就是说,这是实验性功能,且修改开关后必须重启 CLI 才生效,改完记得重开进程。

第 2 步:用--worktree启动隔离会话。

gemini --worktree feature-search # 显式命名 gemini -w # 不传名称,自动随机生成

注意:每个新 worktree 都是全新的代码副本,进入后需按项目规范初始化环境——npm installyarn、虚拟环境或标准构建流程。另外,开关未启用时传--worktree会直接报错,校验逻辑在 packages/cli/src/config/config.ts 第 269-270 行。

第 3 步:退出后按打印的命令恢复。

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

<session_id>就是退出页打印的那串 ID,逐字复制即可。

--worktree 命名规则解析:目录落盘、分支约定与随机名生成

跑通只是第一步,接下来拆开看启动时到底发生了什么。

目录位置与分支命名约定

packages/core/src/services/worktreeService.ts 中createWorktree()(第 121-134 行)完成核心动作:

const worktreePath = getWorktreePath(projectRoot, name); // <项目根>/.gemini/worktrees/<名称> const branchName = `worktree-${name}`; await execa('git', ['worktree', 'add', worktreePath, '-b', branchName], { cwd: projectRoot, env: getSafeGitEnv(), });

目录固定落在<项目根>/.gemini/worktrees/<名称>,分支名固定为worktree-<名称>——后文手动清理命令里的worktree-feature-search正是这个来源。项目根由getProjectRootForWorktree()(第 96-115 行)解析:执行git rev-parse --git-common-dir,取.git目录的父目录作为根;解析失败则退化为当前工作目录。

不传名称时的随机名生成

省略名称时,setup()用 ISO 时间戳加 4 位随机后缀拼装(第 33-42 行):

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

基准 SHA 记录与防重入守卫

创建前会先用git rev-parse HEAD抓取基准提交baseSha,与名称、路径一起组成WorktreeInfo { name, path, baseSha }返回——这是后续判断"worktree 里有没有产生过改动"的依据。

CLI 入口侧,packages/cli/src/gemini.tsx(第 380-388 行)在启动早期调用 packages/cli/src/utils/worktreeSetup.ts 的setupWorktree(),并用性能分析器打点setup_worktree。该函数内部有防重入守卫:

if (process.env['GEMINI_CLI_WORKTREE_HANDLED'] === '1') { return undefined; } ... process.chdir(worktreeInfo.path); process.env['GEMINI_CLI_WORKTREE_HANDLED'] = '1';

worktree 创建成功后立即chdir切入新目录并置位环境变量,确保 CLI 因自身目的重新拉起进程时,不会在 worktree 里再嵌套创建一层。对应测试见 packages/cli/src/utils/worktreeSetup.test.ts。

Worktree 会话退出策略:现场完整保留与 --resume 恢复

那会话结束后呢?Gemini 会把目录清掉保持干净吗?当前版本的答案是全部保留

  • 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 转义;渲染验证见 packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx(第 199-218 行)。

值得注意的是,核心层其实已具备更完整的条件清理能力:hasWorktreeChanges()(worktreeService.ts 第 151-184 行)先用git status --porcelain检查未提交改动,再比较HEAD是否偏离基准 SHA,任何 git 命令失败时保守判定为"有改动",防止误删用户工作maybeCleanup()(第 62-84 行)在无改动时自动执行git worktree remove --forcegit branch -D,有改动则保留。但在当前版本里,maybeCleanup的调用方主要是 packages/core/src/services/worktreeService.test.ts 中的单元测试(第 271-304 行),CLI 退出路径仍遵循"不自动删除"——条件自动清理属于该实验性功能的演进方向。

进阶控制:手动 git worktree 命令与自动托管边界

默认的落盘位置和命名不合意,或需要清理被保留的 worktree 时,可以直接用原生 Git 命令接管。

手动创建(任意目录、任意分支名):

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

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

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

两条路径的差异对比:

维度Gemini 托管 worktree手动创建 worktree
目录位置固定.gemini/worktrees/<名称>任意
分支名固定worktree-<名称>任意
启动行为自动 chdir、记录基准 SHA、退出提示不介入,按普通项目使用
清理方式退出提示 + 手动命令手动命令

托管边界由 worktreeService.ts 中的isGeminiWorktree()(第 136-149 行)划定:通过realpath比对判断目录是否位于.gemini/worktrees/之下,只有 Gemini 托管的 worktree 才走自动管理逻辑,你手动放在别处的完全不受干预。此外,该功能的所有 git 子进程都经由getSafeGitEnv()(见 packages/core/src/utils/gitUtils.ts)构造安全环境变量执行,宿主机上异常的 git 配置不会干扰 worktree 操作。

速查表:Gemini CLI Git Worktree 场景 → 命令/配置

场景命令 / 配置
开启功能(需重启)/settings搜索 Enable Git Worktrees 置true;或settings.json{"experimental": {"worktrees": true}}
命名启动gemini --worktree feature-search(简写-w
随机名启动gemini --worktree
确认目录与分支.gemini/worktrees/<名称>;分支worktree-<名称>
退出后恢复会话cd .gemini/worktrees/<名称> && gemini --resume <session_id>
清理 worktreegit worktree remove <路径> --forcegit branch -D worktree-<名称>
自定义 worktreegit worktree add <目录> -b <分支>cd <目录> && gemini

相关文档与源码路径

内容路径
官方 worktree 文档docs/cli/git-worktrees.md
核心服务(创建/改动检测/清理)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

一句话收束:开关打开后--worktree起跑,退出时照着打印的两条命令恢复或清理——Gemini CLI Git Worktree 的并行会话隔离,就这么简单。

【免费下载链接】awesome-design-systems💅🏻 ⚒ A collection of awesome design systems项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-design-systems

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询