Hyrum, This fixes all tests except for blame 7 [on the ev2-export branch].
There is a potential hole, noted in the comments which I may try to write a test for. Cheers, -g On Fri, May 18, 2012 at 4:47 PM, <gst...@apache.org> wrote: > Author: gstein > Date: Fri May 18 20:47:43 2012 > New Revision: 1340245 > > URL: http://svn.apache.org/viewvc?rev=1340245&view=rev > Log: > Improve the detection of whether a node can be created at a given path. > > Specifically, if the path represents a child from an ancestor's copy, > move, or rotate, then we should allow further changes to that child. > Since the child is uncommitted, the REPLACES_REV will be > SVN_INVALID_REVNUM. > > * subversion/libsvn_fs/editor.c: > (can_create): update docstring. add ancestor checks for *-here ops. > > Modified: > subversion/trunk/subversion/libsvn_fs/editor.c > > Modified: subversion/trunk/subversion/libsvn_fs/editor.c > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs/editor.c?rev=1340245&r1=1340244&r2=1340245&view=diff > ============================================================================== > --- subversion/trunk/subversion/libsvn_fs/editor.c (original) > +++ subversion/trunk/subversion/libsvn_fs/editor.c Fri May 18 20:47:43 2012 > @@ -34,6 +34,8 @@ > > #include "fs-loader.h" > > +#include "private/svn_fspath.h" > + > > struct edit_baton { > /* The transaction associated with this editor. */ > @@ -269,21 +271,56 @@ can_modify(svn_fs_root_t *txn_root, > > > /* Can we create a node at FSPATH in TXN_ROOT? If something already exists > - at that path, then the client is out of date. */ > + at that path, then the client MAY be out of date. We then have to see if > + the path was created/modified in this transaction. IOW, it is new and > + can be replaced without problem. > + > + Note: the editor protocol disallows double-modifications. This is to > + ensure somebody does not accidentally overwrite another file due to > + being out-of-date. */ > static svn_error_t * > can_create(svn_fs_root_t *txn_root, > const char *fspath, > apr_pool_t *scratch_pool) > { > svn_node_kind_t kind; > + const char *cur_fspath; > > SVN_ERR(svn_fs_check_path(&kind, txn_root, fspath, scratch_pool)); > - if (kind != svn_node_none) > - return svn_error_createf(SVN_ERR_FS_OUT_OF_DATE, NULL, > - _("'%s' already exists, so may be out" > - " of date; try updating"), > - fspath); > - return SVN_NO_ERROR; > + if (kind == svn_node_none) > + return SVN_NO_ERROR; > + > + /* ### I'm not sure if this works perfectly. We might have an ancestor > + ### that was modified as a result of a change on a cousin. We might > + ### misinterpret that as a *-here node which brought along this > + ### child. Need to write a test to verify. We may also be able to > + ### test the ancestor to determine if it has been *-here in this > + ### txn, or just a simple modification. */ > + > + /* Are any of the parents copied/moved/rotated-here? */ > + for (cur_fspath = fspath; > + strlen(cur_fspath) > 1; /* not the root */ > + cur_fspath = svn_fspath__dirname(cur_fspath, scratch_pool)) > + { > + svn_revnum_t created_rev; > + > + SVN_ERR(svn_fs_node_created_rev(&created_rev, txn_root, cur_fspath, > + scratch_pool)); > + if (!SVN_IS_VALID_REVNUM(created_rev)) > + { > + /* The node has no created revision, meaning it is uncommitted. > + Thus, it was created in this transaction, or it has already > + been modified in some way (implying it has already passed a > + modification check. */ > + /* ### verify the node has been *-here ?? */ > + return SVN_NO_ERROR; > + } > + } > + > + return svn_error_createf(SVN_ERR_FS_OUT_OF_DATE, NULL, > + _("'%s' already exists, so may be out" > + " of date; try updating"), > + fspath); > } > > > >