static svn_error_t * get_ra_editor(const svn_delta_editor_t **editor, void **edit_baton, svn_ra_session_t *ra_session, svn_client_ctx_t *ctx, const char *log_msg, const apr_array_header_t *commit_items, const apr_hash_t *revprop_table, apr_hash_t *lock_tokens, svn_boolean_t keep_locks, svn_commit_callback2_t commit_callback, void *commit_baton, apr_pool_t *pool) { apr_hash_t *commit_revprops; apr_hash_t *relpath_map = NULL; SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table, log_msg, ctx, pool)); #ifdef ENABLE_EV2_SHIMS if (commit_items) { int i; apr_pool_t *iterpool = svn_pool_create(pool); relpath_map = apr_hash_make(pool); for (i = 0; i < commit_items->nelts; i++) { svn_client_commit_item3_t *item = APR_ARRAY_IDX(commit_items, i, svn_client_commit_item3_t *); const char *relpath; if (!item->path) continue; svn_pool_clear(iterpool); SVN_ERR(svn_wc__node_get_origin(NULL, NULL, &relpath, NULL, NULL, NULL, NULL, ctx->wc_ctx, item->path, FALSE, pool, iterpool)); if (relpath) svn_hash_sets(relpath_map, relpath, item->path); } svn_pool_destroy(iterpool); } #endif /* Fetch RA commit editor. */ SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session, svn_client__get_shim_callbacks(ctx->wc_ctx, relpath_map, pool))); SVN_ERR(svn_ra_get_commit_editor3(ra_session, editor, edit_baton, commit_revprops, commit_callback, commit_baton, lock_tokens, keep_locks, pool)); return SVN_NO_ERROR; }
static svn_error_t * new_node_record(void **node_baton, apr_hash_t *headers, void *revision_baton, apr_pool_t *pool) { struct revision_baton *rb = revision_baton; const struct svn_delta_editor_t *commit_editor = rb->pb->commit_editor; void *commit_edit_baton = rb->pb->commit_edit_baton; struct node_baton *nb; apr_hash_index_t *hi; void *child_baton; const char *nb_dirname; nb = apr_pcalloc(rb->pool, sizeof(*nb)); nb->rb = rb; nb->is_added = FALSE; nb->copyfrom_path = NULL; nb->copyfrom_url = NULL; nb->copyfrom_rev = SVN_INVALID_REVNUM; nb->prop_changes = apr_hash_make(rb->pool); /* If the creation of commit_editor is pending, create it now and open_root on it; also create a top-level directory baton. */ if (!commit_editor) { /* The revprop_table should have been filled in with important information like svn:log in set_revision_property. We can now use it all this information to create our commit_editor. But first, clear revprops that we aren't allowed to set with the commit_editor. We'll set them separately using the RA API after closing the editor (see close_revision). */ svn_hash_sets(rb->revprop_table, SVN_PROP_REVISION_AUTHOR, NULL); svn_hash_sets(rb->revprop_table, SVN_PROP_REVISION_DATE, NULL); SVN_ERR(svn_ra__register_editor_shim_callbacks(rb->pb->session, get_shim_callbacks(rb, rb->pool))); SVN_ERR(svn_ra_get_commit_editor3(rb->pb->session, &commit_editor, &commit_edit_baton, rb->revprop_table, commit_callback, revision_baton, NULL, FALSE, rb->pool)); rb->pb->commit_editor = commit_editor; rb->pb->commit_edit_baton = commit_edit_baton; SVN_ERR(commit_editor->open_root(commit_edit_baton, rb->rev - rb->rev_offset - 1, rb->pool, &child_baton)); LDR_DBG(("Opened root %p\n", child_baton)); /* child_baton corresponds to the root directory baton here */ push_directory(rb, child_baton, "", TRUE /*is_added*/, NULL, SVN_INVALID_REVNUM); } for (hi = apr_hash_first(rb->pool, headers); hi; hi = apr_hash_next(hi)) { const char *hname = svn__apr_hash_index_key(hi); const char *hval = svn__apr_hash_index_val(hi); /* Parse the different kinds of headers we can encounter and stuff them into the node_baton for writing later */ if (strcmp(hname, SVN_REPOS_DUMPFILE_NODE_PATH) == 0) nb->path = apr_pstrdup(rb->pool, hval); if (strcmp(hname, SVN_REPOS_DUMPFILE_NODE_KIND) == 0) nb->kind = strcmp(hval, "file") == 0 ? svn_node_file : svn_node_dir; if (strcmp(hname, SVN_REPOS_DUMPFILE_NODE_ACTION) == 0) { if (strcmp(hval, "add") == 0) nb->action = svn_node_action_add; if (strcmp(hval, "change") == 0) nb->action = svn_node_action_change; if (strcmp(hval, "delete") == 0) nb->action = svn_node_action_delete; if (strcmp(hval, "replace") == 0) nb->action = svn_node_action_replace; } if (strcmp(hname, SVN_REPOS_DUMPFILE_TEXT_DELTA_BASE_MD5) == 0) nb->base_checksum = apr_pstrdup(rb->pool, hval); if (strcmp(hname, SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV) == 0) nb->copyfrom_rev = atoi(hval); if (strcmp(hname, SVN_REPOS_DUMPFILE_NODE_COPYFROM_PATH) == 0) nb->copyfrom_path = apr_pstrdup(rb->pool, hval); } nb_dirname = svn_relpath_dirname(nb->path, pool); if (svn_path_compare_paths(nb_dirname, rb->db->relpath) != 0) { char *ancestor_path; apr_size_t residual_close_count; apr_array_header_t *residual_open_path; int i; apr_size_t n; /* Before attempting to handle the action, call open_directory for all the path components and set the directory baton accordingly */ ancestor_path = svn_relpath_get_longest_ancestor(nb_dirname, rb->db->relpath, pool); residual_close_count = svn_path_component_count(svn_relpath_skip_ancestor(ancestor_path, rb->db->relpath)); residual_open_path = svn_path_decompose(svn_relpath_skip_ancestor(ancestor_path, nb_dirname), pool); /* First close all as many directories as there are after skip_ancestor, and then open fresh directories */ for (n = 0; n < residual_close_count; n ++) { /* Don't worry about destroying the actual rb->db object, since the pool we're using has the lifetime of one revision anyway */ LDR_DBG(("Closing dir %p\n", rb->db->baton)); SVN_ERR(commit_editor->close_directory(rb->db->baton, rb->pool)); rb->db = rb->db->parent; } for (i = 0; i < residual_open_path->nelts; i ++) { char *relpath_compose = svn_relpath_join(rb->db->relpath, APR_ARRAY_IDX(residual_open_path, i, const char *), rb->pool); SVN_ERR(commit_editor->open_directory(relpath_compose, rb->db->baton, rb->rev - rb->rev_offset - 1, rb->pool, &child_baton)); LDR_DBG(("Opened dir %p\n", child_baton)); push_directory(rb, child_baton, relpath_compose, TRUE /*is_added*/, NULL, SVN_INVALID_REVNUM); } }
APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item; } SVN_ERR(svn_client__get_log_msg(&log_msg, &tmp_file, commit_items, ctx, pool)); if (! log_msg) return SVN_NO_ERROR; } else log_msg = ""; SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table, log_msg, ctx, pool)); /* Fetch RA commit editor */ SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session, svn_client__get_shim_callbacks(ctx->wc_ctx, NULL, pool))); SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton, commit_revprops, commit_callback, commit_baton, NULL, TRUE, /* No lock tokens */ pool)); /* Call the path-based editor driver. */ err = svn_delta_path_driver2(editor, edit_baton, relpaths, TRUE, path_driver_cb_func, (void *)editor, pool); if (err) { return svn_error_trace(