将所有 `dev*` 分支按计划合并到目标分支（默认 `main`），按准备→分析→计划→执行→清理执行；先探测当前仓库的规则、模块边界、验证命令和提交风格，再基于探测结果执行，避免写死仓库结构。

## 约束

- 全程仅使用 `git merge` 完成分支集成，禁止 `rebase`
- `git add` 仅允许明确文件路径，禁止 `git add .`、`git add -A`
- 不直接使用默认 `git pull`；同步目标分支时仅允许显式策略：`git fetch` + `git merge`，或 `git pull --no-rebase`
- `git reset --hard` 仅允许回到已记录的安全锚点 tag，且执行前必须再次确认
- `git stash push`、`git stash apply`、`git stash drop`、`git revert`、`git branch -d`、`git push {remote} --delete {branch}` 执行前都必须再次确认
- 禁止自动推送代码；远端分支删除仅在步骤 5 获得确认后执行
- 冲突文件禁止 AI 自主决定写入内容
- 用户选择 `--ours`、`--theirs`、保留删除的一侧、保留重命名的一侧等机械方案后，AI 可执行对应写入
- 凡涉及“双保留”“重组逻辑”“补写缺失代码”等内容生成，必须逐文件展示最终结果并再次获得确认后写入
- 步骤 3 的“确认执行”仅授权按计划执行正常 merge，不授权自动执行 `stash`、`reset --hard`、`revert`、`drop`、删除分支、远端删除、冲突内容重写
- 合并提交与语义审查修复提交必须分离；语义审查修复允许拆成多条独立提交
- 若仓库文档定义了命令、包管理器、提交格式、目录规范，优先遵守文档；若未定义，再根据清单文件、脚本和近期提交历史推断
- 不把当前仓库的路径结构、技术栈、构建命令写死到流程里；一切按探测结果执行
- 信息展示按“概览 → 详情 → 原始数据”分层输出，避免一次性输出全部 diff

## 记录项

执行中持续维护以下记录，后续所有决策和总结都基于这些记录：

| 记录项                              | 内容                                                                                    |
| ----------------------------------- | --------------------------------------------------------------------------------------- |
| `session_timestamp`                 | 本次流程唯一时间戳                                                                      |
| `target`                            | 目标分支名                                                                              |
| `target_upstream`                   | 目标分支上游，如 `{remote}/{target}`；无则记为空                                        |
| `target_remote`                     | 从 `target_upstream` 解析出的远端名；无上游则优先使用默认远端，否则为空                 |
| `repo_rules`                        | 从 README、CONTRIBUTING、开发文档、脚本、清单文件中识别出的规则                         |
| `commit_style`                      | 仓库现有提交信息风格和默认合并/修复提交模板                                             |
| `module_map`                        | 按当前仓库结构推断出的模块边界、公共目录、配置目录、基础设施目录                        |
| `validation_commands`               | 按模块或作用域归纳出的 lint/build/test 命令                                             |
| `auto_stashes[]`                    | 本流程创建的 stash 列表，记录唯一 message、创建时 ref、创建顺序、后续是否恢复/保留      |
| `created_local_tracking_branches[]` | 为远端独有 `dev*` 分支创建的本地跟踪分支                                                |
| `global_tag`                        | 全局安全锚点                                                                            |
| `branch_tags[]`                     | 每个待合并分支对应的分支级安全锚点                                                      |
| `analysis[]`                        | 每个分支的分析快照：HEAD hash、提交数、变更文件、依赖、初始冲突预测、风险、语义审查模式 |
| `results[]`                         | 每个分支的最终状态：已合并、已跳过、已回退、失败原因、修复提交列表、验证结果            |

## 安全锚点

| 锚点                                | 创建时机                     | 用途                                                     |
| ----------------------------------- | ---------------------------- | -------------------------------------------------------- |
| `pre-merge-backup-{timestamp}`      | 步骤 1 完成目标分支准备后    | 全局回退点，恢复到本轮合并开始前的目标分支状态           |
| `merge-before-{branch}-{timestamp}` | 步骤 4 每个分支正式 merge 前 | 分支级回退点，回退当前分支的合并提交和其后的语义修复提交 |

除非用户明确要求“全部回退”或“放弃当前分支并回到分支级锚点”，否则不主动使用 `git reset --hard`。

## 1. 准备

