十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Worktrunk 深度指南:wt remove 的 worktree 移除命令、安全分支清理与后台回收机制

Worktrunk 深度指南:wt remove 的 worktree 移除命令、安全分支清理与后台回收机制 Worktrunk 深度指南wt remove 的 worktree 移除命令、安全分支清理与后台回收机制【免费下载链接】worktrunkWorktrunk is a CLI for Git worktree management, designed for parallel AI agent workflows项目地址: https://gitcode.com/GitHub_Trending/wo/worktrunkwt remove是 WorktrunkwtCLI中负责回收 git worktree 的命令默认作用于当前 worktree若分支的改动已经并入默认分支则连同分支一并删除。读完本篇你将掌握它的完整命令行参数、六层“分支是否可安全删除”的判定算法、后台移除与.git/wt/trash/回收站机制、--reap进程清理守卫以及面向自动化调用的 JSON 输出契约并能在源码层面理解其“先验证、再审批、后执行”的内部调用链。命令基本用法wt remove接受零个或多个目标不带参数时移除当前所在的 worktree带参数时按分支名或 worktree 路径移除指定目标。以下示例继承自官方参考文档 remove.md。移除当前 worktree会先触发pre-remove钩子如将云主机缩容到 0$ wt remove ◎ Running pre-remove project:cleanup flyctl scale count 0 Scaling app to 0 machines ◎ Removing api worktree branch in background (same commit as main, _) ○ Switched to worktree for main ~/repo移除指定 worktree / 分支支持一次传多个$ wt remove feature-branch $ wt remove old-feature another-branch保留分支只移除 worktree$ wt remove --no-delete-branch feature-branch强制删除未合并的分支$ wt remove -D experimental分支清理六层安全删除判定wt remove的核心价值在于它替你回答“删掉这个分支会不会丢工作”。默认情况下只有当分支若合并到默认分支不会带来任何新增改动时分支才会被删除。这一判定同时兼容未变的 git 历史也兼容 squash-merge 或 rebase 工作流提交历史不同但文件改动一致。具体而言Worktrunk 按成本从低到高依次检查六个条件任一命中即认为分支可删Same commit同一提交— 分支 HEAD 与默认分支相等。在wt list中显示为_。Ancestor祖先— 分支位于目标分支的历史之内fast-forward 或 rebase 之后的情形。显示⊂。No added changes无新增改动— 三点 difftarget...branch为空。显示⊂。Trees match树相同— 分支的 tree SHA 与目标的 tree SHA 相等。显示⊂。Merge adds nothing合并无增益— 模拟合并产生的 tree 与目标一致。可处理 squash-merged 分支在合并后目标分支又推进、且改动位于不同文件的情形。显示⊂。Patch-id match补丁指纹匹配— 分支的全部 diff 与目标上的某个 squash-merge 提交完全匹配。这是模拟合并因目标分支后来修改了分支碰过的文件而产生冲突时的兜底手段。显示⊂。两个重要的边界限制默认分支遍历有上限。为了让单次检查保持快速第 6 层判定只回溯有限深度如果合并点之后又落地了数百个提交才发生的 squash merge会落在上限之外此时必须显式用-D才能移除。“同提交”检查使用本地默认分支其余检查中的“target”指默认分支或当默认分支的 upstream例如origin/main严格领先于本地时使用 upstream 作为 target。满足上述条件且工作树为空的分支会在wt list中以暗色显示提示其可安全删除。需要特别理解的是这六层判定回答的是“删除是否丢失工作”而另一种失败属于拓扑约束——若某分支被第二个 worktree checkout只能通过git worktree add --force构造出来删除该 ref 会让那个 worktree 无法解析HEAD这正是git branch -d拒绝删除的原因。此类分支无论-D与否都会被保留命令会指明存活的 checkout 位置。从源码看这一保护在 src/git/repository/worktrees.rs 的worktree_for_branch中对重复 checkout 的告警逻辑中有所体现Worktrunk 自身从不创建这种状态遇到时只会解析到 git 列出的第一个 worktree 并告警。两个 force 标志作用域不同Worktrunk 为两种“破坏性场景”提供了两个独立的 force 标志切勿混用标志作用域适用场景--force-fWorktreeworktree 存在未提交的改动--force-delete-DBranch分支存在未合并的提交$ wt remove feature --force # 移除有未提交改动的 worktree $ wt remove feature -D # 删除未合并的分支 $ wt remove feature --force -D # 两者都用--force会移除含已暂存、已修改和未跟踪文件的脏 worktree不加此标志时worktree 有任何未提交改动即移除失败。若希望无论合并状态如何都保留分支使用--no-delete-branch。注意它与-D互斥src/commands/remove.rs 在入口处显式校验--force-delete与delete-branchfalse来自--no-delete-branch或[remove] delete-branch false配置的组合并直接报错。delete_branch的取值优先级为CLI 标志 项目/用户配置中的[remove] delete-branch默认true见 src/commands/remove.rs。后台移除与回收站机制移除默认在后台执行——命令立即返回。整个流程为worktree 目录被重命名进.git/wt/trash/同一文件系统内的即时 rename、git 元数据被修剪prune、分支被删除最后由一个脱离detached的rm -rf完成物理清理。跨文件系统的 worktree 会回退到git worktree remove。运行日志位于.git/wt/logs/{branch}/internal/remove.log。需要阻塞等待完成时使用--foreground。每次wt remove执行后.git/wt/trash/中超过 24 小时的条目会由一个脱离的rm -rf清扫——这是对“上一次后台移除被中断SIGKILL、重启、磁盘写满而遗留孤儿目录”的最终兜底。从源码结构看src/commands/remove.rs 中的removal_execution函数将--foreground映射为RemovalExecution::Foreground默认则是RemovalExecution::Background(BackgroundFallbackMode::Detached)命令头部注释src/commands/remove.rs完整描述了两种执行路径的差异前台停止 fsmonitor → rename 进.git/wt/trash/name-timestamp/→ 修剪元数据 → 删分支 → 对暂存目录做同步remove_dir_all。后台停止 fsmonitor → rename 修剪 同步删分支 → 在暂存目录上 spawn 脱离的rm -rf跨文件系统或锁定locked的 worktree 在脱离进程内回退到git worktree remove。此外主输出打印完成后还会 fire-and-forget 地运行一次仓库级内部清扫run_internal_sweep清掉过期的 trash 条目并终止 worktree 已不存在的孤儿git fsmonitor--daemon进程确保它永不阻塞用户可见的进度输出。元数据修剪的实现值得注意prune_worktree_entrysrc/git/repository/worktrees.rs选择git worktree remove path而非git worktree prune。原因是后者不接受路径过滤会遍历.git/worktrees/下所有条目——一个“此刻恰好不存在”的 worktree未挂载的卷、网络挂载断开、进行到一半的mv与真正被删除的无法区分批量 prune 会误删旁观者的管理目录index、ORIG_HEAD、per-worktree reflog、进行中的 rebase/merge 全部随之丢失且git worktree repair无法重建。指定路径将一次移除的爆炸半径限制在其意图之内。--reap移除前清理残留进程experimental在并行 AI agent 工作流中一个 worktree 往往跑着post-start启动的 dev server、文件监视器或 language server。--reap会在移除 worktree 前终止这些进程释放它们占用的端口和文件句柄$ wt remove --reap feature ◎ Reaping 2 processes under feature worktree ┃ 51234 node ┃ 51240 esbuild ✓ Reaped 2 processes ◎ Removing feature worktree branch in background (same commit as main, _)进程发现基于工作目录任何 cwd 位于 worktree 路径之下的进程都会被选中先SIGTERM幸存者在随后收到SIGKILL。为避免误杀用户本意要保留的工作--reap内置两道保守守卫交互进程一律豁免。持有控制终端的进程——交互式 shell或带未保存缓冲的vim等终端编辑器——永远不会被 reap只有脱离型进程才是候选。仅按工作目录发现。在 worktree 内启动之后又变更了目录的进程或被重新父化到init的守护进程不再报告位于 worktree 之下的目录因而不会被发现。要可靠地清理这类进程请用wt step tether启动它们——tether 会在 worktree 移除时杀掉整个进程组配置方法见 step 参考文档。Reaping 发生在 worktree 目录被触碰之前因此与前台/后台模式以及--force标志相互独立。仅支持 UnixWindows 上--reap会被直接拒绝src/commands/remove.rs 中通过#[cfg(not(unix))]显式bail!理由是没有廉价的 Windows 等价物宁可报错也不静默空转。发现、控制终端/自身排除以及SIGTERM→SIGKILL升级逻辑位于 src/git/reap.rs命令层只负责渲染用户可见的进度输出src/commands/remove.rs。JSON 输出面向自动化调用的结果契约--formatjson在移除完成后向 stdout 打印每个目标一个对象worktree 移除输出{kind, branch, path, branch_outcome, branch_checked_out_at}仅删分支branch-only移除则用pruned字段替代path。branch_outcome字段命名了分支的最终去向使调用方能区分“移除拒绝了删除请求”与“根本未请求删除”值含义deleted分支已删除deferred移交给脱离的后台进程处理本次运行永远看不到其结果--foreground模式不会报告此值not_attempted未尝试删除detached worktree、兄弟 checkout或--no-delete-branchretained_unmerged被拒绝分支未并入目标retained_checked_out被拒绝最终拓扑读取发现有活着的 worktree 正 checkout 该分支retained_raced被 compare-and-swap 拒绝——分支在合并判定与删除之间移动了应重新读取 ref 后重试retained_failed删除命令本身失败从源码看该值对应RemovalPlan::to_json(fate)的第二个参数BranchFate在 src/commands/remove.rs单目标路径与 src/commands/remove.rs多目标路径fate 按执行顺序与 JSON 输出顺序严格一致中被收集。Hooks 集成pre-remove钩子在 worktree 被删除之前运行此时仍可访问 worktree 文件适合做停服、备份等收尾post-remove钩子在移除之后运行。钩子的配置、审批模型用户需显式批准项目声明的钩子命令见 hook 参考文档。从源码看钩子审批遵循“先验证、后审批”的门禁Approve at the Gatehandle_remove_command先调用prepare_worktree_removal完成全部校验clean 检查、分支删除安全检查、force 标志处理通过后才构建并批准钩子计划src/commands/remove.rs--no-hooks或用户拒绝审批都会得到空计划移除继续但跳过全部项目钩子。Detached HEAD worktree 的处理Detached worktree 没有分支名此时应传 worktree 路径而非分支名$ wt remove /path/to/worktree多目标移除的执行顺序与部分成功当一次传入多个目标时Worktrunk 采取“先全量验证、再执行”的策略并把计划分三类有序执行其他 worktreeothers先行仅分支branch-only的删除次之当前 worktree 最后执行——这与示例输出中“Removing … in background”完成后“Switched to worktree for main ~/repo”的行为一致。每个目标的错误被独立收集而非立即中断支持部分成功src/commands/remove.rs。输入还会去重同一 worktree 的分支名拼写与路径拼写会被解析为同一规范标识后只规划一次src/commands/remove.rs 及测试validation_deduplicates_branch_and_path_aliases。另一处细节若解析时目标还是已注册 worktree、而准备阶段发现其目录已消失该计划会降级为 BranchOnly 并被归入 branch-only 桶执行而不是保留验证前的陈旧分类测试validation_buckets_missing_worktree_by_returned_plansrc/commands/remove.rs。完整命令参考以下是wt remove的完整参数参考继承自 remove.md 的命令参考小节wt remove - Remove worktree; delete branch if merged Defaults to the current worktree. Usage: wt remove [OPTIONS] [BRANCHES]... Arguments: [BRANCHES]... Branch name or worktree path [default: current] Options: --no-delete-branch Keep branch after removal -D, --force-delete Delete unmerged branches --foreground Run removal in foreground (block until complete) --reap Kill processes started in the worktree [experimental] Before removal, terminate processes whose working directory is under the worktree — dev servers, watchers, language servers. Processes holding a controlling terminal (interactive shells, terminal editors) are left alone. Unix only. -f, --force Force worktree removal Remove a dirty worktree, including staged, modified, and untracked files. Without this flag, removal fails if the worktree has any uncommitted changes. -h, --help Print help (see a summary with -h) Automation: --no-hooks Skip hooks --format FORMAT Output format JSON prints structured result to stdout after removal completes. [default: text] [possible values: text, json] Global Options: -C path Working directory for this command --config path User config file path --config-set toml Override config with inline TOML, e.g. --config-set list.fulltrue (repeatable) -v, --verbose... Verbose output (-v: info logs hook/alias template variables on stderr; -vv: also debug logs and raw subprocess output written to .git/wt/logs/). Set WORKTRUNK_VERBOSE0|1|2 to apply the same level everywhere — including shell completion, which no flag can reach -y, --yes Skip approval prompts使用前提说明[BRANCHES]...接受分支名或 worktree 路径缺省为当前 worktree-C path改变的是命令的工作目录仓库定位而非 worktree 选择——若已带分支参数再叠加-C会重复命名同一 worktree这一寻址规则详见 skills/worktrunk/SKILL.md 的“Which worktree a command acts on”一节。相关源码与测试入口命令入口与执行编排src/commands/remove.rsworktree 解析、重复 checkout 告警与元数据修剪src/git/repository/worktrees.rs后台移除的物理清理rename 进 trash、prune、rm -rfsrc/git/remove.rs--reap的进程发现与信号升级src/git/reap.rs集成测试tests/integration_tests/remove.rs、tests/integration_tests/step_prune.rs【免费下载链接】worktrunkWorktrunk is a CLI for Git worktree management, designed for parallel AI agent workflows项目地址: https://gitcode.com/GitHub_Trending/wo/worktrunk创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表