svn_error_t * svn_fs_x__dag_open(dag_node_t **child_p, dag_node_t *parent, const char *name, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { const svn_fs_id_t *node_id; /* Ensure that NAME exists in PARENT's entry list. */ SVN_ERR(dir_entry_id_from_node(&node_id, parent, name, scratch_pool, scratch_pool)); if (! node_id) return svn_error_createf (SVN_ERR_FS_NOT_FOUND, NULL, "Attempted to open non-existent child node '%s'", name); /* Make sure that NAME is a single path component. */ if (! svn_path_is_single_path_component(name)) return svn_error_createf (SVN_ERR_FS_NOT_SINGLE_PATH_COMPONENT, NULL, "Attempted to open node with an illegal name '%s'", name); /* Now get the node that was requested. */ return svn_fs_x__dag_get_node(child_p, svn_fs_x__dag_get_fs(parent), node_id, result_pool); }
svn_error_t * svn_fs_x__dag_delete(dag_node_t *parent, const char *name, const svn_fs_x__id_part_t *txn_id, apr_pool_t *pool) { node_revision_t *parent_noderev; svn_fs_t *fs = parent->fs; svn_fs_dirent_t *dirent; svn_fs_id_t *id; apr_pool_t *subpool; /* Make sure parent is a directory. */ if (parent->kind != svn_node_dir) return svn_error_createf (SVN_ERR_FS_NOT_DIRECTORY, NULL, "Attempted to delete entry '%s' from *non*-directory node", name); /* Make sure parent is mutable. */ if (! svn_fs_x__dag_check_mutable(parent)) return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, "Attempted to delete entry '%s' from immutable directory node", name); /* Make sure that NAME is a single path component. */ if (! svn_path_is_single_path_component(name)) return svn_error_createf (SVN_ERR_FS_NOT_SINGLE_PATH_COMPONENT, NULL, "Attempted to delete a node with an illegal name '%s'", name); /* Get a fresh NODE-REVISION for the parent node. */ SVN_ERR(get_node_revision(&parent_noderev, parent)); subpool = svn_pool_create(pool); /* Search this directory for a dirent with that NAME. */ SVN_ERR(svn_fs_x__rep_contents_dir_entry(&dirent, fs, parent_noderev, name, subpool, subpool)); /* If we never found ID in ENTRIES (perhaps because there are no ENTRIES, perhaps because ID just isn't in the existing ENTRIES ... it doesn't matter), return an error. */ if (! dirent) return svn_error_createf (SVN_ERR_FS_NO_SUCH_ENTRY, NULL, "Delete failed--directory has no entry '%s'", name); /* Copy the ID out of the subpool and release the rest of the directory listing. */ id = svn_fs_x__id_copy(dirent->id, pool); svn_pool_destroy(subpool); /* If mutable, remove it and any mutable children from db. */ SVN_ERR(svn_fs_x__dag_delete_if_mutable(parent->fs, id, pool)); /* Remove this entry from its parent's entries list. */ return svn_fs_x__set_entry(parent->fs, txn_id, parent_noderev, name, NULL, svn_node_unknown, pool); }
/* Make a new entry named NAME in PARENT. If IS_DIR is true, then the node revision the new entry points to will be a directory, else it will be a file. The new node will be allocated in POOL. PARENT must be mutable, and must not have an entry named NAME. Use POOL for all allocations, except caching the node_revision in PARENT. */ static svn_error_t * make_entry(dag_node_t **child_p, dag_node_t *parent, const char *parent_path, const char *name, svn_boolean_t is_dir, const svn_fs_x__id_part_t *txn_id, apr_pool_t *pool) { const svn_fs_id_t *new_node_id; node_revision_t new_noderev, *parent_noderev; /* Make sure that NAME is a single path component. */ if (! svn_path_is_single_path_component(name)) return svn_error_createf (SVN_ERR_FS_NOT_SINGLE_PATH_COMPONENT, NULL, _("Attempted to create a node with an illegal name '%s'"), name); /* Make sure that parent is a directory */ if (parent->kind != svn_node_dir) return svn_error_create (SVN_ERR_FS_NOT_DIRECTORY, NULL, _("Attempted to create entry in non-directory parent")); /* Check that the parent is mutable. */ if (! svn_fs_x__dag_check_mutable(parent)) return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, _("Attempted to clone child of non-mutable node")); /* Create the new node's NODE-REVISION */ memset(&new_noderev, 0, sizeof(new_noderev)); new_noderev.kind = is_dir ? svn_node_dir : svn_node_file; new_noderev.created_path = svn_fspath__join(parent_path, name, pool); SVN_ERR(get_node_revision(&parent_noderev, parent)); new_noderev.copyroot_path = apr_pstrdup(pool, parent_noderev->copyroot_path); new_noderev.copyroot_rev = parent_noderev->copyroot_rev; new_noderev.copyfrom_rev = SVN_INVALID_REVNUM; new_noderev.copyfrom_path = NULL; SVN_ERR(svn_fs_x__create_node (&new_node_id, svn_fs_x__dag_get_fs(parent), &new_noderev, svn_fs_x__id_copy_id(svn_fs_x__dag_get_id(parent)), txn_id, pool)); /* Create a new dag_node_t for our new node */ SVN_ERR(svn_fs_x__dag_get_node(child_p, svn_fs_x__dag_get_fs(parent), new_node_id, pool)); /* We can safely call set_entry because we already know that PARENT is mutable, and we just created CHILD, so we know it has no ancestors (therefore, PARENT cannot be an ancestor of CHILD) */ return set_entry(parent, name, svn_fs_x__dag_get_id(*child_p), new_noderev.kind, txn_id, pool); }
svn_error_t *svn_ra_do_status2(svn_ra_session_t *session, const svn_ra_reporter3_t **reporter, void **report_baton, const char *status_target, svn_revnum_t revision, svn_depth_t depth, const svn_delta_editor_t *status_editor, void *status_baton, apr_pool_t *pool) { SVN_ERR_ASSERT(svn_path_is_empty(status_target) || svn_path_is_single_path_component(status_target)); return session->vtable->do_status(session, reporter, report_baton, status_target, revision, depth, status_editor, status_baton, pool); }
svn_error_t *svn_ra_do_update2(svn_ra_session_t *session, const svn_ra_reporter3_t **reporter, void **report_baton, svn_revnum_t revision_to_update_to, const char *update_target, svn_depth_t depth, svn_boolean_t send_copyfrom_args, const svn_delta_editor_t *update_editor, void *update_baton, apr_pool_t *pool) { SVN_ERR_ASSERT(svn_path_is_empty(update_target) || svn_path_is_single_path_component(update_target)); return session->vtable->do_update(session, reporter, report_baton, revision_to_update_to, update_target, depth, send_copyfrom_args, update_editor, update_baton, pool); }
svn_error_t *svn_ra_do_diff3(svn_ra_session_t *session, const svn_ra_reporter3_t **reporter, void **report_baton, svn_revnum_t revision, const char *diff_target, svn_depth_t depth, svn_boolean_t ignore_ancestry, svn_boolean_t text_deltas, const char *versus_url, const svn_delta_editor_t *diff_editor, void *diff_baton, apr_pool_t *pool) { SVN_ERR_ASSERT(svn_path_is_empty(diff_target) || svn_path_is_single_path_component(diff_target)); return session->vtable->do_diff(session, reporter, report_baton, revision, diff_target, depth, ignore_ancestry, text_deltas, versus_url, diff_editor, diff_baton, pool); }
svn_error_t * svn_fs_x__dag_clone_child(dag_node_t **child_p, dag_node_t *parent, const char *parent_path, const char *name, const svn_fs_x__id_part_t *copy_id, const svn_fs_x__id_part_t *txn_id, svn_boolean_t is_parent_copyroot, apr_pool_t *pool) { dag_node_t *cur_entry; /* parent's current entry named NAME */ const svn_fs_id_t *new_node_id; /* node id we'll put into NEW_NODE */ svn_fs_t *fs = svn_fs_x__dag_get_fs(parent); apr_pool_t *subpool = svn_pool_create(pool); /* First check that the parent is mutable. */ if (! svn_fs_x__dag_check_mutable(parent)) return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, "Attempted to clone child of non-mutable node"); /* Make sure that NAME is a single path component. */ if (! svn_path_is_single_path_component(name)) return svn_error_createf (SVN_ERR_FS_NOT_SINGLE_PATH_COMPONENT, NULL, "Attempted to make a child clone with an illegal name '%s'", name); /* Find the node named NAME in PARENT's entries list if it exists. */ SVN_ERR(svn_fs_x__dag_open(&cur_entry, parent, name, pool, subpool)); /* Check for mutability in the node we found. If it's mutable, we don't need to clone it. */ if (svn_fs_x__dag_check_mutable(cur_entry)) { /* This has already been cloned */ new_node_id = cur_entry->id; } else { node_revision_t *noderev, *parent_noderev; /* Go get a fresh NODE-REVISION for current child node. */ SVN_ERR(get_node_revision(&noderev, cur_entry)); if (is_parent_copyroot) { SVN_ERR(get_node_revision(&parent_noderev, parent)); noderev->copyroot_rev = parent_noderev->copyroot_rev; noderev->copyroot_path = apr_pstrdup(pool, parent_noderev->copyroot_path); } noderev->copyfrom_path = NULL; noderev->copyfrom_rev = SVN_INVALID_REVNUM; noderev->predecessor_id = svn_fs_x__id_copy(cur_entry->id, pool); if (noderev->predecessor_count != -1) noderev->predecessor_count++; noderev->created_path = svn_fspath__join(parent_path, name, pool); SVN_ERR(svn_fs_x__create_successor(&new_node_id, fs, cur_entry->id, noderev, copy_id, txn_id, pool)); /* Replace the ID in the parent's ENTRY list with the ID which refers to the mutable clone of this child. */ SVN_ERR(set_entry(parent, name, new_node_id, noderev->kind, txn_id, pool)); } /* Initialize the youngster. */ svn_pool_destroy(subpool); return svn_fs_x__dag_get_node(child_p, fs, new_node_id, pool); }