treehouse租约机制完全指南:用get --lease为自动化创建持久化隔离环境
【免费下载链接】treehouseManage worktrees without managing worktrees.项目地址https://gitcode.com/gh_mirrors/treehou/treehouse点击查看免费下载treehouse是一个管理 git worktree 池的命令行工具核心理念是Manage worktrees without managing worktrees。本文聚焦它的租约lease机制用treehouse get --lease以非交互方式获取一个 worktree 并写入持久化租约标记让自动化脚本、CI 任务和 AI Agent 拥有一个即使内部零进程也不会被回收的持久化隔离环境最后用treehouse return安全释放。为什么自动化需要租约普通的treehouse get会打开一个交互式子 shellshell 的存活期就是占用期exit之后 worktree 立即归还池子。这对人很合适但对自动化很尴尬脚本拿到路径后如果脚本进程退出了基于进程检测的占用判断就会失效空闲且干净的 worktree 可能在下一次get时被复用或被treehouse prune清理导致家被重置。租约正是为此设计的它把占用从进程活着升级为状态文件里有一条持久记录。哪怕 worktree 里一个进程都不在get不会把它分给别人prune不会动它直到你显式return。实现见 internal/pool/pool.go 中的AcquireLeaseInfoWithOptions。一键获取持久化隔离环境get --lease 基础用法只需给get加上--lease即可不打开子 shell、非交互地租下一个 worktreepath$(treehouse get --lease) # $path 是租约 worktree 的绝对路径所有提示横幅都走 stderr它和普通get的获取流程完全一致fetch 最新引用、优先复用池中干净空闲的 worktree否则新建区别只在于结束后 worktree 被标记为leased并写入持久化状态。默认stdout 只输出路径本身人看的提示全部走 stderr因此可以放心地用$(...)捕获——这就是命令实现在 cmd/get.go 中刻意保持的输出契约。标记租约持有者--lease-holder 与 TREEHOUSE_LEASE_HOLDER多个 Agent 或任务共享一个池时建议给每条租约记录一个持有者标签方便排查treehouse get --lease --lease-holder agent-a # 或在会话级导出环境变量所有租约自动带上标签 export TREEHOUSE_LEASE_HOLDERagent-a标签会记录进池状态随后treehouse status中会显示为(held by agent-a)一眼看出这个家是谁的。机器可读的租约分配get --lease --json自动化最需要的是一份稳定的 JSON 分配结果。加上--json后stdout 输出一条包含租约身份的记录treehouse get --lease --lease-holder automation-A --json # {path:...,lease_id:...,lease_holder:automation-A,leased_at:...,base_branch:main}几个关键字段字段说明path租约 worktree 的绝对路径lease_id每次获取都重新生成的随机租约身份即使是同一路径、同一持有者重新获取也会换新 IDlease_holder持有者标签未设置则为空leased_at租约建立时间base_branch本次切出的基础分支lease_id的存在意义在于防 ABA 问题同一路径可能被释放后再次租出仅凭路径相同无法确认归还的是同一次获取。把lease_id存下来归还时用它做条件校验就能精确锁住我租下的那一次。给已有 worktree 补租约treehouse leaseget --lease只能保护它自己获取到的 worktree。如果某个池内 worktree 是早就用普通get拿的、或者在租约功能出现前就存在了可以原地补一个租约treehouse lease 3 --lease-holder secondmate-home这里的3是treehouse status第一列打印的 worktree 名称。lease是一个纯状态操作它不会 reset、fetch、clean 或 checkout因此对装着活跃工作的 slot 也安全若名字不存在、目录已消失、slot 正在被销毁或已被租约保护它会直接拒绝且不写任何状态。命令实现在 cmd/lease.go。查看租约状态treehouse statustreehouse status # 1 leased ~/.treehouse/myrepo-a1b2c3/1/myrepo (held by agent-a) # 3 available ~/.treehouse/myrepo-a1b2c3/3/myrepoleased状态会被高亮持有者标签紧跟其后。脚本侧可用treehouse status --json获取包含lease_id、lease_holder、leased_at的结构化数组用于对账或巡检实现见 cmd/status.go。释放租约treehouse return 及条件归还释放租约用treehouse return支持按路径或名称定位treehouse return $path treehouse return 1return不是简单清个标记——它会先终止 worktree 内残留进程、验证没有外部进程还活着然后才重置并归还池子任何一步失败都会非零退出并把 worktree 原样保留绝不回收一个可能还在被写的 slot。完整流程见 cmd/return_cmd.go。重试安全的条件归还对自动化最推荐的写法是把归还条件绑定到获取时拿到的租约身份treehouse return --force \ --if-lease-id $lease_id \ --if-lease-holder $lease_holder \ $path校验在持有池状态锁时进行租约不存在或身份不匹配就在进程终止、重置之前直接非零退出。这让路径相同但已经不是同一次获取的场景不会误释放。读懂 return 的退出码退出码含义0worktree 已归还租约已释放1归还失败租约条件不满足、进程终止失败或重置失败3未归还存在未提交改动且确认被放弃或无法应答确认slot 保持原状prune也不会回收它3与1分开是有意的1值得重试而3重试会原地循环——要么先清理要么按提示用treehouse return --force path强制清理归还。一次性归还整个池当一批 Agent 全部结束、想整池回收时treehouse return --all # Returned 2 of 2 held worktree(s); 0 skipped; 1 not held.它会归还所有被持有的 slotleased、in-use、dirty 等但绝不碰available、damaged以及仅你站着但无人持有的 slot。注意它比prune/destroy --all范围更广——后两者永远不会触碰带租约的 slot。租约的安全边界谁能动一个 leased worktree租约提供的是强保护值得逐条确认❌ 后续的treehouse get永远不会把它分出去❌treehouse prune包括--all永远不会删除它❌treehouse destroy pool --all批量删除也永远跳过它✅ 唯一能删掉它的方式显式点名完整路径 treehouse destroy path --include-leased --yes。换句话说租约 worktree 是一个持久化家除非你亲手点名拆除否则树池的任何自动清理都不会误伤它。与 get 的其他选项自由组合--lease不是孤立开关几乎所有get选项都能与之搭配让自动化按需定制这个持久环境选项用途--base branch从指定分支切出覆盖配置中的base_branch-b name/--branch在获取到的 commit 上创建并检出新分支--no-fetch跳过 fetch直接用本地引用调用方已自行 fetch 时省一次网络--include-file path用自定义清单播种 gitignored 文件如.env、本地配置--unique-leaf新 worktree 目录名带 slot 编号避免工具按目录名推导身份时撞车--worktree-path template自定义 worktree 落盘路径--apfs-sharing freshmacOS/APFS 上新建 slot 的跟踪文件与主检出共享copy-on-write例如treehouse get --lease --base release/2.x --no-fetch --json。另外用户级配置里的post_create钩子在租约模式下其 stdout 会被路由到 stderr保证机器可读输出不被污染。池的配置示例可参考 treehouse.toml.example。完整自动化生命周期示例# 1. 租下隔离环境保存路径与租约身份 alloc$(treehouse get --lease --lease-holder nightly-ci --json) path$(echo $alloc | grep -o path:[^]* | cut -d -f4) lease_id$(echo $alloc | grep -o lease_id:[^]* | cut -d -f4) # 2. 在 $path 里装依赖、跑任务……期间进程可以全部退出 # 3. 条件归还身份匹配才执行避免误释放后来者 treehouse return --force --if-lease-id $lease_id --if-lease-holder nightly-ci $path延伸阅读设计文档docs/design.md租约获取核心internal/pool/pool.go池状态与租约字段持久化internal/pool/state.go三个关键命令cmd/get.go、cmd/lease.go、cmd/return_cmd.go安装脚本docs/install.sh、docs/install.ps1 上手建议先跑一次不带--lease的treehouse熟悉交互模式再用get --lease --json接入脚本——两者获取逻辑相同唯一区别是占用是否持久。赞分享【免费下载链接】treehouseManage worktrees without managing worktrees.项目地址https://gitcode.com/gh_mirrors/treehou/treehouse点击查看免费下载相关推荐Multipass终极指南10分钟创建自动化测试环境隔离开发更安全 Multipass终极指南10分钟创建自动化测试环境隔离开发更安全 Multipass 是一款强大的虚拟化工具能够帮助开发者快速创建和管理Ubunt虚拟化开发工具云原生treehouse 如何判断 worktree 正被使用进程扫描、所有者短租与持久租约三大机制详解treehouse 如何判断 worktree 正被使用进程扫描、所有者短租与持久租约三大机制详解 在多人、多 Agent 共享同一个 worktree 池的如何在Winboat中实现多租户隔离为团队提供安全独立的Windows应用环境如何在Winboat中实现多租户隔离为团队提供安全独立的Windows应用环境 Winboat是一款能让Linux系统无缝运行Windows应用的开源工具它桌面应用虚拟化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考