You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2010/11/04 18:00:39 UTC
svn commit: r1031078 - in /subversion/trunk/subversion: include/svn_wc.h
libsvn_client/copy.c libsvn_wc/adm_ops.c
Author: julianfoad
Date: Thu Nov 4 17:00:38 2010
New Revision: 1031078
URL: http://svn.apache.org/viewvc?rev=1031078&view=rev
Log:
Make repos->WC copies work when the target WC path is scheduled for delete.
Get rid of svn_client__checkout_internal().
* subversion/libsvn_client/copy.c
(notification_adjust_func, notification_adjust_baton): New function and
baton.
(repos_to_wc_copy_single): Check out to a temporary location, and then
copy the metadata and move the disk tree from there to the final path.
* subversion/include/svn_wc.h
(svn_wc__integrate_nested_wc_as_copy): Delete.
(svn_wc_add4): Adjust a comment about that case.
* subversion/libsvn_wc/adm_ops.c
(svn_wc__integrate_nested_wc_as_copy): Delete.
Modified:
subversion/trunk/subversion/include/svn_wc.h
subversion/trunk/subversion/libsvn_client/copy.c
subversion/trunk/subversion/libsvn_wc/adm_ops.c
Modified: subversion/trunk/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_wc.h?rev=1031078&r1=1031077&r2=1031078&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_wc.h (original)
+++ subversion/trunk/subversion/include/svn_wc.h Thu Nov 4 17:00:38 2010
@@ -4230,23 +4230,6 @@ svn_wc_add_from_disk(svn_wc_context_t *w
apr_pool_t *scratch_pool);
/**
- * Convert the nested pristine working copy rooted at @a local_abspath into
- * a copied subtree in the outer working copy.
- *
- * @a local_abspath must be the root of a nested working copy that has no
- * local modifications. The parent directory of @a local_abspath must be a
- * versioned directory in the outer WC, and must belong to the same
- * repository as the nested WC. The nested WC will be integrated into the
- * parent's WC, and will no longer be a separate WC.
- *
- * This is a replacement for svn_wc_add4() case 1.
- */
-svn_error_t *
-svn_wc__integrate_nested_wc_as_copy(svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- apr_pool_t *scratch_pool);
-
-/**
* Put @a local_abspath under version control by registering it as addition
* or copy in the database containing its parent. The new node is scheduled
* for addition to the repository below its parent node.
@@ -4283,7 +4266,7 @@ svn_wc__integrate_nested_wc_as_copy(svn_
* When the @a local_abspath has been added, then @a notify_func will be
* called (if it is not @c NULL) with the @a notify_baton and the path.
*
- * @note For case 1, prefer svn_wc__integrate_nested_wc_as_copy().
+ * @note Case 1 is deprecated. Consider doing a WC-to-WC copy instead.
* @note For case 2a, prefer svn_wc_add_from_disk().
*
* @since New in 1.7.
Modified: subversion/trunk/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/copy.c?rev=1031078&r1=1031077&r2=1031078&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/copy.c (original)
+++ subversion/trunk/subversion/libsvn_client/copy.c Thu Nov 4 17:00:38 2010
@@ -45,6 +45,7 @@
#include "svn_private_config.h"
#include "private/svn_wc_private.h"
#include "private/svn_mergeinfo_private.h"
+#include "../libsvn_wc/adm_files.h"
/*
@@ -1409,6 +1410,35 @@ wc_to_repos_copy(const apr_array_header_
return SVN_NO_ERROR;
}
+/* A baton for notification_adjust_func(). */
+struct notification_adjust_baton
+{
+ svn_wc_notify_func2_t inner_func;
+ void *inner_baton;
+ const char *checkout_abspath;
+ const char *final_abspath;
+};
+
+/* A svn_wc_notify_func2_t function that wraps BATON->inner_func (whose
+ * baton is BATON->inner_baton) and adjusts the notification paths that
+ * start with BATON->checkout_abspath to start instead with
+ * BATON->final_abspath. */
+static void
+notification_adjust_func(void *baton,
+ const svn_wc_notify_t *notify,
+ apr_pool_t *pool)
+{
+ struct notification_adjust_baton *nb = baton;
+ svn_wc_notify_t *inner_notify = svn_wc_dup_notify(notify, pool);
+ const char *relpath;
+
+ relpath = svn_dirent_skip_ancestor(nb->checkout_abspath, notify->path);
+ inner_notify->path = svn_dirent_join(nb->final_abspath, relpath, pool);
+
+ if (nb->inner_func)
+ nb->inner_func(nb->inner_baton, inner_notify, pool);
+}
+
/* Peform each individual copy operation for a repos -> wc copy. A
helper for repos_to_wc_copy().
@@ -1429,27 +1459,72 @@ repos_to_wc_copy_single(svn_client__copy
if (pair->src_kind == svn_node_dir)
{
svn_boolean_t sleep_needed = FALSE;
+ const char *tmp_abspath;
+
+ /* Find a temporary location in which to check out the copy source.
+ * (This function is deprecated, but we intend to replace this whole
+ * code path with something else.) */
+ SVN_ERR(svn_wc_create_tmp_file2(NULL, &tmp_abspath, dst_abspath,
+ svn_io_file_del_on_close, pool));
/* Make a new checkout of the requested source. While doing so,
* resolve pair->src_revnum to an actual revision number in case it
* was until now 'invalid' meaning 'head'. Ask this function not to
* sleep for timestamps, by passing a sleep_needed output param.
- * This sends notifications for all nodes except the root node. */
- SVN_ERR(svn_client__checkout_internal(&pair->src_revnum,
- pair->src_original,
- dst_abspath,
- &pair->src_peg_revision,
- &pair->src_op_revision, NULL,
- svn_depth_infinity,
- ignore_externals, FALSE, TRUE,
- &sleep_needed, ctx, pool));
+ * Send notifications for all nodes except the root node, and adjust
+ * them to refer to the destination rather than this temporary path. */
+ {
+ svn_wc_notify_func2_t old_notify_func2 = ctx->notify_func2;
+ void *old_notify_baton2 = ctx->notify_baton2;
+ struct notification_adjust_baton nb;
+
+ nb.inner_func = ctx->notify_func2;
+ nb.inner_baton = ctx->notify_baton2;
+ nb.checkout_abspath = tmp_abspath;
+ nb.final_abspath = dst_abspath;
+ ctx->notify_func2 = notification_adjust_func;
+ ctx->notify_baton2 = &nb;
+
+ SVN_ERR(svn_client__checkout_internal(&pair->src_revnum,
+ pair->src_original,
+ tmp_abspath,
+ &pair->src_peg_revision,
+ &pair->src_op_revision, NULL,
+ svn_depth_infinity,
+ ignore_externals, FALSE, TRUE,
+ &sleep_needed, ctx, pool));
+
+ ctx->notify_func2 = old_notify_func2;
+ ctx->notify_baton2 = old_notify_baton2;
+ }
- if (! same_repositories)
+ /* Schedule dst_path for addition in parent, with copy history.
+ Don't send any notification here.
+ Then remove the temporary checkout's .svn dir in preparation for
+ moving the rest of it into the final destination. */
+ if (same_repositories)
+ {
+ SVN_ERR(svn_wc_copy3(ctx->wc_ctx, tmp_abspath, dst_abspath,
+ TRUE /* metadata_only */,
+ ctx->cancel_func, ctx->cancel_baton,
+ NULL, NULL, pool));
+ SVN_ERR(svn_io_remove_dir2(svn_wc__adm_child(tmp_abspath, NULL, pool),
+ FALSE /* ignore_enoent */,
+ ctx->cancel_func, ctx->cancel_baton, pool));
+ }
+ else
{
/* ### We want to schedule this as a simple add, or even better
a copy from a foreign repos, but we don't yet have the
- WC APIs to do that. */
+ WC APIs to do that, so we will just move the whole WC into
+ place as a disjoint, nested WC. */
+ }
+ /* Move the temporary disk tree into place. */
+ SVN_ERR(svn_io_file_rename(tmp_abspath, dst_abspath, pool));
+
+ if (! same_repositories)
+ {
svn_io_sleep_for_timestamps(dst_abspath, pool);
return svn_error_createf
@@ -1457,14 +1532,6 @@ repos_to_wc_copy_single(svn_client__copy
_("Source URL '%s' is from foreign repository; "
"leaving it as a disjoint WC"), pair->src_abspath_or_url);
}
-
- /* Schedule dst_path for addition in parent, with copy history.
- Don't send any notification here.
-
- ### This is a wierd way to do it. See the doc string of
- svn_wc_add_repos_file4() for more about the controversy. */
- SVN_ERR(svn_wc__integrate_nested_wc_as_copy(ctx->wc_ctx, dst_abspath,
- pool));
} /* end directory case */
else if (pair->src_kind == svn_node_file)
Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1031078&r1=1031077&r2=1031078&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Thu Nov 4 17:00:38 2010
@@ -1156,33 +1156,6 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
}
svn_error_t *
-svn_wc__integrate_nested_wc_as_copy(svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- apr_pool_t *scratch_pool)
-{
- svn_wc__db_t *db = wc_ctx->db;
- svn_boolean_t is_wc_root;
-
- /* Precondition: LOCAL_ABSPATH is the root of a separate WC. */
- SVN_ERR(svn_wc__check_wc_root(&is_wc_root, NULL, NULL,
- db, local_abspath, scratch_pool));
- if (! is_wc_root)
- return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
- _("'%s' is not a WC root"),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
-
- /* Precondition: parent(LOCAL_ABSPATH) is a versioned directory in an
- * acceptable state. */
- SVN_ERR(check_can_add_to_parent(NULL, NULL, wc_ctx, local_abspath,
- scratch_pool, scratch_pool));
-
- SVN_ERR(integrate_nested_wc_as_copy(wc_ctx, local_abspath, scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
svn_wc_add_from_disk(svn_wc_context_t *wc_ctx,
const char *local_abspath,
svn_wc_notify_func2_t notify_func,