Skip to content

一、 为什么当前会报错(Why) ​

  1. Azure DevOps REST API 的严格约束:Azure DevOps 在提交变更 (pushes API) 时,每个文件变更必须严格显式声明 changeType 为 'add'(新增)或 'edit'(覆盖修改)。如果文件在目标分支已存在,却以 'add' 类型提交,API 会直接抛出硬错误拒绝推送。
  2. 当前逻辑痛点:目前推送是在点击后静默进行一次性探测,缺乏提交前的预检(Pre-flight)与用户交互决策界面;且一旦路径探测返回异常,默认降级为 'add' 便直接引发阻断。

二、 完整解决方案与落地机制(How) ​

要实现“同名对比、让用户选择覆盖或忽略”,整体流程分为三个阶段:

1. 预检嗅探(Pre-flight Check) ​

在弹窗加载完成或用户选定目标仓库/分支后,提前对待同步的文件清单进行一次远程探测:

  • Azure DevOps:调用 GET items?path={path}&versionDescriptor.version={branch} 获取文件元数据;
  • GitHub:调用 GET /repos/{owner}/{repo}/contents/{path}?ref={branch} 获取远程 SHA 与内容。

2. 前端交互界面(UI Decision Layer) ​

在“待同步文章”列表中,给每个文件增加状态徽标与用户操作切换器:

  • 🟢 新增 (New):远程不存在,以 'add' 提交。
  • 🟡 同名存在 (Conflict):
    • 默认提供单选/切换开关:覆盖 (Overwrite) vs 忽略 (Skip)。
    • 顶部增加一键快捷操作:“全部覆盖” 与 “跳过同名”。
    • (可选进阶)点击文件名可弹出轻量 Diff 预览,查看本地与远程文章的内容差异。
  • ⚪ 内容无变更 (Identical):若本地内容与远程内容比对无差异,自动标记“已是最新,跳过”。

3. 提交载荷精准映射(Payload Mapping) ​

用户点击“一键直通发布”后,根据用户的选择构建最终的 Push Payload:

  • 选择覆盖的文件:changeType: 'edit';
  • 选择新增的文件:changeType: 'add';
  • 选择忽略的文件:从当前提交的 changes 列表中直接剔除,不发送给远程。

三、 总结 ​

该机制不仅可以彻底杜绝 already exists 导致的发布失败,还能保障文章不会被无意冲掉。