summaryrefslogtreecommitdiff
path: root/subversion/libsvn_client/relocate.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_client/relocate.c')
-rw-r--r--subversion/libsvn_client/relocate.c125
1 files changed, 33 insertions, 92 deletions
diff --git a/subversion/libsvn_client/relocate.c b/subversion/libsvn_client/relocate.c
index ed8d09c..dcd9017 100644
--- a/subversion/libsvn_client/relocate.c
+++ b/subversion/libsvn_client/relocate.c
@@ -127,85 +127,6 @@ validator_func(void *baton,
return SVN_NO_ERROR;
}
-
-/* Examing the array of svn_wc_external_item2_t's EXT_DESC (parsed
- from the svn:externals property set on LOCAL_ABSPATH) and determine
- if the external working copies described by such should be
- relocated as a side-effect of the relocation of their parent
- working copy (from OLD_PARENT_REPOS_ROOT_URL to
- NEW_PARENT_REPOS_ROOT_URL). If so, attempt said relocation. */
-static svn_error_t *
-relocate_externals(const char *local_abspath,
- apr_array_header_t *ext_desc,
- const char *old_parent_repos_root_url,
- const char *new_parent_repos_root_url,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool)
-{
- apr_pool_t *iterpool;
- int i;
-
- /* Parse an externals definition into an array of external items. */
-
- iterpool = svn_pool_create(scratch_pool);
-
- for (i = 0; i < ext_desc->nelts; i++)
- {
- svn_wc_external_item2_t *ext_item =
- APR_ARRAY_IDX(ext_desc, i, svn_wc_external_item2_t *);
- const char *target_repos_root_url;
- const char *target_abspath;
- svn_error_t *err;
-
- svn_pool_clear(iterpool);
-
- /* If this external isn't pulled in via a relative URL, ignore
- it. There's no sense in relocating a working copy only to
- have the next 'svn update' try to point it back to another
- location. */
- if (! ((strncmp("../", ext_item->url, 3) == 0) ||
- (strncmp("^/", ext_item->url, 2) == 0)))
- continue;
-
- /* If the external working copy's not-yet-relocated repos root
- URL matches the primary working copy's pre-relocated
- repository root URL, try to relocate that external, too.
- You might wonder why this check is needed, given that we're
- already limiting ourselves to externals pulled via URLs
- relative to their primary working copy. Well, it's because
- you can use "../" to "crawl up" above one repository's URL
- space and down into another one. */
- SVN_ERR(svn_dirent_get_absolute(&target_abspath,
- svn_dirent_join(local_abspath,
- ext_item->target_dir,
- iterpool),
- iterpool));
- err = svn_client_get_repos_root(&target_repos_root_url, NULL /* uuid */,
- target_abspath, ctx, iterpool, iterpool);
-
- /* Ignore externals that aren't present in the working copy.
- * This can happen if an external is deleted from disk accidentally,
- * or if an external is configured on a locally added directory. */
- if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
- {
- svn_error_clear(err);
- continue;
- }
- else
- SVN_ERR(err);
-
- if (strcmp(target_repos_root_url, old_parent_repos_root_url) == 0)
- SVN_ERR(svn_client_relocate2(target_abspath,
- old_parent_repos_root_url,
- new_parent_repos_root_url,
- FALSE, ctx, iterpool));
- }
-
- svn_pool_destroy(iterpool);
-
- return SVN_NO_ERROR;
-}
-
svn_error_t *
svn_client_relocate2(const char *wcroot_dir,
const char *from_prefix,
@@ -256,10 +177,9 @@ svn_client_relocate2(const char *wcroot_dir,
/* Relocate externals, too (if any). */
- SVN_ERR(svn_wc__externals_gather_definitions(&externals_hash, NULL,
- ctx->wc_ctx, local_abspath,
- svn_depth_infinity,
- pool, pool));
+ SVN_ERR(svn_wc__externals_defined_below(&externals_hash,
+ ctx->wc_ctx, local_abspath,
+ pool, pool));
if (! apr_hash_count(externals_hash))
return SVN_NO_ERROR;
@@ -269,18 +189,39 @@ svn_client_relocate2(const char *wcroot_dir,
hi != NULL;
hi = apr_hash_next(hi))
{
- const char *this_abspath = svn__apr_hash_index_key(hi);
- const char *value = svn__apr_hash_index_val(hi);
- apr_array_header_t *ext_desc;
+ svn_node_kind_t kind;
+ const char *this_abspath = apr_hash_this_key(hi);
svn_pool_clear(iterpool);
- SVN_ERR(svn_wc_parse_externals_description3(&ext_desc, this_abspath,
- value, FALSE,
- iterpool));
- if (ext_desc->nelts)
- SVN_ERR(relocate_externals(this_abspath, ext_desc, old_repos_root_url,
- new_repos_root_url, ctx, iterpool));
+ SVN_ERR(svn_wc__read_external_info(&kind, NULL, NULL, NULL, NULL,
+ ctx->wc_ctx,
+ local_abspath, this_abspath,
+ FALSE, iterpool, iterpool));
+
+ if (kind == svn_node_dir)
+ {
+ const char *this_repos_root_url;
+ svn_error_t *err;
+
+ err = svn_client_get_repos_root(&this_repos_root_url, NULL /* uuid */,
+ this_abspath, ctx, iterpool, iterpool);
+
+ /* Ignore externals that aren't present in the working copy.
+ * This can happen if an external is deleted from disk accidentally,
+ * or if an external is configured on a locally added directory. */
+ if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ {
+ svn_error_clear(err);
+ continue;
+ }
+ SVN_ERR(err);
+
+ if (strcmp(old_repos_root_url, this_repos_root_url) == 0)
+ SVN_ERR(svn_client_relocate2(this_abspath, from_prefix, to_prefix,
+ FALSE /* ignore_externals */,
+ ctx, iterpool));
+ }
}
svn_pool_destroy(iterpool);