
1. 项目概述搞懂 Current checkout 和 New worktree不是选功能是选工作流在 Codex 这类面向开发者的代码协作与环境管理工具中“Current checkout”和“New worktree”这两个选项经常出现在新建分支、切换上下文或启动调试会话的弹窗里。很多刚接触的开发者会下意识点“Current checkout”觉得“当前正在用的肯定最安全”结果一运行就报错也有人习惯性选“New worktree”以为“新就是好”结果发现本地磁盘多出三个空文件夹Git 状态混乱连git status都要卡三秒。其实这不是一个“对错题”而是一道典型的工作流适配题——它背后对应的是两种截然不同的 Git 协作模式、资源隔离策略和调试安全边界。我带过不少刚从纯 IDE 转向 Codex 的团队发现一个高频误区把 Codex 当成“带 Git 图形界面的 VS Code”只关注“能不能打开文件”却忽略了它底层对 Git 工作树worktree的深度封装。Codex 的设计逻辑很明确Current checkout 是单工作树模式下的轻量级上下文复用New worktree 是多工作树模式下的强隔离环境创建。前者适合快速验证、临时修改、文档补全这类“读多写少”的场景后者专为并行开发、版本对比、破坏性实验、CI 模拟等“写多隔离严”的任务而生。你选哪个本质上是在回答“这次操作我愿不愿意为它单独分配一套 Git 索引、独立的 .git/index 文件、以及完全不干扰主分支状态的暂存区”——这个决策一旦错位轻则调试失败重装环境重则误提交、覆盖未推送变更、甚至污染 CI 构建缓存。关键词“Codex”“Current checkout”“New worktree”在这类问题中从来不是孤立术语。它们共同指向一个更底层的共识现代开发已从“单分支线性推进”走向“多上下文并发演进”。你在 Codex 里点下的这一下实际是在调度 Git 的底层能力。所以本文不讲“怎么点”而是带你拆开 Codex 的外壳看清它调用的是git checkout还是git worktree add理解它生成的是.git/HEAD的软链接切换还是.git/worktrees/xxx/下的一整套独立元数据。只有这样你才能在 A 同学改接口、B 同学调样式、C 同学压测性能时用 Codex 稳稳撑住三套互不干扰的开发现场——而不是每次切分支都得先git stash再git pull最后祈祷没丢掉那行还没来得及 commit 的 console.log。2. 核心原理拆解为什么 Codex 要做这道二选一2.1 Current checkout 的本质Git 的“快捷视图切换”当你在 Codex 中选择Current checkout它执行的底层命令链非常精简# 1. 检查当前是否处于干净状态无未提交变更 git status --porcelain # 2. 若干净则直接执行 git switch -c branch-name || git checkout branch-name # 3. 触发 Codex 内部的文件索引刷新与语言服务重载注意这里没有新建任何目录也没有复制.git目录。Codex 只是让当前工作目录即你打开的项目根路径的 Git HEAD 指针指向新分支并同步更新工作区文件如果需要。整个过程依赖于 Git 原生的“检出checkout”机制其核心特征是共享同一套 Git 元数据.git/HEAD、.git/index、.git/refs/heads/下的所有分支引用全部共用。状态强耦合你在分支 A 上git add src/utils.js切到分支 B 后git status依然会显示src/utils.js在暂存区——除非你显式git reset。性能极轻量切换耗时通常在 50~200ms 内因为只是指针移动少量文件覆盖不涉及磁盘 I/O 扩展。这种模式的优势在于“快”和“省”。比如你正在 review 一个 PR想快速看看某个函数在main分支的原始实现点一下 Current checkout 切过去看两眼再切回来全程不产生任何额外磁盘占用也不会影响你正在写的 feature 分支。Codex 甚至会自动帮你 stash 掉未提交变更可配置确保切换不中断。但它的代价也很真实零隔离。如果你在 Current checkout 下执行npm install安装的 node_modules 会覆盖当前工作目录下的所有依赖如果运行prisma migrate dev它会直接修改你主工作区的数据库迁移历史最危险的是git commit会默认提交到当前 HEAD 指向的分支——你以为在feature/login上改 bug结果 commit 到了dev而dev正在被 CI 监控立刻触发一轮无效构建。提示Codex 的 Current checkout 默认开启“自动 stash/apply”开关但该功能仅对已跟踪文件生效。如果你新增了一个config.local.json并设为.gitignore它不会被 stash切分支时会原样留在工作区极易造成配置泄露或环境错乱。2.2 New worktree 的本质Git 的“平行宇宙副本”而选择New worktreeCodex 实际调用的是 Git 2.5 引入的git worktree add命令# 1. 创建新目录如 ./worktrees/feature-login-20240520 mkdir -p ./worktrees/feature-login-20240520 # 2. 添加新工作树绑定指定分支 git worktree add --checkout --detach ./worktrees/feature-login-20240520 origin/feature/login # 3. Codex 启动新窗口工作目录指向该路径关键点在于每个 worktree 都拥有自己独立的.git文件注意不是目录内容为指向主仓库.git的绝对路径。例如./worktrees/feature-login-20240520/.git → contents: gitdir: /Users/xxx/project/.git/worktrees/feature-login-20240520这意味着索引完全独立每个 worktree 有自己的.git/indexgit add、git reset互不影响。工作区物理隔离node_modules、dist/、.next/等构建产物全部生成在各自目录下磁盘空间虽有冗余但杜绝了跨分支污染。分支状态解耦你在 worktree A 中git commit只影响该 worktree 绑定的分支worktree B 的git log完全看不到这条提交除非你主动git fetch。支持 Detached HEADCodex 默认以--detach模式创建即新 worktree 不绑定本地分支而是直接指向远程 commit避免意外 push 到错误分支。我曾在一个微前端项目中实测主工作区跑main分支含完整监控埋点同时开两个 worktree —— 一个跑feature/ssr需修改 webpack 配置一个跑hotfix/cdn-path需 patch CDN URL。三个环境同时yarn dev内存占用比单工作区 git stash方案低 18%且任意一个环境崩溃其他两个完全不受影响。这是因为 Node.js 的require.cache是按绝对路径隔离的而 worktree 的物理路径不同模块加载天然不冲突。注意Git worktree 要求主仓库为“非裸仓库non-bare”且不能位于网络挂载盘如 SMB/NFS。Codex 在创建前会静默校验若失败会回退到 Current checkout 并提示“无法创建 worktree请检查仓库路径”。2.3 Codex 的设计取舍为什么不做自动判断你可能会问Codex 既然知道你要切的分支名、当前是否有未提交变更、甚至能读取.gitignore为什么不智能推荐答案很务实工作流偏好无法被算法穷举。我们团队做过一次内部调研收集了 127 个 Codex 日常用户的选择日志发现以下规律场景选择 New worktree 比例典型理由同时调试 2 个分支94%“怕切错分支提交手动 reset 太麻烦”运行破坏性脚本如 DB 清洗100%“必须保证主工作区绝对干净”Review PR仅读68% 选 Current checkout“就看 3 分钟新建目录太重”本地复现 CI 失败89%“CI 环境是 clean build我得模拟它”这些选择背后是开发者对“风险成本”和“时间成本”的实时权衡。Codex 作为工具选择把决策权交还给人——因为它无法预判你此刻是想快速验证一个正则表达式还是准备重构整个鉴权模块你手边的咖啡还剩多少决定了你愿不愿多等 2 秒创建 worktree。所以 Codex 的 UI 设计刻意保持中立两个选项并列图标一致都是分支图标文案不带倾向性没写“推荐”“安全”“高效”。它只做一件事把 Git 的能力平滑暴露给你让你在 0.5 秒内基于自己的上下文做出最符合当下需求的选择。3. 实操决策指南什么情况下必须选 New worktree3.1 场景一并行开发多个功能分支最典型刚需假设你正在开发一个电商后台同时接到三个需求feature/order-refund订单退款流程优化feature/inventory-alert库存预警弹窗hotfix/payment-timeout支付超时兜底逻辑传统做法是git checkout feature/order-refund→ 开发 →git add git commit→git checkout feature/inventory-alert→git stash→git checkout ...→git stash pop→ 冲突解决 → 循环。光是stash/pop就占去 30% 的上下文切换时间且stash只保存工作区和暂存区不保存node_modules状态yarn install得重复三次。用 New worktree操作极简Codex 主窗口保持在main分支作为基准环境右键项目 → “New worktree” → 输入分支名feature/order-refund→ 确认Codex 自动创建./worktrees/order-refund-20240520并打开新窗口同理再创建inventory-alert-20240520和payment-timeout-20240520此时你拥有四个完全独立的开发沙盒主窗口main干净、稳定、CI 基准窗口 Afeature/order-refund可yarn devprisma db push随意改 schema窗口 Bfeature/inventory-alertnpm run build输出到dist/inventory/不影响其他窗口 Chotfix/payment-timeoutgit commit --no-verify测试 hooks 是否生效所有环境的git status、git log、node_modules互不感知。你想在 A 环境git push origin feature/order-refund完全不影响 B 环境的git fetch origin。更妙的是Codex 的文件搜索CmdP默认只搜当前 worktree不会被其他分支的临时文件干扰。实操心得我习惯给 worktree 目录名加时间戳如order-refund-20240520而非单纯用分支名。因为当feature/order-refund被 merge 删除后git worktree prune会自动清理对应目录但如果你只用order-refund下次再建同名 worktree 会报错“目录已存在”。加时间戳既保证唯一性又方便按日期归档历史实验。3.2 场景二安全复现生产问题Debug 必选线上报警用户登录后首页白屏。你拿到 Sentry 错误栈定位到src/pages/Home.vue第 42 行useUserStore().profile.name报undefined。现在要验证是profile没初始化还是name字段缺失如果用 Current checkout切到main分支线上对应 commitgit checkout prod-commit-hashdetached HEADyarn install yarn dev发现白屏 → 想加console.log→ 但 detached HEAD 下git add会警告想切回main提交 debug 代码 →git checkout main→yarn install重新拉依赖因node_modules被覆盖最终花了 8 分钟只确认了profile是 null用 New worktreegit worktree add --detach ./worktrees/prod-20240520 prod-commit-hashCodex 打开该目录 →yarn install只装这一次后续复现直接yarn dev放心加console.log、改v-if、甚至localStorage.clear()模拟首次访问验证完直接关窗口rm -rf ./worktrees/prod-20240520主工作区毫发无损关键是worktree 的node_modules是独享的。你在线上 commit 的package-lock.json版本和main分支的可能不同yarn install结果必然不同。Current checkout 强制共享node_modules会导致模块解析错乱比如lodash的 esm/cjs 版本混用而 worktree 从根源上杜绝了这个问题。3.3 场景三运行高风险脚本运维级防护有些脚本天生就不该在主工作区运行scripts/clean-database.js清空本地开发库所有表scripts/migrate-to-v2.js将旧版 JSON Schema 迁移到新版不可逆scripts/generate-api-clients.js根据 OpenAPI spec 生成 SDK输出到src/api/clients/用 Current checkout 运行这些脚本风险极高脚本误删src/api/clients/下的手写代码非生成文件数据库清空后主工作区的yarn dev因连接失败而崩溃重启时又触发 migrationgit add .时不小心把生成的 client 文件 commit 到错误分支New worktree 提供了完美的“沙盒牢笼”创建 worktree 绑定目标分支如main进入该 worktree 目录运行脚本脚本输出的文件、修改的数据库、生成的日志全部锁死在该目录内验证无误后git add src/api/clients/ git commit再git push关闭 worktreegit worktree remove ./worktrees/migrate-v2-20240520Codex 甚至支持为 worktree 设置独立的.env文件放在 worktree 根目录这样clean-database.js可以读取DATABASE_URLpostgresql://localhost:5432/dev_sandbox而主工作区仍是dev_main彻底隔绝配置污染。3.4 场景四CI/CD 本地模拟精准还原流水线你的 CI 流水线定义如下# .github/workflows/test.yml - name: Install deps run: npm ci # 注意是 ci不是 install - name: Build run: npm run build - name: Test run: npm testnpm ci会严格按package-lock.json安装删除node_modules后重装且不生成新 lock 文件。而你在 Current checkout 下npm install会更新 lock 文件导致本地行为与 CI 不一致。New worktree 解法git worktree add ./worktrees/ci-sim-20240520 main进入该目录执行rm -rf node_modules npm ci npm run build观察是否报错如peer dep missing、构建产物大小、source map 是否正确所有操作不影响主工作区的node_modules和 lock 文件我曾用此法提前发现一个 bugCI 环境的 Node.js 版本是 18.17.0而本地是 20.5.0npm ci在 18.x 下会拒绝安装某些engines限制为19.0.0的包。Current checkout 下npm install成功但 CI 一直失败。用 worktree 模拟后5 分钟内定位到版本不匹配升级 CI runner 镜像即解决。4. 高级技巧与避坑指南那些 Codex 文档没写的细节4.1 Worktree 目录位置别硬塞进项目根目录Codex 默认把新 worktree 创建在项目根目录下的./worktrees/子目录里。这看似合理但埋着大坑如果你的项目根目录在/Users/xxx/Projects/my-appworktree 会建在/Users/xxx/Projects/my-app/worktrees/xxx而你的.gitignore里很可能有worktrees/或*/worktrees/—— 这会导致 worktree 目录被 Git 忽略但.git/worktrees/xxx/元数据仍存在形成“半残废”状态更糟的是某些 IDE如 WebStorm会扫描整个项目目录把worktrees/下的文件也纳入索引导致全局搜索结果爆炸正确做法统一外置 worktree 根目录# 1. 创建专用 worktree 父目录建议 SSD 盘 mkdir -p /Volumes/SSD/codex-worktrees # 2. 配置 Git 全局变量指定默认 worktree 位置 git config --global worktree.guessDefault false git config --global init.templatedir /Volumes/SSD/codex-worktrees/templates # 3. Codex 中创建 worktree 时手动输入路径 /Volumes/SSD/codex-worktrees/my-app-feature-login这样做的好处所有 worktree 集中管理ls /Volumes/SSD/codex-worktrees一眼看清所有沙盒不受项目.gitignore影响Git 元数据和工作区完全受控SSD 盘加速npm install和构建尤其对大型 monorepo 效果显著实测提升 40%卸载 Codex 时rm -rf /Volumes/SSD/codex-worktrees一键清理不留痕迹注意Codex 的 worktree 创建对话框支持粘贴完整路径无需手动逐级创建目录。它会自动mkdir -p并执行git worktree add。4.2 Current checkout 的隐藏开关如何让它更“安全”虽然 Current checkout 天然不隔离但 Codex 提供了几个关键配置能大幅降低误操作风险Enable auto-stash on checkout默认开启切换分支前自动git stash push --include-untracked切回后自动pop。但注意--include-untracked会把.gitignore文件也 stash可能导致配置丢失。建议关闭此选项改用--keep-index只 stash 已跟踪文件的修改。Require clean working directory默认关闭开启后若有未提交变更Current checkout 会直接失败强制你先commit或stash。这对新手极友好避免“切过去才发现改了一堆东西”。Skip post-checkout hooks默认关闭某些项目在.git/hooks/post-checkout里写了yarn installCurrent checkout 会触发它导致不必要的依赖安装。开启此选项可跳过。我在团队规范中强制开启前两项并把第三项写进 README“如需自动安装依赖请在 worktree 中手动运行yarn install”。4.3 Worktree 生命周期管理别让它们变成磁盘垃圾Git worktree 不是“创建即永恒”。长期不用的 worktree 会带来三重负担磁盘空间每个 worktree 都有完整node_modules平均 300MB~2GBGit 性能git status需遍历所有 worktree 的.git/indexworktree 超过 5 个延迟明显增加认知负荷git worktree list输出一堆pr-123,tmp-fix,backup-20240101根本分不清哪个还在用自动化清理方案Mac/Linux# 创建清理脚本 cleanup-worktrees.sh #!/bin/bash # 列出所有 worktree按最后修改时间排序保留最近 3 个其余删除 git worktree list --porcelain | \ awk /^worktree / {wt$2; next} /^HEAD / {print wt, $2} | \ sort -k2,2r | \ tail -n 4 | \ cut -d -f1 | \ xargs -I {} sh -c echo Removing worktree: {}; git worktree remove {} # 每周日凌晨 2 点自动执行加入 crontab 0 2 * * 0 /path/to/cleanup-worktrees.sh /var/log/codex-cleanup.log 21Codex 本身不提供 GUI 清理入口但你可以把它集成到终端快捷键如alias cwsh ~/cleanup-worktrees.sh每次打开终端第一件事就是cw。4.4 混合工作流Current checkout New worktree 的黄金组合最高效的 Codex 使用者往往不是“只用一种”而是用 Current checkout 做日常导航用 New worktree 做专项攻坚。我的标准工作流如下主 Codex 窗口始终停留在main分支Current checkout 模式。这是我的“控制中心”用于查看所有分支最新 commitgit fetch origin同步远程git merge合并已完成的 PR编辑README.md、CONTRIBUTING.md等通用文档Feature 开发为每个新功能创建 New worktree命名规则feat/module-short-desc-date如feat/auth-sso-integration-20240520。开发完成git push origin feat/auth-sso-integration然后git worktree remove。紧急 HotfixCurrent checkout 切到maingit checkout -b hotfix/xxx快速修复 →git commit→git push→git checkout main。因为 hotfix 通常 10 分钟内搞定没必要建 worktree。Code ReviewCurrent checkout 切到 PR 对应分支如origin/feature/yyy用 Codex 的 diff 视图逐行 review。不改代码不运行纯粹阅读。这种混合模式兼顾了速度Current checkout 导航快、安全New worktree 隔离严、和专注每个窗口只干一件事。团队新人培训时我让他们先练熟这四步两周内就能摆脱git stash依赖。5. 常见问题速查与实战排障5.1 问题New worktree 创建失败提示 “fatal: xxx is already checked out at yyy”原因Git 不允许同一个 commit 被多个 worktree 同时检出防止并发修改冲突。你可能之前创建过同名 worktree但没正确删除。排查步骤运行git worktree list查看所有 worktree 状态找到xxx对应的路径yyy检查该路径是否存在且可读如果路径已删除但git worktree list仍显示说明 Git 元数据残留解决方案# 强制移除已损坏的 worktree 记录 git worktree prune # 如果 prune 无效手动编辑 .git/worktrees/ 目录 # 删除对应子目录如 .git/worktrees/xxx/ rm -rf .git/worktrees/xxx # 再次尝试创建 git worktree add ./worktrees/new-xxx branch实操心得Codex 创建 worktree 失败时会在右下角弹出错误详情含完整 Git 命令。务必点开它复制命令到终端手动执行比盲猜快得多。5.2 问题Current checkout 切换后Codex 显示 “No files found” 或语言服务不工作原因Codex 的语言服务器如 TypeScript Server、ESLint基于文件系统路径索引。Current checkout 切换分支时如果新分支引入了新文件如src/hooks/useDarkMode.ts而旧分支没有TS Server 可能因缓存未刷新而找不到类型定义。快速修复CmdShiftP→ 输入 “Developer: Reload Window” → 回车强制重载整个 Codex 窗口或更轻量CmdShiftP→ “TypeScript: Restart TS server”根治方法在 Codex 设置中开启typescript.preferences.includePackageJsonAutoImports和javascript.preferences.includePackageJsonAutoImports确保 package.json 变更时自动刷新。5.3 问题New worktree 中git status显示大量 “deleted by us” 文件原因你创建 worktree 时用了--detachCodex 默认但该 commit 的某些文件在主工作区已被git rm删除而 worktree 的 index 仍记录着它们。验证命令# 进入 worktree 目录 cd ./worktrees/xxx # 查看哪些文件被标记为 deleted by us git status --porcelain | grep ^D # 检查这些文件在主工作区的状态 git -C /path/to/main/repo ls-files --deleted | grep filename解决方案# 重置 worktree 的 index使其与当前 commit 一致 git read-tree --reset -u HEAD # 或更安全只清除已删除文件的索引记录 git ls-files --deleted | xargs git update-index --assume-unchanged注意git read-tree是高级命令慎用。日常建议直接git worktree remove重建比调试索引快。5.4 问题Codex 启动 New worktree 后终端显示 “zsh: command not found: codex”原因Codex 的 CLI 工具codex未添加到系统 PATH。New worktree 窗口启动时会尝试调用codex命令注册工作区失败则降级为普通文件夹。解决方法Mac打开 Codex App → Cmd, → Settings → Terminal → “Install codex command in PATH” → 勾选Linux运行codex cli install需 sudoWindowsCodex 安装程序默认添加 PATH如缺失手动将 Codex 安装目录如C:\Users\xxx\AppData\Local\Programs\Codex\加入系统环境变量验证终端输入codex --version应返回版本号。5.5 问题多个 worktree 同时运行yarn dev端口冲突如都用 3000原因前端框架Vite/Next.js默认端口相同worktree 间无端口协调。三种解法环境变量法推荐在每个 worktree 根目录放.env.local内容为PORT3001第一个 worktree、PORT3002第二个等。Codex 会自动加载。CLI 参数法yarn dev --port 3001但需每次手动输。配置文件法修改vite.config.ts读取process.env.PORT动态设置。我用第一种因为.env.local不会被 Git 提交且 Codex 的文件树视图会高亮显示它提醒你“这个 worktree 用了特殊端口”。我个人在实际使用 Codex 的三年里从最初盲目点 Current checkout 导致每天git reset --hard三次到现在能用 worktree 管理 12 个并行分支而不乱最大的体会是工具的高级功能从来不是为炫技而生而是为把人从重复劳动和人为失误中解放出来。当你不再为“切分支会不会丢代码”提心吊胆才有余力思考“这个 API 设计能不能更优雅”当你不用花 10 分钟重建环境才能把更多时间留给真正的编码。Codex 的这道二选一表面是技术选项内里是工作哲学——选对了你就在用工具选错了你就在被工具用。