### 1.1 仓库规则探测

并行收集当前仓库的规则来源：

- 根目录文档：`README*`、`CONTRIBUTING*`、`DEVELOPMENT*`、`docs/**` 中与开发、构建、测试、提交流程有关的文档
- 常见任务入口：`Makefile`、`justfile`、`Taskfile.yml`、`package.json`、工作区配置、CI 文件、脚本目录
- 常见清单/锁文件：`package-lock.json`、`pnpm-lock.yaml`、`yarn.lock`、`bun.lock*`、`go.mod`、`Cargo.toml`、`pyproject.toml`、`pom.xml`、`build.gradle*` 等
- 近期提交：`git log --oneline -20`

探测目标：

| 项目              | 识别方式                                                      | 记录结果                     |
| ----------------- | ------------------------------------------------------------- | ---------------------------- |
| 包管理器/任务入口 | 文档、锁文件、任务文件、脚本                                  | 记录允许的执行方式和优先级   |
| 模块边界          | 顶层目录、工作区配置、语言清单文件、子项目 README             | 记录 `module_map`            |
| 公共/基础设施目录 | shared/common/lib/core/config/scripts/ci 等目录和根级配置文件 | 记录到 `module_map`          |
| 验证命令          | 文档中的 lint/build/test 命令，或脚本中的标准任务             | 记录到 `validation_commands` |
| 提交风格          | 文档约束优先，否则看近期 `git log`                            | 记录 `commit_style`          |

识别规则：

- 文档和脚本冲突时，以文档为准
- 文档缺失时，以仓库当前可见的任务入口和近期提交习惯为准
- 无法确定时，先在步骤 3 的计划表中展示“待确认规则”，由用户确认

### 1.2 初始化现场

- 执行 `git status --short --branch`，记录当前分支和工作区状态
- 执行 `git remote -v`，记录可用远端
- 用提问工具确认目标分支：`main` / `master` / `develop` / 用户自定义

### 1.3 处理非干净工作区

- 若 `git status --porcelain` 非空，先展示变更文件概览，再用提问工具让用户选择：
  - `stash 后继续`
  - `终止`
- 用户选择 `stash 后继续` 后，执行 `git stash push --include-untracked -m smart-merge-{timestamp}-precheck-{n}`
- 记录 stash 唯一 message 和创建时 ref 到 `auto_stashes[]`

### 1.4 切换并校验目标分支

- 执行 `git checkout {target}`
- 若失败，使用提问工具让用户选择：
  - `重新指定目标分支`
  - `终止`

### 1.5 解析上游并同步远端引用

- 执行 `git for-each-ref --format='%(upstream:short)' refs/heads/{target}` 获取 `target_upstream`
- 若存在 `target_upstream`：
  - 解析 `target_remote`
  - 执行 `git fetch {target_remote} --prune`
  - 执行 `git rev-list --left-right --count {target}...{target_upstream}` 计算 ahead/behind
- 若不存在 `target_upstream`：
  - 若仓库存在默认远端，记为 `target_remote`
  - 否则 `target_remote` 置空

目标分支同步决策：

| 状态             | 处理                                                                                                              |
| ---------------- | ----------------------------------------------------------------------------------------------------------------- |
| 无 upstream      | 记录后继续，不自动同步                                                                                            |
| 仅落后 upstream  | 用提问工具选择：`快进同步` / `保持当前本地 HEAD` / `终止`；若选同步，执行 `git merge --ff-only {target_upstream}` |
| 仅领先 upstream  | 记录后继续，不自动 push                                                                                           |
| 与 upstream 分叉 | 用提问工具选择：`保持当前本地 HEAD` / `终止`；不自动把 upstream merge 进 target                                   |

### 1.6 收集候选分支

- 本地分支：`git branch --list 'dev*'`
- 若 `target_remote` 非空，远端分支：`git branch -r --list '{target_remote}/dev*'`
- 过滤掉 `HEAD ->` 这类符号引用
- 计算“远端存在、本地不存在”的分支列表

对远端独有分支，不直接 `checkout`，改为先展示清单，再用提问工具选择：

- `全部创建本地跟踪分支`
- `选择部分创建`
- `仅使用已有本地分支`
- `终止`

创建本地跟踪分支使用：`git branch --track {local_branch} {remote}/{remote_branch}`

