Philip Martin wrote on Thu, Jun 27, 2013 at 10:16:22 +0100: > Philip Martin <[email protected]> writes: > > > Philip Martin <[email protected]> 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()). >

