
【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载导读本文剖析 gsd-core 中 PR #2990 的一次关键缺陷修复gsd-code-fixer 代理在工作树worktree隔离场景下因 Git 拒绝在同一仓库的两个 worktree 中同时检出同一分支而启动即失败的问题。通过阅读本文你将掌握该修复引入的gsd-reviewfix/临时分支创建、--ff-only快进合并清理、崩溃恢复哨兵recovery sentinel以及workflow.use_worktrees配置开关等一整套可落地的 Git worktree 隔离与清理方案并能从源码与回归测试中验证其行为。一、修复背景gsd-code-fixer 与代码审查修复流程gsd-core 的/gsd:code-review命令先由 gsd-code-reviewer 代理审查阶段代码并产出REVIEW.md当用户追加--fix标志时工作流会委托给 code-review-fix.md由其 spawn gsd-code-fixer 子代理读取REVIEW.md的逐条 findingCR-*/BL-*/WR-*/IN-*智能地应用修复、逐条原子提交并产出REVIEW-FIX.md报告。关键约束在于gsd-code-fixer 是一个在后台进行 git 提交的代理如果它直接在主工作树上操作就会与前台会话竞争共享的 HEAD、索引和磁盘文件即 issue #2686 描述的竞态。因此代理必须在独立 worktree中完成所有读取、编辑与提交这就是本文修复所在的隔离机制。二、Bug 本质Git 默认拒绝在两个 worktree 检出同一分支修复前的代理指令执行的是git worktree add $wt $branch其中$branch是用户当前检出的分支。Git 出于安全设计默认禁止在同一个仓库的两个 worktree 中同时检出同一个分支否则两个工作树会争抢同一份 HEAD 与索引。由于用户的主 checkout 已经持有$branch这条命令必然失败——而且失败发生在代理能够做任何修复工作之前整个 code-review-fix 流程直接被卡死。这正是 changeset 中 the agent now creates a new gsd-reviewfix/ branch 所对应的原始缺陷#2990。三、修复方案git worktree add -b创建 gsd-reviewfix 临时分支修复的核心思路是不再把 worktree 挂到用户分支上而是从当前分支尖端派生一条全新的临时分支再让 worktree 检出这条新分支。这样 worktree 与用户 checkout 各持一条分支互不冲突临时分支与$branch共享创建时刻之前的历史因此 worktree 内的提交可以在清理阶段快进合并回用户分支。代理定义 agents/gsd-code-fixer.md 中 setup_worktree 步骤的完整逻辑如下# 从当前分支派生临时分支名phase 编号 PID保证并发唯一 reviewfix_branchgsd-reviewfix/${padded_phase}-$$ # 关键修复#2990-b 创建新分支并挂载 worktree # 而不是直接检出用户已经持有的 $branch git worktree add -b $reviewfix_branch $wt $branch配套的 worktree 路径同样经过了专门设计#2647仓库相对路径落在.claude/worktrees/目录下与 harness 托管的 executor worktree 共用目录天然被.claude/的.gitignore规则覆盖也处于代理会话的权限允许范围内main_repo$(git worktree list --porcelain | awk /^worktree / { sub(/^worktree /, ); print; exit }) wt$main_repo/.claude/worktrees/rf-${padded_phase}-$$-$(date %s) mkdir -p $wt git worktree add -b $reviewfix_branch $wt $branch其中$$PID$(date %s)纪元秒后缀保证了同一阶段并发运行多次时路径互不冲突替代了旧实现中在 Windows/Git Bash 下不可移除、且落在项目树之外的/tmpmktemp 路径。值得注意的防御性设计padded_phase会被插值进 worktree路径和 git分支名因此代理指令在插入前先做一次下沉校验只接受^[0-9][A-Z]?(\.[0-9])*$的规范阶段号语法如02、36.14、12A拒绝../、空格与 shell 元字符防止路径穿越或分支名注入#2647 的 defense-in-depth。四、清理尾段--ff-only快进合并与事务性四步清理修复提交后代理必须把成果归还给用户的$branch。清理尾段是严格有序的四步事务定义在 agents/gsd-code-fixer.md 的 Cleanup tail 小节# Step 1在主仓库中把用户分支快进到临时分支#2990 if git -C $main_repo merge --ff-only $reviewfix_branch 21; then ff_status0 else ff_status$? echo WARN: could not fast-forward $branch to $reviewfix_branch (exit $ff_status). echo The temp branch $reviewfix_branch is preserved for manual merge. fi # Step 2移除 worktree git worktree remove $wt --force # Step 3仅在快进成功后删除临时分支失败则保留供人工合并 if [ $ff_status -eq 0 ]; then git -C $main_repo branch -D $reviewfix_branch || true fi # Step 4最后删除恢复哨兵 rm -f $sentinel四个步骤的顺序不可颠倒原因如下--ff-only确保合并是纯快进若用户在此期间并发提交导致分支分叉合并会响亮地失败而不是静默改写历史——此时临时分支被保留供用户手动检视与合并worktree 必须在删除临时分支之前移除反过来会在中断时留下无哨兵引用的孤儿 worktree正是 #2839 的原始 bug临时分支只有在快进成功后才删除哨兵只有在git worktree remove成功后才删除从而保证从编排器视角看整个清理是原子的。五、崩溃恢复.review-fix-recovery-pending.json哨兵机制由于清理尾段发生在最后一次提交之后、git worktree remove之前进程若在此窗口内被系统重启或 OOM kill 中断就会留下孤儿 worktree 与未合并的临时分支。为此代理在git worktree add成功之后、清理开始之前于阶段目录写入恢复哨兵#2839并经 #3001 CR 增强node -e const fs require(fs); const [sentinelPath, worktree_path, branch, reviewfix_branch, padded_phase] process.argv.slice(1); fs.writeFileSync(sentinelPath, JSON.stringify({ worktree_path, branch, reviewfix_branch, padded_phase, started_at: new Date().toISOString() }, null, 2)); $sentinel $wt $branch $reviewfix_branch $padded_phase哨兵路径为${phase_dir}/.review-fix-recovery-pending.json记录worktree_path、branch、reviewfix_branch、padded_phase与started_at。其中reviewfix_branch字段是 #3001 的 CR 补充——若先前运行死在git worktree remove之后、git branch -D之前仅记录 worktree 路径无法清除幸存下来的孤儿分支。下次运行/gsd:code-review --fix或/gsd:resume-work、/gsd:progress若发现哨兵已存在会先执行自愈恢复解析 JSON 取出两个字段best-effort 地git worktree remove --force清除孤儿 worktree、git branch -D清除孤儿临时分支再删除旧哨兵并重新开始。这样修复流程对中断具有幂等自愈能力。六、配置开关workflow.use_worktrees退出隔离并非所有用户都需要 worktree 隔离。代理同样遵循workflow.use_worktrees配置#2825——这是与/gsd:execute-phase、/gsd:quick等兄弟 writer 工作流一致的可文档化退出通道。该配置位于 docs/CONFIGURATION.md设置类型默认值说明workflow.use_worktreesbooleantrue设为false时禁用并行执行的 git worktree 隔离当取值为false时gsd-code-fixer不会创建任何 worktreewt.、reviewfix_branch$branch、不写哨兵、清理尾段直接 early-exit。其安全性依据有二其一用户显式退出过 worktree就绝不能违背其意图再创建其二手工 worktree 内没有node_modules无法安全运行项目门禁直接在主 checkout 编辑/提交反而是安全路径也规避了 Windows 上 junction/reparse point 被rm -rf递归删除真实node_modules的隐患。详见功能文档 worktree-toggle.md。读取该标志的时机也有讲究setup_worktree步骤运行于规范的 gsd_run launcher preamble 被 source之前此时调用 CLI 属于未定义行为因此代理直接以node解析.planning/config.jsonUSE_WORKTREES$(node -e try { const fs require(fs); const p (process.env.GSD_PROJECT_DIR || process.cwd()) /.planning/config.json; const cfg JSON.parse(fs.readFileSync(p, utf8)); process.stdout.write(String((cfg.workflow cfg.workflow.use_worktrees) ?? true)); } catch { process.stdout.write(true); } )七、回归测试保障source-text-is-the-product该修复配套了完备的回归测试折叠在 tests/agent-frontmatter.test.cjs 的folded:bug-2990-code-fixer-worktree-branch套件中。测试遵循项目源码文本即产品source-text-is-the-product的测试哲学gsd-code-fixer 的指令文本就是运行时实际执行的内容因此直接解析代理 markdown 中的 bash 代码块并断言其形态就是在测试已部署的运行时契约。测试覆盖的关键断言包括解析所有git worktree add调用断言不存在裸检出现象attachesToBareBranch违规列表为空且存在使用-b $reviewfix_branch $wt $branch的规范调用#2990断言 worktree 路径是仓库相对路径、位于.claude/worktrees/rf-之下、且同时携带$$与$(date %s)双后缀保证并发唯一#2647解析清理尾段 bash 块断言恰好一次merge --ff-only针对$reviewfix_branch、恰好一次git branch -D针对$reviewfix_branch且 merge 必须先于branch 删除执行断言恢复哨兵 JSON 必须同时包含reviewfix_branch与worktree_path字段#3001 CR恢复脚本必须通过parsed.reviewfix_branch读取该字段并在哨兵检测与rm -f $sentinel之间调用git branch -D $prior_branch同文件中的 #2686 套件进一步断言git worktree add必须出现在任何分支切换git checkout与 commit 命令之前且指令必须包含git worktree remove清理。这些断言把同分支检出失败孤儿 worktree孤儿临时分支等历史 bug 逐一定格为不可回归的契约。八、底层关联worktree-base-ref 退化检查gsd-code-fixer 的手工 worktree 之外仓库还有一套自动化的 worktree 基线检测逻辑见 src/worktree-base-ref.cts 的evaluateWorktreeBaseDegrade当本分支 HEAD 与origin/HEADharness 创建并行 worktree 的 fork 基点发生漂移时系统会打印警告并自动降级为顺序执行避免基线错配。该模块通过--mode区分harness-worktree与orchestrator-worktree两种隔离来源并支持.claude/settings.local.json中worktree.baseRef: head的无覆盖写入gsd-tools worktree set-baseref。它回答了哪些运行时由 GSD 自己创建 worktree、哪些由 harness 创建的能力边界问题与 gsd-code-fixer 的手工 worktree 互为补充。九、总结PR #2990 的修复看似只有一行-b参数实则牵动了整条隔离链路的重新设计从拒绝同分支双检出的 Git 语义出发建立了gsd-reviewfix/${padded_phase}-$$临时分支 --ff-only快进归还 有序四步清理 崩溃恢复哨兵 use_worktrees退出开关的完整闭环并由 agents/gsd-code-fixer.md 的 bash 契约与 tests/agent-frontmatter.test.cjs 的文本级断言双重锁定。对于任何在 AI 代理工作流中做 git 隔离的工程实践这套派生临时分支 → 隔离执行 → 快进归还 → 哨兵自愈的模式都值得直接借鉴。赞分享【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载相关推荐gsd-core 代码修复 Agent 的同分支 worktree 隔离机制git worktree add -b 与事务化清理的工程实践gsd core 代码修复 Agent 的同分支 worktree 隔离机制 git worktree add b 与事务化清理的工程实践 导读 本文以 ggsd-core/gsd-quick Worktree 合并的复活检测守卫与 3195 对新建 .planning/ 文件的误删修复gsd core/gsd quick Worktree 合并的复活检测守卫与 3195 对新建 .planning/ 文件的误删修复 本文围绕 gsdgsd-core 嵌套 Git 仓库检测修复解析/gsd-new-project 与 /gsd-ingest-docs 如何通过 git rev-parse 语义避免误建 .gitgsd core 嵌套 Git 仓库检测修复解析 /gsd new project 与 /gsd ingest docs 如何通过 git rev parse上一篇Unleash API 请求/响应 Schema 分离实践基于 ADR 的 OpenAPI 契约设计指南下一篇oauth2-proxy 内置 HTTP 端点完全指南认证流程、健康检查与安全配置创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考