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 2012/12/13 15:40:07 UTC

[Subversion Wiki] Update of "MultiLayerMoves" by PhilipMartin

Dear Wiki user,

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

The "MultiLayerMoves" page has been changed by PhilipMartin:
http://wiki.apache.org/subversion/MultiLayerMoves?action=diff&rev1=31&rev2=32

  ||    2     ||    B/G        || normal       ||          ||
  |||||||| '''table D6''' ||
  
+ = No Mixed-Revision Moves =
+ 
+ Subversion does support mixed-revision copies but moves will be restricted to single-revision trees.  This doesn't restrict users in practice since these are the only sort of moves that can be committed.  When committing a move the source part, the delete, is essentially a single-revision equivalent to HEAD; nothing else can be deleted.  The destination part, the copy, must be the same as the source part since a move has to involve the same node at both places.
+ 
+ It will be possible to move single-revision trees with local modifications, e.g. a tree A with a locally added A/G:
+ 
+ 
+ || op-depth || local-relpath || presence || moved-to || moved-here ||
+ ||    0     ||    A          || normal   ||          ||            ||
+ ||    0     ||    A/F        || normal   ||          ||            ||
+ ||    2     ||    A/G        || normal   ||          ||            ||
+ |||||||||| '''table E1''' ||
+ 
+ Move A to B gives a single-revision move of A-to-B with a locally added B/G:
+ 
+ || op-depth || local-relpath || presence     || moved-to || moved-here ||
+ ||    0     ||    A          || normal       ||          ||            ||
+ ||    0     ||    A/F        || normal       ||          ||            ||
+ ||    1     ||    A          || base-deleted ||    B     ||            ||
+ ||    1     ||    A/F        || base-deleted ||          ||            ||
+ ||    1     ||    B          || normal       ||          ||     1      ||
+ ||    1     ||    B/F        || normal       ||          ||     1      ||
+ ||    2     ||    B/G        || normal       ||          ||            ||
+ |||||||||| '''table E2''' ||
+ 
+ 
  = Updating a Move =
  
- This section assumed that the move destination would be updated at the same time as the move source during the update editor drive. I'm currently looking at having update create a tree-conflict, like 1.7, and then update the move as a type of conflict resolution.  See MultiLayerMoveUpdate.
+ When a single-revision BASE tree is updated from one revision to another it temporarily becomes mixed revision (for both v1 and v2 editors). We cannot use the mixed-revision copy representation for these mixed-revision states as mixed-revision copies are represented as multiple-op-depth nested copies.  The use of multiple-op-depth for mixed-revision moves would interfere with the use of multiple-op-depth for copies inside move destinations.
  
- A mixed revision move produces a multiple op-depth working tree:
+ See MultiLayerMoveUpdate.
  
- || op-depth || local-relpath || presence     || revision ||moved-to ||
- ||    0     ||    A          || normal       ||    4     ||         ||
- ||    0     ||    A/B        || normal       ||    3     ||         ||
- ||    1     ||    A          || base-deleted ||          ||    X    ||
- ||    1     ||    A/B        || base-deleted ||          ||         ||
- ||    1     ||    X          || normal       ||    4     ||         ||
- ||    1     ||    X/B        || not-present  ||          ||         ||
- ||    2     ||    X/B        || normal       ||    3     ||         ||
- |||||||||| '''table F1''' ||
- 
- Since updating a single revision tree passes through states with multiple revisions this means that the move must change from single op-depth to multiple op-depth and back. So when the single revision move below is updated
- 
- || op-depth || local-relpath || presence     || revision ||moved-to ||
- ||    0     ||    A          || normal       ||    3     ||         ||
- ||    0     ||    A/B        || normal       ||    3     ||         ||
- ||    1     ||    A          || base-deleted ||          ||    X    ||
- ||    1     ||    A/B        || base-deleted ||          ||         ||
- ||    1     ||    X          || normal       ||    3     ||         ||
- ||    1     ||    X/B        || normal       ||    3     ||         ||
- |||||||||| '''table F2''' ||
- 
- the first change is that A becomes r4 and incomplete.  This is a mixed-revision move and looks like:
- 
- || op-depth || local-relpath || presence     || revision ||moved-to ||
- ||    0     ||    A          || incomplete   ||    4     ||         ||
- ||    0     ||    A/B        || normal       ||    3     ||         ||
- ||    1     ||    A          || base-deleted ||          ||    X    ||
- ||    1     ||    A/B        || base-deleted ||          ||         ||
- ||    1     ||    X          || incomplete   ||    4     ||         ||
- ||    1     ||    X/B        || not-present  ||          ||         ||
- ||    2     ||    X/B        || normal       ||    3     ||         ||
- |||||||||| '''table F3''' ||
- 
- then A/B becomes r4 (going through incomplete/complete if it is a directory) at which point we are back to a single revision at r4. Finally A becomes complete at r4.
- 
-  * Does the incomplete state have to propagate to the working tree?
- 
-  * Suppose the user attempts to revert, or delete, X/B in the mixed-revision move: does that break the move leaving A deleted and X/B copied?  Does revert fail?
- 
- == Update Conflict ==
- 
- Move A to B:
- 
- || op-depth || local-relpath || presence     || revision || repos || moved-to ||
- ||  0       ||    A          || normal       ||   1      ||   A   ||          ||
- ||  0       ||    A/f        || normal       ||   1      ||   A/f ||          ||
- ||  1       ||    A          || base-deleted ||   1      ||   A   ||   B      ||
- ||  1       ||    A/f        || base-deleted ||   1      ||   A/f ||          ||
- ||  1       ||    B          || normal       ||   1      ||   A   ||          ||
- ||  1       ||    B/f        || normal       ||   1      ||   A/f ||          ||
- |||||||||||| '''table G1''' ||
- 
- Delete B/f and replace with something copied from elsewhere:
- 
- || op-depth || local-relpath || presence     || revision || repos || moved-to ||
- ||  0       ||    A          || normal       ||   1      ||   A   ||          ||
- ||  0       ||    A/f        || normal       ||   1      ||   A/f ||          ||
- ||  1       ||    A          || base-deleted ||   1      ||   A   ||   B      ||
- ||  1       ||    A/f        || base-deleted ||   1      ||   A/f ||          ||
- ||  1       ||    B          || normal       ||   1      ||   A   ||          ||
- ||  1       ||    B/f        || normal       ||   1      ||   A/f ||          ||
- ||  2       ||    B/f        || normal       ||   1      ||   X   ||          ||
- |||||||||||| '''table G2''' ||
- 
- Now consider updating A and B: as A goes through a mixed-rev state B has to do the same but we can't represent the mixed-rev state in B since that would require B/f at op-depth=2 to record both A/f@2 and X@1. The final state, when A is single-rev again can be represented in B.
- 
- Perhaps that is not a problem: since B/f is deleted there is no working file to accept the A/f changes so this is a form of tree conflict. Perhaps we end up with A moved-to B but broken (because the revisions don't match) and a tree conflict (on A/f?). After the update the conflict resolution is either to break the move into copy+delete or to update the revisions.  Since the resolution happens after the update it is probably possible to avoid the mixed-rev state.
- 
- = Problem Case =
- 
- A mixed-rev BASE tree:
- 
- || op-depth || local-relpath || presence     || revision ||
- ||  0       ||    A          || normal       ||   1      ||
- ||  0       ||    A/B        || normal       ||   2      ||
- ||  0       ||    A/B/C      || normal       ||   3      ||
- |||||||| '''table H1''' ||
- 
- Move A to X, a mixed-rev move:
- 
- || op-depth || local-relpath || presence     || revision || moved-to || moved-here ||
- ||  0       ||    A          || normal       ||   1      ||          ||            ||
- ||  0       ||    A/B        || normal       ||   2      ||          ||            ||
- ||  0       ||    A/B/C      || normal       ||   3      ||          ||            ||
- ||  1       ||    A          || base-deleted ||          ||   X      ||            ||
- ||  1       ||    A/B        || base-deleted ||          ||          ||            ||
- ||  1       ||    A/B/C      || base-deleted ||          ||          ||            ||
- ||  1       ||    X          || normal       ||   1      ||          ||      1     ||
- ||  1       ||    X/B        || not-present  ||          ||          ||            ||
- ||  2       ||    X/B        || normal       ||   2      ||          ||      1     ||
- ||  2       ||    X/B/C      || not-present  ||          ||          ||            ||
- ||  3       ||    X/B/C      || normal       ||   3      ||          ||      1     ||
- |||||||||||| '''table H2''' ||
- 
- Nested moves inside X are now a problem. Consider moving X/B to X/Y:
- 
- || op-depth || local-relpath || presence     || revision || moved-to || moved-here ||
- ||  0       ||    A          || normal       ||   1      ||          ||            ||
- ||  0       ||    A/B        || normal       ||   2      ||          ||            ||
- ||  0       ||    A/B/C      || normal       ||   3      ||          ||            ||
- ||  1       ||    A          || base-deleted ||          ||   X      ||            ||
- ||  1       ||    A/B        || base-deleted ||          ||          ||            ||
- ||  1       ||    A/B/C      || base-deleted ||          ||          ||            ||
- ||  1       ||    X          || normal       ||   1      ||          ||     1      ||
- ||  1       ||    X/B        || not-present  ||          ||          ||            ||
- ||  2       ||    X/Y        || normal       ||   2      ||          ||            ||
- ||  2       ||    X/Y/C      || not-present  ||          ||          ||            ||
- ||  3       ||    X/Y/C      || normal       ||   3      ||          ||            ||
- |||||||||||| '''table H3''' ||
- 
- the op-depth=2 tree X/B gets removed and a new op-depth=2 tree X/Y is created.  There is no base-deleted tree for X/B so the move to X/Y is not recorded.  Should the move to X/Y be recorded and if so where?  Perhaps in the not-present node for X/B?
- 
- Part of the problem is the multi-layer mixed-rev copy. If we had chosen a single-layer mixed-rev copy then X, X/B and X/B/C would all be op-depth=1 and the X/B to X/Y move would introduce base-deleted X/B at op-depth=2. [Possibly. It's hard to know exactly how such a model would work.]
-