Hi Quentin

Sorry for replying to these out of order, but theres alot to take in.

On 20/10/2011, at 20:46 PM, Quentin Mathé wrote:

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

That sounds right. Additionally, the pointer has a history, which allows the 
undo/redo bit. It is close but not the same as the concept of a branch when you 
allow more than one commit track on the same persistent root, but I haven't 
allowed that in the implementation yet. It is closest to the idea of a "branch 
with history", where we know what the branch has looked like in the past, but 
we still have a full history graph of the object under branching. The history 
of each branch will look different, but the object history will be the same for 
every branch.

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

I think that branching in the second case is not always necessary, but it 
should probably still be possible. As I outlined in my previous email, an 
option was to hold an object at a revision, but still have it track the branch 
and allow it to be updated manually. I think embedding it completely (i.e. 
coping the whole object in as an embedded object), at least in the case of a 
photo montage is not good, as it would consume alot more resources.

Perhaps allowing the user to branch later from the current revision would be 
better, when they know they want to branch? But this leads to the complexity 
that Eric identifies before, and I don't think its easily solved. Maybe allow 
branches to be marked "private" to a document so that don't show up in 
searches? I think the part about explicitly marking embedded root objects is 
really important here.

One of the things I want to avoid is "hierarchies" of root objects, which may 
exist with nested versioning and make the whole thing really complicated. I 
think trying to keep the object model as flat as possible is important to 
keeping it usable.

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

I don't think its a big conceptual burden for debugging, but yes, it does make 
things more difficult.

The main problem I forsee is the need for COEditingContext to allow multiple 
copies of the same object in the same context *at different revisions* at the 
same time. It doesn't seem entirely unreasonable to want a copy of the same 
object in the same document but at different revisions.

Regards
Chris
--------
Christopher Armstrong
[email protected]






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

Reply via email to