Hey Eric,

Le 19 oct. 2011 à 23:23, Eric Wasylishen a écrit :

> 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.)

That's how I understand commit tracks at least :-)

> 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.

b) seems good enough to begin with. I'm not entirely convinced that branching 
the outer document should branch the inner document automatically, although 
there are use cases where that's the best choice.

For example… For a page layout, I wouldn't want the inner documents to be 
branched, I just expect them to be in their more recent states. For a 
photomontage, getting the inner pictures/photos branched would be convenient, 
to ensure the overall composition look won't change in unexpected ways, no 
matter what I try on the inner elements (and I can manually bring them to their 
more recent states if I want to).

For ObjectMerging, we could use a special ref marker rather than a plain UUID 
to represent references between root objects. 

A ref marker could include an optional branch UUID. Since a branch has a head, 
the ref marker would implicitly point to a specific root object version. If 
there is no optional branch UUID, the (inner document) current branch is 
picked. With this model, we could also automatically branch inner documents in 
a way similar to what you suggest above… 
For example, on branching the outer document, all the inner documents are 
branched. These "nested" branches would be private, in the sense they wouldn't 
be listed at the UI level among the branches of each root object (well, unless 
you request it). We could eventually use the outer document UUID as the inner 
document branch UUID, not sure it's a good idea though.

Rather than serializing a custom reference object, we could still use a plain 
UUID by generating a new UUID that represents a core object UUID + branch UUID 
pair, and a database table to store the mapping. I'm not sure it's a good idea 
either, because it would make the debugging less easy and much harder to 
interpret core objects exported as plists.

>>> 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).

ok

>> 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.

Thanks for the extra infos. If we can keep roughly the same COEditingContext, 
COObject and COTrack API between ObjectMerging and NestedVersioning, migrating 
to a new model should be easy.

This brings me to the fact, I plan to extract a common superclass COTrack for 
COHistoryTrack and COCommitTrack and do the same with the node classes. We 
could then present and manipulate either commit tracks or history tracks in the 
simple history browser I have being working on (not yet committed). 

If there is no objection I'd like to rename COCollection to COGroup and merge 
the related code from CoreObject. In addition, I'd like to bring the CoreObject 
protocol once tweaked a bit to ObjectMerging and COFile and CODirectory.

Once all this is done, I plan to move CoreObject to Deprecated and rename 
ObjectMerging to CoreObject.

Any comments about all that?

As a last question, Eric, what needs to be done to get the remote collaboration 
support working with ObjectMerging? Writing COSynchronizer or more? Bringing 
some classes from the early ObjectMerging prototypes?

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

Reply via email to