Skip to content

3-way diff #2

@ChristianWeissCG

Description

@ChristianWeissCG

I would love to see a 3-way diff:
json-cli threewaydiff base.json left.json right.json

And to get a combined patch for non-conflicting changes:

[
    {"value":4,"op":"test","path":"/key1/0"},
    {"value":5,"op":"replace","path":"/key1/0"},
    {"op":"remove","path":"/key2"},
    {"op":"remove","path":"/key3/sub0"},
    {"value":"a","op":"test","path":"/key3/sub1"},
    {"value":"c","op":"replace","path":"/key3/sub1"},
    {"value":"b","op":"test","path":"/key3/sub2"},
    {"value":false,"op":"replace","path":"/key3/sub2"},
    {"value":0,"op":"add","path":"/key3/sub3"},
    {"op":"remove","path":"/key4/1/b"},
    {"value":false,"op":"add","path":"/key4/1/c"},
    {"value":1,"op":"add","path":"/key4/2/c"},
    {"value":"wat","op":"add","path":"/key5"}
]

Or in case of a conflict:

[
    {"op":"conflict","path":"/key1/0","value_left":4,"value_right":5,"op_left":"replace","op_right":"replace"},
    {"op":"conflict","path":"/key2","value_left":4,"value_right":null,"op_left":"replace","op_right":"remove"},
    {"op":"remove","path":"/key3/sub0"},
    {"value":"a","op":"test","path":"/key3/sub1"},
    {"value":"c","op":"replace","path":"/key3/sub1"},
    {"value":"b","op":"test","path":"/key3/sub2"},
    {"value":false,"op":"replace","path":"/key3/sub2"},
    {"value":0,"op":"add","path":"/key3/sub3"},
    {"op":"remove","path":"/key4/1/b"},
    {"value":false,"op":"add","path":"/key4/1/c"},
    {"value":1,"op":"add","path":"/key4/2/c"},
    {"value":"wat","op":"add","path":"/key5"}
]

Interim patches for "left vs base" and "right vs base" are required. "op"=="test" can be ignored when combining the both patches to a 3-way-patch. If a "path" is touched by a single patch, then it can go directly to the 3-way-patch output. If a path is touched by both patches then it is a potential conflict. If "op" and "value" is equal on both patches then it is not a conflict and can be written as a single line to the 3-way-patch. Else it is a conflict and should be written like in the example:

[
...
{"op":"conflict","path":"/key1/0","value_left":4,"value_right":5,"op_left":"replace","op_right":"replace"}
...
]

This json-cli feature can help to write a 3-way-merge conflict auto resolver (wrapper script) e.g. for sops-encrypted json files.
On conflict this wrapper script can at least auto-merge non-conflicting changes and show the conflicts to the user for manual conflict resolution (e.g. via P4merge, KDiff3).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions