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.3.0.tar.gz (66.1 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.3.0-py3-none-any.whl (40.1 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for blendiff-0.3.0.tar.gz
Algorithm Hash digest
SHA256 d934920d95e0e72c151be6310294a433444fa0e8b2ea4588f7c95f2d6db7e773
MD5 5a8e513cc490fb63aa862c1680f6f56f
BLAKE2b-256 2329589aded5bfd0cda446fdf859e260b4a9c6e4e1e268de7a47bc32bf124e10

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for blendiff-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f7db180f700bbea24cb56007fae67dc6636d6512bf55995c7d186020d5d56558
MD5 701a52534e1145f81c328c9dbb5015f0
BLAKE2b-256 57192663309e94c27b69ec761227338801d25f8840f37c66a44deb62e8926b27

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