📄 tree.c
字号:
parent_path = make_parent_path(child, entry, parent_path, pool); if (txn_id) { SVN_ERR(get_copy_inheritance(&inherit, ©_path, fs, parent_path, txn_id, trail, pool)); parent_path->copy_inherit = inherit; parent_path->copy_src_path = apr_pstrdup(pool, copy_path); } /* Cache the node we found (if it wasn't already cached). */ if (! cached_node) dag_node_cache_set(root, path_so_far, child); } /* Are we finished traversing the path? */ if (! next) break; /* The path isn't finished yet; we'd better be in a directory. */ if (svn_fs_base__dag_node_kind(child) != svn_node_dir) SVN_ERR_W(svn_fs_base__err_not_directory(fs, path_so_far), apr_psprintf(pool, _("Failure opening '%s'"), path)); rest = next; here = child; } *parent_path_p = parent_path; return SVN_NO_ERROR;}/* Make the node referred to by PARENT_PATH mutable, if it isn't already, as part of TRAIL. ROOT must be the root from which PARENT_PATH descends. Clone any parent directories as needed. Adjust the dag nodes in PARENT_PATH to refer to the clones. Use ERROR_PATH in error messages. */static svn_error_t *make_path_mutable(svn_fs_root_t *root, parent_path_t *parent_path, const char *error_path, trail_t *trail, apr_pool_t *pool){ dag_node_t *clone; const char *txn_id = root->txn; svn_fs_t *fs = root->fs; /* Is the node mutable already? */ if (svn_fs_base__dag_check_mutable(parent_path->node, txn_id)) return SVN_NO_ERROR; /* Are we trying to clone the root, or somebody's child node? */ if (parent_path->parent) { const svn_fs_id_t *parent_id; const svn_fs_id_t *node_id = svn_fs_base__dag_get_id(parent_path->node); const char *copy_id = NULL; const char *copy_src_path = parent_path->copy_src_path; copy_id_inherit_t inherit = parent_path->copy_inherit; const char *clone_path; /* We're trying to clone somebody's child. Make sure our parent is mutable. */ SVN_ERR(make_path_mutable(root, parent_path->parent, error_path, trail, pool)); switch (inherit) { case copy_id_inherit_parent: parent_id = svn_fs_base__dag_get_id(parent_path->parent->node); copy_id = svn_fs_base__id_copy_id(parent_id); break; case copy_id_inherit_new: SVN_ERR(svn_fs_bdb__reserve_copy_id(©_id, fs, trail, pool)); break; case copy_id_inherit_self: copy_id = NULL; break; case copy_id_inherit_unknown: default: abort(); /* uh-oh -- somebody didn't calculate copy-ID inheritance data. */ } /* Now make this node mutable. */ clone_path = parent_path_path(parent_path->parent, pool); SVN_ERR(svn_fs_base__dag_clone_child(&clone, parent_path->parent->node, clone_path, parent_path->entry, copy_id, txn_id, trail, pool)); /* If we just created a brand new copy ID, we need to store a `copies' table entry for it, as well as a notation in the transaction that should this transaction be terminated, our new copy needs to be removed. */ if (inherit == copy_id_inherit_new) { const svn_fs_id_t *new_node_id = svn_fs_base__dag_get_id(clone); SVN_ERR(svn_fs_bdb__create_copy(fs, copy_id, copy_src_path, svn_fs_base__id_txn_id(node_id), new_node_id, copy_kind_soft, trail, pool)); SVN_ERR(svn_fs_base__add_txn_copy(fs, txn_id, copy_id, trail, pool)); } } else { /* We're trying to clone the root directory. */ SVN_ERR(mutable_root_node(&clone, root, error_path, trail, pool)); } /* Update the PARENT_PATH link to refer to the clone. */ parent_path->node = clone; return SVN_NO_ERROR;}/* Open the node identified by PATH in ROOT, as part of TRAIL. Set *DAG_NODE_P to the node we find, allocated in TRAIL->pool. Return the error SVN_ERR_FS_NOT_FOUND if this node doesn't exist. */static svn_error_t *get_dag(dag_node_t **dag_node_p, svn_fs_root_t *root, const char *path, trail_t *trail, apr_pool_t *pool){ parent_path_t *parent_path; dag_node_t *node = NULL; /* Canonicalize the input PATH. */ path = svn_fs_base__canonicalize_abspath(path, pool); /* If ROOT is a revision root, we'll look for the DAG in our cache. */ node = dag_node_cache_get(root, path, pool); if (! node) { /* Call open_path with no flags, as we want this to return an error if the node for which we are searching doesn't exist. */ SVN_ERR(open_path(&parent_path, root, path, 0, NULL, trail, pool)); node = parent_path->node; /* No need to cache our find -- open_path() will do that for us. */ } *dag_node_p = node; return SVN_NO_ERROR;}/* Populating the `changes' table. *//* Add a change to the changes table in FS, keyed on transaction id TXN_ID, and indicated that a change of kind CHANGE_KIND occurred on PATH (whose node revision id is--or was, in the case of a deletion--NODEREV_ID), and optionally that TEXT_MODs or PROP_MODs occurred. Do all this as part of TRAIL. */static svn_error_t *add_change(svn_fs_t *fs, const char *txn_id, const char *path, const svn_fs_id_t *noderev_id, svn_fs_path_change_kind_t change_kind, svn_boolean_t text_mod, svn_boolean_t prop_mod, trail_t *trail, apr_pool_t *pool){ change_t change; change.path = svn_fs_base__canonicalize_abspath(path, pool); change.noderev_id = noderev_id; change.kind = change_kind; change.text_mod = text_mod; change.prop_mod = prop_mod; return svn_fs_bdb__changes_add(fs, txn_id, &change, trail, pool);}/* Generic node operations. */struct node_id_args { const svn_fs_id_t **id_p; svn_fs_root_t *root; const char *path;};static svn_error_t *txn_body_node_id(void *baton, trail_t *trail){ struct node_id_args *args = baton; dag_node_t *node; SVN_ERR(get_dag(&node, args->root, args->path, trail, trail->pool)); *args->id_p = svn_fs_base__id_copy(svn_fs_base__dag_get_id(node), trail->pool); return SVN_NO_ERROR;}static svn_error_t *base_node_id(const svn_fs_id_t **id_p, svn_fs_root_t *root, const char *path, apr_pool_t *pool){ base_root_data_t *brd = root->fsap_data; if (! root->is_txn_root && (path[0] == '\0' || ((path[0] == '/') && (path[1] == '\0')))) { /* Optimize the case where we don't need any db access at all. The root directory ("" or "/") node is stored in the svn_fs_root_t object, and never changes when it's a revision root, so we can just reach in and grab it directly. */ *id_p = svn_fs_base__id_copy(svn_fs_base__dag_get_id(brd->root_dir), pool); } else { const svn_fs_id_t *id; struct node_id_args args; args.id_p = &id; args.root = root; args.path = path; SVN_ERR(svn_fs_base__retry_txn(root->fs, txn_body_node_id, &args, pool)); *id_p = id; } return SVN_NO_ERROR;}struct node_created_rev_args { svn_revnum_t revision; svn_fs_root_t *root; const char *path;};static svn_error_t *txn_body_node_created_rev(void *baton, trail_t *trail){ struct node_created_rev_args *args = baton; dag_node_t *node; SVN_ERR(get_dag(&node, args->root, args->path, trail, trail->pool)); SVN_ERR(svn_fs_base__dag_get_revision(&(args->revision), node, trail, trail->pool)); return SVN_NO_ERROR;}static svn_error_t *base_node_created_rev(svn_revnum_t *revision, svn_fs_root_t *root, const char *path, apr_pool_t *pool){ struct node_created_rev_args args; args.revision = SVN_INVALID_REVNUM; args.root = root; args.path = path; SVN_ERR(svn_fs_base__retry_txn (root->fs, txn_body_node_created_rev, &args, pool)); *revision = args.revision; return SVN_NO_ERROR;}struct node_created_path_args { const char **created_path; svn_fs_root_t *root; const char *path;};static svn_error_t *txn_body_node_created_path(void *baton, trail_t *trail){ struct node_created_path_args *args = baton; dag_node_t *node; SVN_ERR(get_dag(&node, args->root, args->path, trail, trail->pool)); *args->created_path = svn_fs_base__dag_get_created_path(node); return SVN_NO_ERROR;}static svn_error_t *base_node_created_path(const char **created_path, svn_fs_root_t *root, const char *path, apr_pool_t *pool){ struct node_created_path_args args; args.created_path = created_path; args.root = root; args.path = path; SVN_ERR(svn_fs_base__retry_txn (root->fs, txn_body_node_created_path, &args, pool)); return SVN_NO_ERROR;}struct node_kind_args { const svn_fs_id_t *id; svn_node_kind_t kind; /* OUT parameter */};static svn_error_t *txn_body_node_kind(void *baton, trail_t *trail){ struct node_kind_args *args = baton; dag_node_t *node; SVN_ERR(svn_fs_base__dag_get_node(&node, trail->fs, args->id, trail, trail->pool)); args->kind = svn_fs_base__dag_node_kind(node); return SVN_NO_ERROR;}static svn_error_t *node_kind(svn_node_kind_t *kind_p, svn_fs_root_t *root, const char *path, apr_pool_t *pool){ struct node_kind_args args; const svn_fs_id_t *node_id; /* Get the node id. */ SVN_ERR(base_node_id(&node_id, root, path, pool)); /* Use the node id to get the real kind. */ args.id = node_id; SVN_ERR(svn_fs_base__retry_txn(root->fs, txn_body_node_kind, &args, pool)); *kind_p = args.kind; return SVN_NO_ERROR;}static svn_error_t *base_check_path(svn_node_kind_t *kind_p, svn_fs_root_t *root, const char *path, apr_pool_t *pool){ svn_error_t *err = node_kind(kind_p, root, path, pool); if (err && (err->apr_err == SVN_ERR_FS_NOT_FOUND)) { svn_error_clear(err); *kind_p = svn_node_none; } else if (err) { return err; } return SVN_NO_ERROR;}struct node_prop_args{ svn_string_t **value_p; svn_fs_root_t *root; const char *path; const char *propname;};static svn_error_t *txn_body_node_prop(void *baton, trail_t *trail){ struct node_prop_args *args = baton; dag_node_t *node; apr_hash_t *proplist; SVN_ERR(get_dag(&node, args->root, args->path, trail, trail->pool)); SVN_ERR(svn_fs_base__dag_get_proplist(&proplist, node, trail, trail->pool)); *(args->value_p) = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -