monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Monotone-devel] resolving name conflicts; file suturing vs drop


From: William Uther
Subject: Re: [Monotone-devel] resolving name conflicts; file suturing vs drop
Date: Fri, 9 May 2008 11:47:19 +1000


On 08/05/2008, at 8:45 PM, Markus Schiltknecht wrote:


 A full example, starting from your sample:


   A: 1,foo,v   B: 2,foo,w
    /\          /\
   /  \        /  \
  |    \______/____\
  |          /     C: 3,foo,x           # Alice wants to suture the
  |         /        \                  # two files to resolve the
  |        /          \                 # ncc between A and B, but
  |       D: 2,bar,y   \                #
  |______/              |               # Bob renames one and then
  E: 1,foo,v            |               # merges into E
  |  2,bar,y            |               #
  |                     G: 3,foo,u      # both do some edits
  F: 1,foo,u            |               #
 /|  2,bar,y            |               # then Alice want to merge,
/ |                    /                # but figures there's another
/  H: 2,bar,y          /                 # ncc. She still thinks
|   \                 /                  # suturing is fine, thus
|    \               /                   # votes again for her
|     \             /                    # suturing approach, by
|      \           /                     # dropping the offending
|       \         /                      # node id 1.
|        \       /                       #
|        I: 3,foo,z                      # Resulting in dragging in
|            |                           # changes from node id 2,
|            |                           # but loosing other changes
|            |                           # to node id 1 from Bob.
|            |                           #
|            |                           # After a lengthy detabe with
|            |                           # Alice, he finally agrees on
|            |                           # suturing the files, but he
| | # still want to keep his edit.
|            |                           #
K: 4,foo,u   |                           # So he copies his latest
\ 2,bar,y   |                           # version of foo...
 \          /                           #
  \        /                            #
   \      /                             # ..and sutures that together
    \    /                              # with Alice's version, thus
    L: 5,foo,t                          # suturing 3 and 4 into 5.
                                        # (2 has been sutured into 3,
                                        # so it disappears).


In the implementation of suturing in my head, node-id 3 is a synonym for "1&2". In this example, if you were to merge revs D and G, then node-id 2 from rev D should match with node-id 3 from rev G. The result is that the rename between B and D gets cleanly merged, and there is a three-way merge of contents between D and G with B as the ancestor.

This automatic merging of changes to one of the files in a suture into the child of the suture seems to be one of the primary features of a suture.

Given that, I don't see how you get node I. In that case I would expect that node I would collect all the changes to node ids 1, 2 or 3. If you have DieDieDie merge, then the fact that you've killed node 1 would kill the other nodes? Or you could make suture conflict with rename and drop. In any case, I don't understand what happens at node I.

I'm also confused by what you mean by 'copy' in node K. There are two definitions of 'copy' floating around. One is the 'add a new node-id with the same contents as this other node' that you could currently implement with "mtn cat ; mtn add". That version of copy would not merge changes cleanly.

The other version of copy is this magical 1->N operation that still merges changes from before the copy (into each of the children?). I haven't seen a credible description of how to implement this. (I haven't seen a complete description of how to implement suturing either, but at least I've seen a hand-wavey version of that.)

This might or might not be easier to the end user, very much dependent on the UI and how much we polish it. However, it certainly prevents multi-stage content merging, while still giving a way to resurrect files *and* preventing endless growth of node ids required.

I might still be missing something, but IMO (asymmetric) copying together with suturing make for a pretty good file resurrection implementation.

I guess that depends on whether the deletion of node 2 between revs K and L causes the deletion of nodes 3 and 5 because they're all equivalent.

Hrm. If you have sutures conflict with deletes, then you're making the user choose what happens every time that comes up in a merge. You're relying on the fact that that wouldn't happen very often.

A simpler way to achieve resurrection might be to have a "merge, but make liveness questions interactive". Any time a file is alive on one side of a merge, but dead on the other, then the user is asked whether to keep the file or not. If they decide to keep the file, then it is resurrected.

This way, in normal use, die-die-die would remain. But if you want to resurrect a file, then you need to merge all heads with this interactive flag and decide to keep the node-id. Once you've merged all the so the remaining head has the node-id, the file is effectively resurrected.

Hrm - I might try and implement this on a branch so I can play with it. It should be a simple way to get resurrection that works reasonably well without major work or a monotonically increasing sized graveyard. In fact, I just did. It is in rev 7bedf809be5453501c62668a2e00d2a900dc160a on the branch net.venge.monotone.simple-resurrect.

Be well,

Will          :-}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]