One of the limitations I am hitting on shelving is inconsistent API for sending 
modifications from and to a WC.

The APIs need to support complete WC changes including multi-layered copy 
operations.

For getting changes out of the WC, what better API than the one we use to 
commit? That necessarily supports all committable changes, and it includes the 
copy-from info relating to multi-layered copies.

We could direct this 'commit' output to places other than the repository:

* 'commit' to a shelf -- even perhaps implemented as a small real FSFS inside 
the WC metadata area, initialized to match the base state of the WC; or

* 'commit' to another WC, duplicating the state of one WC into another WC:
  - first set up WC2 with the same WC base state:
    "svn viewspec export WC1 | svn viewspec import WC2"
  - then duplicate the changes from WC1 into WC2
    drive the 'commit' API from WC1 connected to a 'receiver' API of WC2

What is the 'commit receiver' WC API? It doesn't exist yet. It would be another 
delta-editor API, and it needs to make changes to the WC working state rather 
like 'merge' does, except merge does not try to recreate the source branch's 
copies in the target WC.

Merge uses the svn_ra_do_diff3() as a diff source, and this sends no copyfrom 
info. Merge converts each incoming add to be recorded in the WC as a copy from 
the merge source, but that is only a single flat subtree for each incoming 
added subtree. By contrast, what we need is when an incoming copied subtree 'A' 
(copy-from pathA@rA) contains another copied sub-subtree 'A/B' (from pathB@rB), 
we need to layer both copies in the WC. Not terribly hard: just the same as if 
we manually ran "svn cp URL_A@rA A; svn cp URL_B@B A/B".

The benefit of designing this second thing -- this featurette to duplicate 
changes from WC1 to WC2 -- is not that it has any current practical use, but 
that it would testably prove the two-way API, without needing to build any 
shelf storage infrastructure behind it. Once that is stable, we could use these 
APIs to build better shelving.

On the 'changes in to WC' side, I might start by:
- extracting the diff-and-apply functionality from the 'merge' code;
- asking it to call svn_ra_do_switch() instead of _diff() in order to get 
copyrom info sent;
- making the delta-editor-to-diff-processor conversion pass copyfrom info 
along, in libsvn_client/repos_diff.c;
- making merge_dir_added() and merge_file_added() perform a repo-to-WC copy 
when copyfrom is present.

On the 'changes out from WC' side, I might start by:
- extracting the basic 'drive a commit' functionality from the 'commit' code;
- that's it.

-- 
- Julian

Reply via email to