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