What if we would implement a "3-way-merge" system into TW?

I wonder if there is any plausible way to determine this case?

That’s already possible.

  • Create a tiddler with some text
  • Save it
  • Edit it
  • In the preview you have “differenced from current”

Which imo is what you describe here

No, You can only do this visually, The difference engine only counts the changes in a single field, text by default, you can’t get a change count for a tiddler to then use to control other code. You can’t write the tools I am suggesting.

  • I believe additional TiddlyWiki access to the JS in the librry is there.

That’s exactly what I wanted to describe in my very first response. … If we are OK, that we get the Klingon version of a prose text tiddler, that would probably work, because it does not matter.

For code-shadows an automatic process may work for some trivial changes … until it does not work any more. …

If such changes are done by the core update process and it creates something that is broken, it is perceived as a core bug. Users will call for help because the update process is broken.

This will add additional maintenance pressure on the dev team.


I think it would be nice, if the upgrade process can show if shadow tiddlers have been overwritten without a real change. – So it will be OK to delete them.

I think that would be a very welcome improvement. Since unchanged but overwritten shadows also cause extra maintenance requests. … If we can avoid that. → good


I think only the first point it viable. … It will be obvious that there have been changes. → Yes I would support that.

It will not be reliable in the sense that it is guaranteed that the changes will work.
It will reliably overwrite the working shadow tiddler with something that may ore may not work.

It will look like if it would be easy for trivial cases and it would be easy to create examples where it works. … BUT the problems are caused by real world cases where it does not work.

1 Like

I understand the concern that non trivial cases may not work if the difference is applied automaticaly but having the information about past changes is just more information than we currently have.

I am suggesting we have the tools to address a feature gap and designers can make their own design decisions.

That’s all cool stuff and it’s possible to do so, with the libraries we do have in the core. As the examples show but somebody would have to implement it.

I think several community members can implement the wikitext elements that are possible already, as I showed at HowTo Compare the Content of a Shadow Tiddler With the Content of an Overwritten Shadow … The merge options would need some js-code, but to make the differences visible is wikitext only.

The core devs have to deal with about 1.1k open issues, where probably half of them are still valid and about 160 open pull requests with probably about 30% are still thinkable.

So until we can clone several devs none of that will happen in the near future if the community does not step up more and actually start to try to contribute to the core using GitHub

1 Like

I hope to be able to do this, but it will likely be several months before I feel confident enough as a TW user to even consider becoming a TW developer.

I’ve just published a draft PR for three additional filter operators that expose more of the functionality of the diff-match-patch library that is already integrated into TW5:

  • Compute the Levenshtein distance between two strings (the Levenshtein distance is defined as the number of characters that must be inserted, deleted or substituted to turn one string into another); it is a useful way to measure the similarity of two strings
  • Create a set of patches to represent the difference between two strings
  • Apply a previously created patch to a string

See Introduce new levenshtein, makepatches, applypatches operators by Jermolene · Pull Request #7290 · Jermolene/TiddlyWiki5 · GitHub

I think these primitives are sufficient for exploring the three way merging idea.

5 Likes

Nice. I did create some examples to play with. Texts are from the original examples. Order to click the buttons from top to bottom. If you import the StoryList the tiddlers are sorted in the right way

Import the JSON to the preview wiki: https://tiddlywiki5-git-diff-match-patch-operators-jermolene.vercel.app/

diff-match-patch-examples.json (2.8 KB)

have fun!
mario

1 Like

Please see here [RFC] Running a difference check on whole of tiddler including fields - #3 by TW_Tones a desire to get a little more from that Library, specifically to return a count so we can then use this in a condition test, even to sum the number of changes.

Note the count is currently returned inside a message and not usable.

  • Even just returning zero, one or more would help.
  • Perhaps the levenshtein operator can be used for this but perhaps a simpler operator is different or has differences …

The difftext-widget already returns the number of differences. See diff-count

But;

This means the count is something you can return, once for each comparison, it gets more complex trying to sum the count of multiple comparisons. Or multiple widget calls.

  • However I will revisit it to check diff-text
  • @jeremyruston’s Levenshtein (distance between two strings) operator is a reasonable proxy because for a set of comparisons, as I want to know if there are 0, 1 or more changes between two tiddlers fields.
  • However I think we can make full tiddler comparisons easier.