若本地已存在同名分支，使用提问工具逐项选择：

- `使用现有本地分支`
- `改名创建跟踪分支`
- `跳过该远端分支`

所有自动创建的本地跟踪分支都记录到 `created_local_tracking_branches[]`。

### 1.7 无候选分支时直接结束

- 若最终没有任何 `dev*` 分支，输出概览：目标分支、工作区状态、探测到的仓库规则、是否创建过 stash、是否创建过本地跟踪分支
- 若本流程已创建 stash，进入步骤 5 的“工作区恢复”
- 否则直接结束

### 1.8 创建全局安全锚点

- 执行 `git tag pre-merge-backup-{timestamp}`
- 记录为 `global_tag`

## 2. 分析

### 2.1 信息收集（并行）

对每个候选分支并行收集以下信息：

| 维度     | 命令/方式                                                          | 结果                                   |
| -------- | ------------------------------------------------------------------ | -------------------------------------- |
| 基础     | `git rev-parse {branch}`                                           | 记录分支 HEAD hash                     |
| 合并状态 | `git merge-base --is-ancestor {branch} {target}`                   | 判断该分支是否已完全被目标分支包含     |
| 提交范围 | `git log --oneline {target}..{branch}`                             | 记录独有提交数和提交消息，推断分支意图 |
| 变更范围 | `git diff --name-status {target}...{branch}`                       | 记录文件列表、状态、变更集中区域       |
| 行数统计 | `git diff --stat {target}...{branch}`                              | 估算改动体量                           |
| 模块归属 | 按 `module_map` 归类；若未命中则按顶层目录或最近的语言清单文件归类 | 识别受影响模块                         |

模块归类优先级：

1. 仓库文档明确声明的子项目、包、服务、应用、库
2. 工作区配置或语言清单文件定义的模块边界
3. 顶层目录边界
4. 根级共享文件、配置文件、脚本、CI 文件，统一归为 `shared/config/infra`

常见的 `shared/config/infra` 候选包括但不限于：

- 根目录配置文件、锁文件、工作区文件
- 构建脚本、部署脚本、CI 配置、容器配置、基础设施配置
- 公共库目录、共享类型目录、通用组件目录、公共工具目录

### 2.2 依赖判定

依赖同时从 ancestry 和文件重叠两个维度判断：

| 维度          | 方法                                                  | 判定规则                              |
| ------------- | ----------------------------------------------------- | ------------------------------------- |
| ancestry 依赖 | `git merge-base --is-ancestor {a} {b}`                | 若 `a` 是 `b` 的祖先，记为 `b 依赖 a` |
| 文件重叠      | 比较各分支 `git diff --name-only {target}...{branch}` | 同一文件被多个分支修改，记为重叠      |
| 公共文件依赖  | 关注 `shared/config/infra` 范围和公共抽象             | 即使文件数少，也记为高优先级依赖      |

为每个分支输出：

- `depends_on[]`：它依赖哪些分支
- `blocks[]`：哪些分支依赖它
- `shared_files[]`：与其他分支重叠的文件
- `common_files[]`：被识别为公共/基础设施的文件

### 2.3 初始冲突预测（串行）

仅对“未合并且有实际差异”的分支串行执行：

1. 执行 `git merge --no-commit --no-ff {branch}`
2. 若工作区进入 merge 状态：
   - 执行 `git diff --name-only --diff-filter=U` 记录冲突文件
   - 若存在 `MERGE_HEAD`，执行 `git merge --abort`
3. 若命令输出为 `Already up to date`、无 `MERGE_HEAD`、无冲突文件，记为“已包含或无差异”，不执行 `git merge --abort`
4. 若 `git merge --abort` 失败：
   - 报告错误和当前状态
   - 用提问工具让用户选择：
     - `回到全局锚点后继续分析`：执行 `git reset --hard {global_tag}`
     - `终止`
   - `reset --hard` 失败则终止并提示用户手动处理

### 2.4 风险分级与排序

风险评级：

- 低：无预测冲突、无依赖、单一模块、小体量改动
- 中：存在依赖，或存在预测冲突，或跨两个以上模块，或触及公共文件
- 高：预测冲突文件 `>= 3`，或冲突占改动文件比例 `>= 30%`，或存在 ancestry 依赖且触及公共文件 / 根级配置 / 基础设施文件

初始排序规则：

