PlantUML 图随 git 演化:重命名、迁移、archive 策略
写完 .puml 不是结束。3 个月后 service 重命名、架构拆分、组件废弃——图跟代码同源演化才能避免「文档说 A,代码里早就叫 B」的尴尬。这篇是 rename migration 工具、archive 策略、git log 跟图同步。
重命名的两个层级
层级 1:文件名重命名——user-service.puml → identity-service.puml(service 改叫 identity)
层级 2:图内引用重命名——component "user-service" → component "identity-service",且所有 --> us 改成 --> identity
两个都要同步——只改文件名不改图内引用,git diff 看不出来;只改图内引用不改文件名,git history 断了。
工具 1:git mv 跟 sed 组合
1 | # 1. 文件重命名 |
git mv 比手动 mv 跟 add 强在 git 会检测到这是 rename(就算你重命名后改了内容,git rename detection 仍然能识别)。
工具 2:用 mvdan/sh 重命名脚本
更稳的写法——加 dry-run、错误处理、grep 验证:
1 |
|
1 | chmod +x rename-component.sh |
工具 3:PlantUML !define 间接引用
预防胜于治疗——一开始就用 !define 抽名字:
1 | !define USER_SVC identity-service |
要改 service 名时只改 !define 一行——但这种约定在团队里需要遵守,否则新人直接写 identity-service 文字,绕过 define。
工具 4:CI 检测「代码 vs 图」漂移
架构图最常见的腐烂——代码改了 service 名,图没改。
1 | # tests/test_architecture_drift.py |
CI 跑测试——代码改了 service 但图没改 → fail。
架构拆分的图演化
服务从 monolith 拆成微服务,图要跟着演。
阶段 1:monolith
1 | @startuml |
阶段 2:拆出 User 服务
1 | @startuml |
新旧图同时存在——architecture-v1-monolith.puml(归档)+ architecture.puml(当前)。
阶段 3:再拆出 Order
1 | @startuml |
演进过程留 trace 在 git 里——新人能从 git log 看架构演化史。
Archive 策略
老图不该直接删——放 archive/ 目录,加日期前缀:
1 | docs/ |
_config.yml 配 skip_render 防止 archive 渲染:
1 | skip_render: |
archive 目录不进 CI 流程,但 git 历史里能查到。
跨版本引用:用 git 历史当图元数据
PlantUML 不支持图内 git 引用——但可以用 %load_json 读 git log:
1 | # 生成 diagrams/git-history.json |
1 | @startuml |
图里显示最近改这个图的 commits——谁改的、什么时候改的、改了什么。
文档跟代码同步的 git hooks
客户端 hook 在 commit 时自动同步图:
1 | # .git/hooks/pre-commit |
提交 service 代码时,架构图自动重新生成并加入 commit——开发者不用手动改图。
跨年大重构的图迁移
遇到 service 大批重命名(比如从 user-service 改成 identity-service 同时改 30 个 service):
步骤:
- 冻结图编辑——README 写「服务重命名进行中,图暂停更新」
- 批量改代码 + 图——一次 PR 全部改完,不要分多次
- CI 验证——drift 测试跑过才合并
- 删旧图 + archive——重命名完成后,旧
user-service.puml移到archive/ - 更新文档——README 引用新 service 名
反过来——如果图已经过时了(3 个月没维护):
- 承认过时——README 顶部加 ⚠️ 「图与代码有差异,以代码为准」
- 派单重建——专门写一个 ticket 重画
- 加 drift 测试——避免下次再腐烂
实战踩坑
- git rename detection 不生效——你改了文件 50% 以上,git 就当是 delete + add,不显示 rename。重命名 + 替换同步做(单 commit 内),rename detection 才能识别。
- PlantUML alias
us跟 user-service 改 identity 不一致——alias 是语法糖,改不改不影响渲染,但 grep 检查「us」引用会搜到「us-east-1」之类的无关词。用 grep 加边界正则:grep -E "(as|component) +us\b"。 - 跨语言引用——Java 服务叫
UserService,Go 叫user-service,PlantUML 用user-service——统一用 kebab-case 是最简单约定。 - CI 测试飘红——drift 测试要求 service 目录跟图严格同步,但有时故意图里加「future service」——用
// future:注释标记:测试跳过带1
// future: payment-service (not yet deployed)
future:注释的 component。
总结
| 场景 | 工具 |
|---|---|
| Service 重命名 | git mv + sed |
| 架构拆分 | archive 旧图 + 新图分阶段 |
| 防止腐烂 | CI drift 测试 |
| 自动同步 | git pre-commit hook 调 Python 脚本 |
| 跨年大改 | 单 PR 全改,避免中间状态 |
核心原则:图跟代码同源演化——图要么自动生成(drift 测试兜底),要么人工改但有 CI 提醒。没有自动化就没有长期维护的图。
- 标题: PlantUML 图随 git 演化:重命名、迁移、archive 策略
- 作者: puml.online
- 创建于 : 2026-07-30 17:15:00
- 更新于 : 2026-08-14 21:34:29
- 链接: https://puml.online/blog/plantuml-versioning-renaming/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。