You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by Apache subversion Wiki <co...@subversion.apache.org> on 2013/09/04 17:23:51 UTC

[Subversion Wiki] Update of "MoveDev/Ev15MovesDesign" by JulianFoad

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Subversion Wiki" for change notification.

The "MoveDev/Ev15MovesDesign" page has been changed by JulianFoad:
https://wiki.apache.org/subversion/MoveDev/Ev15MovesDesign

New page:
'''Ev1.5 Representation of Moves'''

<<TableOfContents(3)>>

== Summary ==
The original “svn_delta_editor_t” is colloquially known as “Ev1” now that a proposed new “svn_editor_t” known as “Editor version 2” (Ev2) has been around for some time.

This document sets out a proposal for revising Ev1 to support move tracking – specifically, to enable move semantics to be transmitted over the editor interface.

Since the name “Ev2” is already taken, let's call the result “Ev1.5”.

== Specification ==
Changes to ''svn_delta_editor_t'' to support moves:

 * Add an operation: move-away(path, id, parent_baton).  The    ''path'' references a child of the directory represented by     ''parent_baton.''  The node-line at ''path'' existed in the     initial tree state: it was not created within this edit.  The ''id''    is different from that of every other move-away in the whole edit.      After this operation, the ''path'' and all its descendents are no       longer visible in the current tree state.

 * Add an operation: move-here(path, id, parent_baton) →        child_baton.  The ''path'' references a non-existent child name         in the directory represented by ''parent_baton''.  The ''id''   matches the id given in a previous move-away.  The      ''path'' is then “open”         for editing, like when a path is created by the “add” operation.

 * Add an operation: rename(path1, path2, parent_baton) →       child_baton.  The ''path1'' references a child of the   directory represented by ''parent_baton.''  The node-line at ''path''   existed in the initial tree state: it was not created within this       edit.  The ''path2'' references a non-existent child name in the        same directory.  The    ''path'' is then “open”         for editing, like when a path is created by the “add” operation.         This is functionally identical to move-away(path1) immediately         followed by move-here(path2).

 * The edit driver MUST open the parent directory before and    close the parent directory after each of these operations, like all     other operations in the editor.

 * The edit driver MUST send exactly one move-away and one      move-here for each id.

 * The name     and/or the      parent directory node-line      MUST differ between     move-away and the corresponding move-here.

 * The edit driver SHOULD NOT move-away a subtree that has been         altered (except by move-away of deeper subtrees).

 * The edit driver SHOULD NOT move-away a path that has been    moved here (the path itself or through any parent).

 * The edit driver SHOULD use the ''rename''    operation instead of move-away and move-here, when possible.

== Examples ==
Here are some examples of move scenarios that can be difficult, and their solutions.

==== Example 1: Insert a directory level ====
{{{
|                     |
+--A  mv--\     (add) +--A
           \             |
            \-->         +--B
}}}
The add cannot happen before the move-away, but must happen before the move-here.

 1. move-away(A, id=1)
 1. add-directory(A, copy-from=null)
 1. move-here(A/B, id=1)
 1. close-directory(A/B)
 1. close-directory(A)

==== Example 1b: Remove a directory level (by deletion) ====
{{{
|                     |
+--A (del)     /-->   +--A
   |          /
   +--B  mv--/
}}}
The move-away must happen before the delete, while the move-here cannot happen before the delete.

 1. open-directory(A)
 1. move-away(A/B, id=1)
 1. close-directory(A)
 1. delete(A)
 1. move-here(A, id=1)
 1. close-directory(A)

==== Example 1c: Remove a directory level (by move-away) ====
{{{
|                       |
|              /-->     +--X
|             /         |
+--A   mv----/   /-->   +--A
   |            /
   +--B  mv----/
}}}
Move-away B, then move-away A, then move-here original B at new path A:

 1. open-directory(A)
 1. move-away(A/B, id=1)
 1. close-directory(A)
 1. move-away(A, id=2)
 1. move-here(A, id=1)
 1. close-directory(A)
 1. move-here(X, id=2)
 1. close-directory(X)

