Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 59B7511F08 for ; Mon, 30 Jun 2014 14:09:49 +0000 (UTC) Received: (qmail 44292 invoked by uid 500); 30 Jun 2014 14:09:49 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 44264 invoked by uid 500); 30 Jun 2014 14:09:49 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 44254 invoked by uid 99); 30 Jun 2014 14:09:49 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 30 Jun 2014 14:09:49 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 30 Jun 2014 14:09:43 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 1B70623889FD; Mon, 30 Jun 2014 14:09:17 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1606748 [2/2] - in /subversion/branches/move-tracking-2/subversion: include/private/svn_editor3.h libsvn_delta/editor3.c Date: Mon, 30 Jun 2014 14:09:16 -0000 To: commits@subversion.apache.org From: julianfoad@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20140630140917.1B70623889FD@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Copied: subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c (from r1606692, subversion/branches/move-tracking-2/subversion/libsvn_delta/editor.c) URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c?p2=subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c&p1=subversion/branches/move-tracking-2/subversion/libsvn_delta/editor.c&r1=1606692&r2=1606748&rev=1606748&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_delta/editor.c (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c Mon Jun 30 14:09:16 2014 @@ -28,28 +28,17 @@ #include "svn_pools.h" #include "svn_dirent_uri.h" -#include "private/svn_editor.h" +#include "private/svn_editor3.h" #ifdef SVN_DEBUG /* This enables runtime checks of the editor API constraints. This may introduce additional memory and runtime overhead, and should not be used - in production builds. - - ### Remove before release? - - ### Disabled for now. If I call svn_editor_alter_directory(A) then - svn_editor_add_file(A/f) the latter fails on SHOULD_ALLOW_ADD. - If I modify svn_editor_alter_directory to MARK_ALLOW_ADD(child) - then if I call svn_editor_alter_directory(A) followed by - svn_editor_alter_directory(A/B/C) the latter fails on - VERIFY_PARENT_MAY_EXIST. */ -#if 0 + in production builds. */ #define ENABLE_ORDERING_CHECK #endif -#endif -struct svn_editor_t +struct svn_editor3_t { void *baton; @@ -57,20 +46,15 @@ struct svn_editor_t svn_cancel_func_t cancel_func; void *cancel_baton; - /* Our callback functions match that of the set-many structure, so - just use that. */ - svn_editor_cb_many_t funcs; + /* The callback functions. */ + svn_editor3_cb_funcs_t funcs; /* This pool is used as the scratch_pool for all callbacks. */ apr_pool_t *scratch_pool; #ifdef ENABLE_ORDERING_CHECK svn_boolean_t within_callback; - - apr_hash_t *pending_incomplete_children; - apr_hash_t *completed_nodes; svn_boolean_t finished; - apr_pool_t *state_pool; #endif }; @@ -80,201 +64,45 @@ struct svn_editor_t #define START_CALLBACK(editor) \ do { \ - svn_editor_t *editor__tmp_e = (editor); \ + svn_editor3_t *editor__tmp_e = (editor); \ SVN_ERR_ASSERT(!editor__tmp_e->within_callback); \ editor__tmp_e->within_callback = TRUE; \ } while (0) #define END_CALLBACK(editor) ((editor)->within_callback = FALSE) -/* Marker to indicate no further changes are allowed on this node. */ -static const int marker_done = 0; -#define MARKER_DONE (&marker_done) - -/* Marker indicating that add_* may be called for this path, or that it - can be the destination of a copy or move. For copy/move, the path - will switch to MARKER_ALLOW_ALTER, to enable further tweaks. */ -static const int marker_allow_add = 0; -#define MARKER_ALLOW_ADD (&marker_allow_add) - -/* Marker indicating that alter_* may be called for this path. */ -static const int marker_allow_alter = 0; -#define MARKER_ALLOW_ALTER (&marker_allow_alter) - -/* Just like MARKER_DONE, but also indicates that the node was created - via add_directory(). This allows us to verify that the CHILDREN param - was comprehensive. */ -static const int marker_added_dir = 0; -#define MARKER_ADDED_DIR (&marker_added_dir) - #define MARK_FINISHED(editor) ((editor)->finished = TRUE) #define SHOULD_NOT_BE_FINISHED(editor) SVN_ERR_ASSERT(!(editor)->finished) -#define CLEAR_INCOMPLETE(editor, relpath) \ - svn_hash_sets((editor)->pending_incomplete_children, relpath, NULL); - -#define MARK_RELPATH(editor, relpath, value) \ - svn_hash_sets((editor)->completed_nodes, \ - apr_pstrdup((editor)->state_pool, relpath), value) - -#define MARK_COMPLETED(editor, relpath) \ - MARK_RELPATH(editor, relpath, MARKER_DONE) -#define SHOULD_NOT_BE_COMPLETED(editor, relpath) \ - SVN_ERR_ASSERT(svn_hash_gets((editor)->completed_nodes, relpath) == NULL) - -#define MARK_ALLOW_ADD(editor, relpath) \ - MARK_RELPATH(editor, relpath, MARKER_ALLOW_ADD) -#define SHOULD_ALLOW_ADD(editor, relpath) \ - SVN_ERR_ASSERT(allow_either(editor, relpath, MARKER_ALLOW_ADD, NULL)) - -#define MARK_ALLOW_ALTER(editor, relpath) \ - MARK_RELPATH(editor, relpath, MARKER_ALLOW_ALTER) -#define SHOULD_ALLOW_ALTER(editor, relpath) \ - SVN_ERR_ASSERT(allow_either(editor, relpath, MARKER_ALLOW_ALTER, NULL)) - -#define MARK_ADDED_DIR(editor, relpath) \ - MARK_RELPATH(editor, relpath, MARKER_ADDED_DIR) -#define CHECK_UNKNOWN_CHILD(editor, relpath) \ - SVN_ERR_ASSERT(check_unknown_child(editor, relpath)) - -/* When a child is changed in some way, mark the parent directory as needing - to be "stable" (no future structural changes). IOW, only allow "alter" on - the parent. Prevents parent-add/delete/move after any child operation. */ -#define MARK_PARENT_STABLE(editor, relpath) \ - mark_parent_stable(editor, relpath) - -/* If the parent is MARKER_ALLOW_ADD, then it has been moved-away, and we - know it does not exist. All other cases: it might exist. */ -#define VERIFY_PARENT_MAY_EXIST(editor, relpath) \ - SVN_ERR_ASSERT(svn_hash_gets((editor)->completed_nodes, \ - svn_relpath_dirname(relpath, \ - (editor)->scratch_pool)) \ - != MARKER_ALLOW_ADD) - -/* If the parent is MARKER_ADDED_DIR, then we should not be deleting - children(*). If the parent is MARKER_ALLOW_ADD, then it has been - moved-away, so children cannot exist. That leaves MARKER_DONE, - MARKER_ALLOW_ALTER, and NULL as possible values. Just assert that - we didn't get either of the bad ones. - - (*) if the child as added via add_*(), then it would have been marked - as completed and delete/move-away already test against completed nodes. - This test is to beware of trying to delete "children" that are not - actually (and can't possibly be) present. */ -#define CHILD_DELETIONS_ALLOWED(editor, relpath) \ - SVN_ERR_ASSERT(!allow_either(editor, \ - svn_relpath_dirname(relpath, \ - (editor)->scratch_pool), \ - MARKER_ADDED_DIR, MARKER_ALLOW_ADD)) - -static svn_boolean_t -allow_either(const svn_editor_t *editor, - const char *relpath, - const void *marker1, - const void *marker2) -{ - void *value = svn_hash_gets(editor->completed_nodes, relpath); - return value == marker1 || value == marker2; -} - -static svn_boolean_t -check_unknown_child(const svn_editor_t *editor, - const char *relpath) -{ - const char *parent; - - /* If we already know about the new child, then exit early. */ - if (svn_hash_gets(editor->pending_incomplete_children, relpath) != NULL) - return TRUE; - - parent = svn_relpath_dirname(relpath, editor->scratch_pool); - - /* Was this parent created via svn_editor_add_directory() ? */ - if (svn_hash_gets(editor->completed_nodes, parent) - == MARKER_ADDED_DIR) - { - /* Whoops. This child should have been listed in that add call, - and placed into ->pending_incomplete_children. */ - return FALSE; - } - - /* The parent was not added in this drive. */ - return TRUE; -} - -static void -mark_parent_stable(const svn_editor_t *editor, - const char *relpath) -{ - const char *parent = svn_relpath_dirname(relpath, editor->scratch_pool); - const void *marker = svn_hash_gets(editor->completed_nodes, parent); - - /* If RELPATH has already been marked (to disallow adds, or that it - has been fully-completed), then do nothing. */ - if (marker == MARKER_ALLOW_ALTER - || marker == MARKER_DONE - || marker == MARKER_ADDED_DIR) - return; - - /* If the marker is MARKER_ALLOW_ADD, then that means the parent was - moved away. There is no way to work on a child. That should have - been tested before we got here by VERIFY_PARENT_MAY_EXIST(). */ - SVN_ERR_ASSERT_NO_RETURN(marker != MARKER_ALLOW_ADD); - - /* MARKER is NULL. Upgrade it to MARKER_ALLOW_ALTER. */ - MARK_RELPATH(editor, parent, MARKER_ALLOW_ALTER); -} - #else -/* Be wary with the definition of these macros so that we don't - end up with "statement with no effect" warnings. Obviously, this - depends upon particular usage, which is easy to verify. */ - #define START_CALLBACK(editor) /* empty */ #define END_CALLBACK(editor) /* empty */ #define MARK_FINISHED(editor) /* empty */ #define SHOULD_NOT_BE_FINISHED(editor) /* empty */ -#define CLEAR_INCOMPLETE(editor, relpath) /* empty */ - -#define MARK_COMPLETED(editor, relpath) /* empty */ -#define SHOULD_NOT_BE_COMPLETED(editor, relpath) /* empty */ - -#define MARK_ALLOW_ADD(editor, relpath) /* empty */ -#define SHOULD_ALLOW_ADD(editor, relpath) /* empty */ - -#define MARK_ALLOW_ALTER(editor, relpath) /* empty */ -#define SHOULD_ALLOW_ALTER(editor, relpath) /* empty */ - -#define MARK_ADDED_DIR(editor, relpath) /* empty */ -#define CHECK_UNKNOWN_CHILD(editor, relpath) /* empty */ - -#define MARK_PARENT_STABLE(editor, relpath) /* empty */ -#define VERIFY_PARENT_MAY_EXIST(editor, relpath) /* empty */ -#define CHILD_DELETIONS_ALLOWED(editor, relpath) /* empty */ - #endif /* ENABLE_ORDERING_CHECK */ svn_error_t * -svn_editor_create(svn_editor_t **editor, - void *editor_baton, - svn_cancel_func_t cancel_func, - void *cancel_baton, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +svn_editor3_create(svn_editor3_t **editor, + const svn_editor3_cb_funcs_t *editor_funcs, + void *editor_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { *editor = apr_pcalloc(result_pool, sizeof(**editor)); + (*editor)->funcs = *editor_funcs; (*editor)->baton = editor_baton; (*editor)->cancel_func = cancel_func; (*editor)->cancel_baton = cancel_baton; (*editor)->scratch_pool = svn_pool_create(result_pool); #ifdef ENABLE_ORDERING_CHECK - (*editor)->pending_incomplete_children = apr_hash_make(result_pool); - (*editor)->completed_nodes = apr_hash_make(result_pool); + (*editor)->within_callback = FALSE; (*editor)->finished = FALSE; (*editor)->state_pool = result_pool; #endif @@ -284,581 +112,344 @@ svn_editor_create(svn_editor_t **editor, void * -svn_editor_get_baton(const svn_editor_t *editor) +svn_editor3_get_baton(const svn_editor3_t *editor) { return editor->baton; } -svn_error_t * -svn_editor_setcb_add_directory(svn_editor_t *editor, - svn_editor_cb_add_directory_t callback, - apr_pool_t *scratch_pool) -{ - editor->funcs.cb_add_directory = callback; - return SVN_NO_ERROR; -} - - -svn_error_t * -svn_editor_setcb_add_file(svn_editor_t *editor, - svn_editor_cb_add_file_t callback, - apr_pool_t *scratch_pool) -{ - editor->funcs.cb_add_file = callback; - return SVN_NO_ERROR; -} - - -svn_error_t * -svn_editor_setcb_add_symlink(svn_editor_t *editor, - svn_editor_cb_add_symlink_t callback, - apr_pool_t *scratch_pool) -{ - editor->funcs.cb_add_symlink = callback; - return SVN_NO_ERROR; -} - - -svn_error_t * -svn_editor_setcb_add_absent(svn_editor_t *editor, - svn_editor_cb_add_absent_t callback, - apr_pool_t *scratch_pool) -{ - editor->funcs.cb_add_absent = callback; - return SVN_NO_ERROR; -} - - -svn_error_t * -svn_editor_setcb_alter_directory(svn_editor_t *editor, - svn_editor_cb_alter_directory_t callback, - apr_pool_t *scratch_pool) -{ - editor->funcs.cb_alter_directory = callback; - return SVN_NO_ERROR; -} - - -svn_error_t * -svn_editor_setcb_alter_file(svn_editor_t *editor, - svn_editor_cb_alter_file_t callback, - apr_pool_t *scratch_pool) -{ - editor->funcs.cb_alter_file = callback; - return SVN_NO_ERROR; -} - - -svn_error_t * -svn_editor_setcb_alter_symlink(svn_editor_t *editor, - svn_editor_cb_alter_symlink_t callback, - apr_pool_t *scratch_pool) -{ - editor->funcs.cb_alter_symlink = callback; - return SVN_NO_ERROR; -} - - -svn_error_t * -svn_editor_setcb_delete(svn_editor_t *editor, - svn_editor_cb_delete_t callback, - apr_pool_t *scratch_pool) -{ - editor->funcs.cb_delete = callback; - return SVN_NO_ERROR; -} - - -svn_error_t * -svn_editor_setcb_copy(svn_editor_t *editor, - svn_editor_cb_copy_t callback, - apr_pool_t *scratch_pool) +static svn_error_t * +check_cancel(svn_editor3_t *editor) { - editor->funcs.cb_copy = callback; - return SVN_NO_ERROR; -} + svn_error_t *err = NULL; + if (editor->cancel_func) + { + START_CALLBACK(editor); + err = editor->cancel_func(editor->cancel_baton); + END_CALLBACK(editor); + } -svn_error_t * -svn_editor_setcb_move(svn_editor_t *editor, - svn_editor_cb_move_t callback, - apr_pool_t *scratch_pool) -{ - editor->funcs.cb_move = callback; - return SVN_NO_ERROR; + return svn_error_trace(err); } -svn_error_t * -svn_editor_setcb_complete(svn_editor_t *editor, - svn_editor_cb_complete_t callback, - apr_pool_t *scratch_pool) -{ - editor->funcs.cb_complete = callback; - return SVN_NO_ERROR; -} - +/* + * =================================================================== + * Editor for Commit from WC, with Incremental Path-Based Tree Changes + * =================================================================== + */ svn_error_t * -svn_editor_setcb_abort(svn_editor_t *editor, - svn_editor_cb_abort_t callback, - apr_pool_t *scratch_pool) +svn_editor3_mk(svn_editor3_t *editor, + svn_node_kind_t new_kind, + pathrev_t parent_loc, + const char *new_name) { - editor->funcs.cb_abort = callback; - return SVN_NO_ERROR; -} - - -svn_error_t * -svn_editor_setcb_many(svn_editor_t *editor, - const svn_editor_cb_many_t *many, - apr_pool_t *scratch_pool) -{ -#define COPY_CALLBACK(NAME) if (many->NAME) editor->funcs.NAME = many->NAME - - COPY_CALLBACK(cb_add_directory); - COPY_CALLBACK(cb_add_file); - COPY_CALLBACK(cb_add_symlink); - COPY_CALLBACK(cb_add_absent); - COPY_CALLBACK(cb_alter_directory); - COPY_CALLBACK(cb_alter_file); - COPY_CALLBACK(cb_alter_symlink); - COPY_CALLBACK(cb_delete); - COPY_CALLBACK(cb_copy); - COPY_CALLBACK(cb_move); - COPY_CALLBACK(cb_complete); - COPY_CALLBACK(cb_abort); - -#undef COPY_CALLBACK - - return SVN_NO_ERROR; -} + svn_error_t *err = SVN_NO_ERROR; + /* SVN_ERR_ASSERT(...); */ -static svn_error_t * -check_cancel(svn_editor_t *editor) -{ - svn_error_t *err = NULL; + SVN_ERR(check_cancel(editor)); - if (editor->cancel_func) + if (editor->funcs.cb_mk) { START_CALLBACK(editor); - err = editor->cancel_func(editor->cancel_baton); + err = editor->funcs.cb_mk(editor->baton, + new_kind, parent_loc, new_name, + editor->scratch_pool); END_CALLBACK(editor); } + svn_pool_clear(editor->scratch_pool); return svn_error_trace(err); } - svn_error_t * -svn_editor_add_directory(svn_editor_t *editor, - const char *relpath, - const apr_array_header_t *children, - apr_hash_t *props, - svn_revnum_t replaces_rev) +svn_editor3_cp(svn_editor3_t *editor, + pathrev_t from_loc, + pathrev_t parent_loc, + const char *new_name) { svn_error_t *err = SVN_NO_ERROR; - SVN_ERR_ASSERT(svn_relpath_is_canonical(relpath)); - SVN_ERR_ASSERT(children != NULL); - SVN_ERR_ASSERT(props != NULL); - /* ### validate children are just basenames? */ - SHOULD_NOT_BE_FINISHED(editor); - SHOULD_ALLOW_ADD(editor, relpath); - VERIFY_PARENT_MAY_EXIST(editor, relpath); - CHECK_UNKNOWN_CHILD(editor, relpath); + /* SVN_ERR_ASSERT(...); */ SVN_ERR(check_cancel(editor)); - if (editor->funcs.cb_add_directory) + if (editor->funcs.cb_cp) { START_CALLBACK(editor); - err = editor->funcs.cb_add_directory(editor->baton, relpath, children, - props, replaces_rev, - editor->scratch_pool); + err = editor->funcs.cb_cp(editor->baton, + from_loc, parent_loc, new_name, + editor->scratch_pool); END_CALLBACK(editor); } - MARK_ADDED_DIR(editor, relpath); - MARK_PARENT_STABLE(editor, relpath); - CLEAR_INCOMPLETE(editor, relpath); - -#ifdef ENABLE_ORDERING_CHECK - { - int i; - for (i = 0; i < children->nelts; i++) - { - const char *child_basename = APR_ARRAY_IDX(children, i, const char *); - const char *child = svn_relpath_join(relpath, child_basename, - editor->state_pool); - - svn_hash_sets(editor->pending_incomplete_children, child, ""); - } - } -#endif - svn_pool_clear(editor->scratch_pool); return svn_error_trace(err); } - svn_error_t * -svn_editor_add_file(svn_editor_t *editor, - const char *relpath, - const svn_checksum_t *checksum, - svn_stream_t *contents, - apr_hash_t *props, - svn_revnum_t replaces_rev) +svn_editor3_mv(svn_editor3_t *editor, + pathrev_t from_loc, + pathrev_t new_parent_loc, + const char *new_name) { svn_error_t *err = SVN_NO_ERROR; - SVN_ERR_ASSERT(svn_relpath_is_canonical(relpath)); - SVN_ERR_ASSERT(checksum != NULL - && checksum->kind == SVN_EDITOR_CHECKSUM_KIND); - SVN_ERR_ASSERT(contents != NULL); - SVN_ERR_ASSERT(props != NULL); - SHOULD_NOT_BE_FINISHED(editor); - SHOULD_ALLOW_ADD(editor, relpath); - VERIFY_PARENT_MAY_EXIST(editor, relpath); - CHECK_UNKNOWN_CHILD(editor, relpath); + /* SVN_ERR_ASSERT(...); */ SVN_ERR(check_cancel(editor)); - if (editor->funcs.cb_add_file) + if (editor->funcs.cb_mv) { START_CALLBACK(editor); - err = editor->funcs.cb_add_file(editor->baton, relpath, - checksum, contents, props, - replaces_rev, editor->scratch_pool); + err = editor->funcs.cb_mv(editor->baton, + from_loc, new_parent_loc, new_name, + editor->scratch_pool); END_CALLBACK(editor); } - MARK_COMPLETED(editor, relpath); - MARK_PARENT_STABLE(editor, relpath); - CLEAR_INCOMPLETE(editor, relpath); - svn_pool_clear(editor->scratch_pool); return svn_error_trace(err); } - svn_error_t * -svn_editor_add_symlink(svn_editor_t *editor, - const char *relpath, - const char *target, - apr_hash_t *props, - svn_revnum_t replaces_rev) +svn_editor3_res(svn_editor3_t *editor, + pathrev_t from_loc, + pathrev_t parent_loc, + const char *new_name) { svn_error_t *err = SVN_NO_ERROR; - SVN_ERR_ASSERT(svn_relpath_is_canonical(relpath)); - SVN_ERR_ASSERT(props != NULL); - SHOULD_NOT_BE_FINISHED(editor); - SHOULD_ALLOW_ADD(editor, relpath); - VERIFY_PARENT_MAY_EXIST(editor, relpath); - CHECK_UNKNOWN_CHILD(editor, relpath); + /* SVN_ERR_ASSERT(...); */ SVN_ERR(check_cancel(editor)); - if (editor->funcs.cb_add_symlink) + if (editor->funcs.cb_res) { START_CALLBACK(editor); - err = editor->funcs.cb_add_symlink(editor->baton, relpath, target, props, - replaces_rev, editor->scratch_pool); + err = editor->funcs.cb_res(editor->baton, + from_loc, parent_loc, new_name, + editor->scratch_pool); END_CALLBACK(editor); } - MARK_COMPLETED(editor, relpath); - MARK_PARENT_STABLE(editor, relpath); - CLEAR_INCOMPLETE(editor, relpath); - svn_pool_clear(editor->scratch_pool); return svn_error_trace(err); } - svn_error_t * -svn_editor_add_absent(svn_editor_t *editor, - const char *relpath, - svn_node_kind_t kind, - svn_revnum_t replaces_rev) +svn_editor3_rm(svn_editor3_t *editor, + pathrev_t loc) { svn_error_t *err = SVN_NO_ERROR; - SVN_ERR_ASSERT(svn_relpath_is_canonical(relpath)); - SHOULD_NOT_BE_FINISHED(editor); - SHOULD_ALLOW_ADD(editor, relpath); - VERIFY_PARENT_MAY_EXIST(editor, relpath); - CHECK_UNKNOWN_CHILD(editor, relpath); + /* SVN_ERR_ASSERT(...); */ SVN_ERR(check_cancel(editor)); - if (editor->funcs.cb_add_absent) + if (editor->funcs.cb_rm) { START_CALLBACK(editor); - err = editor->funcs.cb_add_absent(editor->baton, relpath, kind, - replaces_rev, editor->scratch_pool); + err = editor->funcs.cb_rm(editor->baton, + loc, + editor->scratch_pool); END_CALLBACK(editor); } - MARK_COMPLETED(editor, relpath); - MARK_PARENT_STABLE(editor, relpath); - CLEAR_INCOMPLETE(editor, relpath); - svn_pool_clear(editor->scratch_pool); return svn_error_trace(err); } - svn_error_t * -svn_editor_alter_directory(svn_editor_t *editor, - const char *relpath, - svn_revnum_t revision, - const apr_array_header_t *children, - apr_hash_t *props) +svn_editor3_put(svn_editor3_t *editor, + pathrev_t loc, + const svn_editor3_node_content_t *new_content) { svn_error_t *err = SVN_NO_ERROR; - SVN_ERR_ASSERT(svn_relpath_is_canonical(relpath)); - SVN_ERR_ASSERT(children != NULL || props != NULL); - /* ### validate children are just basenames? */ - SHOULD_NOT_BE_FINISHED(editor); - SHOULD_ALLOW_ALTER(editor, relpath); - VERIFY_PARENT_MAY_EXIST(editor, relpath); + /* SVN_ERR_ASSERT(...); */ SVN_ERR(check_cancel(editor)); - if (editor->funcs.cb_alter_directory) + if (editor->funcs.cb_put) { START_CALLBACK(editor); - err = editor->funcs.cb_alter_directory(editor->baton, - relpath, revision, - children, props, - editor->scratch_pool); + err = editor->funcs.cb_put(editor->baton, + loc, new_content, + editor->scratch_pool); END_CALLBACK(editor); } - MARK_COMPLETED(editor, relpath); - MARK_PARENT_STABLE(editor, relpath); - -#ifdef ENABLE_ORDERING_CHECK - /* ### this is not entirely correct. we probably need to adjust the - ### check_unknown_child() function for this scenario. */ -#if 0 - { - int i; - for (i = 0; i < children->nelts; i++) - { - const char *child_basename = APR_ARRAY_IDX(children, i, const char *); - const char *child = svn_relpath_join(relpath, child_basename, - editor->state_pool); - - apr_hash_set(editor->pending_incomplete_children, child, - APR_HASH_KEY_STRING, ""); - /* Perhaps MARK_ALLOW_ADD(editor, child); ? */ - } - } -#endif -#endif - svn_pool_clear(editor->scratch_pool); return svn_error_trace(err); } +/* + * ======================================================================== + * Editor for Commit from WC, with Separate Unordered Per-Node Tree Changes + * ======================================================================== + */ + svn_error_t * -svn_editor_alter_file(svn_editor_t *editor, - const char *relpath, - svn_revnum_t revision, - const svn_checksum_t *checksum, - svn_stream_t *contents, - apr_hash_t *props) +svn_editor3_add(svn_editor3_t *editor, + svn_editor3_nbid_t local_nbid, + svn_node_kind_t new_kind, + svn_editor3_nbid_t new_parent_nbid, + const char *new_name, + const svn_editor3_node_content_t *new_content) { svn_error_t *err = SVN_NO_ERROR; - SVN_ERR_ASSERT(svn_relpath_is_canonical(relpath)); - SVN_ERR_ASSERT((checksum != NULL && contents != NULL) - || (checksum == NULL && contents == NULL)); - SVN_ERR_ASSERT(props != NULL || checksum != NULL); - if (checksum) - SVN_ERR_ASSERT(checksum->kind == SVN_EDITOR_CHECKSUM_KIND); - SHOULD_NOT_BE_FINISHED(editor); - SHOULD_ALLOW_ALTER(editor, relpath); - VERIFY_PARENT_MAY_EXIST(editor, relpath); + /* SVN_ERR_ASSERT(...); */ SVN_ERR(check_cancel(editor)); - if (editor->funcs.cb_alter_file) + if (editor->funcs.cb_add) { START_CALLBACK(editor); - err = editor->funcs.cb_alter_file(editor->baton, - relpath, revision, - checksum, contents, props, - editor->scratch_pool); + err = editor->funcs.cb_add(editor->baton, + local_nbid, new_kind, + new_parent_nbid, new_name, + new_content, + editor->scratch_pool); END_CALLBACK(editor); } - MARK_COMPLETED(editor, relpath); - MARK_PARENT_STABLE(editor, relpath); + /* MARK_...(editor, ...); */ svn_pool_clear(editor->scratch_pool); return svn_error_trace(err); } - svn_error_t * -svn_editor_alter_symlink(svn_editor_t *editor, - const char *relpath, - svn_revnum_t revision, - const char *target, - apr_hash_t *props) +svn_editor3_copy_one(svn_editor3_t *editor, + svn_editor3_nbid_t local_nbid, + svn_revnum_t src_revision, + svn_editor3_nbid_t src_nbid, + svn_editor3_nbid_t new_parent_nbid, + const char *new_name, + const svn_editor3_node_content_t *new_content) { svn_error_t *err = SVN_NO_ERROR; - SVN_ERR_ASSERT(svn_relpath_is_canonical(relpath)); - SVN_ERR_ASSERT(props != NULL || target != NULL); - SHOULD_NOT_BE_FINISHED(editor); - SHOULD_ALLOW_ALTER(editor, relpath); - VERIFY_PARENT_MAY_EXIST(editor, relpath); + /* SVN_ERR_ASSERT(...); */ SVN_ERR(check_cancel(editor)); - if (editor->funcs.cb_alter_symlink) + if (editor->funcs.cb_copy_one) { START_CALLBACK(editor); - err = editor->funcs.cb_alter_symlink(editor->baton, - relpath, revision, - target, props, - editor->scratch_pool); + err = editor->funcs.cb_copy_one(editor->baton, + local_nbid, + src_revision, src_nbid, + new_parent_nbid, new_name, + new_content, + editor->scratch_pool); END_CALLBACK(editor); } - MARK_COMPLETED(editor, relpath); - MARK_PARENT_STABLE(editor, relpath); + /* MARK_...(editor, ...); */ svn_pool_clear(editor->scratch_pool); return svn_error_trace(err); } - svn_error_t * -svn_editor_delete(svn_editor_t *editor, - const char *relpath, - svn_revnum_t revision) +svn_editor3_copy_tree(svn_editor3_t *editor, + svn_revnum_t src_revision, + svn_editor3_nbid_t src_nbid, + svn_editor3_nbid_t new_parent_nbid, + const char *new_name) { svn_error_t *err = SVN_NO_ERROR; - SVN_ERR_ASSERT(svn_relpath_is_canonical(relpath)); - SHOULD_NOT_BE_FINISHED(editor); - SHOULD_NOT_BE_COMPLETED(editor, relpath); - VERIFY_PARENT_MAY_EXIST(editor, relpath); - CHILD_DELETIONS_ALLOWED(editor, relpath); + /* SVN_ERR_ASSERT(...); */ SVN_ERR(check_cancel(editor)); - if (editor->funcs.cb_delete) + if (editor->funcs.cb_copy_one) { START_CALLBACK(editor); - err = editor->funcs.cb_delete(editor->baton, relpath, revision, - editor->scratch_pool); + err = editor->funcs.cb_copy_tree(editor->baton, + src_revision, src_nbid, + new_parent_nbid, new_name, + editor->scratch_pool); END_CALLBACK(editor); } - MARK_COMPLETED(editor, relpath); - MARK_PARENT_STABLE(editor, relpath); + /* MARK_...(editor, ...); */ svn_pool_clear(editor->scratch_pool); return svn_error_trace(err); } - svn_error_t * -svn_editor_copy(svn_editor_t *editor, - const char *src_relpath, - svn_revnum_t src_revision, - const char *dst_relpath, - svn_revnum_t replaces_rev) +svn_editor3_delete(svn_editor3_t *editor, + svn_revnum_t since_rev, + svn_editor3_nbid_t nbid) { svn_error_t *err = SVN_NO_ERROR; - SVN_ERR_ASSERT(svn_relpath_is_canonical(src_relpath)); - SVN_ERR_ASSERT(svn_relpath_is_canonical(dst_relpath)); - SHOULD_NOT_BE_FINISHED(editor); - SHOULD_ALLOW_ADD(editor, dst_relpath); - VERIFY_PARENT_MAY_EXIST(editor, src_relpath); - VERIFY_PARENT_MAY_EXIST(editor, dst_relpath); + /* SVN_ERR_ASSERT(...); */ SVN_ERR(check_cancel(editor)); - if (editor->funcs.cb_copy) + if (editor->funcs.cb_delete) { START_CALLBACK(editor); - err = editor->funcs.cb_copy(editor->baton, src_relpath, src_revision, - dst_relpath, replaces_rev, - editor->scratch_pool); + err = editor->funcs.cb_delete(editor->baton, + since_rev, nbid, + editor->scratch_pool); END_CALLBACK(editor); } - MARK_ALLOW_ALTER(editor, dst_relpath); - MARK_PARENT_STABLE(editor, dst_relpath); - CLEAR_INCOMPLETE(editor, dst_relpath); + /* MARK_...(editor, ...); */ svn_pool_clear(editor->scratch_pool); return svn_error_trace(err); } - svn_error_t * -svn_editor_move(svn_editor_t *editor, - const char *src_relpath, - svn_revnum_t src_revision, - const char *dst_relpath, - svn_revnum_t replaces_rev) +svn_editor3_alter(svn_editor3_t *editor, + svn_revnum_t since_rev, + svn_editor3_nbid_t nbid, + svn_editor3_nbid_t new_parent_nbid, + const char *new_name, + const svn_editor3_node_content_t *new_content) { svn_error_t *err = SVN_NO_ERROR; - SVN_ERR_ASSERT(svn_relpath_is_canonical(src_relpath)); - SVN_ERR_ASSERT(svn_relpath_is_canonical(dst_relpath)); - SHOULD_NOT_BE_FINISHED(editor); - SHOULD_NOT_BE_COMPLETED(editor, src_relpath); - SHOULD_ALLOW_ADD(editor, dst_relpath); - VERIFY_PARENT_MAY_EXIST(editor, src_relpath); - CHILD_DELETIONS_ALLOWED(editor, src_relpath); - VERIFY_PARENT_MAY_EXIST(editor, dst_relpath); + /* SVN_ERR_ASSERT(...); */ SVN_ERR(check_cancel(editor)); - if (editor->funcs.cb_move) + if (editor->funcs.cb_alter) { START_CALLBACK(editor); - err = editor->funcs.cb_move(editor->baton, src_relpath, src_revision, - dst_relpath, replaces_rev, - editor->scratch_pool); + err = editor->funcs.cb_alter(editor->baton, + since_rev, nbid, + new_parent_nbid, new_name, + new_content, + editor->scratch_pool); END_CALLBACK(editor); } - MARK_ALLOW_ADD(editor, src_relpath); - MARK_PARENT_STABLE(editor, src_relpath); - MARK_ALLOW_ALTER(editor, dst_relpath); - MARK_PARENT_STABLE(editor, dst_relpath); - CLEAR_INCOMPLETE(editor, dst_relpath); + /* MARK_...(editor, ...); */ svn_pool_clear(editor->scratch_pool); return svn_error_trace(err); } - svn_error_t * -svn_editor_complete(svn_editor_t *editor) +svn_editor3_complete(svn_editor3_t *editor) { svn_error_t *err = SVN_NO_ERROR; SHOULD_NOT_BE_FINISHED(editor); -#ifdef ENABLE_ORDERING_CHECK - SVN_ERR_ASSERT(apr_hash_count(editor->pending_incomplete_children) == 0); -#endif if (editor->funcs.cb_complete) { @@ -873,9 +464,8 @@ svn_editor_complete(svn_editor_t *editor return svn_error_trace(err); } - svn_error_t * -svn_editor_abort(svn_editor_t *editor) +svn_editor3_abort(svn_editor3_t *editor) { svn_error_t *err = SVN_NO_ERROR;