PlantUML git lifecycle — pre-commit / CI / git-lfs / PR review
PlantUML source + rendered output both live in a git repo. This post distils the end-to-end practice: edit puml → validate → auto-render → commit → CI → PR review → rebase → all smooth.
Two kinds of “files” PlantUML uses in git
1 | project/ |
Workflow for these two directories:
- puml edited → triggers render → SVG edited → commit together.
- only SVG edited → audit alarm: “should have edited puml not SVG.”
- only puml edited → CI failure: “diagram rendering failed.”
The ideal state:
In any commit, puml and SVG are both changed or both unchanged.
pre-commit hook enforces consistency
Using husky + lint-staged
1 | npm install --save-dev husky lint-staged |
.husky/pre-commit:
1 |
|
.lintstagedrc.json:
1 | { |
Check that the diagram has been committed (force puml+SVG together)
1 |
|
Real usage:
1 | git add docs/diagrams/auth.puml |
CI rendering script
Render everything in one pass
1 | # .github/workflows/render-diagrams.yml |
Key: git diff --exit-code makes “diagram output changed but puml not” a build failure.
Error recovery
CI rendering failure (some diagram type’s support library missing):
1 | plantuml -tsvg docs/diagrams/*.puml |
Fix:
- Install the lib:
sudo apt-get install graphviz - Validate on both client and server: local CLI + online / TeaVM client
- Push again
git-lfs for large diagrams
When to use git-lfs
- Single SVG > 50 KB (CJK diagrams commonly)
- PNG > 500 KB
- Total image library > 50 MB
- Want to avoid git diff / git clone slowdown
Configure .gitattributes
1 | # .gitattributes |
First time:
1 | git lfs install |
Migrate history (large images not under lfs yet):
1 | git lfs migrate import --include="*.svg" |
Pitfall: lfs files need git-lfs binary at checkout — CI runner must install:
1 | - name: Setup git-lfs |
PR review with image diff
GitHub native SVG diff
GitHub auto-renders SVG diffs — but in reality:
- SVG is treated as binary diff by default — content changes not shown.
- Enable: in
.gitattributesadd*.svg diff=svg.
Then PR shows text diff (clearer node position, colour changes).
Pre-rendered raster diff
More controllable: CI runs a “render and generate diff image” step:
1 | # 1. pre-merge state render |
Paste diff.png into the PR comment for reviewers to see “how the diagram changed” at a glance.
Text diff is lighter weight
puml itself is text — git diff for source changes:
1 | git diff docs/diagrams/auth.puml |
PR reviewers spot it instantly. SVG is render output — frequent conflicts in rebase / merge. Source repo holds puml; render cache maintained by CI.
rebase / merge diagram sync problem
Conflict during rebase
1 | .feature-branch |
git sees both branches changed the SVG, conflict.
Solution 1: source repo only stores puml
1 | .gitignore: |
After rebase:
1 | plantuml -tsvg docs/diagrams/*.puml -o public/img/diagrams/ |
Solution 2: auto re-render on git pull
1 | .gitattributes: |
But union merge can’t resolve “both branches changed content” (topology changed), only “image overlay changes” work. For PlantUML SVG, union merge often produces composite but invalid — not recommended.
Solution 3: CI enforces SVG consistency
1 | CI: |
The cleanest solution — SVG fully maintained by CI, never in the puml-dev workflow.
A complete configuration sample
1 | # scripts/setup-puml-git.sh |
Single-author vs multi-author workflow
Single author
- Just
git add . && git commit - pre-commit validates + local renders
- push
Multi-author team
- Central repo (main + feature branches)
- feature branches may modify diagrams — don’t push directly to main
- PR review sees text diff + CI sees render diff
- When merging to main: rebase + re-render
Fork-based
- fork edits puml + renders → PR upstream
- Upstream can’t see fork’s “local” SVG
- main accepts PR → immediately re-render → publish public repo
Key checklist (quarterly audit)
1 | [ ] .gitignore excludes SVG output |
puml.online’s own practice
Our project:
source/_posts/plantuml-*.mdis sourcepublic/blog/plantuml-*/index.htmlis rendered output- ✅ do NOT track
public/in git — in .gitignore - ✅ CI does hexo re-generate on
npm run build - ❌ no pre-commit (we use review-only)
- ❌ no git-lfs (hexo output small)
Practice: source of truth = markdown (containing puml). Rendered output never enters git.
Recap
- PlantUML’s key in git: separate source (puml/md) and output (svg) — source in git, output re-rendered by CI.
- pre-commit hook forces authors to “edit puml and re-render SVG together”.
- git-lfs solves large-image repo size.
- Force re-render during rebase / merge is the cleanest posture.
Next
- Title: PlantUML git lifecycle — pre-commit / CI / git-lfs / PR review
- Author: puml.online
- Created at : 2026-07-30 13:16:00
- Updated at : 2026-08-14 21:34:29
- Link: https://puml.online/blog/plantuml-git-lifecycle-en/
- License: This work is licensed under CC BY-NC-SA 4.0.