Blendit (Blender + Git) - Version Control for Blender

When does a commit happen?

When the user explicitly chooses to commit.

What are you actually commiting?

A Python file full of commands like this.

...
bpy.ops.transform.translate(value=(-0, -0, -0.306203), orient_axis_ortho='X', orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(False, False, True), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
bpy.ops.transform.rotate(value=-0.135777, orient_axis='X', orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(True, False, False), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
bpy.ops.transform.resize(value=(1.15803, 1, 1), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(True, False, False), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
[obj.select_set(False) for obj in bpy.context.view_layer.objects.selected.values()]
[bpy.context.view_layer.objects.get(obj).select_set(True) for obj in ['Suzanne']]
bpy.context.view_layer.objects.active = bpy.data.objects['Suzanne']
bpy.ops.material.new()
bpy.context.object.active_material = bpy.data.materials[-1]
bpy.data.materials["Material"].node_tree.nodes["Principled BSDF"].inputs[0].default_value = (0.8, 0.192546, 0.0567258, 1)
...

Each action you perform on Blender has a corresponding “function call” under the hood which actually performs the action. This is what you see in the Info window

Why do you need the Message Bus?

Because Blender does not log a function call in the Info window for all actions you perform. (There are ways to make Blender log all actions, but that would add huge overhead in the system.)

For instance, when changing the active object by clicking. This does not add to the Info window but this function is required when regenerating the file.
So I use the Message Bus to subscribe to the event of change in Active Object.

Message Bus Subscriber
def subscribe():
    """Subscribes to different event publishers"""

    # Active Object
    bpy.msgbus.subscribe_rna(
        key=(bpy.types.LayerObjects, "active"),
        owner=blenditSubscriber,
        args=(),
        notify=activeObjectCallback,
        options={'PERSISTENT'}
    )

Therefore I’m not actually reading the .blend file and accessing the binary data in any way.

2 Likes