1. 已合并 / 无差异（默认跳过，仅展示）
2. 被其他分支依赖的基础分支
3. 仅改公共/基础设施文件的分支
4. 独立、低风险分支
5. 存在依赖或共享文件的分支
6. 高风险、跨模块分支

### 2.5 验证命令归纳

根据步骤 1 探测结果，为后续语义修复和构建验证归纳命令：

| 作用域                 | 优先级                                  |
| ---------------------- | --------------------------------------- |
| 模块级 lint/build/test | 优先使用模块文档或模块脚本中声明的命令  |
| 仓库级 lint/build/test | 若模块级命令缺失，使用仓库统一命令      |
| 无现成命令             | 记录为“无法自动验证”，步骤 3 显示给用户 |

归纳原则：

- 优先使用仓库文档明确写出的命令
- 其次使用标准任务入口中的现有命令
- 再其次使用就近模块的标准脚本
- 不自行发明新的构建或测试命令

### 2.6 分析结果汇总

为每个分支形成分析快照：

| 字段                   | 内容                               |
| ---------------------- | ---------------------------------- |
| `status`               | 已合并 / 无差异 / 待合并           |
| `head`                 | 步骤 2 记录的 HEAD hash            |
| `modules`              | 受影响模块                         |
| `files`                | 改动文件数                         |
| `depends_on`           | 依赖分支                           |
| `predicted_conflicts`  | 初始冲突文件列表                   |
| `risk`                 | 低 / 中 / 高                       |
| `semantic_review_mode` | 默认 `仅报告`                      |
| `validation_scope`     | 该分支后续优先使用的验证范围和命令 |

## 3. 计划（用户确认）

输出合并计划表，列至少包含：

| 分支 | 状态 | 模块 | 文件数 | 依赖 | 预测冲突 | 风险 | 语义审查 | 验证命令 |
| ---- | ---- | ---- | ------ | ---- | -------- | ---- | -------- | -------- |

默认规则：

- `已合并`、`无差异` 分支仅展示，不进入执行队列
- `待合并` 分支按步骤 2.4 的排序进入执行队列
- `语义审查` 默认值为 `仅报告`
- 若某分支缺少可自动执行的验证命令，在计划表中明确标记

同时展示仓库级探测结果摘要：

- 识别出的模块边界
- 公共/基础设施范围
- 识别出的验证命令
- 提交风格摘要
- 无法确定、需要用户补充的规则

用提问工具让用户选择：

- `确认执行`
- `调整顺序`
- `排除分支`
- `调整语义审查模式`
- `补充或修正规则`
- `重新分析全部分支`
- `终止`

语义审查模式仅允许三种：

- `关闭`
- `仅报告`
- `报告并修复`

若用户选择 `调整顺序`、`排除分支`、`调整语义审查模式`、`补充或修正规则`、`重新分析全部分支`，则更新计划表后再次确认，直到用户选择 `确认执行` 或 `终止`。

最终确认后，记录最终执行队列。并明确提示：

- 正常 merge 已获授权
- 冲突内容重写、`stash`、`revert`、`reset --hard`、删除分支、远端删除仍需单独确认

## 4. 执行（顺序执行，冲突/异常时中断）

对执行队列中的分支依次处理。若队列为空，直接进入步骤 5。

### 4.1 单分支合并前检查

每个分支开始前都执行以下检查：

1. `git status --short --branch`，确认当前仍在 `{target}`
2. 若不在 `{target}`，执行 `git checkout {target}`；失败则中断并询问
3. 若工作区非干净，展示异常文件，并用提问工具让用户选择：
   - `stash 后继续`
   - `终止`
4. 若用户选择 `stash 后继续`，执行 `git stash push --include-untracked -m smart-merge-{timestamp}-runtime-{n}`，记录到 `auto_stashes[]`
5. 检查分支是否仍存在；不存在则记录为 `已跳过：分支不存在`
6. 执行 `git rev-parse {branch}`，对比步骤 2 记录的 `head`
7. 若 HEAD 已变化，先对该分支重新执行步骤 2 的单分支分析，再更新计划快照

### 4.2 基于当前 HEAD 的动态复核

步骤 2 的分析基于初始目标分支；每次实际 merge 前都必须基于“当前最新 HEAD”重新复核当前分支：

