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.2.0.tar.gz (56.3 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.2.0-py3-none-any.whl (36.8 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for blendiff-0.2.0.tar.gz
Algorithm Hash digest
SHA256 5c920060541931171e9af4a2fb402c778d26a14b21a9894324baeae8b3a3cca4
MD5 389a46e27b870376426aa692efb083d6
BLAKE2b-256 810802a8b0b6e49f6af8946f9c4c31340b52370d3bf8ed5c3764a99070ce314f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: blendiff-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 36.8 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fc65423d953899dca17a620927167533bfdcc7f6bb9ef51671e44949b6b93b05
MD5 777c6750480d2c146f7955ac40d57a47
BLAKE2b-256 0ef6208ba0bb6f818a0408fd7a43e9ccc83466e89883d6b75f79d2bd620bfbd8

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