Branko Čibej <brane_at_wandisco.com> writes:

*> On 24.06.2013 17:52, Branko Čibej wrote:
*

*>> You're breaking the once rule here.
*

*>>
*

*>> And the case you're describing can never occur. You cannot have a
*

*>> working copy that describes what you're doing. Tree mutations can only
*

*>> be parallelized across distinct subtrees, which isn't the case in your
*

*>> example; where the operations interact, they must be sequential or they
*

*>> don't mean anything.
*

*>>
*

*>> Your case is either:
*

*>>
*

*>> A->A2; A2/B -> B2
*

*>>
*

*>> or
*

*>>
*

*>> A/B -> B2; A -> A2
*

*>>
*

*>> which happen to be the two simplest sequences of working copy changes
*

*>> that'll generate your end result.
*

*>
*

*> Add to the mix the "parents before children" rule and only the first
*

*> case remains valid. So we get:
*

*>
*

*> alter_dir . (removes A, adds A2 and B2)
*

*> move A A2
*

*> alter_dir A2 (removes B)
*

*> move A2/B B2
*

*>
*

*> The above sequence does not violate the once rule.
*

What about rotates that overlap. Consider a repository:

svnadmin create repo

svn mkdir -mm --parents file://`pwd`/repo/A/B/C ^/X/Y/Z

Rotate /A and /X/Y/Z and /X and /A/B/C:

svn mv wc/A wc/A2

svn mv wc/X wc/X2

svn mv wc/A2/B/C wc/X

svn mv wc/X2/Y/Z wc/A

svn mv wc/A2/B wc/A/B

svn mv wc/X2/Y wc/X/Y

svn mv wc/A2 wc/X/Y/Z

svn mv wc/X2 wc/A/B/C

This is supported by 1.7 and status shows two pairs swapped (or rotated)

A and X/Y/Z, X and A/B/C. After commit the log looks like:

R /A (from /X/Y/Z:1)

A /A/B (from /A/B:1)

R /A/B/C (from /X:1)

D /A/B/C/Y

R /X (from /A/B/C:1)

A /X/Y (from /X/Y:1)

R /X/Y/Z (from /A:1)

D /X/Y/Z/B

How would Ev2 describe that? Perhaps

rotate(A, X/Y/Z)

rotate(X, A/B/C)

copy(A/B)

copy(X/Y)

delete(A/B/C/Y)

delete(X/Y/Z/B)

The deletes at the end are probably straightforward but will the Ev2

receiver be able to generate a sequence for the rotates and copies?

Where do the alters fit? Your example had an alter(A2) where A2 is the

post-move path, so I can add alters before the deletes:

rotate(A, X/Y/Z)

rotate(X, A/B/C)

copy(A/B)

copy(X/Y)

alter(A/B/C) (the post-rotate A/B/C, i.e. pre-rotate X)

delete(A/B/C/Y)

alter(X/Y/Z) (the post-rotate X/Y/Z, i.e. pre-rotate A)

delete(X/Y/Z/B)

I can do the same for the copies:

rotate(A, X/Y/Z)

rotate(X, A/B/C)

alter(A) (the post-rotate A, i.e. the pre-rotate X/Y/Z)

copy(A/B)

alter(X) (the post-rotate X, i.e. the pre-rotate A/B/C)

copy(X/Y)

alter(A/B/C) (pre-rotate X)

delete(A/B/C/Y)

alter(X/Y/Z) (pre-rotate A)

delete(X/Y/Z/B)

Now the rotates. Do I give alters for the pre-rotate paths or the

post-rotate paths? Perhaps this for the first rotate:

alter(.)

alter(X/Y)

rotate(A, X/Y/Z)

rotate(X, A/B/C)

alter(A) (pre-rotate X/Y/Z)

copy(A/B)

alter(X) (pre-rotate A/B/X)

copy(X/Y)

alter(A/B/C) (pre-rotate X)

delete(A/B/C/Y)

alter(X/Y/Z) (pre-rotate A)

delete(X/Y/Z/B)

What about the second rotate? I don't need another alter(.) but what

about alter(A/B)? The A/B path is affected by the first rotate but I

can't do the first rotate without the second rotate and the copies. So

perhaps I send all the pre-rotate alters before all the rotates:

alter(.)

alter(A/B)

alter(X/Y)

rotate(A, X/Y/Z)

rotate(X, A/B/C)

alter(A) (pre-rotate X/Y/Z)

copy(A/B)

alter(X) (pre-rotate A/B/X)

copy(X/Y)

alter(A/B/C) (pre-rotate X)

delete(A/B/C/Y)

alter(X/Y/Z) (pre-rotate A)

delete(X/Y/Z/B)

Is that the way it is supposed to work?

When the receiver processes these operations it cannot complete the

rotates until it has received the copies. At the end of the drive the

rotates have to be possible but at intermediate steps the receiver

doesn't know whether it has enough operations for the rotates to be

possible. Perhaps the receiver postpones rotates that can't be done and

retries every time a new operation is received?

--
Philip Martin | Subversion Committer
WANdisco | Non-Stop Data
www.wandisco.com

Received on 2013-06-25 13:43:39 CEST