== Towards using a Delta Editor to get changes into and out of WC ==

I wanted to find out about the options for using a standard interface to 
transfer local modifications from the WC to a shelf and from a shelf to the WC. 
Therefore I studied the svn_delta_editor_t, as this is known to be functionally 
complete. (Earlier I looked at the svn_diff_tree_processor_t, and this seems 
not to be ready for such a task.)

svn_delta_editor_t is used widely throughout Subversion but not consistently. 
In particular, handling of copy source ('copyfrom') is inconsistent.


=== Copy-from in a commit ===

A WC working state is a place for preparing a commit -- a single new revision. 
The new revision will be built from the changes specified by the WC, through a 
delta editor. One of the possible changes is 'add with history', with copyfrom 
revision and path parameters to specify the backward-pointing line of history 
for that node. When the commit is finalized, it will be based on a repository 
revision that is newer than (or equal to) the copy source revision of any 
added-with-history subtree. It is the repository's job (I assume) to enforce a 
valid copy source, where a node of the right kind already existed.

The WC commit editor driver therefore sends copyfrom info, and the repository 
commit editor receives copyfrom info, in order for the repository to link a 
copied node to its line of history.


=== Copy-from sent to the client ===

In the other direction, we have several editor implementations for sending 
changes from repository to client:

  * do_diff   / diff editor
  * do_status / status editor
    - using 'reporter'; no copyfrom info

  * do_update / update editor
  * do_switch / switch editor
    - using 'reporter'; optional weak copyfrom info (see below)

  * replay (one revision at a time)
    - sends full copyfrom info (see below)

The 'do_diff' functionality can be used to diff any pair of locations in the 
repository. (Actually, using the reporter to describe the left-hand side, it 
can compare any mixed tree on the left-hand side with any single tree on the 
right-hand side.) The change that it describes does not necessarily represent 
the construction of one revision from the previous revision. Information about 
the line of history of each node in the right-hand-side tree is rather 
incidental. For example, it is not fundamentally more interesting than the 
history of the left-hand-side tree, and knowing the backward history 
connections is not fundamentally more interesting than knowing the forward 
connections. In contrast, 'commit' fundamentally can only create backward 
connections from the new nodes.

'do_status' is meant to provide a cheap preview of 'do_update' and/or 
'do_switch', AFAIK; I am not considering it further here.

'do_update' and 'do_switch' are not concerned with history connections. They 
only need to provide a new base layer for the WC, containing a snapshot of 
content but not history connections. Bear in mind that update and switch can go 
backward in time as well as forward.


=== Why do update and switch have optional weak copyfrom? ===

Was this added in an attempt to transmit 'move' information to the update 
editor?

There is a big difference between a (backward pointing) history connection in 
the repository and a "move" modification. A "move" modification has to be 
understood in the context of the modification being studied -- the left and 
right sides of a diff.


=== Other editors that send/receive copyfrom ===

'copy' command
svnmucc
svnrdump load
svnsync
  - these send copyfrom (as a full URL) to commit editor

ra_serf/update.c
  - uses copyfrom to select a base file version for delta
  - passes any copyfrom through to the update editor
  - the update editor asserts that no copyfrom shall ever arrive
    (svn_wc__get_update_editor/svn_wc__get_switch_editor)

svnrdump dump
  - calls svn_ra_do_update3(send_copy_from_args=False) for
    the initial full revision (if not 'incremental')
  - then expects to receive copyfrom info (files and dirs)
    so it can write out a complete dump record
  - ### it won't receive any copyfrom so will write a broken
    initial full revision record :-(


=== Sending 'copyfrom' to svn_delta_editor_t ===

I found the following sending of 'copyfrom' arguments:

Client commit editor (do_item_commit()):
  - sends copyfrom for both dirs and files,
  - fully with nesting (as is required for a commit).

svn_repos_begin_report3(send_copy_from_args=True):
  - sends copyfrom to editor->add_file(),
  - for files only (in "add_file_smartly()"),
  - only when the file itself was the copy root.

RA-local/serf/svn driving svn_repos_begin_report3():
  - do_diff, do_status: send_copy_from_args=False;
  - do_update, do_switch: send_copy_from_args is optional.

Callers of svn_ra_do_update|switch():
  - none request send_copyfrom_args.

svn_repos_replay2():
  - sends copyfrom for both dirs and files,
  - fully with nesting (as is required for 'svnsync')

svn_repos_dir_delta2():
  - doesn't send any copyfrom;
  - this function is almost obsolete anyway.


== Conclusions and Actions ==

To get a copyfrom-delta out of WC, use the "commit" code:
  -> decouple the delta-sending part from the repository-aware part
     of client "commit"
  -> write features that perform a "commit" from WC to other existing
     delta editors (useful for testing, at least; maybe for users too):
     - "commit to dumpfile"

To get a copyfrom-delta into a WC as working modifications:
  -> write a WC modifications editor (receiver)
  -> write features that push modifications into a WC:
     - copy the mods from one WC into another
     - pull a single rev from a repo into the WC
  -> write round-trip testing using these facilities

No current caller of svn_ra_do_update|switch requests sending copyfrom. If any 
third-party code does, it only gets copyfrom in very limited cases. So,
  -> can the 'send_copy_from_args' option be deprecated, server-side?
  -> this API option should be deprecated, client-side;
  -> the ra_serf update code using copyfrom should be removed
     (following r998193 which removed its last use)

Test and fix svnrdump dump (initial full revision):
  -> test whether it works -- presumably not
  -> write more thorough tests, e.g. run it alongside 'svnadmin dump'
     'everywhere' and compare their outputs
  -> fix it


-- 
- Julian

Reply via email to