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