1. 执行 `git diff --name-status HEAD...{branch}`，获取当前变更文件列表
2. 串行执行 `git merge --no-commit --no-ff {branch}` 做实时 dry-run
3. 若进入 merge 状态，收集 `git diff --name-only --diff-filter=U` 冲突文件后执行 `git merge --abort`
4. 若无 `MERGE_HEAD`，按实际结果记为“无冲突”或“已包含 / 无差异”
5. 将实时结果与步骤 3 的计划快照对比

视为“计划漂移”的情况：

- 冲突文件集合发生变化
- 改动文件数变化明显（以 `20%` 为阈值）
- 新出现公共文件 / 根级配置 / 基础设施文件
- 原本 `无冲突` 变成 `有冲突`
- 原本模块级验证命令不再覆盖当前改动范围

若发生计划漂移，用提问工具让用户选择：

- `按更新后的当前结果继续`
- `重新生成剩余分支计划`：对“当前分支 + 尚未处理的剩余分支”重新执行步骤 2，再回到步骤 3
- `跳过当前分支`
- `终止`

### 4.3 生成提交模板并创建分支级锚点

先根据 `commit_style` 生成本轮使用的提交模板：

- 若仓库文档明确约束了提交格式，严格遵守
- 若文档未约束，但近期提交风格稳定，沿用仓库现有风格
- 若无法识别，合并提交使用 `chore: merge {branch} into {target}`，语义修复提交使用 `refactor: address post-merge issues in {branch}`

然后：

- 执行 `git tag merge-before-{branch}-{timestamp}`
- 记录到 `branch_tags[]`

### 4.4 正式合并

- 执行正式合并：`git merge --no-ff -m "{merge_commit_message}" {branch}`

正式合并结果分三类：

- 无冲突：进入步骤 4.6
- 有冲突：进入步骤 4.5
- 非冲突错误：展示错误信息，用提问工具选择：`跳过当前分支` / `终止`

### 4.5 冲突处理（中断点）

先执行 `git diff --name-only --diff-filter=U` 获取冲突文件清单，再按文件生成冲突决策面板：

| #   | 文件 | 冲突类型 | HEAD 改动摘要 | 分支改动摘要 | 可批量机械处理 | 推荐方案 |
| --- | ---- | -------- | ------------- | ------------ | -------------- | -------- |

推荐方案规则：

- 仅当解决方案明确等价于 `--ours`、`--theirs`、保留删除的一侧、保留重命名的一侧时，才允许给出“可批量机械处理”的推荐
- 只要需要合并两边逻辑、补全缺失分支、重排代码顺序、解决同一函数 / 类 / 配置段双改，就标记为 `需逐文件确认`
- `需逐文件确认` 的文件不能被“全部按推荐方案”一键处理

用提问工具让用户选择：

- `处理全部机械型冲突`
- `审查部分文件`
- `放弃当前合并`

若用户选择 `审查部分文件`，先让用户输入文件编号，再对这些文件逐个展示：

- 上下文 diff
- 原始冲突块 `<<<<<<<` / `=======` / `>>>>>>>`
- 当前建议与风险说明

逐文件可选方案：

- `保留目标 (--ours)`
- `保留分支 (--theirs)`
- `AI 起草双保留结果`
- `用户手动编辑`

执行规则：

- `--ours` / `--theirs`：执行 `git checkout --ours/--theirs {file}`
- `AI 起草双保留结果`：
  - 先生成完整最终结果或统一 diff
  - 说明具体合并逻辑
  - 再次用提问工具确认后写入文件
- `用户手动编辑`：告知文件路径，等待用户回复“完成”后再执行 `git add {file}`
- 所有冲突文件都必须逐文件 `git add {file}`
- 执行 `git diff --name-only --diff-filter=U`，确认已无未解决冲突
- 再执行 `git commit --no-edit`

若用户选择 `放弃当前合并`：

- 用提问工具确认是否执行 `git merge --abort`
- 若 `abort` 成功，记录当前分支为 `已跳过：用户放弃合并`
- 若 `abort` 失败，再用提问工具确认是否执行 `git reset --hard merge-before-{branch}-{timestamp}` 回到分支级锚点

### 4.6 语义审查

语义审查基于 `git diff merge-before-{branch}-{timestamp}..HEAD`。

辅助数据源：

