You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2010/06/29 13:44:28 UTC
svn commit: r958938 - /subversion/trunk/subversion/libsvn_wc/copy.c
Author: rhuijben
Date: Tue Jun 29 11:44:27 2010
New Revision: 958938
URL: http://svn.apache.org/viewvc?rev=958938&view=rev
Log:
Replace two entry read operations and a few small wc_node calls with a
few more advanced wc_db read operations in svn_wc_copy3().
* subversion/libsvn_wc/copy.c
(svn_wc_copy3): Read repository information directly from the wc_db
api and restructore error creation code to use the already read
db status where possible.
Modified:
subversion/trunk/subversion/libsvn_wc/copy.c
Modified: subversion/trunk/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=958938&r1=958937&r2=958938&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/copy.c (original)
+++ subversion/trunk/subversion/libsvn_wc/copy.c Tue Jun 29 11:44:27 2010
@@ -599,52 +599,118 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
void *notify_baton,
apr_pool_t *scratch_pool)
{
+ svn_wc__db_t *db = wc_ctx->db;
svn_node_kind_t src_kind;
- const svn_wc_entry_t *dst_entry, *src_entry;
- svn_wc__db_kind_t kind;
- const char *dstdir_abspath, *dst_basename;
-
- svn_dirent_split(&dstdir_abspath, &dst_basename, dst_abspath, scratch_pool);
-
- SVN_ERR(svn_wc__get_entry_versioned(&dst_entry, wc_ctx->db, dstdir_abspath,
- svn_node_dir, FALSE, FALSE,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__get_entry_versioned(&src_entry, wc_ctx->db, src_abspath,
- svn_node_unknown, FALSE, FALSE,
- scratch_pool, scratch_pool));
-
- if ((src_entry->repos != NULL && dst_entry->repos != NULL) &&
- strcmp(src_entry->repos, dst_entry->repos) != 0)
- return svn_error_createf
- (SVN_ERR_WC_INVALID_SCHEDULE, NULL,
- _("Cannot copy to '%s', as it is not from repository '%s'; "
- "it is from '%s'"),
- svn_dirent_local_style(dst_abspath, scratch_pool),
- src_entry->repos, dst_entry->repos);
- if (dst_entry->schedule == svn_wc_schedule_delete)
- return svn_error_createf
- (SVN_ERR_WC_INVALID_SCHEDULE, NULL,
- _("Cannot copy to '%s' as it is scheduled for deletion"),
- svn_dirent_local_style(dst_abspath, scratch_pool));
+ svn_wc__db_kind_t src_db_kind, dst_kind;
+ const char *dstdir_abspath;
+
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
+
+ dstdir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
+
+ {
+ svn_wc__db_status_t src_status, dstdir_status;
+ const char *src_repos_root_url, *dst_repos_root_url;
+ const char *src_repos_uuid, *dst_repos_uuid;
+ svn_error_t *err;
+
+ err = svn_wc__db_read_info(&src_status, &src_db_kind, NULL, NULL,
+ &src_repos_root_url, &src_repos_uuid, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ db, src_abspath, scratch_pool, scratch_pool);
+
+ if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ {
+ /* Replicate old error code and text */
+ svn_error_clear(err);
+ return svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL,
+ _("'%s' is not under version control"),
+ svn_dirent_local_style(src_abspath,
+ scratch_pool));
+ }
+ else
+ SVN_ERR(err);
+
+ SVN_ERR(svn_wc__db_read_info(&dstdir_status, NULL, NULL, NULL,
+ &dst_repos_root_url, &dst_repos_uuid, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ db, dstdir_abspath, scratch_pool, scratch_pool));
+
+ if (!src_repos_root_url)
+ {
+ if (src_status == svn_wc__db_status_added)
+ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
+ &src_repos_root_url,
+ &src_repos_uuid, NULL, NULL, NULL,
+ NULL,
+ db, src_abspath,
+ scratch_pool, scratch_pool));
+ else
+ /* If not added, the node must have a base or we can't copy */
+ SVN_ERR(svn_wc__db_scan_base_repos(NULL, &src_repos_root_url,
+ &src_repos_uuid,
+ db, src_abspath,
+ scratch_pool, scratch_pool));
+ }
+
+ if (!dst_repos_root_url)
+ {
+ if (dstdir_status == svn_wc__db_status_added)
+ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
+ &dst_repos_root_url,
+ &dst_repos_uuid, NULL, NULL, NULL,
+ NULL,
+ db, dstdir_abspath,
+ scratch_pool, scratch_pool));
+ else
+ /* If not added, the node must have a base or we can't copy */
+ SVN_ERR(svn_wc__db_scan_base_repos(NULL, &dst_repos_root_url,
+ &dst_repos_uuid,
+ db, dstdir_abspath,
+ scratch_pool, scratch_pool));
+ }
+
+ if (strcmp(src_repos_root_url, dst_repos_root_url) != 0
+ || strcmp(src_repos_uuid, dst_repos_uuid) != 0)
+ return svn_error_createf(
+ SVN_ERR_WC_INVALID_SCHEDULE, NULL,
+ _("Cannot copy to '%s', as it is not from repository '%s'; "
+ "it is from '%s'"),
+ svn_dirent_local_style(dst_abspath, scratch_pool),
+ src_repos_root_url, dst_repos_root_url);
+
+ if (dstdir_status == svn_wc__db_status_deleted)
+ return svn_error_createf(
+ SVN_ERR_WC_INVALID_SCHEDULE, NULL,
+ _("Cannot copy to '%s' as it is scheduled for deletion"),
+ svn_dirent_local_style(dst_abspath, scratch_pool));
+ }
/* TODO(#2843): Rework the error report. */
/* Check if the copy target is missing or hidden and thus not exist on the
disk, before actually doing the file copy. */
- SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, dst_abspath, TRUE,
- scratch_pool));
+ {
+ svn_wc__db_status_t dst_status;
+ svn_error_t *err;
+
+ err = svn_wc__db_read_info(&dst_status, &dst_kind, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ db, dst_abspath, scratch_pool, scratch_pool);
- if (kind != svn_wc__db_kind_unknown)
- {
- svn_wc__db_status_t status;
+ if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ return svn_error_return(err);
- 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,
- wc_ctx->db, dst_abspath,
- scratch_pool, scratch_pool));
+ svn_error_clear(err);
- switch (status)
+ if (!err)
+ switch (dst_status)
{
case svn_wc__db_status_excluded:
return svn_error_createf(
@@ -658,18 +724,29 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
_("'%s' is already under version control"),
svn_dirent_local_style(dst_abspath, scratch_pool));
- /* Explicitly ignore other statii */
+ case svn_wc__db_status_deleted:
+ case svn_wc__db_status_obstructed_delete:
+ case svn_wc__db_status_not_present:
+ break; /* OK to add */
+
default:
- break;
+ return svn_error_createf(SVN_ERR_ENTRY_EXISTS, NULL,
+ _("There is already a versioned item '%s'"),
+ svn_dirent_local_style(dst_abspath,
+ scratch_pool));
}
- }
+ }
SVN_ERR(svn_io_check_path(src_abspath, &src_kind, scratch_pool));
+#ifndef SINGLE_DB
if (src_kind == svn_node_file ||
- (src_entry->kind == svn_node_file && src_kind == svn_node_none))
+ (src_kind == svn_node_none
+ && (src_db_kind == svn_wc__db_kind_file
+ || src_db_kind == svn_wc__db_kind_symlink)))
+#endif
{
- svn_node_kind_t dst_kind, dst_db_kind;
+ svn_node_kind_t dst_kind;
/* This is the error checking from copy_file_administratively
but converted to wc-ng. It's not in copy_file since this
@@ -681,30 +758,17 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
_("'%s' already exists and is in the way"),
svn_dirent_local_style(dst_abspath,
scratch_pool));
- SVN_ERR(svn_wc_read_kind(&dst_db_kind, wc_ctx, dst_abspath, TRUE,
- scratch_pool));
- if (dst_db_kind != svn_node_none)
- {
- svn_boolean_t is_deleted, is_present;
-
- SVN_ERR(svn_wc__node_is_status_deleted(&is_deleted, wc_ctx,
- dst_abspath, scratch_pool));
- SVN_ERR(svn_wc__node_is_status_present(&is_present, wc_ctx,
- dst_abspath, scratch_pool));
- if (is_present && !is_deleted)
- return svn_error_createf(SVN_ERR_ENTRY_EXISTS, NULL,
- _("There is already a versioned item '%s'"),
- svn_dirent_local_style(dst_abspath,
- scratch_pool));
-
- }
+ }
+ if (src_db_kind == svn_wc__db_kind_file
+ || src_db_kind == svn_wc__db_kind_symlink)
+ {
SVN_ERR(copy_versioned_file(wc_ctx, src_abspath, dst_abspath,
cancel_func, cancel_baton,
notify_func, notify_baton,
scratch_pool));
}
- else if (src_kind == svn_node_dir)
+ else
{
SVN_ERR(copy_versioned_dir(wc_ctx, src_abspath, dst_abspath,
cancel_func, cancel_baton,