> For the complete documentation index, see [llms.txt](https://code-visualization.shawnxie.top/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://code-visualization.shawnxie.top/di-san-pian-cheng-xu-fen-xi-yu-dai-ma-tu-pu/change-analysis.md).

# 变更分析：系统是如何演进的

代码库不是静态对象，而是持续演进的系统。理解当前结构只是第一步，理解它如何变化、哪些地方频繁变化、哪些文件经常一起变化，才能更准确地判断风险。

静态分析回答“代码现在是什么样”，动态分析回答“代码运行时发生了什么”，变更分析回答“代码为什么变成今天这样，以及变化会带来什么风险”。

## 从快照到历史

很多代码可视化工具只展示当前快照：当前有哪些模块、类、方法和调用关系。但工程风险经常来自历史。

例如两个文件当前没有明显静态依赖，但过去一年几乎每次都一起修改，这说明它们可能存在隐性业务耦合。一个文件当前复杂度不算最高，但最近几个月被频繁修改且经常引发回归，它就应该进入风险视图。

变更分析把时间维度引入代码理解。

## Git Diff：一次修改改了什么

Diff 是变更分析的入口。它告诉我们一次修改涉及哪些文件和行。但行级 Diff 对代码理解不够友好，需要进一步映射到代码实体。

更有价值的映射包括：

* 哪些方法被修改。
* 哪些类或接口被修改。
* 哪些配置项被修改。
* 哪些测试被新增或删除。
* 哪些 API、数据库访问或消息 topic 相关代码被修改。

这一步通常需要 AST 和符号信息。行号落在哪个方法范围内，就可以把 Diff 转换成“变更方法”。之后才能沿调用图和依赖图追踪影响面。

## Commit：谁在什么时候改了什么

Commit 记录了代码演进历史。除了文件变化，它还包含作者、时间、提交信息和可能关联的 Issue。

Commit 数据可以用于分析：

* 文件或模块的变更频率。
* 哪些人长期维护某个模块。
* 哪些文件经常一起变化。
* 哪些修改集中在某个时间段。
* 哪些代码经历过大规模重构或迁移。

提交信息质量不稳定，但仍然能提供线索。它可以帮助理解某些代码的历史意图，也可以帮助 AI Agent 找到相关背景。

## PR：讨论、Review 和验证记录

相比单个 Commit，PR 提供了更丰富的工程上下文：

* 需求背景。
* 设计讨论。
* Review 意见。
* 测试结果。
* CI 失败和修复过程。
* 合并前的风险判断。

这些信息对代码理解非常有价值。某个看起来奇怪的实现，可能在 PR 讨论中解释了兼容性原因；某个测试用例，可能来自历史事故；某个架构约束，可能在 Review 中反复出现。

在 AI 时代，PR 历史可以成为 Agent 上下文的一部分。修改某个模块前，Agent 不应该只读当前代码，还应该知道这个模块过去有哪些关键决策。

## 变更频率：哪里一直在动

变更频率是最直接的演进指标。频繁变更的文件通常说明：

* 业务需求活跃。
* 设计不稳定。
* 多个团队共同修改。
* 代码承担了过多职责。

变更频率本身不是坏事。一个新业务模块频繁变更很正常。真正值得关注的是组合信号：

* 高频变更 + 高复杂度。
* 高频变更 + 低测试覆盖。
* 高频变更 + 多人交叉修改。
* 高频变更 + 线上缺陷集中。

这些组合通常比单个指标更能说明风险。

## 变更耦合：哪些代码总是一起变

变更耦合指两个或多个文件经常在同一次提交或 PR 中一起修改。它能揭示静态依赖图看不出来的关系。

例如：

* 一个 Controller 和一个前端页面经常一起修改。
* 一个配置文件和多个业务类经常一起修改。
* 两个服务仓库经常在同一需求中联动修改。

这些关系可能说明真实业务边界、隐性协议或缺失的抽象。对遗留系统来说，变更耦合尤其有用，因为目录结构和架构图往往已经不能反映真实演进关系。

## 缺陷历史和回归风险

如果能把缺陷、事故、测试失败和代码变更关联起来，风险判断会更强。

例如：

* 某个模块历史上多次引发线上事故。
* 某类测试经常在特定模块变更后失败。
* 某个文件反复出现紧急修复。
* 某个功能路径缺陷密度明显偏高。

这些信息可以帮助影响面分析排序。不是所有受影响路径风险相同，历史上更脆弱的路径应该被优先验证。

## Owner 和知识分布

变更历史还能反映团队知识分布。一个模块长期由少数人维护，说明知识集中；一个模块被多个团队频繁修改，说明协作成本高；一个核心模块缺少稳定 owner，说明治理风险高。

Owner 信息让代码图谱从技术结构扩展为组织结构。它可以回答：

* 这个改动应该找谁 Review。
* 哪个团队负责这个服务。
* 哪些模块存在知识孤岛。
* 哪些路径跨越多个团队边界。

在 AI Review 中，Owner 也可以作为证据。AI 修改核心模块时，系统可以提示需要特定 owner 审核。

## 变更数据如何进入代码图谱

变更数据可以转化为节点属性和关系：

* 文件节点增加变更次数、最近修改时间、主要作者。
* 方法节点关联最近变更和缺陷记录。
* 文件之间增加共同变更边。
* PR 节点连接变更文件、测试结果和 Review 评论。
* Owner 节点连接模块、文件和服务。

有了这些数据，图谱就能回答更接近工程决策的问题：哪些代码最活跃，哪些模块风险高，哪些变更需要更多验证。

## 和 AI Agent 的关系

Agent 修改代码时，如果只看当前文件，很容易忽略历史背景。变更分析可以为 Agent 提供：

* 相关历史 PR。
* 经常一起变化的文件。
* 过去失败的相关测试。
* 模块 owner。
* 历史事故或缺陷线索。

这些上下文可以减少“局部正确、整体不稳”的修改。

## 小结

变更分析把时间维度引入代码理解。它让我们看到系统如何演进、风险如何积累、哪些代码真实耦合、哪些团队拥有关键知识。

静态分析、动态分析和变更分析结合后，就可以进入下一步：把这些事实统一建模为代码图谱。
