ralph-merge-worktrees
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRalph Merge Worktrees
Ralph 合并Worktree
Analyze completed Ralph worktree PRDs, build a dependency-aware merge queue, and sequentially squash-merge each branch into main — removing the worktree after each successful merge.
分析已完成的Ralph worktree PRD,构建感知依赖的合并队列,按顺序将每个分支压缩合并(squash-merge)到main分支,每次合并成功后移除对应的worktree。
Overview
概述
Ralph worktrees live at with PRDs at inside each worktree. A worktree is "completed" when every user story in its PRD has . This skill finds all completed worktrees, determines the safest merge order, presents the plan for approval, and then executes it one branch at a time.
.claude/worktrees/ralph/<feature>/scripts/ralph/prd.jsonpasses: trueRalph worktree存放在 路径下,每个worktree内的PRD位于 。当PRD中所有用户故事的 字段值都为 时,该worktree即标记为“已完成”。本skill会查找所有已完成的worktree,确定最安全的合并顺序,展示合并计划等待确认,之后逐个执行合并操作。
.claude/worktrees/ralph/<feature>/scripts/ralph/prd.jsonpassestrueStep 1: Scan and Identify Completed Worktrees
步骤1:扫描并识别已完成的Worktree
Read every file. For each PRD:
.claude/worktrees/ralph/*/scripts/ralph/prd.json- Parse the JSON — extract ,
branchName, anddescriptionuserStories[] - A worktree is completed when ALL stories have
passes: true - Skip any worktree whose PRD has at least one story with
passes: false - Also skip worktrees that don't have a (malformed or empty)
prd.json
If no completed worktrees are found, tell the user and stop.
读取所有 文件,针对每个PRD执行以下操作:
.claude/worktrees/ralph/*/scripts/ralph/prd.json- 解析JSON,提取 、
branchName和description字段userStories[] - 当所有用户故事都满足 时,该worktree判定为已完成
passes: true - 跳过PRD中至少有一个故事为 的worktree
passes: false - 同时跳过没有 文件的worktree(结构异常或为空)
prd.json
如果未找到已完成的worktree,告知用户后终止流程。
Step 2: Analyze Each Completed Branch
步骤2:分析每个已完成的分支
For each completed worktree, gather merge intelligence:
bash
undefined针对每个已完成的worktree,收集合并所需信息:
bash
undefinedFrom the main repo root, diff the branch against main
从仓库根目录执行,对比分支与main分支的差异
git diff main...<branchName> --stat
git diff main...<branchName> --name-only
git log main..<branchName> --oneline
Collect for each branch:
- **Files changed** — the full list of modified/added/deleted files
- **Change categories** — classify files into buckets:
- `terraform` — anything under `terraform/` (infra, resolvers, functions, lambda)
- `types` — anything under `types/`
- `graphql` — anything under `app/graphql/`
- `services` — anything under `services/`
- `composables` — anything under `app/composables/`
- `components` — anything under `app/components/`
- `pages` — anything under `app/pages/`
- `layouts` — anything under `app/layouts/`
- `content` — anything under `content/`
- `config` — root config files (`nuxt.config.ts`, `terraform-scaffold.config.ts`, etc.)
- `other` — everything else
- **Commit count** — number of commits on the branch
- **Story count** — total user stories in the PRD
- **File count** — total files changed
- **Overlap matrix** — which files are touched by multiple branches (potential conflict zones)git diff main...<branchName> --stat
git diff main...<branchName> --name-only
git log main..<branchName> --oneline
为每个分支收集以下信息:
- **变更文件**:所有修改/新增/删除的文件完整列表
- **变更分类**:将文件划分到不同类别:
- `terraform`:`terraform/` 目录下的所有文件(基础设施、解析器、函数、lambda)
- `types`:`types/` 目录下的所有文件
- `graphql`:`app/graphql/` 目录下的所有文件
- `services`:`services/` 目录下的所有文件
- `composables`:`app/composables/` 目录下的所有文件
- `components`:`app/components/` 目录下的所有文件
- `pages`:`app/pages/` 目录下的所有文件
- `layouts`:`app/layouts/` 目录下的所有文件
- `content`:`content/` 目录下的所有文件
- `config`:根目录配置文件(`nuxt.config.ts`、`terraform-scaffold.config.ts`等)
- `other`:其余所有文件
- **提交数**:分支上的commit总数
- **故事数**:PRD中的用户故事总数
- **文件数**:变更的文件总数
- **重叠矩阵**:哪些文件被多个分支修改(潜在冲突区域)Step 3: Build the Priority Queue
步骤3:构建优先级队列
Rank branches for merge order using these heuristics (most important first):
按照以下启发式规则对分支的合并顺序进行排序(优先级从高到低):
3a. Dependency Layer Ordering
3a. 依赖层排序
Merge bottom-up through the stack so downstream features inherit upstream changes:
- Infrastructure first — branches that primarily touch ,
terraform/,types/,services/(schema, tables, resolvers, types)config - Data/API layer — branches focused on ,
app/graphql/(client-side data plumbing)app/composables/ - UI layer last — branches primarily touching ,
app/components/,app/pages/,app/layouts/content/
Determine the "primary layer" by whichever category has the most changed files. If a branch spans multiple layers, it belongs to the lowest layer it touches (infra > api > ui).
按照技术栈自底向上合并,确保下游功能可以继承上游变更:
- 基础设施优先:主要修改 、
terraform/、types/、services/的分支(schema、表、解析器、类型定义)config - 数据/API层次之:聚焦于 、
app/graphql/的分支(客户端数据链路)app/composables/ - UI层最后:主要修改 、
app/components/、app/pages/、app/layouts/的分支content/
通过变更文件最多的类别判定分支的“主要层级”。如果一个分支跨多个层级,则归属到它所涉及的最低层级(基础设施 > API > UI)。
3b. Within the Same Layer
3b. 同层级排序
When two branches are in the same layer, break ties using:
- Less file overlap first — branches that share fewer files with other pending branches get merged first (lower conflict risk after merge)
- Smaller changeset first — fewer files changed = less risk, gets quick wins merged early, and the larger branch can rebase more easily if needed
- Fewer commits first — proxy for scope/complexity
当两个分支属于同一层级时,按照以下规则判定优先级:
- 文件重叠更少的优先:与其他待合并分支共享文件更少的分支优先合并(合并后产生冲突的风险更低)
- 变更集更小的优先:变更文件越少 = 风险越低,可快速合并低风险变更,后续更大的分支如有需要也更容易变基
- 提交数更少的优先:可作为分支范围/复杂度的参考指标
3c. Special Cases
3c. 特殊情况
- If a branch only touches files (e.g., legal pages, markdown), it's very low-risk — can go anywhere in the queue, but default to early since it won't conflict with code changes
content/ - If a branch touches or
terraform-scaffold.config.ts, prefer merging it early — other branches may have stale copies of these high-contention filesterraform/envs/staging/main.tf
- 如果分支仅修改 目录下的文件(比如法律页面、markdown文件),风险极低,可以放在队列的任意位置,默认优先合并,因为不会和代码变更产生冲突
content/ - 如果分支修改了 或
terraform-scaffold.config.ts,优先合并:其他分支可能持有这些高竞争文件的过期副本terraform/envs/staging/main.tf
Step 4: Present the Merge Plan
步骤4:展示合并计划
Show the user the proposed merge queue in a clear table format:
Ralph Merge Queue — N completed branches ready
Priority | Branch | Stories | Files | Layer | Reason
---------|--------------------------------|---------|-------|--------------|------------------
1 | ralph/legal-pages | 6/6 | 8 | content | Content-only, low risk
2 | ralph/post-creation | 12/12 | 34 | infra+ui | Core data model, merge early
3 | ralph/like-thread-post-comment | 8/8 | 15 | infra+ui | Depends on thread model
...
File overlap warnings:
- terraform/envs/staging/main.tf: touched by 3 branches (post-creation, chat-and-messaging, like-thread-post-comment)
- terraform/envs/staging/schema.graphql: touched by 4 branches
Proceed with merge queue? (y/n)Wait for user confirmation before proceeding. If the user wants to reorder or skip branches, adjust the queue accordingly.
用清晰的表格向用户展示拟议的合并队列:
Ralph Merge Queue — N completed branches ready
Priority | Branch | Stories | Files | Layer | Reason
---------|--------------------------------|---------|-------|--------------|------------------
1 | ralph/legal-pages | 6/6 | 8 | content | Content-only, low risk
2 | ralph/post-creation | 12/12 | 34 | infra+ui | Core data model, merge early
3 | ralph/like-thread-post-comment | 8/8 | 15 | infra+ui | Depends on thread model
...
File overlap warnings:
- terraform/envs/staging/main.tf: touched by 3 branches (post-creation, chat-and-messaging, like-thread-post-comment)
- terraform/envs/staging/schema.graphql: touched by 4 branches
Proceed with merge queue? (y/n)执行前等待用户确认。如果用户需要调整顺序或跳过某些分支,对应调整队列即可。
Step 5: Execute the Merge Queue
步骤5:执行合并队列
For each branch in the queue, in order:
按顺序处理队列中的每个分支:
5a. Pre-merge Check
5a. 合并前检查
bash
undefinedbash
undefinedEnsure main is clean and up to date
确保main分支干净且为最新版本
git checkout main
git status --porcelain
If there are uncommitted changes on main, stop and alert the user.git checkout main
git status --porcelain
如果main分支上有未提交的变更,终止流程并通知用户。5b. Squash-Merge via /git-squash
5b. 通过/git-squash执行压缩合并
Invoke the skill with the branch name. This handles:
/git-squash- Pre-flight checks (branch exists, has diverged from main)
git merge --squash <branchName>- Delegates commit to (Conventional Commits, Co-Authored-By trailer)
/git-commit - Post-merge verification
- Local branch cleanup ()
git branch -d/-D
If the squash-merge fails due to conflicts:
git merge --abort- Report which files conflicted
- Skip this branch — move it to the end of the queue or remove it
- Ask the user: "Branch X has conflicts. Skip it and continue with the next branch, or stop the queue?"
- Continue or stop based on the user's answer
调用 skill并传入分支名称,该skill会处理:
/git-squash- 前置检查(分支存在、已与main分支产生分叉)
git merge --squash <branchName>- 委托 生成提交(符合约定式提交规范、附带Co-Authored-By尾部信息)
/git-commit - 合并后校验
- 本地分支清理()
git branch -d/-D
如果压缩合并因冲突失败:
- 执行
git merge --abort - 上报冲突的文件
- 跳过该分支——将其移到队列末尾或移除
- 询问用户:“分支X存在冲突。跳过该分支继续处理下一个,还是终止队列?”
- 根据用户回答继续或终止流程
5c. Remove the Worktree
5c. 移除Worktree
After a successful merge and branch deletion:
bash
undefined合并成功且分支删除后:
bash
undefinedRemove the git worktree
移除git worktree
git worktree remove .claude/worktrees/ralph/<feature-name>
git worktree remove .claude/worktrees/ralph/<feature-name>
If worktree remove fails (dirty), force it since we already merged
如果worktree移除失败(存在脏数据),强制移除,因为代码已经合并完成
git worktree remove --force .claude/worktrees/ralph/<feature-name>
Verify the worktree directory is gone. If the directory still exists after `git worktree remove`, it may need manual cleanup — warn the user but continue.git worktree remove --force .claude/worktrees/ralph/<feature-name>
校验worktree目录已删除。如果执行 `git worktree remove` 后目录仍然存在,可能需要手动清理——提醒用户后继续流程即可。5d. Prune and Report
5d. 修剪并上报结果
bash
git worktree pruneLog the result:
[1/N] ralph/legal-pages — merged and worktree removed
[2/N] ralph/post-creation — merged and worktree removed
[3/N] ralph/chat-and-messaging — SKIPPED (merge conflict in schema.graphql)
...bash
git worktree prune记录执行结果:
[1/N] ralph/legal-pages — merged and worktree removed
[2/N] ralph/post-creation — merged and worktree removed
[3/N] ralph/chat-and-messaging — SKIPPED (merge conflict in schema.graphql)
...5e. Continue to Next Branch
5e. 继续处理下一个分支
Move to the next branch in the queue. Each subsequent merge benefits from the prior merges already being on main, which reduces drift.
切换到队列中的下一个分支。后续的合并会基于已经合并了之前变更的main分支执行,可以减少分支漂移。
Step 6: Final Summary
步骤6:最终总结
After processing the entire queue:
Ralph Merge Complete
--------------------
Merged: 5 branches
Skipped: 1 branch (conflicts)
Remaining worktrees: 3 (incomplete PRDs)
Skipped branches (need manual resolution):
- ralph/chat-and-messaging: conflict in terraform/envs/staging/schema.graphql
Remaining incomplete worktrees:
- ralph/follow-and-unfollow (4/10 stories)
- ralph/test-coverage (0/8 stories)
- ralph/implement-reporting (2/6 stories)If any branches were skipped due to conflicts, suggest next steps:
- Go into the skipped worktree
- to incorporate the newly merged changes
git rebase main - Resolve conflicts
- Re-run to merge the remaining completed branches
/ralph-merge-worktrees
处理完整个队列后:
Ralph Merge Complete
--------------------
Merged: 5 branches
Skipped: 1 branch (conflicts)
Remaining worktrees: 3 (incomplete PRDs)
Skipped branches (need manual resolution):
- ralph/chat-and-messaging: conflict in terraform/envs/staging/schema.graphql
Remaining incomplete worktrees:
- ralph/follow-and-unfollow (4/10 stories)
- ralph/test-coverage (0/8 stories)
- ralph/implement-reporting (2/6 stories)如果有分支因冲突被跳过,建议后续操作:
- 进入被跳过的worktree
- 执行 拉取最新合并的变更
git rebase main - 解决冲突
- 重新运行 合并剩余的已完成分支
/ralph-merge-worktrees
Important Notes
重要注意事项
- Always get user confirmation before starting the merge queue — this is a destructive operation (worktree removal)
- Each merge builds on the last — if branch 2 conflicts, branches 3+ might have different conflict profiles than predicted. Re-check is automatic since we run which does pre-flight
/git-squash - The skill reads PRD files from the worktree directories, not from main — each worktree has its own copy
- Worktree paths use the feature name without the prefix:
ralph/for branch.claude/worktrees/ralph/post-creation/ralph/post-creation - After all merges complete, run on main to verify the combined codebase is healthy
bun run lint - Quote file paths with spaces in all git/bash commands (the project path contains spaces)
- 启动合并队列前必须获得用户确认——这是一个破坏性操作(会删除worktree)
- 每次合并都基于前一次合并的结果:如果分支2存在冲突,分支3及之后的分支的冲突情况可能和预估的不同。调用 时会自动执行前置检查,无需额外校验
/git-squash - 本skill从worktree目录读取PRD文件,而非从main分支读取——每个worktree都有自己的PRD副本
- Worktree路径使用不带 前缀的功能名:比如分支
ralph/对应的路径是ralph/post-creation.claude/worktrees/ralph/post-creation/ - 所有合并完成后,在main分支执行 校验合并后的代码库是否正常
bun run lint - 所有git/bash命令中的文件路径如果包含空格需要加引号(项目路径包含空格)