Here is a method to communicate moves over an svn_delta_editor_t edit drive.
It requires modifying the sender and the receiver but uses the existing editor protocol. It requires a small amount of extra communication – the list of moves – which may be communicated out of band or carried inside the edit drive (for example, as properties that the consumer recognizes as special).
The aim is for a move-aware producer to be able to drive a move-unaware consumer and vice-versa.
It assumes:
- A depth-first tree walk.
- Nodes identified by path alone (no node ids).
- The only tree-change operations are:
- add node
- copy subtree (from ... [1])
- delete subtree.
- A way to communicate the moves.
- No additional ordering requirements.
This method can probably be adapted to other editors such as svn_wc_diff_callbacks_t.
Basic Method
- Producer sends the "from" and "to" paths of each move, before or during the corresponding "delete" and "copy" operations.
- When the consumer sees a "delete" that corresponds to a move:
- It does not perform a delete.
- If necessary (to allow a subsequent replacement), it moves the path to a temporary location and keeps track of it.
- When the consumer sees a "copy" that corresponds to a move:
- It performs a move from the "move-from" path.
- It applies any modifications.
Example
Starting from:
/ +-- A/ +--foo
Rename 'A' to 'B':
/ +-- B/ +-- foo
Where the copy and the delete are in the same directory, so our present edit producers send the 'del' before the 'copy'.
Old sequence (assuming del before cp):
- del A
- cp B from A@10
- modify-props B
- ?? cp B/foo from A/foo@10
New sequence (assuming del before cp):
- moves = [A -> B ]
- Tells us just the move-root path-pairs
- del A
- Move 'A' to a temporary location (in case a replacement arrives)
- cp B from A@10
- Move temp-A to B. Assert cp-from matches.
- modify-props B
- ?? cp B/foo from A/foo@10
- Is it a move-root? No.
- Is it a move-child? Yes. Assert cp-from matches.