[Please don’t start polluting the database with unknown consequences as a quick fix.]
A mixed mode move *is* a copy with replacements, as it always was. It is nice if we can make it work nicer as part of resolving ut we shouldn’t make the rest of the wc library much harder to maintain as a consequence. I don’t see a problem if ‘svn’ warns when you do this, but some api users can’t do this without breaking usability. You aren’t ‘working on subversion’ when your IDE performs a refactoring for you. And you don’t want to break a refactoring half way. A few weeks ago I proposed updating the database to exactly that move with replacements on the first update step. This adds the nodes that were not added by the initial move (aka the copy) in the op-depth of the move. From that point the normal status api will exactly report the replacements that will happen when committing. (Before adding those nodes the replacements would also happen, but you would only see them after the commit) After that initial step we can help the users who got themselves in this situation (by moving from a mixed revision working copy) by trying to remove as much of those replacements as possible. In many cases it will only be the revision number that has changed. But in these cases we have two NODES layers on top of each other with the same repos_id and repos_relpath where the top one has a moved-from set. We can then -as part of the same sql transaction, or as a different sql transaction- try to eliminate layers as part of the conflict resolving. This might involve text and property merges and in some cases installing new conflicts. We can than remove the shadowing. Putting everything into a single layer ‘as a quick fix’ makes these options unavailable, as you no longer have access to both versions. It also complicates committing and breaks several revert scenarios that are build on these layers. Bert Huijben Sent from Windows Mail *From:* Philip Martin <philip.mar...@wandisco.com> *Sent:* November 12, 2012 1:24 PM *To:* dev@subversion.apache.org *Subject:* move updating and mixed revisions Stefan and I wanted to get some move updating into 1.8. Our plan was limited to getting some simple cases working but it keeps getting more and more complex as I think about it. The basic plan is as follows: In wc.db a move A-to-B looks like this: op-depth local-relpath presence revision moved-to moved-here 0 normal 3 0 A normal 3 0 A/f normal 3 1 A deleted B 1 A/f deleted 1 B normal 3 1 1 B/f normal 3 1 When update attempts to modify the A tree it changes the op-depth=0 tree and raises a tree-conflict on A stored in the actual node: op-depth local-relpath presence revision moved-to moved-here 0 normal 6 0 A normal 6 0 A/f normal 6 1 A deleted B 1 A/f deleted 1 B normal 3 1 1 B/f normal 3 1 The plan for move updating is that the tree-conflict resolver would merge the changes causing the tree-conflict into the working files and update the B nodes rows. The text/property changes can be derived from the "before" tree (B) and "after" tree (A) as both are present in wc.db. The result is a wc.db without a tree-conflict that looks like: op-depth local-relpath presence revision moved-to moved-here 0 normal 6 0 A normal 6 0 A/f normal 6 1 A deleted B 1 A/f deleted 1 B normal 6 1 1 B/f normal 6 1 Two problems occurred to me over the weekend. First, we have to update the nodes rows even when there is no tree-conflict otherwise the source and destination no longer match. Second, we cannot simply use the trees in wc.db to drive the merge into the working files as we don't know whether A/f@3 and A/f@6 are the same node. In order to merge the changes properly the resolver is going to have to contact the repository (only the tree changes are required, all the content changes are already in the wc.db). The underlying problem is that move only makes sense when source and destination are the same single-revision while update is a node-by-node, interruptable, operation that causes single-revision trees to go through mixed-revision states. Why only single-revision moves? The delete half of a move can only be committed it if is equivalent to HEAD which means the move source has to be single revision (or a mixed-revision where the revisions are equivalent to HEAD). The destination part of a move should be the same revision as the source part otherwise it is not the same object being moved. So mixed-revision moves don't make sense at commit time. Mixed-revision copies are OK, we represent them as a set of nested copies both in the working copy and at commit. In wc.db each copy is a single-revision, single-op-depth copy so the mixed-revision copy is a multiple op-depth copy. Using that representation, even transiently, for mixed-revision moves is hard. It would look more like a single-revision move with nested copies as modifications on top of the move, and any such representation would clash with a user's modifications. I suppose we could introduce a single-op-depth, mixed-revision representation for moves that could be updated in parallel with the single-op-depth, mixed-revision base node layer. I've been trying to avoid that as it means all the working copy code has to become aware that such a representation is valid. The alternative is that we have to handle "broken" moves where the source and destination revision do no match. In the end the user has to update to a committable state so provided we get the move properly updated at that point things should work. So I think a "broken" move has to be stored as a conflict, or detected on the fly, and should cause the commit to be impossible until the move is fixed. This has been a rather rambling email, really I'm trying to get my thoughts in order. -- Certified & Supported Apache Subversion Downloads: http://www.wandisco.com/subversion/download