(A possible alternative, starting with move-away A, then move-away B from inside the moved A, is only possible if we've been able to complete that move by this time, and also violates the rule that the edit driver should not move a previously moved node.)

==== Example 2: Swap two siblings ====
{{{
|                     |
+--A     mv--\ /-->   +--A
|             X       |
+--B     mv--/ \-->   +--B
}}}
Neither of the moves can be completed before doing the move-away part of the other one.

 1. move-away(A, id=1)
 1. rename(B, A)
 1. close-directory(A)
 1. move-here(B, id=1)
 1. close-directory(B)

==== Example 3: Swap two directory levels ====
{{{
|                     |
+--A     mv--\ /-->   +--A
   |          X          |
   +--B  mv--/ \-->      +--B
}}}
Neither of the moves can be completed before doing the move-away part of the other one.

 1. open-directory(A)
 1. move-away(A/B, id=1)
 1. close-directory(A)
 1. move-away(A, id=2)
 1. move-here(A, id=1)
 1. move-here(A/B, id=2)
 1. close-directory(A/B)
 1. close-directory(A)

==== Example 4: Swap A with A/B/C ====
{{{
|                            |
+-- A          mv--\   /-->  +-- A
    |               \ /          |
    +-- B      mv--- X --->      +-- B
        |           / \              |
        +-- C  mv--/   \-->          +-- C
}}}
 1. open-directory(A)
 1. open-directory(A/B)
 1. move-away(A/B/C, id=1)
 1. close-directory(A/B)
 1. move-away(A/B, id=2)
 1. close-directory(A)
 1. move-away(A, id=3)
 1. move-here(A, id=1)
 1. move-here(A/B, id=2)
 1. move-here(A/B/C, id=3)
 1. close-directory(A/B/C)
 1. close-directory(A/B)
 1. close-directory(A)

(Other similar examples are possible.  Instead of B being moved (as shown), it could be deleted from the old A and re-created in the new A, or the original B could move away and the new B could move into place, each by naturally following along with the move of its own parent directory.)

== Concerns and Enhancements ==
=== Half-Moves at the Edge of the Subtree ===
An edit is scoped to a pathwise subtree of the repository (for a commit) or of the WC (for an update).  It is possible for the edit to involve a node that, if seen in a wider scope, would move into or out of this subtree.  With this specification the edit driver has to describe such a move as an add or delete.

There are potential advantages to describing it as a move (or rather as half of a move).  This would give the consumer the ability to inform or warn the user, raise a tree conflict, or even perhaps commit or update an additional subtree in order to avoid breaking the move.

The consumer can convert a move-out to a delete trivially.  The consumer can convert a move-in to an add (of sorts) by requesting the node's content from the server, which is trivial during a commit (when the consumer is the server), but hard during an update (when the consumer is the client).

== References ==
=== Related Proposals ===
There is a proposal for a way to transparently encode move semantics into an old Ev1 editor drive and decode it on the receiving end – in other words, a way to tunnel move semantics through an old Ev1 connection.

There is a proposal for defining moves in Ev2.

Re: [Subversion Wiki] Update of "MoveDev/Ev15MovesDesign" by JulianFoad

Posted by Branko Čibej <br...@wandisco.com>.
On 04.09.2013 17:23, Apache subversion Wiki wrote:
> Dear Wiki user,
>
> You have subscribed to a wiki page or wiki category on "Subversion Wiki" for change notification.
>
> The "MoveDev/Ev15MovesDesign" page has been changed by JulianFoad:
> https://wiki.apache.org/subversion/MoveDev/Ev15MovesDesign
>
> New page:
> '''Ev1.5 Representation of Moves'''
>
> <<TableOfContents(3)>>
>
> == Summary ==
> The original “svn_delta_editor_t” is colloquially known as “Ev1” now that a proposed new “svn_editor_t” known as “Editor version 2” (Ev2) has been around for some time.
>
> This document sets out a proposal for revising Ev1 to support move tracking – specifically, to enable move semantics to be transmitted over the editor interface.

Uh. What? What on earth is this good for?

Older clients and servers that don't support Ev2 will revert to
copy+delete. This is already handler by the shims, IIRC. You don't need
this at all. Instead, you nead Ev2 caps negotiation.

-- Brane


-- 
Branko Čibej | Director of Subversion
WANdisco // Non-Stop Data
e. brane@wandisco.com