blob: cc29ab5f02c2d766b0788e7f9da48815bd8ab2c6 [file] [log] [blame]
** Proposed new commit system **
Purpose:
1. [speed] Detect conflicts early: without ever seeing a bit of
svndiff data
2. [speed] Less merging: always merging against head.
3. [speed] Zero undeltification: detect conflicts without having
to undeltify directories.
4. [theory] Unified commit-system across RA implementations;
guarantees that "Hudson" scenarios will consistently work.
Status Quo:
The first two advantages listed above are already being achieved by
ra_dav in its own way, so for a long time the 3rd point was our
motivating force. However, because undeltification isn't so
horrible anymore, we've prioritized this task as Beta.
But now point #4 has come into play; as long as we put off this
task, ra_dav will have two theoretical deficiencies:
* to replace a file, the user must {delete, add, commit}. If
the user attempts to {delete, commit, add, commit}, the second
commit will fail.
* unable to prevent users from committing propchanges on
out-of-date dirs. Thus users could end up with working copies
containing dirs whose revision numbers are incorrect.
Another TODO:
We would like to get rid of the ghudson-scenario 'deleted' existence
flag in the working copy. It makes the commit-crawler insanely
complex.
Here's how:
- 'deleted' flag is only needed in the commit case, because the
crawler is assuming that it's building a perfect mirror of the
working copy on the server (which is true with ra_local).
After our commit process is always merging against HEAD
on-the-fly, we no longer need to send extra delete commands.
- 'deleted' flag is used during updates, where we really *are*
always building a perfect mirror of the working copy on the
server. But we don't *have* to build a perfect mirror; if we
left out the extra deletes, then dir_deltas will send us back
an extra delete. This isn't a problem if we make the update
editor treat an 'extra' delete as a no-op!
-----------------------------------------------------------------------
Key: HEAD := the latest revision number in the repository
NRID := Node-Rev-ID of some object in HEAD revision
CR := Created Revision; the revision in which NRID was created
--
Editor: RA->get_commit_editor()
ra_local: Fetches editor from libsvn_repos, composes with tracking editor.
ra_dav: Has own editor, composes with tracking editor.
Creates a transaction (MKACTIVITY) based on HEAD. (### too early!)
Sets the log message on the transaction:
(CHECKOUT baseline; PROPPATCH baseline)
new system: ?
--
Editor: set_target_revision (rev)
comment: [Not used by the commit driver. This is for updates.]
---
Editor: replace_root (rev)
ra_local: Creates a transaction based on REV.
ra_dav: Ignores REV; gets versioned-resource-url from working copy.
new system: Creates a transaction based on HEAD.
--
Editor: add_directory/file (name, copyfrom_path, copyfrom_rev)
ra_local: Normally calls fs_make_dir() or fs_make_file().
If copyfrom args, then fs_copy() instead.
ra_dav: CHECKOUT parent into activity.
if dir, MKCOL. (could return out-of-date error?).
if file, do nothing.
(--> currently ignores copyfrom) (### bad)
new system: look up path in transaction (HEAD)
if path exists already, return out-of-date error.
else:
do what ra_local does.
--
Editor: replace_file/dir (name, rev)
ra_local: If REV != parent's rev, fs_link() the different file into
the transaction.
ra_dav: Ignores REV.
If dir, just telescope the baton's path.
If file, CHECKOUT the file/dir into the activity.
(could return out-of-date error?)
new system: look up the path in the transaction (HEAD).
if path non-existent, return out-of-date error.
else: (### ?file only?)
get CR of path, by examining path's NRID.
if (REV < CR), return out-of-date error.
if (CR <= REV <= HEAD), do nothing, all is good.
--
Editor: delete_entry (name)
ra_local: Calls fs_delete_tree().
ra_dav: CHECKOUT parent into activity.
DELETE object. (### this should not return an out-of-date error)
new system: look up the path in the transaction (HEAD).
if path non-existent, go home. (merge allows this)
else:
get CR of path, by examining path's NRID.
if (REV < CR), return out-of-date error.
if (CR <= REV <= HEAD), remove the object from the transaction.
--
Editor: apply_textdelta ()
ra_local: returns window handler from fs_apply_textdelta().
ra_dav: returns window handler that writes to tmp file.
when stream is closed, do a PUT of the file
(could return out-of-date error?)
new system: ?
--
Editor: change_file/dir_prop (name, val)
ra_local: Calls fs_change_node_prop()
ra_dav: CHECKOUT the object.
Cache the propchange.
new system: ?
--
Editor: close_file/dir ()
ra_local: frees batons.
ra_dav: Send cached propchanges via PROPPATCH.
new system: ?
--
Editor: abort_edit ()
ra_local: Calls fs_abort_txn()
ra_dav: Non-existent!!! (### bad)
new system: ?
--
Editor: close_edit ()
ra_local: Calls fs_commit_txn(). All conflicts are found at this time.
If merge works, then (selectively) bumps revisions.
ra_dav: Sends MERGE request: "please merge this activity"
mod_dav_svn calls fs_commit_txn().
mod_dav_svn runs dir_delta() on new revision to generate response.
ra_dav parses response and (selectively) bumps revisions/wcprops.
new system: ?