Hey Chris and Quentin,

Sorry to be silent for a while.

Sounds like we're on the same page – now I think I understand commit tracks; so 
it is in fact a different idea than nested versioning.

If I understand commit tracks correctly, it has the effect of giving each 
persistent root its own history graph, and for each persistent root, you can 
easily move a "pointer" which marks the current state of that persistent root. 
It sounds like a great idea to me (now I think the idea I was experimenting 
with in COHistoryTrack, where normal undo/redo would be implemented as 
selective undo, would end up being  a mess.)

I'll give some more details on nested versioning..

>> From what I have understood, the main interest is to support undoing 
>> arbitrary branch operations such as deletion, switch or merge cleanly and in 
>> a transparent way for the user.

That is one motivation; but my main motivation is to better handle composite 
documents (at least, that's what I hope it does.)

My motivating example is a composite document called "outer" containing another 
document, "inner". The pair could be a paper and a figure in the paper, or a 
photo library and a photo, etc.

With the ObjectMerging model you have to make a choice between

a) make the inner document a normal object inside a persistent root.. this 
means you forfeit native versioning support for the inner document. You can't 
easily present the user with undo/redo controls for the inner document, without 
resorting to using selective undo. You could still view a history graph of the 
inner document by taking the persistent root's history graph and filtering out 
nodes that don't affect the inner document, and then selectively undo changes 
affecting the inner document. You can't really maintain multiple branches of 
the inner document. On the positive side, when you make a change like 
reverting, tagging, or branching the outer document, the inner document is also 
affected.

or

b) make both the inner document and the outer document persistent roots. This 
gives full versioning/branching/undo/redo support to both the outer and inner 
document, but the problem is, the link to the inner document from the outer 
document is now a weak reference by UUID, so the outer document no longer owns 
the inner one, and tagging/branching/reverting the outer document has no effect 
on the inner document. If the user wants to record the state of the outer 
document including the inner one, he has to write down the version number of 
both the outer and inner document. 

IMHO, neither of these options is very good, although a) is closer.

With nested versioning, the inner document can be a persistent root with full, 
native versioning support (branch/tag/undo/redo), but it can be nested inside 
the outer document, so branch/tag/undo/redo on the outer document also affect 
the inner document.

As far as I'm aware, no one has done this in an organized way before, although 
you could always do it ad-hoc, like using the versioning feature in an 
OpenOffice.org Writer document and storing the file inside git or another 
version control system.

>> Is it possible to expand the commit track model to support undo/redo on 
>> arbitrary branch operations? It seems to me that if the commit track model 
>> was expanded it would be pretty much equivalent to Eric's NestedVersioning.
> 
> It easily supports undo/redo on changing the revision that a branch points 
> to. However, it doesn't really account for undo/redo on a branch 
> creation/deletion, and as far as I can see, its not easily added. However, I 
> think it's less important; I would implement branch deletion as a toggle 
> switch, and allow the user to purge the metadata of a commit track if they 
> really wanted.

I agree with Chris; I think if you want to version the history graph 
(meta-versioning?) it's best to design for that from the ground up (be able to 
treat history graph as data to be versioned).

> Nested versioning (I believe) could be quite complicated to implement, but 
> I'm happy to be proven wrong.

I'm still playing with it, so we'll see. :-)

My idea so far is:

- it's built on top a simple store that doesn't provide any versioning, unlike 
the store API in ObjectMerging
- the data model of the store is more or less the same as ObjectMerging: 
objects with key : value pairs, and the objects can be organized in a 
hierarchical structure (still not sure whether to do this like the way 
ObjectMerging does, by marking certain keys as being 'composition' 
relationships, or to have a special "children" key)
- versioning is achieved by copying an object and its children in the 
hierarchy. The store is optimized so that the copy will be "cheap".
- to be useful, it needs to have a data structure to keep track of the copied 
versions. This is the diagram Quentin mentioned earlier: 
https://github.com/ericwa/NestedVersioning/blob/master/Docs/NestedVersioningDiagram.pdf?raw=true
- what's important is that the data structure for keeping track of versions of 
an object is itself constructed of regular objects, so the data structure for 
keeping track of the versions of an object could be part of a larger tree which 
is itself being versioned - that's where the nesting comes from.

There is more brainstorming in the Docs directory on my github, but it may not 
be very coherent.

Cheers,
Eric
_______________________________________________
Etoile-dev mailing list
[email protected]
https://mail.gna.org/listinfo/etoile-dev

Reply via email to