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 2018/12/13 20:26:10 UTC
svn commit: r1848892 - in /subversion/trunk/subversion:
include/private/svn_client_private.h libsvn_client/conflicts.c
libsvn_client/copy.c libsvn_client/wc_editor.c
tests/libsvn_client/client-test.c
Author: julianfoad
Date: Thu Dec 13 20:26:10 2018
New Revision: 1848892
URL: http://svn.apache.org/viewvc?rev=1848892&view=rev
Log:
Let repository-to-WC copies go through the WC editor.
For issue #4786 "Create a WC working-mods editor".
* subversion/include/private/svn_client_private.h
(svn_client__repos_to_wc_copy): Rename to
'svn_client__repos_to_wc_copy_internal'.
(svn_client__repos_to_wc_copy_by_editor): New.
* subversion/libsvn_client/conflicts.c
(merge_incoming_added_dir_replace): Update to use
'svn_client__repos_to_wc_copy_by_editor'.
* subversion/libsvn_client/copy.c
(copy_foreign_dir): Remove 'depth' parameter: not needed and was wrongly
implemented anyway.
(svn_client__repos_to_wc_copy_dir): Adjust caller.
(is_same_repository): New, moved from 'wc_editor.c'.
(svn_client__repos_to_wc_copy_by_editor): New.
(svn_client__repos_to_wc_copy,
repos_to_wc_copy_single): Determine same-repository here and here...
(repos_to_wc_copy_locked): ... instead of here.
* subversion/libsvn_client/wc_editor.c
(is_same_repository): Delete; moved to 'copy.c'.
(dir_add,
file_add): Don't determine same-repository here. Do set the 'created' flag.
* subversion/tests/libsvn_client/client-test.c
(test_foreign_repos_copy): Update caller.
Modified:
subversion/trunk/subversion/include/private/svn_client_private.h
subversion/trunk/subversion/libsvn_client/conflicts.c
subversion/trunk/subversion/libsvn_client/copy.c
subversion/trunk/subversion/libsvn_client/wc_editor.c
subversion/trunk/subversion/tests/libsvn_client/client-test.c
Modified: subversion/trunk/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_client_private.h?rev=1848892&r1=1848891&r2=1848892&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_client_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_client_private.h Thu Dec 13 20:26:10 2018
@@ -398,10 +398,7 @@ svn_client__get_diff_summarize_callbacks
* The caller should be holding a WC write lock that allows DST_ABSPATH to
* be created, such as on the parent of DST_ABSPATH.
*
- * SAME_REPOSITORIES must be true if and only if the source of this copy
- * is from the same repository at the WC parent of DST_ABSPATH.
- * If SAME_REPOSITORIES, then fill in the 'copy-from' in the WC target.
- * If not SAME_REPOSITORIES, then remove any svn:mergeinfo property.
+ * If not same repositories, then remove any svn:mergeinfo property.
*
* Use RA_SESSION to fetch the data. The session may point to a different
* URL after returning.
@@ -410,16 +407,39 @@ svn_client__get_diff_summarize_callbacks
* on copied directories.
*/
svn_error_t *
-svn_client__repos_to_wc_copy(svn_boolean_t *timestamp_sleep,
+svn_client__repos_to_wc_copy_internal(svn_boolean_t *timestamp_sleep,
svn_node_kind_t kind,
const char *src_url,
svn_revnum_t src_rev,
const char *dst_abspath,
- svn_boolean_t same_repositories,
svn_ra_session_t *ra_session,
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool);
+/* Copy a directory tree or a file (according to KIND) from SRC_URL @ SRC_REV,
+ * to DST_ABSPATH in a WC.
+ *
+ * The caller should be holding a WC write lock that allows DST_ABSPATH to
+ * be created, such as on the parent of DST_ABSPATH.
+ *
+ * If not same repositories, then remove any svn:mergeinfo property.
+ *
+ * Use RA_SESSION to fetch the data. The session may point to a different
+ * URL after returning.
+ *
+ * This API does not process any externals definitions that may be present
+ * on copied directories.
+ */
+svn_error_t *
+svn_client__repos_to_wc_copy_by_editor(svn_boolean_t *timestamp_sleep,
+ svn_node_kind_t kind,
+ const char *src_url,
+ svn_revnum_t src_rev,
+ const char *dst_abspath,
+ svn_ra_session_t *ra_session,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
+
/** Return an editor for applying local modifications to a WC.
*
* Return an editor in @a *editor_p, @a *edit_baton_p that will apply
Modified: subversion/trunk/subversion/libsvn_client/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/conflicts.c?rev=1848892&r1=1848891&r2=1848892&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_client/conflicts.c Thu Dec 13 20:26:10 2018
@@ -8041,12 +8041,11 @@ merge_incoming_added_dir_replace(svn_cli
if (err)
goto unlock_wc;
- err = svn_client__repos_to_wc_copy(×tamp_sleep,
- svn_node_dir,
- url, incoming_new_pegrev,
- local_abspath,
- TRUE /*same_repositories*/,
- ra_session, ctx, scratch_pool);
+ err = svn_client__repos_to_wc_copy_by_editor(×tamp_sleep,
+ svn_node_dir,
+ url, incoming_new_pegrev,
+ local_abspath,
+ ra_session, ctx, scratch_pool);
if (err)
goto unlock_wc;
Modified: subversion/trunk/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/copy.c?rev=1848892&r1=1848891&r2=1848892&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/copy.c (original)
+++ subversion/trunk/subversion/libsvn_client/copy.c Thu Dec 13 20:26:10 2018
@@ -2355,7 +2355,7 @@ notification_adjust_func(void *baton,
/** Copy a directory tree from a remote repository.
*
- * Copy from RA_SESSION:LOCATION, depth DEPTH, to WC_CTX:DST_ABSPATH.
+ * Copy from RA_SESSION:LOCATION to WC_CTX:DST_ABSPATH.
*
* Create the directory DST_ABSPATH, if not present. Its parent should be
* already under version control in the WC and in a suitable state for
@@ -2368,7 +2368,6 @@ static svn_error_t *
copy_foreign_dir(svn_ra_session_t *ra_session,
const svn_client__pathrev_t *location,
const char *dst_abspath,
- svn_depth_t depth,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
svn_cancel_func_t cancel_func,
@@ -2403,8 +2402,9 @@ copy_foreign_dir(svn_ra_session_t *ra_se
FALSE, FALSE, wrapped_editor, wrapped_baton,
scratch_pool, scratch_pool));
- SVN_ERR(reporter->set_path(reporter_baton, "", location->rev, depth,
- TRUE /* incomplete */,
+ SVN_ERR(reporter->set_path(reporter_baton, "", location->rev,
+ svn_depth_infinity /* irrelevant */,
+ TRUE /*start_empty*/,
NULL, scratch_pool));
SVN_ERR(reporter->finish_report(reporter_baton, scratch_pool));
@@ -2440,7 +2440,6 @@ svn_client__repos_to_wc_copy_dir(svn_boo
SVN_ERR(svn_ra_reparent(ra_session, src_url, scratch_pool));
SVN_ERR(copy_foreign_dir(ra_session, location,
dst_abspath,
- svn_depth_infinity,
ctx->notify_func2, ctx->notify_baton2,
ctx->cancel_func, ctx->cancel_baton,
ctx, scratch_pool));
@@ -2568,18 +2567,43 @@ svn_client__repos_to_wc_copy_file(svn_bo
return SVN_NO_ERROR;
}
+/* Are RA_SESSION and the versioned *parent* dir of WC_TARGET_ABSPATH in
+ * the same repository?
+ */
+static svn_error_t *
+is_same_repository(svn_boolean_t *same_repository,
+ svn_ra_session_t *ra_session,
+ const char *wc_target_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *src_uuid, *dst_uuid;
+
+ /* Get the repository UUIDs of copy source URL and WC parent path */
+ SVN_ERR(svn_ra_get_uuid2(ra_session, &src_uuid, scratch_pool));
+ SVN_ERR(svn_client_get_repos_root(NULL /*root_url*/, &dst_uuid,
+ svn_dirent_dirname(wc_target_abspath,
+ scratch_pool),
+ ctx, scratch_pool, scratch_pool));
+ *same_repository = (strcmp(src_uuid, dst_uuid) == 0);
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
-svn_client__repos_to_wc_copy(svn_boolean_t *timestamp_sleep,
+svn_client__repos_to_wc_copy_internal(svn_boolean_t *timestamp_sleep,
svn_node_kind_t kind,
const char *src_url,
svn_revnum_t src_rev,
const char *dst_abspath,
- svn_boolean_t same_repositories,
svn_ra_session_t *ra_session,
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
{
svn_boolean_t timestamp_sleep_ignored;
+ svn_boolean_t same_repositories;
+
+ SVN_ERR(is_same_repository(&same_repositories,
+ ra_session, dst_abspath, ctx, scratch_pool));
if (!timestamp_sleep)
timestamp_sleep = ×tamp_sleep_ignored;
@@ -2605,6 +2629,54 @@ svn_client__repos_to_wc_copy(svn_boolean
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_client__repos_to_wc_copy_by_editor(svn_boolean_t *timestamp_sleep,
+ svn_node_kind_t kind,
+ const char *src_url,
+ svn_revnum_t src_rev,
+ const char *dst_abspath,
+ svn_ra_session_t *ra_session,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const svn_delta_editor_t *editor;
+ void *eb;
+ const char *src_anchor = svn_uri_dirname(src_url, scratch_pool);
+ const char *dst_target = svn_dirent_basename(dst_abspath, scratch_pool);
+ void *rb, *db;
+
+ SVN_ERR(svn_ra_reparent(ra_session, src_anchor, scratch_pool));
+
+ SVN_ERR(svn_client__wc_editor(&editor, &eb,
+ svn_dirent_dirname(dst_abspath, scratch_pool),
+ ctx->notify_func2, ctx->notify_baton2,
+ ra_session,
+ ctx, scratch_pool));
+
+ SVN_ERR(editor->open_root(eb, SVN_INVALID_REVNUM, scratch_pool, &rb));
+ if (kind == svn_node_dir)
+ {
+ SVN_ERR(editor->add_directory(dst_target, rb,
+ src_url, src_rev,
+ scratch_pool,
+ &db));
+ SVN_ERR(editor->close_directory(db, scratch_pool));
+ }
+ else
+ {
+ SVN_ERR(editor->add_file(dst_target, rb,
+ src_url, src_rev,
+ scratch_pool,
+ &db));
+ SVN_ERR(editor->close_file(db, NULL, scratch_pool));
+ }
+ SVN_ERR(editor->close_edit(eb, scratch_pool));
+
+ if (timestamp_sleep)
+ *timestamp_sleep = TRUE;
+ return SVN_NO_ERROR;
+}
+
/* Peform each individual copy operation for a repos -> wc copy. A
helper for repos_to_wc_copy().
@@ -2614,7 +2686,6 @@ svn_client__repos_to_wc_copy(svn_boolean
static svn_error_t *
repos_to_wc_copy_single(svn_boolean_t *timestamp_sleep,
const svn_client__copy_pair_t *pair,
- svn_boolean_t same_repositories,
svn_boolean_t ignore_externals,
svn_boolean_t pin_externals,
const apr_hash_t *externals_to_pin,
@@ -2624,11 +2695,14 @@ repos_to_wc_copy_single(svn_boolean_t *t
{
apr_hash_t *src_mergeinfo;
const char *dst_abspath = pair->dst_abspath_or_url;
+ svn_boolean_t same_repositories;
SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(pair->src_revnum));
SVN_ERR_ASSERT(svn_path_is_url(pair->src_abspath_or_url));
SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
+ SVN_ERR(is_same_repository(&same_repositories,
+ ra_session, dst_abspath, ctx, pool));
if (!same_repositories && ctx->notify_func2)
{
svn_wc_notify_t *notify;
@@ -2644,13 +2718,13 @@ repos_to_wc_copy_single(svn_boolean_t *t
SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
}
- SVN_ERR(svn_client__repos_to_wc_copy(timestamp_sleep,
- pair->src_kind,
- pair->src_abspath_or_url,
- pair->src_revnum,
- dst_abspath,
- same_repositories,
- ra_session, ctx, pool));
+ SVN_ERR(svn_client__repos_to_wc_copy_by_editor(
+ timestamp_sleep,
+ pair->src_kind,
+ pair->src_abspath_or_url,
+ pair->src_revnum,
+ dst_abspath,
+ ra_session, ctx, pool));
/* Fetch externals, pinning them if requested */
if (!ignore_externals && pair->src_kind == svn_node_dir)
@@ -2746,32 +2820,8 @@ repos_to_wc_copy_locked(svn_boolean_t *t
apr_pool_t *scratch_pool)
{
int i;
- svn_boolean_t same_repositories;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- /* Decide whether the two repositories are the same or not. */
- {
- const char *parent_abspath;
- const char *src_uuid, *dst_uuid;
-
- /* Get the repository uuid of SRC_URL */
- SVN_ERR(svn_ra_get_uuid2(ra_session, &src_uuid, iterpool));
-
- /* 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_abspath = svn_dirent_dirname(top_dst_abspath, scratch_pool);
- else
- parent_abspath = top_dst_abspath;
-
- SVN_ERR(svn_client_get_repos_root(NULL /* root_url */, &dst_uuid,
- parent_abspath, ctx,
- iterpool, iterpool));
- /* ### Also check repos_root_url? */
- 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++)
{
@@ -2784,7 +2834,6 @@ repos_to_wc_copy_locked(svn_boolean_t *t
SVN_ERR(repos_to_wc_copy_single(timestamp_sleep,
APR_ARRAY_IDX(copy_pairs, i,
svn_client__copy_pair_t *),
- same_repositories,
ignore_externals,
pin_externals, externals_to_pin,
ra_session, ctx, iterpool));
Modified: subversion/trunk/subversion/libsvn_client/wc_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/wc_editor.c?rev=1848892&r1=1848891&r2=1848892&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/wc_editor.c (original)
+++ subversion/trunk/subversion/libsvn_client/wc_editor.c Thu Dec 13 20:26:10 2018
@@ -209,28 +209,6 @@ dir_open(const char *path,
return SVN_NO_ERROR;
}
-/* Are RA_SESSION and the versioned *parent* dir of WC_TARGET_ABSPATH in
- * the same repository?
- */
-static svn_error_t *
-is_same_repository(svn_boolean_t *same_repository,
- svn_ra_session_t *ra_session,
- const char *wc_target_abspath,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool)
-{
- const char *src_uuid, *dst_uuid;
-
- /* Get the repository UUIDs of copy source URL and WC parent path */
- SVN_ERR(svn_ra_get_uuid2(ra_session, &src_uuid, scratch_pool));
- SVN_ERR(svn_client_get_repos_root(NULL /*root_url*/, &dst_uuid,
- svn_dirent_dirname(wc_target_abspath,
- scratch_pool),
- ctx, scratch_pool, scratch_pool));
- *same_repository = (strcmp(src_uuid, dst_uuid) == 0);
- return SVN_NO_ERROR;
-}
-
static svn_error_t *
dir_add(const char *path,
void *parent_baton,
@@ -246,21 +224,14 @@ dir_add(const char *path,
if (copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_revision))
{
- svn_boolean_t same_repository;
- svn_boolean_t timestamp_sleep;
-
- SVN_ERR(is_same_repository(&same_repository,
- db->eb->ra_session, db->local_abspath,
- db->eb->ctx, db->pool));
-
- SVN_ERR(svn_client__repos_to_wc_copy(×tamp_sleep,
+ SVN_ERR(svn_client__repos_to_wc_copy_internal(NULL /*timestamp_sleep*/,
svn_node_dir,
copyfrom_path,
copyfrom_revision,
db->local_abspath,
- same_repository,
db->eb->ra_session,
db->eb->ctx, db->pool));
+ db->created = TRUE;
}
*child_baton = db;
@@ -436,21 +407,14 @@ file_add(const char *path,
if (copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_revision))
{
- svn_boolean_t same_repository;
- svn_boolean_t timestamp_sleep;
-
- SVN_ERR(is_same_repository(&same_repository,
- fb->eb->ra_session, fb->local_abspath,
- fb->eb->ctx, fb->pool));
-
- SVN_ERR(svn_client__repos_to_wc_copy(×tamp_sleep,
+ SVN_ERR(svn_client__repos_to_wc_copy_internal(NULL /*timestamp_sleep*/,
svn_node_file,
copyfrom_path,
copyfrom_revision,
fb->local_abspath,
- same_repository,
fb->eb->ra_session,
fb->eb->ctx, fb->pool));
+ fb->created = TRUE;
}
*file_baton = fb;
Modified: subversion/trunk/subversion/tests/libsvn_client/client-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_client/client-test.c?rev=1848892&r1=1848891&r2=1848892&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_client/client-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_client/client-test.c Thu Dec 13 20:26:10 2018
@@ -766,22 +766,18 @@ test_foreign_repos_copy(const svn_test_o
loc->url = svn_path_url_add_component2(repos2_url, "A", pool);
SVN_WC__CALL_WITH_WRITE_LOCK(
- svn_client__repos_to_wc_copy(NULL /*sleep*/, svn_node_dir,
+ svn_client__repos_to_wc_copy_by_editor(NULL /*sleep*/, svn_node_dir,
loc->url, loc->rev,
svn_dirent_join(wc_path, "A-copied", pool),
- /*svn_depth_infinity,*/
- FALSE /*same_repositories*/,
ra_session, ctx, pool),
ctx->wc_ctx, wc_path, FALSE, pool);
SVN_ERR(svn_ra_reparent(ra_session, repos2_url, pool));
loc->url = svn_path_url_add_component2(repos2_url, "iota", pool);
SVN_WC__CALL_WITH_WRITE_LOCK(
- svn_client__repos_to_wc_copy(NULL /*sleep*/, svn_node_file,
+ svn_client__repos_to_wc_copy_by_editor(NULL /*sleep*/, svn_node_file,
loc->url, loc->rev,
svn_dirent_join(wc_path, "iota-copied", pool),
- /*svn_depth_infinity,*/
- FALSE /*same_repositories*/,
ra_session, ctx, pool),
ctx->wc_ctx, wc_path, FALSE, pool);