
Worktrunk 实战技巧与模式并行 AI Agent 工作流的高效配置指南【免费下载链接】worktrunkWorktrunk is a CLI for Git worktree management, designed for parallel AI agent workflows项目地址: https://gitcode.com/GitHub_Trending/wo/worktrunkWorktrunk 是一款专为 Git worktree 管理设计的 CLI天然契合并行 AI Agent 工作流。本文基于官方 Tips Patterns 文档系统梳理了仓库布局、别名与钩子hooks、按 worktree 隔离服务、Agent 交接以及状态与日志管理五大类高频实战配方并深入源码层验证每个配方的底层原理如hash_port、sanitize_db过滤器的实现与wt step tether的进程组管理机制。读完本文你将能够为日常开发搭建一整套一键创建工作区、按分支隔离服务、多 Agent 并行协作的可复用配置。Setup and layout工作区初始化与仓库布局Shell 别名一条命令创建 worktree 并启动 Agent最常见的并行 Agent 工作流是为每个任务开一个 worktree并在其中启动一个 Agent CLI。把这两步合成一条命令alias wscwt switch --create --executeclaude wsc new-feature # Creates worktree, runs hooks, launches Claude wsc feature -- Fix GH #322 # Runs claude Fix GH #322--executeclaude会在 worktree 创建完成、钩子执行完毕后在目标 worktree 目录内启动claude。--之后的内容会原样透传给该程序因此wsc feature -- Fix GH #322等价于在新建的 worktree 中执行claude Fix GH #322。注意由于安全考虑--execute在项目级别名和钩子体中默认被禁用这与下文 direnv/mise 的信任提示背后的安全理由一致此别名应放在 shell 配置如~/.bashrc、~/.zshrc中。快捷参数Shortcuts跨命令通用快捷参数在所有命令中通用完整列表见 wt switch 文档。最常用的三个wt switch --create hotfix --base # Branch from current HEAD wt switch - # Switch to previous worktree wt remove # Remove current worktree代表当前 worktree配合--base可以从当前 HEAD 而非默认分支创建新分支-代表上一个 worktree。其语义类似cd -或git checkout -可快速在最近两个 worktree 之间往返相关说明见 src/cli/config.rspr:number/mr:number以及 PR/MR 的 Web URL 也属于快捷参数同仓库的 PR/MR 直接切换到对应分支fork 的 PR/MR 会先 fetch 对应 refrefs/pull/N/head或refs/merge-requests/N/head再切换详见 src/cli/mod.rs 附近的说明。堆叠分支Stacked branches当你想从当前功能分支继续派生子分支而非从默认分支派生时wt switch --create feature-part2 --base这会在当前 HEAD 上切出新分支适合把一个大功能拆成多个可独立评审/合并的小分支。复用default-branch脚本在任何仓库都能跑默认分支检测让脚本无需硬编码main或mastergit rebase $(wt config state default-branch)在钩子和别名模板中同样的值通过{{ default_branch }}模板变量获得。二者有明确分工模板变量只读、无进程开销适合钩子/别名这类由 worktrunk 渲染的环境而wt config state default-branch是子进程调用更适合纯 shell 脚本。源码层面{{ default_branch }}在 src/commands/command_executor.rs 中通过var_default_branchspan 冷检测注入且属于repo 级变量——它在整个仓库的所有 worktree 中取值恒定不像branch、worktree_path等active 变量那样随 worktree 变化。为单个克隆覆盖default-branch当集成分支与远端HEAD不一致时可用克隆级覆盖clone-local overridewt config state default-branch set integration该设置只影响当前克隆不会污染全局配置。Bare 仓库布局所有分支一视同仁裸仓库没有工作树因此包括默认分支在内的所有分支都是链接 worktree处于相同层级没有任何分支享受特殊待遇。把裸仓库克隆到project/.git所有 worktree 就会集中在同一目录下git clone --bare url myproject/.git cd myproject配合worktree-path {{ repo_path }}/../{{ branch | sanitize }}worktree 会成为myproject/的子目录myproject/ ├── .git/ # bare repository ├── main/ # default branch worktree ├── feature/ # feature branch worktree └── bugfix/ # bugfix branch worktree这里{{ branch | sanitize }}用的是sanitize过滤器它把路径分隔符/和\替换为-防止目录穿越并保证分支名是单一路径组件实现见 src/config/expansion.rs 的sanitize_branch_name。配置 worktree 路径在隐藏路径.git、.bare下的裸仓库中首次执行wt switch时worktrunk 会检测到默认模板会产生myproject/.git.main这类坏路径并主动提出修复▲ Bare repo at myproject/.git — worktrees will be at myproject/.git.main ◎ Configure worktree-path to place worktrees at myproject/main? [y/N/?]接受后会把项目级配置写入用户配置# ~/.config/worktrunk/config.toml [projects.github.com/myorg/myrepo] worktree-path {{ repo_path }}/../{{ branch | sanitize }}在任意 worktree 内运行wt config show可在 PROJECT CONFIG 段找到Identifier: …即项目标识符。如果希望所有裸仓库都采用此布局可以把worktree-path ...写到顶层作为全局设置。创建第一个 worktreewt switch main刚克隆的裸仓库中默认分支已存在因此wt switch main不带--create即可。新建分支则用wt switch --create branch。此后wt switch --create feature会在myproject/feature/创建 worktree。设置项目配置项目配置.config/wt.toml必须位于某个 worktree 内部——裸.git目录没有可跟踪文件。等第一个 worktree 创建后在其中初始化cd myproject/main wt config create --project提交该文件后它会自动出现在每个 worktree 中。Aliases and hooks别名与钩子配方wt别名组合模板过滤器与 vars别名可以用模板过滤器和 vars 组合出强大的快捷命令# .config/wt.toml [aliases] # Open this worktrees dev server open open http://localhost:{{ branch | hash_port }} # Test with branch-specific features from vars test cargo test --features {{ vars.features | default(default) }} # Switch via the interactive picker, print the chosen branch pick wt switch --formatjson | jq -r .branch别名的作用域、审批与引用方式详见 Aliases 文档。按分支变量Per-branch variableswt config state vars按分支保存状态可从模板{{ vars.key }}和 CLI 访问。典型用途跨流水线步骤协调状态——见下文 Database per worktree 完整配方把分支绑定到环境——wt config state vars set envstaging然后在钩子中用{{ vars.env | default(dev) }}按分支参数化别名——见上文wt别名中的test示例。存储格式、JSON 支持与参考见wt config state vars。钩子中调用任务运行器可以在钩子中直接引用 Taskfile / Justfile / Makefile[pre-start] setup task install [pre-merge] validate just test lint这样把工具链的统一入口保留在项目自身的任务定义中钩子只负责编排调用时机。渐进式验证Progressive validation把检查按钩子类型拆分——提交前做快速反馈合并前跑昂贵套件[[pre-commit]] lint npm run lint typecheck npm run typecheck [[pre-merge]] test npm test build npm run buildpre-commit在wt merge期间、squash 提交之前运行pre-merge在 rebase 之后每次合并运行一次因此是慢速测试的正确位置。这种拆分让每个循环的反馈延迟最小化。目标特定钩子Target-specific hooks用{{ target }}按合并目标分支区分行为——例如从main部署生产、从 release 分支部署 stagingpost-merge if [ {{ target }} main ]; then npm run deploy:production elif [ {{ target }} staging ]; then npm run deploy:staging fi {{ target }}是被合并进入的分支。post-merge在目标分支的 worktree 中运行若目标没有 worktree 则在主 worktree 中运行因此部署命令能直接看到合并后的代码。Per-worktree services按 worktree 隔离服务每个 worktree 一个开发服务器每个 worktree 在确定性端口上运行自己的开发服务器。hash_port过滤器根据分支名生成 10000-19999 区间的稳定端口# .config/wt.toml [post-start] server wt step tether -- npm run dev -- --port {{ branch | hash_port }} [list] url http://localhost:{{ branch | hash_port }}hash_port的底层实现在 src/config/expansion.rs10000 (DefaultHasher(branch) % 10000)同一分支在任何机器上都得到同一端口。(db- ~ branch)这类字符串拼接会产生不同的哈希结果从而让数据库端口与开发服务器端口互不冲突。wt step tether在自己的进程组中运行服务器并在 worktree 被移除时拆除整个进程组因此无需pre-remove钩子。源码层面src/commands/step/tether.rs子进程通过setpgid(0, 0)成为新进程组组长Unix 上用有界SIGTERM → SIGKILL升级的killpg清扫整个进程组即使子进程在父进程退出后 reparent 到 PID 1 也能被覆盖Windows 没有可杀的进程组改用taskkill /T /F终止进程树。URL 列会显示每个 worktree 的开发服务器地址$ wt list Branch Status HEAD± main↕ main…± Remote⇅ URL Commit main ? ^⇅ 5 ⇡1 ⇣1 http://localhost:12107 41ee083 feature-api ↕⇡ 54 -5 ↑4 ↓1 234 -24 ⇡3 http://localhost:10703 6814f02 fix-auth ↕| ↑2 ↓1 25 -11 | http://localhost:16460 b772e68 fix-typos _| | http://localhost:14301 41ee083 ○ Showing 4 worktrees, 2 with changes, 2 ahead, hidden: Path, Age, Messagefix-auth在任何机器上都固定拿到端口 16460。服务器未运行时URL 会变暗提示。URL 列由项目配置中的模板驱动参见 src/commands/list/collect/mod.rs 对 URL 模板的说明。每个 worktree 一个数据库每个 worktree 可以拥有独立的隔离数据库。流水线第一步把名称和端口存为 vars后续步骤与钩子再引用它们[[post-start]] set-vars wt config state vars set \ container{{ repo }}-{{ branch | sanitize }}-postgres \ port{{ (db- ~ branch) | hash_port }} \ db_urlpostgres://postgres:devlocalhost:{{ (db- ~ branch) | hash_port }}/{{ branch | sanitize_db }} [[post-start]] db docker run -d --rm \ --name {{ vars.container }} \ -p {{ vars.port }}:5432 \ -e POSTGRES_DB{{ branch | sanitize_db }} \ -e POSTGRES_PASSWORDdev \ postgres:16 [pre-remove] db-stop docker stop {{ vars.container }} 2/dev/null || true第一个流水线步骤从分支派生值并存入 vars第二个步骤引用{{ vars.container }}与{{ vars.port }}——模板在每个步骤运行时渲染所以此时 vars 已就绪。pre-remove读取同一组 vars 来停止容器。(db- ~ branch)的拼接哈希与裸branch不同保证数据库与开发服务器端口不碰撞。sanitize_db过滤器生成数据库安全标识符全部小写、下划线替换非字母数字、折叠连续下划线、数字开头加_前缀、追加 3 字符哈希后缀、总长截断至 48 字符PostgreSQL 标识符上限 63 字符内留有余量完整规则与示例见 src/config/expansion.rs。哈希后缀还解决了 SQL 保留字与碰撞问题user→user_abca-b与a_b得到不同后缀。连接串不仅钩子可用任何地方都能取DATABASE_URL$(wt config state vars get db_url) npm start按 worktree 的环境变量要把环境变量限定到单个 worktree——工具包路径、profile、API 端点——推荐使用 direnv 或 mise 这类目录环境管理器。二者都钩住 shell 提示符因此会在wt switch已经执行的cd时自动激活无需任何 worktrunk 配置。把配置提交在仓库根目录每个 worktree 就有自己的副本路径相对该 worktree 解析。direnv—— 在仓库根目录提交.envrcexport MY_PACKAGES_PATH$PWD/.packages每个 worktree 首次进入时运行一次direnv allow以信任该文件。之后切进 worktree 加载环境切出则卸载。mise—— 在仓库根目录提交mise.toml[env] MY_PACKAGES_PATH {{ config_root }}/.packages{{ config_root }}是 mise 解析相对路径所依据的项目根——即 worktree 根而非主 worktree。mise 还覆盖 Windows / PowerShell这是 direnv 原生不支持的。两者都向 shell 会话设置真实环境变量因此所有子进程钩子、构建工具、子 shell都能继承无需--execute变通。每个新 worktree 是全新路径需要各自的一次性信任步骤direnv allow/mise trustworktrunk 刻意不绕过该提示。消除冷启动用wt step copy-ignored把被 gitignore 的文件缓存、依赖、.env在 worktree 之间复制[post-start] copy wt step copy-ignored当其他钩子依赖这份拷贝时——例如先复制node_modules/再pnpm install以复用缓存包——用[[post-start]]流水线排序[[post-start]] copy wt step copy-ignored [[post-start]] install pnpm install若--execute命令需要立即使用拷贝文件则改用pre-start。默认复制全部 gitignored 文件。要限制范围创建.worktreeinclude并写入模式——文件必须同时满足 gitignore 且命中.worktreeinclude才会被复制。相关实现见 src/commands/step/copy_ignored.rs 及 src/commands/step/shared.rs其中还定义了默认排除项。该命令还支持--require-include没有.worktreeinclude就不复制任何内容这与 Claude Code 桌面版的复制语义一致。Caddy 子域名路由无需端口号的干净 URL如http://feature-auth.myproject.localhost。对 cookies、CORS 以及贴近生产 URL 结构很有用。前置条件安装 Caddy。# .config/wt.toml [post-start] server wt step tether -- npm run dev -- --port {{ branch | hash_port }} proxy curl -sf --max-time 0.5 http://localhost:2019/config/ || caddy start curl -sf http://localhost:2019/config/apps/http/servers/wt || \ curl -sfX PUT http://localhost:2019/config/apps/http/servers/wt -H Content-Type: application/json \ -d {listen:[:8080],automatic_https:{disable:true},routes:[]} curl -sf -X DELETE http://localhost:2019/id/wt:{{ repo }}:{{ branch | sanitize }} || true curl -sfX PUT http://localhost:2019/config/apps/http/servers/wt/routes/0 -H Content-Type: application/json \ -d {id:wt:{{ repo }}:{{ branch | sanitize }},match:[{host:[{{ branch | sanitize }}.{{ repo }}.localhost]}],handle:[{handler:reverse_proxy,upstreams:[{dial:127.0.0.1:{{ branch | hash_port }}}]}]} [pre-remove] proxy curl -sf -X DELETE http://localhost:2019/id/wt:{{ repo }}:{{ branch | sanitize }} || true [list] url http://{{ branch | sanitize }}.{{ repo }}.localhost:8080工作原理wt switch --create feature-auth运行post-start钩子在确定性端口{{ branch | hash_port }}→ 例如 18283启动开发服务器钩子按需启动 Caddy 并注册路由feature-auth.myproject→localhost:18283*.localhost经操作系统解析到127.0.0.1访问http://feature-auth.myproject.localhost:8080Caddy 匹配子域名并反向代理到开发服务器。pre-remove钩子删除对应路由避免残留。每个 worktree 一个 tmux 会话每个 worktree 获得独立 tmux 会话与多窗格布局# .config/wt.toml [pre-start] tmux S{{ branch | sanitize }} W{{ worktree_path }} tmux new-session -d -s $S -c $W -n dev # Create 4-pane layout: shell | backend / claude | frontend tmux split-window -h -t $S:dev -c $W tmux split-window -v -t $S:dev.0 -c $W tmux split-window -v -t $S:dev.2 -c $W # Start services in each pane tmux send-keys -t $S:dev.1 npm run backend Enter tmux send-keys -t $S:dev.2 claude Enter tmux send-keys -t $S:dev.3 npm run frontend Enter tmux select-pane -t $S:dev.0 echo ✓ Session $S — attach with: tmux attach -t $S 创建 worktree 并立即附加$ wt switch --create feature -x tmux -- attach -t {{ branch | sanitize }}pre-remove钩子负责清理会话tmux kill-session -t {{ branch | sanitize }}。每个 worktree 一个 cmux 工作区每个 worktree 获得独立的 cmux 工作区。切换 worktree 即切换工作区移除 worktree 即关闭其工作区。前置条件jq。# ~/.config/worktrunk/config.toml # cmux is the navigation primitive; dont also cd the invoking shell. [switch] cd false [pre-start] cmux cmux new-workspace --name {{ repo | sanitize }}/{{ branch | sanitize }} --cwd {{ worktree_path }} --focus true [pre-switch] cmux WS$(cmux --json list-workspaces 2/dev/null \ | jq -r --arg t {{ repo | sanitize }}/{{ branch | sanitize }} \ .workspaces[] | select(.title $t) | .ref | head -1) [ -n $WS ] cmux select-workspace --workspace $WS || true [pre-remove] cmux WS$(cmux --json list-workspaces 2/dev/null \ | jq -r --arg t {{ repo | sanitize }}/{{ branch | sanitize }} \ .workspaces[] | select(.title $t) | .ref | head -1) [ -n $WS ] cmux close-workspace --workspace $WS || true 为什么用pre-*而非post-*cmux 限制 socket 只能由 cmux 终端内派生的进程访问。post-*钩子以分离的后台进程运行会打断进程祖先链pre-*钩子前台运行继承终端的进程血缘。这与wt step tether之所以需要显式进程组管理是同一个底层原因——worktrunk 在 src/commands/step/tether.rs 中正是为了对付进程组/祖先链问题。Xcode DerivedData 清理移除 worktree 时清理 Xcode 的 DerivedData。每个 DerivedData 目录都含有一个记录项目路径的info.plist——grep 出 worktree 路径即可找到并删除匹配的构建缓存# ~/.config/worktrunk/config.toml [post-remove] clean-derived grep -Fl {{ worktree_path }} \ ~/Library/Developer/Xcode/DerivedData/*/info.plist 2/dev/null \ | while read plist; do derived_dir$(dirname $plist) rm -rf $derived_dir echo Cleaned DerivedData: $derived_dir done Working with agents与 Agent 协作跟踪 Agent 状态Agent 插件会在wt list中为每个 worktree 标记 工作中或 等待中其他任何工作流都可以用wt config state marker set手工设置标记。详见 Activity tracking。Agent 交接Handoffs在后台生成一个运行 Agent CLI 的 worktree。-x指定要运行的程序--之后的内容全部透传给它因此 OpenCode 的子命令要放在--之后-x opencode -- run task。tmux新建分离会话tmux new-session -d -s fix-auth-bug wt switch --create fix-auth-bug -x claude -- \ The login session expires after 5 minutes. Find the session timeout config and extend it to 24 hours.Zellij当前会话中新建窗格zellij run -- wt switch --create fix-auth-bug -x claude -- \ The login session expires after 5 minutes. Find the session timeout config and extend it to 24 hours.这样可以让一个 Agent 会话把工作交接给另一个在后台运行的 Agent。钩子会在多路复用器的会话/窗格内运行。worktrunk skill 包含指导 Claude Code及其他加载该 skill 的 Agent CLI执行此模式的指引。要启用它可显式要求spawn a parallel worktree for...或加入项目说明文件CLAUDE.md或AGENTS.mdWhen I ask you to spawn parallel worktrees, use the agent handoff pattern from the worktrunk skill.Status, commits, and logs状态、提交与日志跨分支监控 CIwt list --full --branches显示所有分支包括没有 worktree 的分支的 PR/CI 状态。CI 指标是可点击的链接直达 PR 页面。LLM 分支摘要配置summary true并启用commit.generation后wt list --full会为每个分支显示一行 LLM 生成的摘要同样的摘要也出现在wt switch交互式选择器的summary页签中。# ~/.config/worktrunk/config.toml [list] summary true详见 LLM Commits 的分支摘要章节。JSON APIwt list --formatjson面向仪表盘、statusline 与脚本的结构化输出。查询示例见wt list。手工提交信息commit.generation.command从 stdin 接收渲染后的提示词并从 stdout 返回提交信息。想手工写提交信息而非使用 LLM可指向$EDITOR# ~/.config/worktrunk/config.toml [commit.generation] command f$(mktemp); printf \n\n $f; sed s/^/# / $f; ${EDITOR:-vi} $f /dev/tty /dev/tty; grep -v ^# $f这段命令把渲染出的提示词diff、分支名、统计用#前缀注释掉打开编辑器保存时剥离注释行。顶部留两行空行供输入提示词上下文可见于下方作参考。如果想把 LLM 保留为默认、只在特定合并时改用编辑器添加一个 worktrunk 别名# ~/.config/worktrunk/config.toml [aliases] mc WORKTRUNK_COMMIT__GENERATION__COMMANDf$(mktemp); printf \n\n $f; sed s/^/# / $f; ${EDITOR:-vi} $f /dev/tty /dev/tty; grep -v ^# $f wt merge之后wt mc打开编辑器写提交信息普通wt merge继续使用 LLM。监控钩子日志跟踪后台钩子的输出tail -f $(wt config state logs get --hookuser:post-start:server)--hook的格式是source:hook-type:name——例如项目定义的钩子写作project:post-start:build。可用wt config state logs get列出所有可用日志。为高频使用创建别名alias wtlogf() { tail -f $(wt config state logs get --hook$1); }; f小结围绕 worktrunk 的并行 worktree 工作流本文覆盖了从仓库布局bare 仓库、worktree-path模板、别名与钩子vars 状态、渐进验证、目标特定钩子、服务隔离开发服务器、数据库、环境变量、冷启动消除、Caddy 子域名、tmux/cmux、DerivedData 清理到 Agent 协作状态跟踪、交接模式与状态管理CI 监控、LLM 摘要、JSON API、手工提交、日志跟踪的完整配方。所有模板过滤器hash_port、sanitize、sanitize_db、default(…)与命令wt step tether、wt step copy-ignored、wt config state vars都可在 src/config/expansion.rs 与 src/commands/step 中找到对应实现读者可以直接复制本文配置到.config/wt.toml或~/.config/worktrunk/config.toml中按需裁剪使用。【免费下载链接】worktrunkWorktrunk is a CLI for Git worktree management, designed for parallel AI agent workflows项目地址: https://gitcode.com/GitHub_Trending/wo/worktrunk创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考