> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 差异构建

> 只重建蓝图发生变更的工作区，以加快快照构建速度。未发生变更的工作区将沿用上一次成功构建的结果。

<div id="overview">
  ## 概述
</div>

默认情况下，每个快照构建都是一次**完整构建**——从干净的基础镜像启动，克隆所有代码仓库，并从头运行每个蓝图。这样可以确保环境完全可复现，但如果你只改动了多个蓝图中的一个，构建速度可能会比较慢。

**差异构建**通过复用上一次成功构建的快照作为起点来优化这一过程。只有蓝图实际发生变化的工作区会重新构建；未发生变化的工作区则会按原样继承自父构建。这样可以显著缩短构建时间，尤其适用于拥有大量代码仓库的组织。

<div id="enabling-differential-builds">
  ## 启用差异构建
</div>

<Steps>
  <Step title="前往环境设置">
    前往 **设置 > 环境 > Advanced**。
  </Step>

  <Step title="开启开关">
    打开 **差异构建** 开关。说明为：*"通过复用未更改的工作区来加快构建速度。"*
  </Step>

  <Step title="触发构建">
    保存蓝图更改或点击 **构建快照**。如果存在有效的父构建，下一次构建将尝试以差异构建方式运行。
  </Step>
</Steps>

<Warning>
  启用差异构建后的第一次构建始终都会是 **完整构建** — 系统需要一个成功的基线快照作为对比依据。只要存在有效的父构建，后续构建就会采用差异构建。
</Warning>

<div id="how-it-works">
  ## 工作方式
</div>

当启用差异构建并触发构建时，系统会按以下流程运行：

<div id="1-find-a-parent-build">
  ### 1. 查找父构建
</div>

系统会查找最近一次成功的构建 (状态为 `success` 或 `partial`) ，并将其作为父构建使用。如果没有符合条件的父构建，系统会自动退回到完整构建。

<div id="2-compare-blueprints">
  ### 2. 比较蓝图
</div>

系统会将每个工作区的配置与父构建进行比较。系统会计算每个工作区输入内容的摘要值——包括蓝图内容、附加文件、secrets 和代码仓库顺序——并检查哪些内容发生了变化。

<div id="3-assign-workspace-actions">
  ### 3. 分配工作区操作
</div>

根据比较结果，每个工作区都会被分配以下三种操作之一：

| 操作     | 执行结果                                          | 使用时机                |
| ------ | --------------------------------------------- | ------------------- |
| **重建** | 克隆代码仓库，并从头运行所有蓝图步骤 (initialize + maintenance) | 自父构建以来，蓝图已发生变化      |
| **继承** | 拉取最新代码，并仅运行 `maintenance` 步骤                  | 蓝图未发生变化——复用父构建的环境设置 |
| **移除** | 从快照中删除该工作区                                    | 该工作区已从配置中移除         |

<Info>
  对于继承的工作区，`initialize` 不会再次运行。请编写 `maintenance`，
  确保它是自包含的，并且能在拉取最新代码后独立运行。
  它可以使用父快照中已安装的工具和运行时，
  但不得要求必须先立即运行 `initialize`，也不得依赖
  `initialize` 先前写入 `$ENVRC` 的环境变量。
</Info>

<div id="4-execute-the-build">
  ### 4. 执行构建
</div>

构建将基于父构建的快照镜像启动，而不是从全新的基础环境开始。这意味着：

* **继承的工作区** 已预先安装好所需的工具、运行时和依赖。系统会拉取最新代码 (`git pull`) ，并运行 `maintenance` 命令来更新依赖。
* **重新构建的工作区** 会从头开始设置——重新克隆，并完整执行 `initialize` + `maintenance` 流程。
* **已移除的工作区** 的目录会被清理。

组织蓝图和企业蓝图在差异构建期间会跳过 `initialize` (因为这些工具已存在于父镜像中) ，只运行 `maintenance`。

<Note>
  每次构建开始时，都会重置 `$ENVRC`，包括差异构建。
  此前构建写入 `$ENVRC` 的环境变量和 `PATH` 条目
  不会被继承。如果 `maintenance` 需要这些内容，则必须自行
  进行配置。
</Note>

<div id="when-a-full-build-runs-instead">
  ## 何时会改为执行完整构建
</div>

即使启用了差异构建，系统在某些情况下也会回退为完整构建：

* **不存在父构建** — 首次构建，或者之前所有构建都失败了
* **组织或企业蓝图已更改** — 全局更改会影响所有工作区，因此执行一次彻底重建更稳妥
* **代码仓库顺序已更改** — 由于代码仓库的设置可能彼此依赖，重新排序会触发一次完整重建
* **父构建过旧或不兼容** — 系统会验证父构建是否可用

发生回退时，构建详情页面会在构建类型标记下显示原因。

<div id="viewing-build-kind">
  ## 查看构建类型
</div>

构建完成后，你可以查看它是以差异构建还是完整构建方式运行的：

1. 前往 **设置 > 环境 > 快照**
2. 点击历史记录中的某个构建
3. **Build kind** 标记会显示 **Differential** (蓝色) 或 **完整构建** (默认)

将鼠标悬停在标记上，可查看说明每种类型含义的提示：

* **Differential**: *“仅重新构建已更改的工作区；未更改的工作区将沿用上一次使用相同配置成功构建的结果”*
* **完整构建**: *“所有工作区都会从头开始构建”*

<div id="benefits">
  ## 优势
</div>

| 优势         | 描述                                               |
| ---------- | ------------------------------------------------ |
| **构建更快**   | 只有发生变更的工作区才需要经过完整的设置流程。继承的工作区会完全跳过 `initialize`。 |
| **网络用量更少** | 未发生变更的工作区不会重新下载工具、运行时或大型依赖。                      |
| **迭代更快**   | 当你迭代单个代码仓库的蓝图时，其他代码仓库不会拖慢构建速度。                   |
| **可靠性不变**  | 如果发现任何异常，系统会自动回退到完整构建。你也可以随时手动触发完整构建。            |

<div id="manually-triggering-a-full-build">
  ## 手动触发完整构建
</div>

即使已启用差异构建，你也可以通过 **构建快照** 按钮强制执行一次完整构建。使用下拉菜单选择 **完整构建**，而不是默认的差异构建选项。

我们建议你定期执行完整构建，以清除继承的状态，并验证你的蓝图是否仍然能够从头创建环境。在移除或替换可能在快照中留下过时文件、工具或依赖的设置后，也请执行一次完整构建。完整构建会重新运行所有 `initialize` 和 `maintenance` 步骤。

<div id="faq">
  ## 常见问题
</div>

<AccordionGroup>
  <Accordion title="启用差异构建会影响我的会话吗？">
    不会。无论快照是如何构建的，会话始终都会从最终快照启动。唯一的区别只是构建速度。
  </Accordion>

  <Accordion title="如果差异构建生成了有问题的快照怎么办？">
    在 **设置 > 环境 > 快照** 中固定一个先前已知正常的构建，然后触发一次完整构建，以获得干净的快照。你也可以完全禁用差异构建，改回使用完整构建。
  </Accordion>

  <Accordion title="部分构建可以作为父构建吗？">
    可以。状态为 `partial` 的构建 (某些工作区成功，某些失败) 可以作为父构建。系统只会继承父构建中成功的工作区内容。
  </Accordion>
</AccordionGroup>
