Philip Martin wrote:

> Julian Foad <julianf...@btopenworld.com> writes:
>>  Philip Martin wrote:
>>>  There is a related issue with mixed-revision working copies.  Suppose A
>>>  gets moved to B in some commit.  A mixed-revision working copy could
>>>  contain both A and B so what does the update that includes that commit
>>>  do?  I suppose the server still sends some sort of "move A B" operation
>> 
>>  Yes.  That's this scenario:
>> 
>> <https://wiki.apache.org/subversion/MoveDev/MoveTrackingUpdateEditor#One_Move.2C_One_Non-Move>.
>> 
>>    WC: (A@10, B@20); repo: (r10: mkdir A; r20: mv A B)
>>    Update to r20; A moves to B, and also the existing B is updated.

Oops, that should be update to r30, and assume that there are changes in each 
commit as well as the move, because I want to demonstrate that there are two 
different sets of incoming changes when we update.

>>  and the steps would be:
>> 
>>    move away A; move to B (original A)
>>    delete B  # move-away
>>    add B (copy-from ... A)  # move-here: it conflicts
> 
> Not sure I follow that, we don't want to delete B as it may have local
> mods and the final B is the same node so those mods should be preserved.

Notation.  I was using the notation of sending the move info in a separate 
prefix and then using the existing "delete" and "add-with-copy" instructions to 
actually execute the "move-away" and "move-here" operations respectively.

Nevertheless, you bring up a good problem.  I agree "we" (the client) quite 
likely do not want to delete B in such a case; the most likely conflict 
resolution we'd choose would be to merge the local mods from A into those in B. 
 But I was trying to envision an edit driver in the server that does not make 
that decision but rather sends commands for each of the two original paths 
separately and lets the receiver (client) decide how to handle the conflict.

However, I see the problem with that.  There is no sane way for the driver to 
describe both the move from A to B and the update to the original B in the same 
edit drive.

Switching to Ev1.5 notation with "move-away" and "move-here" as first class 
operations, as described in 
<http://wiki.apache.org/subversion/MoveDev/Ev15MovesDesign#Specification>, the 
move from A to B would be:

  rename(A,B)
  [edits in B, relative to original *A*]
  close-directory(B)

and the update to the original B would be:

  open-directory(B)
  [edits in B, relative to original *B*]
  close-directory(B)

I suppose the edit driver *could* just send both sets of instructions, one 
after the other, but that's pretty severely overloading the editor definition.  
It likely would not play nicely with lazy/late closing of the directories, 
which I think we do these days.

The alternative is for the merging (and conflict resolution?) to happen 
earlier.  Is that feasible?  In the server where it receives a report of the WC 
base state and drives the editor, perhaps?


> A current Ev1 drive would be:
> 
>     delete A
>     open B
>     change_prop B
>     close B

Right.  Note that here the changes in B are expressed relative to the 
pre-existing 'B' base state.

> For the Ev1+ drive we add move and drop the "delete A" and "open 
> B":
> 
>     move away A id=1
>     move here id=1 B
>     change prop B
>     close B

Well, now,  are you thinking that the "move here" operation just conveys a 
semantic intent but does not actually do anything to B, and then editor 
expresses the necessary changes in B relative to the existing base state at 
path B (^/B@20); or that the "move here" executes a move (or copy) of the base 
state in the WC and expresses the changes relative to that state (^/A@10)?  It 
matters -- they're different sets of changes.

> However if B did not exist in the initial working copy the Ev1 drive
> would be different:
> 
>     delete A
>     add B
>     change_prop B
>     close B

Agreed.

> but with Ev1+ we would get the same sequence.  So it appears that "move
> here" is somehow replacing both open and add.  The driver can
> distinguish these cases and I think it should be telling the receiver.

My definition in the Wiki has "move-here" meaning to actually move the 
referenced base state to the target path, and any following edits will be based 
on that new state.

(I can't usefully respond to the remainder below until we get more precise in 
our notation.)

- Julian


>>>  but we may want the server to tell the client that B is not being
>>>  replaced.
>> 
>>  That happens naturally.  If B is being replaced by the moved A:
>> 
>>    WC: (A@10, B@10); repo: (r10: mkdir A B; r20: delete B; mv A B)
>>    Update to r20; A moves to B, replacing the previous B.
>> 
>>  then the server would include an additional "delete A" step:
>> 
>>    move away A; move to B (original A)
>>    delete B  # move-away
>>    delete A
>>    add B (copy-from ... A)  # move-here: it conflicts
> 
> There are 3 cases:
> 
>     1)  A moved to B where B does not exist
>     2)  A moved to B where B exists and is the same node
>     3)  A moved to B where B exists but is a different node
> 
> 1 and 2 are the cases above.  For 3 the current Ev1 drive would be:
> 
>     delete A
>     delete B
>     add B
>     change prop B
>     close B
> 
> I suppose the Ev1+ drive might be something like:
> 
>     move away A id=1
>     delete B
>     move here id=1 B
>     change prop B
>     close B
> 
> In this case local mods to B would cause a tree-conflict due to the
> delete/replace.
> 
> It might be interesting to see how Ev2 would handle these 3 cases.
> 
>     1)  A moved to B where B does not exist
> 
>     alter dir ., children=A,B
>     move A B, replaces_rev=-1
>     alter B
> 
>     2)  A moved to B where B exists and is the same node
> 
>     alter dir ., children=A,B
>     move A B, replaces_rev=-1
>     alter B
> 
>     3)  A moved to B where B exists and is a different node
> 
>     alter dir ., children=A,B
>     move A B, replaces_rev=N
>     alter B
> 
> Ev2 distinguishes between add and replace via the replaces_rev flag but
> as with Ev1+ the driver knows about the difference between 1 and 2 but
> doesn't communicate it to the receiver.

Reply via email to