You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2010/03/16 17:40:51 UTC
svn commit: r923858 - /subversion/trunk/subversion/libsvn_client/copy.c
Author: philip
Date: Tue Mar 16 16:40:51 2010
New Revision: 923858
URL: http://svn.apache.org/viewvc?rev=923858&view=rev
Log:
Remove an access baton from client copy.
* subversion/libsvn_client/copy.c
(repos_to_wc_copy_locked): New, copied from the second half of
repos_to_wc_copy.
(repos_to_wc_copy): Acquire and release locks instead of opening an
access baton, moved locked part to repos_to_wc_copy_locked.
Modified:
subversion/trunk/subversion/libsvn_client/copy.c
Modified: subversion/trunk/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/copy.c?rev=923858&r1=923857&r2=923858&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/copy.c (original)
+++ subversion/trunk/subversion/libsvn_client/copy.c Tue Mar 16 16:40:51 2010
@@ -1554,6 +1554,114 @@ repos_to_wc_copy_single(svn_client__copy
return SVN_NO_ERROR;
}
+static svn_error_t*
+repos_to_wc_copy_locked(const apr_array_header_t *copy_pairs,
+ const char *top_dst_path,
+ svn_boolean_t ignore_externals,
+ svn_ra_session_t *ra_session,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ int i;
+ const char *src_uuid = NULL, *dst_uuid = NULL;
+ svn_boolean_t same_repositories;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ /* We've already checked for physical obstruction by a working file.
+ But there could also be logical obstruction by an entry whose
+ working file happens to be missing.*/
+ for (i = 0; i < copy_pairs->nelts; i++)
+ {
+ svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
+ svn_client__copy_pair_t *);
+ const svn_wc_entry_t *ent;
+ const char *dst_abspath;
+
+ svn_pool_clear(iterpool);
+ SVN_ERR(svn_dirent_get_absolute(&dst_abspath, pair->dst, iterpool));
+
+ SVN_ERR(svn_wc__maybe_get_entry(&ent, ctx->wc_ctx, dst_abspath,
+ svn_node_unknown, TRUE, FALSE,
+ iterpool, iterpool));
+ if (ent)
+ {
+ /* TODO(#2843): Rework the error report. Maybe we can simplify the
+ condition. Currently, the first is about hidden items and the
+ second is for missing items. */
+ if (ent->depth == svn_depth_exclude
+ || ent->absent)
+ {
+ return svn_error_createf
+ (SVN_ERR_ENTRY_EXISTS,
+ NULL, _("'%s' is already under version control"),
+ svn_dirent_local_style(pair->dst, iterpool));
+ }
+ else if ((ent->kind != svn_node_dir) &&
+ (ent->schedule != svn_wc_schedule_delete)
+ && ! ent->deleted)
+ return svn_error_createf
+ (SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
+ _("Entry for '%s' exists (though the working file is missing)"),
+ svn_dirent_local_style(pair->dst, iterpool));
+ }
+ }
+
+ /* Decide whether the two repositories are the same or not. */
+ {
+ svn_error_t *src_err, *dst_err;
+ const char *parent;
+ const char *parent_abspath;
+
+ /* Get the repository uuid of SRC_URL */
+ src_err = svn_ra_get_uuid2(ra_session, &src_uuid, scratch_pool);
+ if (src_err && src_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)
+ return svn_error_return(src_err);
+
+ /* Get repository uuid of dst's parent directory, since dst may
+ not exist. ### TODO: we should probably walk up the wc here,
+ in case the parent dir has an imaginary URL. */
+ if (copy_pairs->nelts == 1)
+ parent = svn_dirent_dirname(top_dst_path, scratch_pool);
+ else
+ parent = top_dst_path;
+
+ SVN_ERR(svn_dirent_get_absolute(&parent_abspath, parent, scratch_pool));
+ dst_err = svn_client_uuid_from_path2(&dst_uuid, parent_abspath, ctx,
+ scratch_pool, scratch_pool);
+ if (dst_err && dst_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)
+ return dst_err;
+
+ /* If either of the UUIDs are nonexistent, then at least one of
+ the repositories must be very old. Rather than punish the
+ user, just assume the repositories are different, so no
+ copy-history is attempted. */
+ if (src_err || dst_err || (! src_uuid) || (! dst_uuid))
+ same_repositories = FALSE;
+
+ else
+ same_repositories = (strcmp(src_uuid, dst_uuid) == 0);
+ }
+
+ /* Perform the move for each of the copy_pairs. */
+ for (i = 0; i < copy_pairs->nelts; i++)
+ {
+ /* Check for cancellation */
+ if (ctx->cancel_func)
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(repos_to_wc_copy_single(APR_ARRAY_IDX(copy_pairs, i,
+ svn_client__copy_pair_t *),
+ same_repositories,
+ ignore_externals,
+ ra_session, ctx, iterpool));
+ }
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *
repos_to_wc_copy(const apr_array_header_t *copy_pairs,
svn_boolean_t make_parents,
@@ -1562,11 +1670,10 @@ repos_to_wc_copy(const apr_array_header_
apr_pool_t *pool)
{
svn_ra_session_t *ra_session;
- svn_wc_adm_access_t *adm_access;
const char *top_src_url, *top_dst_path;
- const char *src_uuid = NULL, *dst_uuid = NULL;
- svn_boolean_t same_repositories;
apr_pool_t *iterpool = svn_pool_create(pool);
+ svn_error_t *err1, *err2;
+ const char *anchor_abspath;
int i;
/* Get the real path for the source, based upon its peg revision. */
@@ -1670,105 +1777,15 @@ repos_to_wc_copy(const apr_array_header_
svn_dirent_local_style(dst_parent, pool));
}
}
+ svn_pool_destroy(iterpool);
- /* Probe the wc at the longest common dst ancestor. */
- SVN_ERR(svn_wc__adm_probe_in_context(&adm_access, ctx->wc_ctx, top_dst_path,
- TRUE, -1, ctx->cancel_func,
- ctx->cancel_baton, pool));
-
- /* We've already checked for physical obstruction by a working file.
- But there could also be logical obstruction by an entry whose
- working file happens to be missing.*/
- for (i = 0; i < copy_pairs->nelts; i++)
- {
- svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
- svn_client__copy_pair_t *);
- const svn_wc_entry_t *ent;
- const char *dst_abspath;
-
- svn_pool_clear(iterpool);
- SVN_ERR(svn_dirent_get_absolute(&dst_abspath, pair->dst, iterpool));
-
- SVN_ERR(svn_wc__maybe_get_entry(&ent, ctx->wc_ctx, dst_abspath,
- svn_node_unknown, TRUE, FALSE,
- iterpool, iterpool));
- if (ent)
- {
- /* TODO(#2843): Rework the error report. Maybe we can simplify the
- condition. Currently, the first is about hidden items and the
- second is for missing items. */
- if (ent->depth == svn_depth_exclude
- || ent->absent)
- {
- return svn_error_createf
- (SVN_ERR_ENTRY_EXISTS,
- NULL, _("'%s' is already under version control"),
- svn_dirent_local_style(pair->dst, pool));
- }
- else if ((ent->kind != svn_node_dir) &&
- (ent->schedule != svn_wc_schedule_delete)
- && ! ent->deleted)
- return svn_error_createf
- (SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
- _("Entry for '%s' exists (though the working file is missing)"),
- svn_dirent_local_style(pair->dst, pool));
- }
- }
-
- /* Decide whether the two repositories are the same or not. */
- {
- svn_error_t *src_err, *dst_err;
- const char *parent;
- const char *parent_abspath;
-
- /* Get the repository uuid of SRC_URL */
- src_err = svn_ra_get_uuid2(ra_session, &src_uuid, pool);
- if (src_err && src_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)
- return svn_error_return(src_err);
-
- /* Get repository uuid of dst's parent directory, since dst may
- not exist. ### TODO: we should probably walk up the wc here,
- in case the parent dir has an imaginary URL. */
- if (copy_pairs->nelts == 1)
- parent = svn_dirent_dirname(top_dst_path, pool);
- else
- parent = top_dst_path;
-
- SVN_ERR(svn_dirent_get_absolute(&parent_abspath, parent, pool));
- dst_err = svn_client_uuid_from_path2(&dst_uuid, parent_abspath, ctx, pool,
- pool);
- if (dst_err && dst_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)
- return dst_err;
-
- /* If either of the UUIDs are nonexistent, then at least one of
- the repositories must be very old. Rather than punish the
- user, just assume the repositories are different, so no
- copy-history is attempted. */
- if (src_err || dst_err || (! src_uuid) || (! dst_uuid))
- same_repositories = FALSE;
-
- else
- same_repositories = (strcmp(src_uuid, dst_uuid) == 0);
- }
-
- /* Perform the move for each of the copy_pairs. */
- for (i = 0; i < copy_pairs->nelts; i++)
- {
- /* Check for cancellation */
- if (ctx->cancel_func)
- SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
-
- svn_pool_clear(iterpool);
+ SVN_ERR(svn_wc__acquire_write_lock(&anchor_abspath, ctx->wc_ctx, top_dst_path,
+ pool, pool));
+ err1 = repos_to_wc_copy_locked(copy_pairs, top_dst_path, ignore_externals,
+ ra_session, ctx, pool);
+ err2 = svn_wc__release_write_lock(ctx->wc_ctx, anchor_abspath, pool);
- SVN_ERR(repos_to_wc_copy_single(APR_ARRAY_IDX(copy_pairs, i,
- svn_client__copy_pair_t *),
- same_repositories,
- ignore_externals,
- ra_session, ctx, iterpool));
- }
-
- svn_pool_destroy(iterpool);
- return svn_error_return(svn_wc_adm_close2(adm_access, pool));
+ return svn_error_compose_create(err1, err2);
}
#define NEED_REPOS_REVNUM(revision) \