IMO as soon as there is a number different to 0 it will be needed to show the real differences. Instead of count you can use the levenshtein distance. IMO it’s equally useful, since the only number that does not require any user action is 0

From Wikipedia, the free encyclopedia

In information theory, linguistics, and computer science, the Levenshtein distance is a string metric for measuring the difference between two sequences. Informally, the Levenshtein distance between two words is the minimum number of single-character edits (insertions, deletions or substitutions) required to change one word into the other.

Part of the reason I worded this the way I did is there is also a difference between an empty existing field and no field at all.

Whether we use a javascript a tiddlywiki macro or a widget that calls the existing library we are building a lot of detail into the difference check so it approaches a patch system, all good, however we have not yet built a simple difference test, which allows whole of tiddler or field by field comparisons (with the necessary field exceptions).

  • I can build a wikitext macro on top of the Levenshtein operator
  • However I would seem we should be able to use the existing library
  • perhaps a diff-tiddler widget to complement the DiffText widget.
    • Identifies all fields in two tiddlers and compares them
    • Allows except fieldnames
    • option count new ot deleted empty fields option
    • returns a true/false or count of fields with a difference not changes within differences.

There is a new preview wiki wiki, which contains this PR. make import listing more configurable

This PR allows us to implement user defined extensions to the “overwrite” message area.

If you import this JSON into the preview wiki you’ll get an overview similar to the following screenshot

import-listing-verbose.json (1.5 KB)

This code is far from being finished, since IMO at the moment it adds more visual clutter than useful info. …

But it shows what’s possible.

If the title would adjust to the width of the longest title it would be easier to read.

  • Ideally if the title consumed more than 50% of the width the status would appear on the next row.

If in the area that displays the Status could be populated using a tag such as $:/tags/import-status the existing and incoming information could be placed in a tiddler with the $:/tags/import-status and it would be easy, without core modification for me to include new tools like;

  • Full count of differences by field
  • If suffix “readme” or “instructions” display rendered text from that tiddler.

Should it be possible to use these to create an in-wiki differential tiddler backup / snapshot feature?

I’ve always shied away from in-wiki backups as they would not only explode its tiddler count, but also its size. Using patches at least the size concern would be diminished. File-backups do not increase the tiddler count but can blow up your required hard/cloud drive space. This could be a middle-ground sweet spot, at least for single-file wikis.

1 Like

I’ve long been interested in re-implementing the tiddler store as an append-only log, implemented using the DiffMatchPatch primitives. I had always imagined it being done at the JS layer, though, so that it could handle all tiddler writes, not just those resulting from tm-save-tiddler.

I’m currently exploring the other way around. Instead of appending a series of patches to get the from the original tiddler to its current version, I’m tracking the changes backwards. The current tiddler always has the complete text. To see earlier versions of it, I apply the corresponding “inverse” patches to go back in time.

The upside of this approach is that for pruning, one can just delete all “history” data before day X and be done with it (unless one wants to keep the initial version). We do not need to compute the state on day X from all earlier changes and then throw away the old stuff.
Also, showing the current version is much faster without needing additional memory or initialization time during boot (to calculate the current versions)…

Trapping the tm-save-tiddler only indeed prevents me from tracking changes made via the ActionWidgets, so it won’t make sense to track state and temp tiddlers – which shouldn’t be versioned anyway – and maybe config tiddlers.

Have a nice day
Yaisog

2 Likes

That’s actually not true. Upon further reflection I came to realize that any field of any tiddler can directly be edited by binding it to an $edit-text widget. There would be no way of creating backups automatically for that, unless one does so after each $:/config/Drafts/TypingTimeout. Diffs could only be initiated manually. Since at that point one does not have a previous version to compare to with “inverse” patches (the last patch is based on the current version which has changed in the meantime). So, maybe the past-to-now forward approach is more sensible after all. With on-demand (or automatically triggered, e.g. upon tm-wiki-save) diff snapshots, one could generate a diff of all changed tiddlers in the wiki by comparing their modified date (is this always set?) and making a new diff if necessary…

@jeremyruston: When did you say that append-only tiddler store will go live? :wink: