Skip to content

[Grok/dsh 42] Git worktree 隔离与结果应用 #174

Closed

Description

@Blackman99

Parent

#132

Ticket: 42

Status: ready-for-agent

User Stories: 29, 44(见父规格)

What to build

用户分叉或委派到隔离工作树,检查并显式应用结果,失败或取消后能安全保留/清理目录。

Acceptance criteria

  • 支持参考的本地 worktree 创建/恢复/列举/应用/清理行为,agent 工作目录与界面提示一致。
  • 脏工作区、同名分支、非 Git 目录、冲突和取消不覆盖用户已有修改。
  • 隔离后的权限和会话身份正确;应用结果是可见动作,不因子代理完成自动破坏主工作区。
  • 用临时真实 Git 仓库验证分支、文件和清理效果,公开命令/协议与界面一致。

Blocked by

Delivery contract

用户于2026-09-20批准当前测试与任务拆分。按父规格的已安装产物/真实终端和公开协议测试验收;实际实现须带适用的文档、Changeset及必要检查。ready-for-agent表示任务已定义,不表示前置任务已完成,也不授权自动开始本轮实施、购买付费资源或发布软件版本。

Activity

  1. Blackman99 commented on Sep 25, 2026

    @Blackman99
    OwnerAuthor

    Ticket 42 / #174 已合入 rewrite/grok-dsh-20260920 的 7b96914。

    codsh --rust -w [NAME](--worktree=NAME)在 $GROK_HOME/worktrees/<repo>/<name> 新建 git worktree(分支 codsh/<name>),在 --cwd 之后、读取配置/信任/沙箱之前进入。默认从 HEAD 加上未提交和未跟踪(未忽略)的文件建一个快照提交,原 checkout、索引和分支不变;--worktree-ref/--ref 给干净 checkout。重名加 -2、-3 后缀,已有分支不会被复用或重置。非 git 目录、未初始化仓库、bare 仓库、无效 ref 都被拒绝且不留下任何东西。-w -r <id> / -w -c 把会话复制成新 id 放进新 worktree 并续接副本,原会话不动。状态行显示 worktree 和分支。

    codsh --rust worktree list|show|apply|rm|gc|db 和会话内 /worktree 管理 worktree。apply 默认合并:只有 checkout 仍是 worktree 起点内容时才写入,其余列为冲突不动(退出码 5),--overwrite 取 worktree 版本,--dry-run 只报告;apply 不提交、不暂存,拒绝符号链接和越界路径。rm 对有未提交内容的 worktree 需 -f,分支有提交时保留分支。gc 不给 --max-age 不过期任何东西,保留有未提交/未跟踪/非缓存忽略文件、未被分支持有的提交或存活所有者的 worktree。detach、salvage、clean-artifacts 明确拒绝(没有 Grove 投影)。

    子代理 isolation: "worktree" 在自己的 worktree 中执行:未改动时自动删除,有改动时保留并在工具块和 /tasks 中给出 worktree 与分支,取消时删除。worktree 中的文件权限同时按 worktree 路径和对应的 checkout 路径评估,取更严格的结果,所以 checkout 上的 deny 规则也覆盖 worktree 副本。

    验证(全部只在 Linux 上):新增 scripts/rust-worktree.spec.mjs 19 项通过,和 rust-acp-protocol、rust-subagents、rust-mcp 一起 80/80 通过;新增 scripts/rust-worktree-pty-test.py 通过(会话隔离、/worktree apply、子代理保留、冲突、-w -r 分叉、后缀、非 git 拒绝、rm 与 gc),rust-subagent-pty-test.py 和 rust-queue-pty-test.py 在合入后的代码上也通过;pnpm run typecheck 通过;pnpm test 2350 通过、2 失败(reference-evidence.spec.mjs 和 rust-launcher.spec.mjs 在高负载下 5 秒超时,单独运行分别 11/11、4/4 通过,与本改动无关);Rust 工作区测试 codsh-rust 508 通过、4 失败,其余 crate 982 通过;cargo fmt --check 通过。失败的 4 项都在本改动未触及的文件里:filesystem_sandbox.rs 两项是已知的 Linux 沙箱环境限制;voice 和 privacy 各一项是本地回环服务器只读一次请求导致的时序抖动(privacy 单独重跑 3 次通过 1 次)。strict clippy 只报 filesystem_sandbox.rs 两个既有问题。

    未验证:macOS 与 Windows 完全没有运行过——路径解析(macOS /private 符号链接、大小写不敏感文件系统、Windows 盘符与 junction)、符号链接拒绝和所有 PTY 流程都只在 Linux 上验证。rust-fork-pty-test.py 只能在 macOS 上运行,本次只改了其中一条提示文字,未运行。本机没有 bubblewrap,文件系统沙箱下的 worktree(写入范围不够时 git 报错、不应用任何东西)没有端到端验证。与参考二进制的逐项对照未做。

    未实现:Grove / fast / btrfs worktree;新会话和分叉的 worktree 提示(hints.*_worktree_mode)和自动 gc;x.ai/git/worktree/* ACP 扩展;运行中会话内的 /fork --worktree(被拒绝,改用 -w -r)。已知限制:快照提交不区分已暂存和未暂存;apply 不应用仅权限位(chmod)的变化;du 不统计 worktree 池;worktree 是独立的信任与授权工作区,会重新询问;worktree 会话内 /new 之后登记表里的 sessionId 不更新。

    main、npm 和默认版本都没有改动。

    #191(远程克隆与工作树)和 #208(Ship 完整流程)不再等待本 ticket,但 #191 仍等 #190,#208 仍等 #195、#196。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions