subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache subversion Wiki <comm...@subversion.apache.org>
Subject [Subversion Wiki] Update of "MultiLayerMoves" by PhilipMartin
Date Tue, 06 Mar 2012 11:28:58 GMT
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=15&rev2=16

  
  Now scan_deletion(A/B/C/D) needs to tell us moved_to is Q at op-depth=4, Z/D at op-depth=3,
X at op-depth=2. Quite how it does this is an open question. Does the caller pass the op-depth?
Where would the caller get it?  Does the function return some sort of array of (op-depth,
moved-to) pairs?
  
- = Copy/Move Differences =
+ = Nested Moves =
  
  || op-depth || local-relpath || presence || moved-to ||
  ||    0     ||    A          || normal   ||          ||
  ||    0     ||    A/F        || normal   ||          ||
  
+ Move A to B and then B/F to B/G
- Move A to B and B/F to B/G (or A/F to A/G and A to B):
- 
- '''gstein''': does the B/F to B/G have an op-depth of 2? That would change the table below.
The current depiction seems very difficult to construct a commit process: if you move A to
B, then how do you move A/F (no longer existing) to B/G?? And you can't do the A/F to B/G
first since B does not exist. I think this seeming difficulty is based on the wrong op-depth
for the B/F to B/G move.
- 
- '''philip''': that's essentially the inconsistency mentioned below: it's not clear what
the op-depth should be for nested moves. The node starts at A/F and ends at B/G. The current
non-multi-layer move stuff records that move in base.  Perhaps multi-layer move doesn't record
that move at all, but records the A->B and B/F->B/G. In the short term move information
is not used to contruct a commit, the commit still consists of copies and deletes.
  
  || op-depth || local-relpath || presence     || moved-to ||
  ||    0     ||    A          || normal       ||          ||
  ||    0     ||    A/F        || normal       ||          ||
- ||    1     ||    A          || base-deleted ||  B       ||
+ ||    1     ||    A          || base-deleted ||    B     ||
- ||    1     ||    A/F        || base-deleted ||  B/G     ||
+ ||    1     ||    A/F        || base-deleted ||          ||
  ||    1     ||    B          || normal       ||          ||
  ||    1     ||    B/F        || normal       ||          ||
+ 
+ || op-depth || local-relpath || presence     || moved-to ||
+ ||    0     ||    A          || normal       ||          ||
+ ||    0     ||    A/F        || normal       ||          ||
+ ||    1     ||    A          || base-deleted ||    B     ||
- ||    2     ||    B/F        || base-deleted ||          ||
+ ||    1     ||    A/F        || base-deleted ||          ||
+ ||    1     ||    B          || normal       ||          ||
+ ||    1     ||    B/F        || normal       ||          ||
+ ||    2     ||    B/F        || base-deleted ||    B/G   ||
  ||    2     ||    B/G        || normal       ||          ||
  
- We end up with two moves recorded A->B and A/F->B/G.  We don't record B/F->B/G.
+ Alternatively, move A/F to A/G and then A to B
+ 
+ || op-depth || local-relpath || presence     || moved-to ||
+ ||    0     ||    A          || normal       ||          ||
+ ||    0     ||    A/F        || normal       ||          ||
+ ||    2     ||    A/F        || base-deleted ||   A/G    ||
+ ||    2     ||    A/G        || normal       ||          ||
+ 
+ || op-depth || local-relpath || presence     || moved-to ||
+ ||    0     ||    A          || normal       ||          ||
+ ||    0     ||    A/F        || normal       ||          ||
+ ||    1     ||    A          || base-deleted ||    B     ||
+ ||    1     ||    A/F        || base-deleted ||          ||
+ ||    1     ||    B          || normal       ||          ||
+ ||    1     ||    B/F        || normal       ||          ||
+ ||    2     ||    B/F        || base-deleted ||    B/G   ||
+ ||    2     ||    B/G        || normal       ||          ||
+ 
+ The final database state is the same independent of the order of the moves.  The second
move in the second case causes the explicit moved-to associated with A/F to be removed.
+ 
+ = Copy compared to Move =
  
  Now consider copying A instead of moving it, so copy A to C then move C/F to C/G.
  
@@ -120, +144 @@

  ||    2     ||    C/F        || base-deleted ||   C/G    ||
  ||    2     ||    C/G        || normal       ||          ||
  
- There is only one move recorded C/F->C/G.
+ There is only one move recorded C/F->C/G.  The move inside the copy is recorded in a
similar way to the move inside a move.
  
- It would be possible to both of these in the same working copy, either A to C then A to
B, or A to B then B to C and we end up with three moves recorded A->B, A/F->B/G and
C/F->C/G. There is an inconsistency, we record C/F to C/G but not B/F to B/G. Does this
matter? Perhaps it is wrong to record A/F->B/G, perhaps we should be recording B/F->B/G
instead?
- 
- If we recorded moves-in-moves within the move, the above move A to B and B/F to B/G would
look as follows:
- 
- || op-depth || local-relpath || presence     || moved-to ||
- ||    0     ||    A          || normal       ||          ||
- ||    0     ||    A/F        || normal       ||          ||
- ||    1     ||    A          || base-deleted ||  B       ||
- ||    1     ||    A/F        || base-deleted ||          ||
- ||    1     ||    B          || normal       ||          ||
- ||    1     ||    B/F        || normal       ||          ||
- ||    2     ||    B/F        || base-deleted ||  B/G     ||
- ||    2     ||    B/G        || normal       ||          ||
- 
- 
- This would involve rewriting the moves inside A when A is moved to B.
- 
- The DB state should be independent of the order of moves. We not care about the order in
which moves were performed, only about the resulting state. So the end result should be the
same for both "A -> B; B/F -> B/G;" and "A/F -> A/G; A -> B";
- 
- The first case, A -> B; B/F -> B/G, is shown above.
- 
- For the second sequence we would need transitions between the following states:
- 
- || op-depth || local-relpath || presence || moved-to ||
- ||    0     ||    A          || normal   ||          ||
- ||    0     ||    A/F        || normal   ||          ||
- 
- Move A/F -> A/G
- 
- || op-depth || local-relpath || presence     || moved-to ||
- ||    0     ||    A          || normal       ||          ||
- ||    2     ||    A/F        || base-deleted ||   A/G    ||
- ||    2     ||    A/G        || normal       ||          ||
- 
- Move A -> B
- 
- || op-depth || local-relpath || presence     || moved-to ||
- ||    0     ||    A          || normal       ||          ||
- ||    0     ||    A/F        || normal       ||          ||
- ||    1     ||    A          || base-deleted ||  B       ||
- ||    1     ||    A/F        || base-deleted ||          ||
- ||    1     ||    B          || normal       ||          ||
- ||    1     ||    B/F        || normal       ||          ||
- ||    2     ||    B/F        || base-deleted ||  B/G     ||
- ||    2     ||    B/G        || normal       ||          ||
- 
- So when moving a tree which contains moves, we must clear moved-to information for moved
nodes within the delete-half of the move,
- and add the corresponding path-adjusted moved-to information within the add-half of the
move. The nested moves also become their own op-roots within the copied-half.
- 

Mime
View raw message