diff options
Diffstat (limited to 'subversion/libsvn_wc/node.c')
-rw-r--r-- | subversion/libsvn_wc/node.c | 1005 |
1 files changed, 318 insertions, 687 deletions
diff --git a/subversion/libsvn_wc/node.c b/subversion/libsvn_wc/node.c index 0bd322f..a1d6b02 100644 --- a/subversion/libsvn_wc/node.c +++ b/subversion/libsvn_wc/node.c @@ -139,129 +139,145 @@ svn_wc__node_get_children(const apr_array_header_t **children, svn_error_t * -svn_wc__internal_get_repos_info(const char **repos_root_url, +svn_wc__internal_get_repos_info(svn_revnum_t *revision, + const char **repos_relpath, + const char **repos_root_url, const char **repos_uuid, svn_wc__db_t *db, const char *local_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - svn_error_t *err; svn_wc__db_status_t status; + svn_boolean_t have_work; - err = svn_wc__db_read_info(&status, NULL, NULL, NULL, - repos_root_url, repos_uuid, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, - db, local_abspath, - result_pool, scratch_pool); - if (err) - { - if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND - && err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY) - return svn_error_trace(err); + SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, repos_relpath, + repos_root_url, repos_uuid, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, &have_work, + db, local_abspath, + result_pool, scratch_pool)); - /* This node is not versioned. Return NULL repos info. */ - svn_error_clear(err); + if ((repos_relpath ? *repos_relpath != NULL : TRUE) + && (repos_root_url ? *repos_root_url != NULL: TRUE) + && (repos_uuid ? *repos_uuid != NULL : TRUE)) + return SVN_NO_ERROR; /* We got the requested information */ - if (repos_root_url) - *repos_root_url = NULL; - if (repos_uuid) - *repos_uuid = NULL; - return SVN_NO_ERROR; + if (!have_work) /* not-present, (server-)excluded? */ + { + return SVN_NO_ERROR; /* Can't fetch more */ } - if (((repos_root_url && *repos_root_url) || !repos_root_url) - && ((repos_uuid && *repos_uuid) || !repos_uuid)) - return SVN_NO_ERROR; - if (status == svn_wc__db_status_deleted) { const char *base_del_abspath, *wrk_del_abspath; SVN_ERR(svn_wc__db_scan_deletion(&base_del_abspath, NULL, - &wrk_del_abspath, + &wrk_del_abspath, NULL, db, local_abspath, scratch_pool, scratch_pool)); if (base_del_abspath) - SVN_ERR(svn_wc__db_scan_base_repos(NULL,repos_root_url, - repos_uuid, db, base_del_abspath, + { + SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, repos_relpath, + repos_root_url, repos_uuid, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, + db, base_del_abspath, result_pool, scratch_pool)); + + /* If we have a repos_relpath, it is of the op-root */ + if (repos_relpath) + *repos_relpath = svn_relpath_join(*repos_relpath, + svn_dirent_skip_ancestor(base_del_abspath, + local_abspath), + result_pool); + /* We keep revision as SVN_INVALID_REVNUM */ + } else if (wrk_del_abspath) - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, - repos_root_url, repos_uuid, - NULL, NULL, NULL, NULL, - db, svn_dirent_dirname( + { + const char *op_root_abspath = NULL; + + SVN_ERR(svn_wc__db_scan_addition(NULL, repos_relpath + ? &op_root_abspath : NULL, + repos_relpath, repos_root_url, + repos_uuid, NULL, NULL, NULL, NULL, + db, svn_dirent_dirname( wrk_del_abspath, scratch_pool), - result_pool, scratch_pool)); + result_pool, scratch_pool)); + + /* If we have a repos_relpath, it is of the op-root */ + if (repos_relpath) + *repos_relpath = svn_relpath_join( + *repos_relpath, + svn_dirent_skip_ancestor(op_root_abspath, + local_abspath), + result_pool); + } } - else if (status == svn_wc__db_status_added) + else /* added, or WORKING incomplete */ { + const char *op_root_abspath = NULL; + /* We have an addition. scan_addition() will find the intended repository location by scanning up the tree. */ - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, - repos_root_url, repos_uuid, - NULL, NULL, NULL, NULL, + SVN_ERR(svn_wc__db_scan_addition(NULL, repos_relpath + ? &op_root_abspath : NULL, + repos_relpath, repos_root_url, + repos_uuid, NULL, NULL, NULL, NULL, db, local_abspath, result_pool, scratch_pool)); } - else - SVN_ERR(svn_wc__db_scan_base_repos(NULL, repos_root_url, repos_uuid, - db, local_abspath, - result_pool, scratch_pool)); + SVN_ERR_ASSERT(repos_root_url == NULL || *repos_root_url != NULL); + SVN_ERR_ASSERT(repos_uuid == NULL || *repos_uuid != NULL); return SVN_NO_ERROR; } svn_error_t * -svn_wc__node_get_repos_info(const char **repos_root_url, +svn_wc__node_get_repos_info(svn_revnum_t *revision, + const char **repos_relpath, + const char **repos_root_url, const char **repos_uuid, svn_wc_context_t *wc_ctx, const char *local_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - return svn_error_trace(svn_wc__internal_get_repos_info( - repos_root_url, repos_uuid, wc_ctx->db, local_abspath, - result_pool, scratch_pool)); + return svn_error_trace( + svn_wc__internal_get_repos_info(revision, + repos_relpath, + repos_root_url, + repos_uuid, + wc_ctx->db, local_abspath, + result_pool, scratch_pool)); } /* Convert DB_KIND into the appropriate NODE_KIND value. * If SHOW_HIDDEN is TRUE, report the node kind as found in the DB * even if DB_STATUS indicates that the node is hidden. - * Else, return svn_kind_none for such nodes. + * Else, return svn_node_none for such nodes. * - * ### This is a bit ugly. We should consider promoting svn_wc__db_kind_t + * ### This is a bit ugly. We should consider promoting svn_kind_t * ### to the de-facto node kind type instead of converting between them * ### in non-backwards compat code. - * ### See also comments at the definition of svn_wc__db_kind_t. */ + * ### See also comments at the definition of svn_kind_t. + * + * ### In reality, the previous comment is out of date, as there is + * ### now only one enumeration for node kinds, and that is + * ### svn_node_kind_t (svn_kind_t was merged with that). But it's + * ### still ugly. + */ static svn_error_t * convert_db_kind_to_node_kind(svn_node_kind_t *node_kind, - svn_wc__db_kind_t db_kind, + svn_node_kind_t db_kind, svn_wc__db_status_t db_status, svn_boolean_t show_hidden) { - switch (db_kind) - { - case svn_wc__db_kind_file: - *node_kind = svn_node_file; - break; - case svn_wc__db_kind_dir: - *node_kind = svn_node_dir; - break; - case svn_wc__db_kind_symlink: - *node_kind = svn_node_file; - break; - case svn_wc__db_kind_unknown: - *node_kind = svn_node_unknown; - break; - default: - SVN_ERR_MALFUNCTION(); - } + *node_kind = db_kind; /* Make sure hidden nodes return svn_node_none. */ if (! show_hidden) @@ -280,33 +296,28 @@ convert_db_kind_to_node_kind(svn_node_kind_t *node_kind, } svn_error_t * -svn_wc_read_kind(svn_node_kind_t *kind, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - svn_boolean_t show_hidden, - apr_pool_t *scratch_pool) +svn_wc_read_kind2(svn_node_kind_t *kind, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t show_deleted, + svn_boolean_t show_hidden, + apr_pool_t *scratch_pool) { - svn_wc__db_status_t db_status; - svn_wc__db_kind_t db_kind; - svn_error_t *err; - - err = svn_wc__db_read_info(&db_status, &db_kind, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - wc_ctx->db, local_abspath, - scratch_pool, scratch_pool); + svn_node_kind_t db_kind; - if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) - { - svn_error_clear(err); - *kind = svn_node_none; - return SVN_NO_ERROR; - } + SVN_ERR(svn_wc__db_read_kind(&db_kind, + wc_ctx->db, local_abspath, + TRUE, + show_deleted, + show_hidden, + scratch_pool)); + + if (db_kind == svn_node_dir) + *kind = svn_node_dir; + else if (db_kind == svn_node_file || db_kind == svn_node_symlink) + *kind = svn_node_file; else - SVN_ERR(err); - - SVN_ERR(convert_db_kind_to_node_kind(kind, db_kind, db_status, show_hidden)); + *kind = svn_node_none; return SVN_NO_ERROR; } @@ -355,213 +366,6 @@ svn_wc__node_get_url(const char **url, result_pool, scratch_pool)); } -/* ### This is essentially a copy-paste of svn_wc__internal_get_url(). - * ### If we decide to keep this one, then it should be rewritten to avoid - * ### code duplication.*/ -svn_error_t * -svn_wc__node_get_repos_relpath(const char **repos_relpath, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - svn_wc__db_status_t status; - svn_boolean_t have_base; - - SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, repos_relpath, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - &have_base, NULL, NULL, - wc_ctx->db, local_abspath, - result_pool, scratch_pool)); - if (*repos_relpath == NULL) - { - if (status == svn_wc__db_status_added) - { - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, repos_relpath, - NULL, NULL, NULL, NULL, - NULL, NULL, - wc_ctx->db, local_abspath, - result_pool, scratch_pool)); - } - else if (have_base) - { - SVN_ERR(svn_wc__db_scan_base_repos(repos_relpath, NULL, - NULL, - wc_ctx->db, local_abspath, - result_pool, scratch_pool)); - } - else if (status == svn_wc__db_status_excluded - || (!have_base && (status == svn_wc__db_status_deleted))) - { - const char *parent_abspath, *name, *parent_relpath; - - svn_dirent_split(&parent_abspath, &name, local_abspath, - scratch_pool); - SVN_ERR(svn_wc__node_get_repos_relpath(&parent_relpath, wc_ctx, - parent_abspath, - scratch_pool, - scratch_pool)); - - if (parent_relpath) - *repos_relpath = svn_relpath_join(parent_relpath, name, - result_pool); - } - else - { - /* Status: obstructed, obstructed_add */ - *repos_relpath = NULL; - return SVN_NO_ERROR; - } - } - - return SVN_NO_ERROR; -} - -svn_error_t * -svn_wc__internal_get_copyfrom_info(const char **copyfrom_root_url, - const char **copyfrom_repos_relpath, - const char **copyfrom_url, - svn_revnum_t *copyfrom_rev, - svn_boolean_t *is_copy_target, - svn_wc__db_t *db, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - const char *original_root_url; - const char *original_repos_relpath; - svn_revnum_t original_revision; - svn_wc__db_status_t status; - - if (copyfrom_root_url) - *copyfrom_root_url = NULL; - if (copyfrom_repos_relpath) - *copyfrom_repos_relpath = NULL; - if (copyfrom_url) - *copyfrom_url = NULL; - if (copyfrom_rev) - *copyfrom_rev = SVN_INVALID_REVNUM; - if (is_copy_target) - *is_copy_target = FALSE; - - SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - &original_repos_relpath, - &original_root_url, NULL, - &original_revision, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, - db, local_abspath, result_pool, scratch_pool)); - if (original_root_url && original_repos_relpath) - { - /* If this was the root of the copy then the URL is immediately - available... */ - const char *my_copyfrom_url; - - if (copyfrom_url || is_copy_target) - my_copyfrom_url = svn_path_url_add_component2(original_root_url, - original_repos_relpath, - result_pool); - - if (copyfrom_root_url) - *copyfrom_root_url = original_root_url; - if (copyfrom_repos_relpath) - *copyfrom_repos_relpath = original_repos_relpath; - if (copyfrom_url) - *copyfrom_url = my_copyfrom_url; - - if (copyfrom_rev) - *copyfrom_rev = original_revision; - - if (is_copy_target) - { - /* ### At this point we'd just set is_copy_target to TRUE, *but* we - * currently want to model wc-1 behaviour. Particularly, this - * affects mixed-revision copies (e.g. wc-wc copy): - * - Wc-1 saw only the root of a mixed-revision copy as the copy's - * root. - * - Wc-ng returns an explicit original_root_url, - * original_repos_relpath pair for each subtree with mismatching - * revision. - * We need to compensate for that: Find out if the parent of - * this node is also copied and has a matching copy_from URL. If so, - * nevermind the revision, just like wc-1 did, and say this was not - * a separate copy target. */ - const char *parent_abspath; - const char *base_name; - const char *parent_copyfrom_url; - - svn_dirent_split(&parent_abspath, &base_name, local_abspath, - scratch_pool); - - /* This is a copied node, so we should never fall off the top of a - * working copy here. */ - SVN_ERR(svn_wc__internal_get_copyfrom_info(NULL, NULL, - &parent_copyfrom_url, - NULL, NULL, - db, parent_abspath, - scratch_pool, - scratch_pool)); - - /* So, count this as a separate copy target only if the URLs - * don't match up, or if the parent isn't copied at all. */ - if (parent_copyfrom_url == NULL - || strcmp(my_copyfrom_url, - svn_path_url_add_component2(parent_copyfrom_url, - base_name, - scratch_pool)) != 0) - *is_copy_target = TRUE; - } - } - else if ((status == svn_wc__db_status_added) - && (copyfrom_rev || copyfrom_url || copyfrom_root_url - || copyfrom_repos_relpath)) - { - /* ...But if this is merely the descendant of an explicitly - copied/moved directory, we need to do a bit more work to - determine copyfrom_url and copyfrom_rev. */ - const char *op_root_abspath; - - SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath, NULL, NULL, - NULL, &original_repos_relpath, - &original_root_url, NULL, - &original_revision, db, local_abspath, - result_pool, scratch_pool)); - if (status == svn_wc__db_status_copied || - status == svn_wc__db_status_moved_here) - { - const char *src_parent_url; - const char *src_relpath; - - src_parent_url = svn_path_url_add_component2(original_root_url, - original_repos_relpath, - scratch_pool); - src_relpath = svn_dirent_is_child(op_root_abspath, local_abspath, - scratch_pool); - if (src_relpath) - { - if (copyfrom_root_url) - *copyfrom_root_url = original_root_url; - if (copyfrom_repos_relpath) - *copyfrom_repos_relpath = svn_relpath_join( - original_repos_relpath, - src_relpath, result_pool); - if (copyfrom_url) - *copyfrom_url = svn_path_url_add_component2(src_parent_url, - src_relpath, - result_pool); - if (copyfrom_rev) - *copyfrom_rev = original_revision; - } - } - } - - return SVN_NO_ERROR; -} - - /* A recursive node-walker, helper for svn_wc__internal_walk_children(). * * Call WALK_CALLBACK with WALK_BATON on all children (recursively) of @@ -603,7 +407,7 @@ walker_helper(svn_wc__db_t *db, { const char *child_name = svn__apr_hash_index_key(hi); struct svn_wc__db_walker_info_t *wi = svn__apr_hash_index_val(hi); - svn_wc__db_kind_t child_kind = wi->kind; + svn_node_kind_t child_kind = wi->kind; svn_wc__db_status_t child_status = wi->status; const char *child_abspath; @@ -627,7 +431,7 @@ walker_helper(svn_wc__db_t *db, } /* Return the child, if appropriate. */ - if ( (child_kind == svn_wc__db_kind_file + if ( (child_kind == svn_node_file || depth >= svn_depth_immediates) && svn_wc__internal_changelist_match(db, child_abspath, changelist_filter, @@ -646,7 +450,7 @@ walker_helper(svn_wc__db_t *db, } /* Recurse into this directory, if appropriate. */ - if (child_kind == svn_wc__db_kind_dir + if (child_kind == svn_node_dir && depth >= svn_depth_immediates) { svn_depth_t depth_below_here = depth; @@ -681,7 +485,7 @@ svn_wc__internal_walk_children(svn_wc__db_t *db, void *cancel_baton, apr_pool_t *scratch_pool) { - svn_wc__db_kind_t db_kind; + svn_node_kind_t db_kind; svn_node_kind_t kind; svn_wc__db_status_t status; apr_hash_t *changelist_hash = NULL; @@ -706,13 +510,13 @@ svn_wc__internal_walk_children(svn_wc__db_t *db, changelist_hash, scratch_pool)) SVN_ERR(walk_callback(local_abspath, kind, walk_baton, scratch_pool)); - if (db_kind == svn_wc__db_kind_file + if (db_kind == svn_node_file || status == svn_wc__db_status_not_present || status == svn_wc__db_status_excluded || status == svn_wc__db_status_server_excluded) return SVN_NO_ERROR; - if (db_kind == svn_wc__db_kind_dir) + if (db_kind == svn_node_dir) { return svn_error_trace( walker_helper(db, local_abspath, show_hidden, changelist_hash, @@ -748,13 +552,16 @@ svn_wc__node_is_status_deleted(svn_boolean_t *is_deleted, } svn_error_t * -svn_wc__node_is_status_server_excluded(svn_boolean_t *is_server_excluded, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *scratch_pool) +svn_wc__node_get_deleted_ancestor(const char **deleted_ancestor_abspath, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { svn_wc__db_status_t status; + *deleted_ancestor_abspath = NULL; + SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -762,47 +569,54 @@ svn_wc__node_is_status_server_excluded(svn_boolean_t *is_server_excluded, NULL, NULL, NULL, NULL, NULL, wc_ctx->db, local_abspath, scratch_pool, scratch_pool)); - *is_server_excluded = (status == svn_wc__db_status_server_excluded); + + if (status == svn_wc__db_status_deleted) + SVN_ERR(svn_wc__db_scan_deletion(deleted_ancestor_abspath, NULL, NULL, + NULL, wc_ctx->db, local_abspath, + result_pool, scratch_pool)); return SVN_NO_ERROR; } svn_error_t * -svn_wc__node_is_status_not_present(svn_boolean_t *is_not_present, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *scratch_pool) +svn_wc__node_is_not_present(svn_boolean_t *is_not_present, + svn_boolean_t *is_excluded, + svn_boolean_t *is_server_excluded, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t base_only, + apr_pool_t *scratch_pool) { svn_wc__db_status_t status; - SVN_ERR(svn_wc__db_read_info(&status, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - wc_ctx->db, local_abspath, - scratch_pool, scratch_pool)); - *is_not_present = (status == svn_wc__db_status_not_present); + if (base_only) + { + SVN_ERR(svn_wc__db_base_get_info(&status, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, + wc_ctx->db, local_abspath, + scratch_pool, scratch_pool)); + } + else + { + SVN_ERR(svn_wc__db_read_info(&status, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + wc_ctx->db, local_abspath, + scratch_pool, scratch_pool)); + } - return SVN_NO_ERROR; -} + if (is_not_present) + *is_not_present = (status == svn_wc__db_status_not_present); -svn_error_t * -svn_wc__node_is_status_excluded(svn_boolean_t *is_excluded, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *scratch_pool) -{ - svn_wc__db_status_t status; + if (is_excluded) + *is_excluded = (status == svn_wc__db_status_excluded); - SVN_ERR(svn_wc__db_read_info(&status, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - wc_ctx->db, local_abspath, - scratch_pool, scratch_pool)); - *is_excluded = (status == svn_wc__db_status_excluded); + if (is_server_excluded) + *is_server_excluded = (status == svn_wc__db_status_server_excluded); return SVN_NO_ERROR; } @@ -847,48 +661,80 @@ svn_wc__node_has_working(svn_boolean_t *has_working, } -static svn_error_t * -get_base_rev(svn_revnum_t *base_revision, - svn_wc__db_t *db, - const char *local_abspath, - apr_pool_t *scratch_pool) +svn_error_t * +svn_wc__node_get_base(svn_node_kind_t *kind, + svn_revnum_t *revision, + const char **repos_relpath, + const char **repos_root_url, + const char **repos_uuid, + const char **lock_token, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t ignore_enoent, + svn_boolean_t show_hidden, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { - svn_boolean_t have_base; svn_error_t *err; + svn_wc__db_status_t status; + svn_wc__db_lock_t *lock; + svn_node_kind_t db_kind; - err = svn_wc__db_base_get_info(NULL, NULL, base_revision, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - db, local_abspath, - scratch_pool, scratch_pool); + err = svn_wc__db_base_get_info(&status, &db_kind, revision, repos_relpath, + repos_root_url, repos_uuid, NULL, + NULL, NULL, NULL, NULL, NULL, + lock_token ? &lock : NULL, + NULL, NULL, NULL, + wc_ctx->db, local_abspath, + result_pool, scratch_pool); - if (!err || err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND) + if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND) return svn_error_trace(err); + else if (err + || (!err && !show_hidden + && (status != svn_wc__db_status_normal + && status != svn_wc__db_status_incomplete))) + { + if (!ignore_enoent) + { + if (err) + return svn_error_trace(err); + else + return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL, + _("The node '%s' was not found."), + svn_dirent_local_style(local_abspath, + scratch_pool)); + } + svn_error_clear(err); - svn_error_clear(err); + if (kind) + *kind = svn_node_unknown; + if (revision) + *revision = SVN_INVALID_REVNUM; + if (repos_relpath) + *repos_relpath = NULL; + if (repos_root_url) + *repos_root_url = NULL; + if (repos_uuid) + *repos_uuid = NULL; + if (lock_token) + *lock_token = NULL; + return SVN_NO_ERROR; + } - SVN_ERR(svn_wc__db_read_info(NULL, NULL, base_revision, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, &have_base, NULL, - NULL, NULL, NULL, NULL, NULL, - db, local_abspath, - scratch_pool, scratch_pool)); + if (kind) + *kind = db_kind; + if (lock_token) + *lock_token = lock ? lock->token : NULL; + SVN_ERR_ASSERT(!revision || SVN_IS_VALID_REVNUM(*revision)); + SVN_ERR_ASSERT(!repos_relpath || *repos_relpath); + SVN_ERR_ASSERT(!repos_root_url || *repos_root_url); + SVN_ERR_ASSERT(!repos_uuid || *repos_uuid); return SVN_NO_ERROR; } svn_error_t * -svn_wc__node_get_base_rev(svn_revnum_t *base_revision, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *scratch_pool) -{ - return svn_error_trace(get_base_rev(base_revision, wc_ctx->db, - local_abspath, scratch_pool)); -} - -svn_error_t * svn_wc__node_get_pre_ng_status_data(svn_revnum_t *revision, svn_revnum_t *changed_rev, apr_time_t *changed_date, @@ -922,158 +768,16 @@ svn_wc__node_get_pre_ng_status_data(svn_revnum_t *revision, SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, revision, NULL, NULL, NULL, changed_rev, changed_date, changed_author, NULL, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, wc_ctx->db, local_abspath, result_pool, scratch_pool)); - else - { - /* Sorry, we need a function to peek below the current working and - the BASE layer. And we don't have one yet. - - ### Better to report nothing, than the wrong information */ - } - - return SVN_NO_ERROR; -} - - -svn_error_t * -svn_wc__internal_get_commit_base_rev(svn_revnum_t *commit_base_revision, - svn_wc__db_t *db, - const char *local_abspath, - apr_pool_t *scratch_pool) -{ - svn_wc__db_status_t status; - svn_boolean_t have_base; - svn_boolean_t have_more_work; - svn_revnum_t revision; - svn_revnum_t original_revision; - - *commit_base_revision = SVN_INVALID_REVNUM; - - SVN_ERR(svn_wc__db_read_info(&status, NULL, &revision, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, &original_revision, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - &have_base, &have_more_work, NULL, - db, local_abspath, scratch_pool, scratch_pool)); - - if (SVN_IS_VALID_REVNUM(revision)) - { - /* We are looking directly at BASE */ - *commit_base_revision = revision; - return SVN_NO_ERROR; - } - else if (SVN_IS_VALID_REVNUM(original_revision)) - { - /* We are looking at a copied node */ - *commit_base_revision = original_revision; - return SVN_NO_ERROR; - } - - if (status == svn_wc__db_status_added) - { - /* If the node was copied/moved-here, return the copy/move source - revision (not this node's base revision). */ - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, commit_base_revision, - db, local_abspath, - scratch_pool, scratch_pool)); - - - if (SVN_IS_VALID_REVNUM(*commit_base_revision)) - return SVN_NO_ERROR; - /* Fall through to handle simple replacements */ - } else if (status == svn_wc__db_status_deleted) - { - const char *work_del_abspath; - - SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, - &work_del_abspath, - db, local_abspath, - scratch_pool, scratch_pool)); - if (work_del_abspath != NULL) - { - /* This is a deletion within a copied subtree. Get the copied-from - * revision. */ - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, - commit_base_revision, - db, - svn_dirent_dirname(work_del_abspath, - scratch_pool), - scratch_pool, scratch_pool)); - - SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(*commit_base_revision)); - - return SVN_NO_ERROR; - } - /* else deletion of BASE node, fall through */ - } - - /* Catch replacement by local addition and deleted BASE nodes. */ - if (have_base && !have_more_work) - { - SVN_ERR(svn_wc__db_base_get_info(&status, NULL, commit_base_revision, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - db, local_abspath, - scratch_pool, scratch_pool)); - - if (status == svn_wc__db_status_not_present) - *commit_base_revision = SVN_INVALID_REVNUM; /* No replacement */ - } - - return SVN_NO_ERROR; -} - -svn_error_t * -svn_wc__node_get_commit_base_rev(svn_revnum_t *commit_base_revision, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *scratch_pool) -{ - return svn_error_trace(svn_wc__internal_get_commit_base_rev( - commit_base_revision, wc_ctx->db, local_abspath, - scratch_pool)); -} - -svn_error_t * -svn_wc__node_get_lock_info(const char **lock_token, - const char **lock_owner, - const char **lock_comment, - apr_time_t *lock_date, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - svn_wc__db_lock_t *lock; - svn_error_t *err; - - err = svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, &lock, NULL, - NULL, - wc_ctx->db, local_abspath, - result_pool, scratch_pool); - - if (err) - { - if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND) - return svn_error_trace(err); - - svn_error_clear(err); - lock = NULL; - } - if (lock_token) - *lock_token = lock ? lock->token : NULL; - if (lock_owner) - *lock_owner = lock ? lock->owner : NULL; - if (lock_comment) - *lock_comment = lock ? lock->comment : NULL; - if (lock_date) - *lock_date = lock ? lock->date : 0; + /* Check the information below a WORKING delete */ + SVN_ERR(svn_wc__db_read_pristine_info(NULL, NULL, changed_rev, + changed_date, changed_author, NULL, + NULL, NULL, NULL, NULL, + wc_ctx->db, local_abspath, + result_pool, scratch_pool)); return SVN_NO_ERROR; } @@ -1133,7 +837,7 @@ svn_wc__internal_node_get_schedule(svn_wc_schedule_t *schedule, /* Find out details of our deletion. */ SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, - &work_del_abspath, + &work_del_abspath, NULL, db, local_abspath, scratch_pool, scratch_pool)); @@ -1206,78 +910,6 @@ svn_wc__node_get_schedule(svn_wc_schedule_t *schedule, } svn_error_t * -svn_wc__node_get_conflict_info(const char **conflict_old, - const char **conflict_new, - const char **conflict_wrk, - const char **prejfile, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - svn_boolean_t conflicted; - - SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, &conflicted, - NULL, NULL, NULL, NULL, NULL, NULL, - wc_ctx->db, local_abspath, - scratch_pool, scratch_pool)); - - if (conflict_old) - *conflict_old = NULL; - if (conflict_new) - *conflict_new = NULL; - if (conflict_wrk) - *conflict_wrk = NULL; - if (prejfile) - *prejfile = NULL; - - if (conflicted - && (conflict_old || conflict_new || conflict_wrk || prejfile)) - { - const apr_array_header_t *conflicts; - int j; - SVN_ERR(svn_wc__db_read_conflicts(&conflicts, wc_ctx->db, local_abspath, - scratch_pool, scratch_pool)); - - for (j = 0; j < conflicts->nelts; j++) - { - const svn_wc_conflict_description2_t *cd; - cd = APR_ARRAY_IDX(conflicts, j, - const svn_wc_conflict_description2_t *); - - switch (cd->kind) - { - case svn_wc_conflict_kind_text: - if (conflict_old) - *conflict_old = svn_dirent_basename(cd->base_abspath, - result_pool); - - if (conflict_new) - *conflict_new = svn_dirent_basename(cd->their_abspath, - result_pool); - - if (conflict_wrk) - *conflict_wrk = svn_dirent_basename(cd->my_abspath, - result_pool); - break; - - case svn_wc_conflict_kind_property: - if (prejfile) - *prejfile = svn_dirent_basename(cd->their_abspath, - result_pool); - break; - case svn_wc_conflict_kind_tree: - break; - } - } - } - - return SVN_NO_ERROR; -} - -svn_error_t * svn_wc__node_clear_dav_cache_recursive(svn_wc_context_t *wc_ctx, const char *local_abspath, apr_pool_t *scratch_pool) @@ -1300,18 +932,18 @@ svn_wc__node_get_lock_tokens_recursive(apr_hash_t **lock_tokens, } svn_error_t * -svn_wc__get_server_excluded_subtrees(apr_hash_t **server_excluded_subtrees, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +svn_wc__get_excluded_subtrees(apr_hash_t **server_excluded_subtrees, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { return svn_error_trace( - svn_wc__db_get_server_excluded_subtrees(server_excluded_subtrees, - wc_ctx->db, - local_abspath, - result_pool, - scratch_pool)); + svn_wc__db_get_excluded_subtrees(server_excluded_subtrees, + wc_ctx->db, + local_abspath, + result_pool, + scratch_pool)); } svn_error_t * @@ -1396,8 +1028,8 @@ svn_wc__internal_get_origin(svn_boolean_t *is_copy, SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath, NULL, NULL, NULL, &original_repos_relpath, repos_root_url, - repos_uuid, - revision, db, local_abspath, + repos_uuid, revision, + db, local_abspath, result_pool, scratch_pool)); if (status == svn_wc__db_status_added) @@ -1432,7 +1064,7 @@ svn_wc__internal_get_origin(svn_boolean_t *is_copy, SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, revision, repos_relpath, repos_root_url, repos_uuid, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, + NULL, NULL, NULL, db, local_abspath, result_pool, scratch_pool)); } @@ -1462,68 +1094,38 @@ svn_wc__node_get_origin(svn_boolean_t *is_copy, } svn_error_t * -svn_wc__node_get_commit_status(svn_node_kind_t *kind, - svn_boolean_t *added, +svn_wc__node_get_commit_status(svn_boolean_t *added, svn_boolean_t *deleted, svn_boolean_t *is_replace_root, - svn_boolean_t *not_present, - svn_boolean_t *excluded, svn_boolean_t *is_op_root, - svn_boolean_t *symlink, svn_revnum_t *revision, - const char **repos_relpath, svn_revnum_t *original_revision, const char **original_repos_relpath, - svn_boolean_t *conflicted, - const char **changelist, - svn_boolean_t *props_mod, - svn_boolean_t *update_root, - const char **lock_token, svn_wc_context_t *wc_ctx, const char *local_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { svn_wc__db_status_t status; - svn_wc__db_kind_t db_kind; - svn_wc__db_lock_t *lock; - svn_boolean_t had_props; - svn_boolean_t props_mod_tmp; svn_boolean_t have_base; svn_boolean_t have_more_work; svn_boolean_t op_root; - if (!props_mod) - props_mod = &props_mod_tmp; - /* ### All of this should be handled inside a single read transaction */ - SVN_ERR(svn_wc__db_read_info(&status, &db_kind, revision, repos_relpath, + SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, original_repos_relpath, NULL, NULL, - original_revision, &lock, NULL, NULL, - changelist, conflicted, - &op_root, &had_props, props_mod, + original_revision, NULL, NULL, NULL, + NULL, NULL, + &op_root, NULL, NULL, &have_base, &have_more_work, NULL, wc_ctx->db, local_abspath, result_pool, scratch_pool)); - if (kind) - { - if (db_kind == svn_wc__db_kind_file) - *kind = svn_node_file; - else if (db_kind == svn_wc__db_kind_dir) - *kind = svn_node_dir; - else - *kind = svn_node_unknown; - } if (added) *added = (status == svn_wc__db_status_added); if (deleted) *deleted = (status == svn_wc__db_status_deleted); - if (not_present) - *not_present = (status == svn_wc__db_status_not_present); - if (excluded) - *excluded = (status == svn_wc__db_status_excluded); if (is_op_root) *is_op_root = op_root; @@ -1539,40 +1141,19 @@ svn_wc__node_get_commit_status(svn_node_kind_t *kind, *is_replace_root = FALSE; } - if (symlink) - { - apr_hash_t *props; - *symlink = FALSE; - - if (db_kind == svn_wc__db_kind_file - && (had_props || *props_mod)) - { - SVN_ERR(svn_wc__db_read_props(&props, wc_ctx->db, local_abspath, - scratch_pool, scratch_pool)); - - *symlink = ((props != NULL) - && (apr_hash_get(props, SVN_PROP_SPECIAL, - APR_HASH_KEY_STRING) != NULL)); - } - } - /* Retrieve some information from BASE which is needed for replacing - and/or deleting BASE nodes. (We don't need lock here) */ + and/or deleting BASE nodes. */ if (have_base - && ((revision && !SVN_IS_VALID_REVNUM(*revision)) - || (update_root && status == svn_wc__db_status_normal))) + && !have_more_work + && op_root + && (revision && !SVN_IS_VALID_REVNUM(*revision))) { SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, revision, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, update_root, + NULL, NULL, NULL, NULL, wc_ctx->db, local_abspath, scratch_pool, scratch_pool)); } - else if (update_root) - *update_root = FALSE; - - if (lock_token) - *lock_token = lock ? lock->token : NULL; return SVN_NO_ERROR; } @@ -1637,35 +1218,34 @@ svn_wc__rename_wc(svn_wc_context_t *wc_ctx, svn_error_t * svn_wc__check_for_obstructions(svn_wc_notify_state_t *obstruction_state, svn_node_kind_t *kind, - svn_boolean_t *added, svn_boolean_t *deleted, - svn_boolean_t *conflicted, + svn_boolean_t *excluded, + svn_depth_t *parent_depth, svn_wc_context_t *wc_ctx, const char *local_abspath, svn_boolean_t no_wcroot_check, apr_pool_t *scratch_pool) { svn_wc__db_status_t status; - svn_wc__db_kind_t db_kind; + svn_node_kind_t db_kind; svn_node_kind_t disk_kind; - svn_boolean_t conflicted_p; svn_error_t *err; *obstruction_state = svn_wc_notify_state_inapplicable; if (kind) *kind = svn_node_none; - if (added) - *added = FALSE; if (deleted) *deleted = FALSE; - if (conflicted) - *conflicted = FALSE; + if (excluded) + *excluded = FALSE; + if (parent_depth) + *parent_depth = svn_depth_unknown; SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool)); err = svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, &conflicted_p, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, wc_ctx->db, local_abspath, scratch_pool, scratch_pool); @@ -1682,9 +1262,10 @@ svn_wc__check_for_obstructions(svn_wc_notify_state_t *obstruction_state, } err = svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, parent_depth, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, wc_ctx->db, svn_dirent_dirname(local_abspath, scratch_pool), scratch_pool, scratch_pool); @@ -1699,7 +1280,7 @@ svn_wc__check_for_obstructions(svn_wc_notify_state_t *obstruction_state, else SVN_ERR(err); - if (db_kind != svn_wc__db_kind_dir + if (db_kind != svn_node_dir || (status != svn_wc__db_status_normal && status != svn_wc__db_status_added)) { @@ -1714,7 +1295,7 @@ svn_wc__check_for_obstructions(svn_wc_notify_state_t *obstruction_state, /* Check for obstructing working copies */ if (!no_wcroot_check - && db_kind == svn_wc__db_kind_dir + && db_kind == svn_node_dir && status == svn_wc__db_status_normal) { svn_boolean_t is_root; @@ -1745,14 +1326,14 @@ svn_wc__check_for_obstructions(svn_wc_notify_state_t *obstruction_state, case svn_wc__db_status_excluded: case svn_wc__db_status_server_excluded: + if (excluded) + *excluded = TRUE; + /* fall through */ case svn_wc__db_status_incomplete: *obstruction_state = svn_wc_notify_state_missing; break; case svn_wc__db_status_added: - if (added) - *added = TRUE; - /* Fall through to svn_wc__db_status_normal */ case svn_wc__db_status_normal: if (disk_kind == svn_node_none) *obstruction_state = svn_wc_notify_state_missing; @@ -1771,17 +1352,67 @@ svn_wc__check_for_obstructions(svn_wc_notify_state_t *obstruction_state, SVN_ERR_MALFUNCTION(); } - if (conflicted_p && (conflicted != NULL)) - { - svn_boolean_t text_c, prop_c, tree_c; + return SVN_NO_ERROR; +} - SVN_ERR(svn_wc__internal_conflicted_p(&text_c, &prop_c, &tree_c, - wc_ctx->db, local_abspath, - scratch_pool)); - *conflicted = (text_c || prop_c || tree_c); - } +svn_error_t * +svn_wc__node_was_moved_away(const char **moved_to_abspath, + const char **op_root_abspath, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_boolean_t is_deleted; + + if (moved_to_abspath) + *moved_to_abspath = NULL; + if (op_root_abspath) + *op_root_abspath = NULL; + + SVN_ERR(svn_wc__node_is_status_deleted(&is_deleted, wc_ctx, local_abspath, + scratch_pool)); + if (is_deleted) + SVN_ERR(svn_wc__db_scan_deletion(NULL, moved_to_abspath, NULL, + op_root_abspath, wc_ctx->db, + local_abspath, + result_pool, scratch_pool)); return SVN_NO_ERROR; } + +svn_error_t * +svn_wc__node_was_moved_here(const char **moved_from_abspath, + const char **delete_op_root_abspath, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_error_t *err; + + if (moved_from_abspath) + *moved_from_abspath = NULL; + if (delete_op_root_abspath) + *delete_op_root_abspath = NULL; + + err = svn_wc__db_scan_moved(moved_from_abspath, NULL, NULL, + delete_op_root_abspath, + wc_ctx->db, local_abspath, + result_pool, scratch_pool); + + if (err) + { + /* Return error for not added nodes */ + if (err->apr_err != SVN_ERR_WC_PATH_UNEXPECTED_STATUS) + return svn_error_trace(err); + + /* Path not moved here */ + svn_error_clear(err); + return SVN_NO_ERROR; + } + + return SVN_NO_ERROR; +} |