Skip to main content

Semantic diff, snapshot history, and assisted merge for Blender .blend files

Project description

BlenDiff

Semantic diff, snapshot history, and assisted merge for Blender .blend files.

BlenDiff compares two .blend file states using Blender's Python API — not binary diffing — and provides a full assisted merge system. It ships as both a Blender addon and a pip-installable pure-Python library for headless/CI use.


Features

  • Snapshot history — named, timestamped snapshots stored in a human-readable .blendiff JSON sidecar next to your .blend file
  • Object & collection diffing — detects added, removed, and modified objects with per-property change tracking (transform, visibility, collection membership)
  • Material node graph diffing — per-node, per-socket comparison including image names, input values, and rewired links
  • Render settings diffing — engine, resolution, sampling, output format, color management, Cycles and EEVEE sub-settings
  • Three-way merge — conflict detection and per-property resolution (Use A / Use B / Use Base) with a Blender UI
  • Annotated HTML export — self-contained dark-themed report with per-entry annotation textareas and JSON round-trip
  • Headless CLI — run diffs in CI without launching Blender

Installation

As a pip library (no Blender required)

pip install blendiff

As a Blender addon

Download the latest blendiff.zip from Releases and install via Edit → Preferences → Add-ons → Install.


CLI Usage

# List snapshots in a sidecar file
blendiff list scene.blendiff

# Compare two snapshots
blendiff compare scene.blendiff "Before rigging" "After rigging"

# Fail CI if any changes exist
blendiff latest scene.blendiff --fail-on-changes

# Export an HTML report
blendiff compare scene.blendiff "v1" "v2" --output report.html

Python API

from blendiff.storage.sidecar import SidecarManager
from blendiff.diff_engine.diff_engine import DiffEngine

mgr = SidecarManager("scene.blendiff")
snaps = {s.label: s for s in mgr.list_snapshots()}

engine = DiffEngine()
result = engine.compare(snaps["v1"].data, snaps["v2"].data)

# Render settings diff
print(result.render_diff.summary())

# Object diffs
for diff in result.object_diffs:
    print(diff.name, diff.kind)
    for change in diff.changes:
        print(" ", change.property_path, change.old_value, "→", change.new_value)

Architecture

blendiff/
├── data_model/      # Dataclasses — SceneDiff, RenderDiff, MergeProposal, …
├── diff_engine/     # Pure comparison logic — no bpy
├── serializer/      # mathutils → JSON-safe types
├── storage/         # .blendiff sidecar CRUD
├── export/          # Self-contained HTML report generation
├── cli/             # Headless CLI + importable Python API
├── extractor/       # bpy readers (Blender-only)
└── ui/              # Blender panels and operators (Blender-only)

The extractor is the only bpy-touching module. Everything downstream is pure Python and fully testable without Blender.


Running Tests

pip install blendiff[dev]
pytest tests/ -v

224+ tests, all passing without a Blender installation.


CI Integration

# .github/workflows/diff.yml
- name: Check for scene changes
  run: blendiff latest scene.blendiff --fail-on-changes

See docs/ci_example.yml for a full GitHub Actions workflow template.


License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

blendiff-0.5.0.tar.gz (80.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

blendiff-0.5.0-py3-none-any.whl (47.2 kB view details)

Uploaded Python 3

File details

Details for the file blendiff-0.5.0.tar.gz.

File metadata

  • Download URL: blendiff-0.5.0.tar.gz
  • Upload date:
  • Size: 80.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for blendiff-0.5.0.tar.gz
Algorithm Hash digest
SHA256 5374e3f823f5e7ada9b545c7a5f58462da65ee497e31562e3b34693751c1132c
MD5 4a4a54a45e88cedf24423f154c4dd4cc
BLAKE2b-256 73c615747d0e2672c88ea1b9e0e102c703ab2773024030a12c7d91e4d0229e9a

See more details on using hashes here.

File details

Details for the file blendiff-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: blendiff-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 47.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for blendiff-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f2e2d7771ab7af19d371fe3f6dac3ef1f3a54b171943c2a04c970e8472cb678f
MD5 233475086e128e988301932f5f665e4b
BLAKE2b-256 1ae7a80d5dc88995c98934b93e0e256315ab321fa041424cb4b0ec4f9f7a3266

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page