The WC’s main job is to compose a new revision.
While the WC also supports merge conflict resolution, a mixed-revision base state, commit of selected parts, and many other additional features, the fundamental purpose of the WC is to help the user prepare, review and commit a set of changes which will create a new revision in the repository.
On the repository side is a similar but simpler mechanism. The FS “transaction” API, designed for programmatic rather than human users, allows the system to prepare and commit a set of changes built upon an existing revision, and commit the result as a new revision.
It is really quite important that WC modifications and FS transactions have exactly compatible semantics for the changes that they represent.
It is really quite important for the feasibility of writing higher level code such as shelving, that WC modifications can be read and written by a common, abstract, interface. That is, an interface definition which enables a ‘copy’ function to plug an input interface to an output interface and push all the changes through the pipe.
To better support these needs, changes in the WC should share an API with changes in the repository.
- WC mods API := (basic changes API) + (lots of WC-specific API)
- FS txn API := (basic changes API) + (some FS-specific API)
Is this such a crazy idea?
There are two levels at which we can perform this API refactoring. First, streamy changes via the delta editor API. The repository side already has a commit editor for input and a ‘replay’ edit-driver for output of the changes in one revision. The WC already has a commit edit-driver for output, but no editor for receiving modifications. It needs one.
Second, underneath the delta editor APIs on the FS side is a random-access API for reading and writing the modifications in a transaction: ‘txn_vtable_t’. On the WC side we should be able to use the same API as a base, minus the few FS-specific bits, and extended with lots of WC-specific features.
The common APIs for basic changes could be:
- basic changes API (streamy): delta-editor.
- basic changes API (random-access): most of root_vtable_t.
Also the WC base layer corresponds to the base revision of a FS transaction, again with a lot of WC-specific extensions. Again, common APIs should be used as the base API for reading and writing that base, extended by a WC-specific companion API. In the FS API, the same vtable is used for a rev-root as for a txn-root; each method that does not make sense on a revision returns an error at run-time. In the WC, the base layer is modifiable, albeit with its own semantics.
The common APIs for the WC base layer and the FS txn base revision could be:
- basic base-layer API (random-access): most of root_vtable_t.
There are more parts to talk about: streamy base-layer creation (‘checkout’), WC-shape/layout/viewspec API, and so on, but let’s start here.
WC streamy input/output editor APIs
- WC replay delta
- drives a delta-editor, like ‘commit’ does
- thin wrapper around ‘harvest_committables’ and ‘svn_client__do_commit’
- will be used for ‘shelve’
- WC replay wc metadata
- transmits WC-specific local-mods metadata
- a streamy companion to wc-replay-delta
- WC delta editor
- receives and applies modifications into the WC local-mods
- expects unmodified WC states: no merging except trivial A-or-B merges
- write from scratch
- will be used for ‘unshelve’
- use it for all existing WC modification ops (‘svn add’, ‘svn propset’, etc.)
- what special features does it need, that existing ops expect?
- add those features in wrappers where possible, else internally
- WC-specific metadata editor
- applies WC-specific local-mods metadata
- a streamy companion to WC delta editor
Definition of WC-specific local-mods metadata API:
- includes: conflicts, missing/obstructed, …
I am starting with this streamy I/O layer because I can use it to improve shelving.
The “WC replay delta” is simple and about ready to commit. Implementation of the “WC delta editor” is in progress. I will now look into designing the streamy WC metadata APIs.