Index: subversion/include/svn_client.h =================================================================== --- subversion/include/svn_client.h (revision 23227) +++ subversion/include/svn_client.h (working copy) @@ -2101,7 +2101,8 @@ const char *dst_path, svn_boolean_t copy_as_child, svn_client_ctx_t *ctx, - apr_pool_t *pool); + apr_pool_t *pool, + svn_boolean_t replace); /** * Similar to svn_client_copy4(), with only one @a src_path and Index: subversion/libsvn_client/copy.c =================================================================== --- subversion/libsvn_client/copy.c (revision 23227) +++ subversion/libsvn_client/copy.c (working copy) @@ -426,7 +426,8 @@ const apr_array_header_t *copy_pairs, svn_client_ctx_t *ctx, svn_boolean_t is_move, - apr_pool_t *pool) + apr_pool_t *pool, + svn_boolean_t replace) { apr_array_header_t *paths = apr_array_make(pool, 2 * copy_pairs->nelts, sizeof(const char *)); @@ -548,6 +549,9 @@ /* Fetch the youngest revision. */ SVN_ERR(svn_ra_get_latest_revnum(ra_session, &youngest, pool)); + svn_client_commit_item3_t *item; + apr_array_header_t *commit_items + = apr_array_make(pool, 2 * copy_pairs->nelts, sizeof(item)); for (i = 0; i < copy_pairs->nelts; i++) { svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i, @@ -612,9 +616,18 @@ pool)); if (dst_kind != svn_node_none) { - /* We disallow the overwriting of existing paths. */ - return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL, - _("Path '%s' already exists"), dst_rel); + if (replace) { + item = apr_pcalloc(pool, sizeof(*item)); + item->url = svn_path_join(top_url, dst_rel, pool); + item->state_flags = SVN_CLIENT_COMMIT_ITEM_DELETE; + APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item; + apr_hash_set(action_hash, dst_rel, APR_HASH_KEY_STRING, + info); + } else { + /* We disallow the overwriting of existing paths. */ + return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL, + _("Path '%s' already exists"), dst_rel); + } } info->src_url = pair->src; @@ -625,10 +638,7 @@ /* Create a new commit item and add it to the array. */ if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx)) { - svn_client_commit_item3_t *item; const char *tmp_file; - apr_array_header_t *commit_items - = apr_array_make(pool, 2 * copy_pairs->nelts, sizeof(item)); for (i = 0; i < path_infos->nelts; i++) { @@ -1294,7 +1304,8 @@ svn_boolean_t is_move, svn_boolean_t force, svn_client_ctx_t *ctx, - apr_pool_t *pool) + apr_pool_t *pool, + svn_boolean_t replace) { apr_array_header_t *copy_pairs = apr_array_make(pool, sources->nelts, sizeof(struct copy_pair *)); @@ -1520,7 +1531,7 @@ else { SVN_ERR(repos_to_repos_copy(commit_info_p, copy_pairs, - ctx, is_move, pool)); + ctx, is_move, pool, replace)); } return SVN_NO_ERROR; @@ -1535,7 +1546,8 @@ const char *dst_path, svn_boolean_t copy_as_child, svn_client_ctx_t *ctx, - apr_pool_t *pool) + apr_pool_t *pool, + svn_boolean_t replace) { svn_error_t *err; svn_commit_info_t *commit_info = NULL; @@ -1550,7 +1562,8 @@ FALSE /* is_move */, TRUE /* force, set to avoid deletion check */, ctx, - subpool); + subpool, + replace); /* If the destination exists, try to copy the sources as children of the destination. */ @@ -1573,7 +1586,8 @@ FALSE /* is_move */, TRUE /* force, set to avoid deletion check */, ctx, - subpool); + subpool, + replace); } if (commit_info) @@ -1609,7 +1623,8 @@ dst_path, FALSE, ctx, - pool); + pool, + FALSE); } @@ -1702,7 +1717,8 @@ TRUE /* is_move */, force, ctx, - subpool); + subpool, + FALSE); /* If the destination exists, try to move the sources as children of the destination. */ @@ -1723,7 +1739,8 @@ TRUE /* is_move */, force, ctx, - subpool); + subpool, + FALSE); } if (commit_info) @@ -1840,7 +1857,8 @@ TRUE /* is_move */, force, ctx, - pool); + pool, + FALSE); /* These structs have the same layout for the common fields. */ *commit_info_p = (svn_client_commit_info_t *) commit_info; return err; Index: subversion/svn/cl.h =================================================================== --- subversion/svn/cl.h (revision 23227) +++ subversion/svn/cl.h (working copy) @@ -81,7 +81,8 @@ svn_cl__targets_opt, svn_cl__version_opt, svn_cl__xml_opt, - svn_cl__keep_local_opt + svn_cl__keep_local_opt, + svn_cl__replace_opt } svn_cl__longopt_t; @@ -151,7 +152,7 @@ const char *changelist; /* operate on this changelist */ svn_boolean_t keep_changelist; /* don't remove changelist after commit */ svn_boolean_t keep_local; /* delete path only from repository */ - + svn_boolean_t replace; /* replace destination on repo-to-repo copy */ } svn_cl__opt_state_t; Index: subversion/svn/copy-cmd.c =================================================================== --- subversion/svn/copy-cmd.c (revision 23227) +++ subversion/svn/copy-cmd.c (working copy) @@ -131,7 +131,7 @@ NULL, ctx->config, pool)); err = svn_client_copy4(&commit_info, sources, - dst_path, TRUE, ctx, pool); + dst_path, TRUE, ctx, pool, opt_state->replace); if (ctx->log_msg_func3) SVN_ERR(svn_cl__cleanup_log_msg(ctx->log_msg_baton3, err)); Index: subversion/svn/main.c =================================================================== --- subversion/svn/main.c (revision 23227) +++ subversion/svn/main.c (working copy) @@ -192,6 +192,8 @@ N_("don't delete changelist after commit")}, {"keep-local", svn_cl__keep_local_opt, 0, N_("keep path in working copy")}, + {"replace", svn_cl__replace_opt, 0, + N_("replace destination if it exists on a repo-to-repo copy")}, {0, 0, 0, 0} }; @@ -330,7 +332,7 @@ " URL -> URL: complete server-side copy; used to branch & tag\n" " All the SRCs must be of the same type.\n"), {'r', 'q', - SVN_CL__LOG_MSG_OPTIONS, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} }, + SVN_CL__LOG_MSG_OPTIONS, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt, svn_cl__replace_opt} }, { "delete", svn_cl__delete, {"del", "remove", "rm"}, N_ ("Remove files and directories from version control.\n" @@ -1271,6 +1273,9 @@ case svn_cl__keep_local_opt: opt_state.keep_local = TRUE; break; + case svn_cl__replace_opt: + opt_state.replace = TRUE; + break; default: /* Hmmm. Perhaps this would be a good place to squirrel away opts that commands like svn diff might need. Hmmm indeed. */