| 数据          | 获取方式                                           | 用途                             |
| ------------- | -------------------------------------------------- | -------------------------------- |
| 本次合入 diff | `git diff merge-before-{branch}-{timestamp}..HEAD` | 查看本次实际引入的改动           |
| 分支意图      | 步骤 2 的 commit 消息                              | 推断业务目的                     |
| 主干近期趋势  | `git log --oneline {target} -20` 及相关 diff       | 识别近期重构、迁移、废弃方向     |
| 公共文件现状  | 步骤 2 标记的 `common_files[]`                     | 判断是否重复造轮子或遗漏基础设施 |
| 仓库规则      | `repo_rules`、`module_map`、`validation_commands`  | 判断是否偏离当前仓库约定         |

审查维度：

| 维度         | 检查点                                                                                                 |
| ------------ | ------------------------------------------------------------------------------------------------------ |
| 代码冗余     | 新增函数、组件、类型、工具、配置是否已在仓库公共位置存在等价实现                                       |
| 过时模式     | 是否继续使用近期已迁移、废弃、替换的 API、脚本、配置项、目录模式                                       |
| 基础设施遗漏 | 新代码是否绕过既有公共抽象、统一错误处理、统一日志、统一配置、统一数据访问、统一请求封装等既有基础设施 |
| 风格不一致   | 命名、文件组织、测试组织、错误处理、注释风格是否偏离当前主干                                           |
| 模块边界破坏 | 是否把本应落在公共层、共享层、基础设施层的逻辑塞进业务分支目录                                         |

输出审查结果表：

| #   | 类别 | 严重程度 | 文件 | 描述 | 建议修复方式 |
| --- | ---- | -------- | ---- | ---- | ------------ |

严重程度仅分两类：

- `问题`：有运行时风险、明显架构偏差或维护成本高
- `建议`：功能可用，但与主干一致性较差

按计划中的 `semantic_review_mode` 处理：

- `关闭`：跳过语义审查
- `仅报告`：展示结果后直接进入步骤 4.7
- `报告并修复`：展示结果后，用提问工具选择：`全部修复` / `选择修复` / `跳过`

修复执行规则：

1. 每个问题编号视为一个独立修复单元
2. 一次只处理一个编号，避免回退时互相污染
3. 每个修复单元只修改其必要文件，保持最小变更
4. 修复完成后，按 `validation_commands` 和当前改动作用域执行最小充分检查：

| 作用域                     | 检查策略                               |
| -------------------------- | -------------------------------------- |
| 仅单模块                   | 优先执行该模块的 lint 或等价静态检查   |
| 多模块                     | 执行覆盖这些模块的仓库级检查或组合检查 |
| 触及 `shared/config/infra` | 执行受影响范围内最严格的可用检查       |
| 无自动检查命令             | 记录为“未自动验证”，并在结果中明确说明 |

5. 若检查通过，立即提交独立修复 commit，message 遵循 `commit_style`
6. 若检查失败，只回退当前修复单元的未提交修改：`git restore --staged --worktree --source=HEAD -- {files}`
7. 记录该编号为 `修复失败并已回退`，继续处理下一个编号

### 4.7 构建验证

根据当前分支实际引入的改动范围，从 `validation_commands` 中选择最小充分的构建 / 测试 / 检查命令：

| 改动范围                   | 验证策略                                     |
| -------------------------- | -------------------------------------------- |
| 单模块业务改动             | 优先运行该模块的 build / test / lint 组合    |
| 多模块改动                 | 运行覆盖这些模块的聚合命令                   |
| 触及共享层、配置、基础设施 | 优先运行仓库级验证或覆盖共享层的更高等级验证 |
| 仓库没有可自动执行命令     | 记录为“无法自动验证”，并向用户说明           |

构建成功：

- 记录当前分支为 `已合并`
- 记录冲突处理方式、语义审查结果、修复提交列表、实际执行的验证命令
- 继续下一个分支

构建失败：

1. 展示失败命令和错误摘要
2. 若当前分支存在语义修复提交，用提问工具让用户选择：
   - `依次 revert 当前分支的语义修复提交后重试验证`
   - `放弃当前分支并回到分支级锚点`
   - `终止`
3. 若用户选择 revert：
   - 按提交时间倒序执行 `git revert --no-edit {commit}`
   - 每 revert 一条后重试验证，直到通过或全部 revert 完成
   - 若 revert 冲突，立即中断并询问：`回到分支级锚点` / `保留冲突现场并终止`
4. 若无语义修复提交，或全部 revert 后验证仍失败，用提问工具让用户选择：
   - `git reset --hard merge-before-{branch}-{timestamp}` 放弃当前分支
   - `终止并保留当前现场`
5. 若用户确认回到分支级锚点，记录当前分支为 `已跳过：验证失败并回退`

## 5. 清理（用户确认）

所有分支处理完成后，输出汇总表：

| 项目       | 内容                                                                                 |
| ---------- | ------------------------------------------------------------------------------------ |
| 目标分支   | `{target}`                                                                           |
| 当前 HEAD  | 当前提交 hash                                                                        |
| 合并结果   | 成功 / 跳过 / 已合并 / 无差异 数量                                                   |
| 冲突统计   | 冲突分支数、冲突文件数、机械处理数、逐文件确认数                                     |
| 语义审查   | 每个分支的问题数、建议数、修复成功数、修复失败数                                     |
| 实际验证   | 每个分支实际执行了哪些验证命令，哪些未验证                                           |
| 已创建资源 | `global_tag`、`branch_tags[]`、`auto_stashes[]`、`created_local_tracking_branches[]` |
| 候选删除   | 可删除的本地分支、远端分支、可删除 tag                                               |

用提问工具一次性确认清理策略：

- `确认清理`
- `调整清理范围`
- `跳过清理`

清理项包括：

- 删除已成功合并的本地分支：`git branch -d {branch}`
- 删除已成功合并且用户确认的远端分支：`git push {remote} --delete {branch}`
- 删除用户明确不再保留的安全锚点 tag
- 删除本流程仅为分析/合并而创建、且最终不需要保留的本地跟踪分支

远端分支删除规则：

- 优先删除该分支自己的 upstream remote
- 若分支无 upstream，但来自 `target_remote`，则删除 `target_remote/{branch}`
- 删除失败只记录错误，不影响其余清理项

### 工作区恢复

若 `auto_stashes[]` 非空，用提问工具让用户选择：

- `按顺序恢复全部 stash`
- `查看 stash 列表后选择恢复`
- `暂不恢复，保留 stash`

恢复时按后进先出顺序处理。由于 `stash@{n}` 会随列表变化而漂移，先根据已记录的唯一 message 在 `git stash list` 中定位当前 ref，再对该 stash 执行 `git stash apply {ref}`，不直接 `pop`：

1. `apply` 成功后，再询问是否 `git stash drop {ref}`
2. 若 `apply` 冲突，展示 stash 冲突决策面板，逐文件选择：
   - `保留 stash 内容`
   - `保留当前内容`
   - `AI 起草双保留结果`
   - `用户手动编辑`
   - `放弃恢复该 stash`
3. 冲突解决完成后，再询问是否 `drop` 对应 stash

输出最终总结：目标分支、当前 HEAD、探测到的仓库规则摘要、保留的锚点、各分支最终状态、未删除的远端分支、stash 恢复结果。

## 终止处理

任一步骤选择 `终止` 时，输出终止摘要：

| 项目       | 内容                                                                                 |
| ---------- | ------------------------------------------------------------------------------------ |
| 当前步骤   | 准备 / 分析 / 计划 / 执行 / 清理                                                     |
| 当前 HEAD  | 当前提交 hash                                                                        |
| 已完成分支 | 成功合并的分支                                                                       |
| 已跳过分支 | 分支及原因                                                                           |
| 未处理分支 | 剩余执行队列                                                                         |
| 已创建资源 | `global_tag`、`branch_tags[]`、`auto_stashes[]`、`created_local_tracking_branches[]` |
| 已识别规则 | `repo_rules`、`module_map`、`validation_commands`                                    |

若终止时存在活动 merge 状态，再用提问工具让用户选择：

- `执行 git merge --abort 并结束`
- `回到当前分支级锚点并结束`
- `保留当前冲突现场，交给用户手动处理`

若终止时不存在活动 merge 状态，不自动变更现场；仅提示用户：

- 全部回退可使用 `git reset --hard {global_tag}`
- 当前分支级回退可使用 `git reset --hard merge-before-{branch}-{timestamp}`
- 本流程创建的 stash 和本地跟踪分支仍保留，是否恢复/删除由步骤 5 或用户后续手动决定
