1
0
Files
nex/docs/prompts/prompt-smart-merge.md

26 KiB
Raw Blame History

将所有 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 pushgit stash applygit stash dropgit revertgit branch -dgit push {remote} --delete {branch} 执行前都必须再次确认
  • 禁止自动推送代码;远端分支删除仅在步骤 5 获得确认后执行
  • 冲突文件禁止 AI 自主决定写入内容
  • 用户选择 --ours--theirs、保留删除的一侧、保留重命名的一侧等机械方案后AI 可执行对应写入
  • 凡涉及“双保留”“重组逻辑”“补写缺失代码”等内容生成,必须逐文件展示最终结果并再次获得确认后写入
  • 步骤 3 的“确认执行”仅授权按计划执行正常 merge不授权自动执行 stashreset --hardrevertdrop、删除分支、远端删除、冲突内容重写
  • 合并提交与语义审查修复提交必须分离;语义审查修复允许拆成多条独立提交
  • 若仓库文档定义了命令、包管理器、提交格式、目录规范,优先遵守文档;若未定义,再根据清单文件、脚本和近期提交历史推断
  • 不把当前仓库的路径结构、技术栈、构建命令写死到流程里;一切按探测结果执行
  • 信息展示按“概览 → 详情 → 原始数据”分层输出,避免一次性输出全部 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/** 中与开发、构建、测试、提交流程有关的文档
  • 常见任务入口:MakefilejustfileTaskfile.ymlpackage.json、工作区配置、CI 文件、脚本目录
  • 常见清单/锁文件:package-lock.jsonpnpm-lock.yamlyarn.lockbun.lock*go.modCargo.tomlpyproject.tomlpom.xmlbuild.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} ab 的祖先,记为 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 已获授权
  • 冲突内容重写、stashrevertreset --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_rulesmodule_mapvalidation_commands 判断是否偏离当前仓库约定

审查维度:

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

输出审查结果表:

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

严重程度仅分两类:

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

按计划中的 semantic_review_mode 处理:

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

修复执行规则:

  1. 每个问题编号视为一个独立修复单元
  2. 一次只处理一个编号,避免回退时互相污染
  3. 每个修复单元只修改其必要文件,保持最小变更
  4. 修复完成后,按 validation_commands 和当前改动作用域执行最小充分检查:
作用域 检查策略
仅单模块 优先执行该模块的 lint 或等价静态检查
多模块 执行覆盖这些模块的仓库级检查或组合检查
触及 shared/config/infra 执行受影响范围内最严格的可用检查
无自动检查命令 记录为“未自动验证”,并在结果中明确说明
  1. 若检查通过,立即提交独立修复 commitmessage 遵循 commit_style
  2. 若检查失败,只回退当前修复单元的未提交修改:git restore --staged --worktree --source=HEAD -- {files}
  3. 记录该编号为 修复失败并已回退,继续处理下一个编号

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_tagbranch_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_tagbranch_tags[]auto_stashes[]created_local_tracking_branches[]
已识别规则 repo_rulesmodule_mapvalidation_commands

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

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

若终止时不存在活动 merge 状态,不自动变更现场;仅提示用户:

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