Philip Martin wrote on Thu, Jun 27, 2013 at 10:16:22 +0100:
> Philip Martin <philip.martin_at_wandisco.com> writes:
>
> > Philip Martin <philip.martin_at_wandisco.com> writes:
> >
> >> I can't see any way to do the 9-node change without using temporaries.
> >
> > I think we can reduce the 9 nodes to 6 and still see the problem:
>
> Even 3 nodes is a problem. Start with A, A/B and A/B/C and swap A and
> A/B/C. There are two ways user can do this:
>
> svn mv A <tmp>
> svn mv <tmp>/B/C A
> svn mv <tmp>/B A/B
> svn mv <tmp> A/B/C
>
What if you just delete A, instead of moving it to A/B/C?
svn mv A tmp
svn mv tmp/B/C A
svn mv tmp/B B
svn rm tmp
svn ci
You still have the problem that you can't move B to its new place: you
can't move it under C before C is moved because it'd be a child of
itself; you can't move it under C after C is moved because at that point
"A/B" doesn't exist in the being-edited tree; and you can't move it
aside and move it back because that would be a "temporary name" which is
not allowed.
> or
>
> svn mv A/B/C <tmp>
> svn mv A/B <tmp>/B
> svn mv A <tmp>/B/C
> svn mv <tmp> A
>
> and the commit looks like:
>
> r2 | pm | 2013-06-27 09:51:56 +0100 (Thu, 27 Jun 2013)
> Changed paths:
> R /A (from /A/B/C:1)
> A /A/B (from /A/B:1)
> R /A/B/C (from /A:1)
> D /A/B/C/B
>
> I don't see how Ev2 represents this. If we do rotate(A,A/B/C) that
> leaves just one other node A/B. When/where does Ev2 move it? If we
> look at how the user did it then we see the move of A/B happens in the
> middle of the rotate and not before or after.
I don't see how rotate(A, A/B/C) has a defined meaning when
A/B/C/B does not exist.
It seems we need to change the Ev2 API. Have you thought of a new API
that is able to represent this three-nodes example?
>
My own answer to "how to change Ev2 to enable representing rotate(A,A/B/C)":
I think the above means we have to modify move() to use SRC arguments
relative to the start state of the edited tree, rather than to its
current state. If we do that, we could represent your commit as:
mv(A/B/C, A); mv(A/B, A/B); mv(A, A/B/C);.
While we're making changes, I wonder if we should nuke rotate(). I have
several reasons:
- It appears to be more focused on *how* the change was made than on
what is in the result tree right now. (The way I think of an editor
is something that describes the target tree in terms of the source
tree, not something that describes how to manipulate the source tree
in order to get the target tree.)
- It takes N target arguments, so pushes a lot of complexity into the
consumer implementation of rotate(). (ref. my 9-node example)
- It affects 2 distinct parts of the tree in one operation. (ref. the
above 3-node example)
- There is a simple replacement: N move() calls. A two-node swap is
perfectly possible (and obeys the Once Rule) if we accept that the
first argument to move() is relative to the base state. (Yes, the
consumer would have to keep state to ensure that both parts of the
move are done, but that's already the case for alter_directory() of
the parent of a move destination.)
In fact, the way I think of an editor is something that does
a (generally) preorder walk of the target tree and describes
everything it sees which is not the same as the corresponding thing
in the source tree (including additions and omissions). under that
view, a rotate(X,Y,Z) call would become three move() alls, each of
them interspersed into the tree walk at the appropriate point (sorted
by the DST argument move()).
>
Received on 2013-06-27 12:07:11 CEST