jsondiffpatch icon indicating copy to clipboard operation
jsondiffpatch copied to clipboard

Need method to combine diffs

Open ghost opened this issue 10 years ago • 9 comments

I collect and store a large graph of diffs that I would like to path & unpatch. My issue is I'd prefer to only patch / unpatch once and also have a way to combine diffs. I create my diffs on each 'substantial' change, so they can each be undone. Once a commit happens, I then want to squash all of those tiny diffs into 1 larger diff.

ghost avatar Mar 07 '14 21:03 ghost

It's not a ton, but you do great work so I wanted to put something up as a bounty on this issue.

https://www.bountysource.com/issues/1435798-need-method-to-combine-diffs

ghost avatar Mar 07 '14 22:03 ghost

cool, yeah, some initial thoughts:

  • the hardest part would be to combine 2 text diffs (AFAIK google diff match patch doesn't provide that), in case that gets hard to solve, would it be ok to leave those uncombined?
  • deltas can conflict (eg. replace after remove), would it be ok to just fail on first conflict? or a conflict resolution mechanism would be necessary?

benjamine avatar Mar 08 '14 18:03 benjamine

As far as text diffs, would { name: Tom } to { name: Bob } work?

I think failing on conflicts is fine, as they would be passed in order so I don't think they should conflict if I understand correctly.

ghost avatar Mar 08 '14 18:03 ghost

yep, with text diffs I mean cases where 2 long strings are diffed and the google diff match patch lib is used to generate a unidiff, eg:

@@ -638,17 +638,17 @@
 via, Bra
-z
+s
 il,  %0ACh
@@ -916,20 +916,13 
@@
 re a
-lso known as
+.k.a.
  Car

(where only pieces are added/removed inside the string) regular string replaces, would be just fine.

yes, if your deltas come from continuous operations over the same data, they should never conflict, sounds good.

benjamine avatar Mar 08 '14 18:03 benjamine

Isn't this problem similar to 'git rebase '?

Any time you're trying to make a two way merge where changes occur in different places, then you have a setup where:

Head -> Commit a -> commit b

Is equivalent to Head -> commit b -> commit a

Right?

If this is the case, simply replaying in some order both patches wanting application should just work, correct?

borromeotlhs avatar Jun 25 '14 21:06 borromeotlhs

This symmetry is violated with intraline ( different changes occurring on the same line ) diff's. Therefore, you are stuck with selecting one change as true over another. This leads you to different heuristics you could use, with a possibility that you could dynamically select one method over the other depending on your situation.

borromeotlhs avatar Jun 25 '14 21:06 borromeotlhs

@borromeotlhs actually, I think the original description matches more a git squash, as I understand the deltas to combine would be a sequence of changes made to one object, not branches, so there shouldn't be any conflicts to solve (that's what @dariusriggins clarified to me). merging 2 deltas with the same "base" (or alternatively a rebase) is a more challenging problem, that would be nice to solve too.

benjamine avatar Feb 14 '16 05:02 benjamine

I have very large array I would like to diff but jsondiffpatch uses recursion and it blows max stack size of node. It would be nice if I can split big array in smaller array and later merge diff to create final diff.

malhar-trivedi avatar Jul 15 '16 19:07 malhar-trivedi

@malhar-trivedi it doesn't use recursion actually, it uses a linked list, I'd like to know how did you determined otherwise. But I'm curious to see a test case can you open a separate issue including example data?

benjamine avatar Jul 15 '16 19:07 benjamine