You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by iv...@apache.org on 2015/10/04 09:53:31 UTC
svn commit: r1706652 - /subversion/trunk/subversion/libsvn_client/upgrade.c
Author: ivan
Date: Sun Oct 4 07:53:30 2015
New Revision: 1706652
URL: http://svn.apache.org/viewvc?rev=1706652&view=rev
Log:
Refactor WC upgrade code a bit to avoid goto statement and make error
handling more clear. Slighlty improve memory usage by using ITERPOOL in
iterations instead of SCRATCH_POOL.
* subversion/libsvn_client/upgrade.c
(upgrade_external_item): New helper for upgrade_externals_from_properties().
Extracted from upgrade_external_item().
(upgrade_externals_from_properties): Use upgrade_external_item() helper.
Modified:
subversion/trunk/subversion/libsvn_client/upgrade.c
Modified: subversion/trunk/subversion/libsvn_client/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/upgrade.c?rev=1706652&r1=1706651&r2=1706652&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_client/upgrade.c Sun Oct 4 07:53:30 2015
@@ -179,6 +179,123 @@ svn_client_upgrade(const char *path,
return SVN_NO_ERROR;
}
+/* Helper for upgrade_externals_from_properties: upgrades one external ITEM
+ in EXTERNALS_PARENT. Uses SCRATCH_POOL for temporary allocations. */
+static svn_error_t *
+upgrade_external_item(svn_client_ctx_t *ctx,
+ const char *externals_parent,
+ const char *externals_parent_abspath,
+ const char *externals_parent_url,
+ const char *externals_parent_repos_root_url,
+ svn_wc_external_item2_t *item,
+ struct repos_info_baton *info_baton,
+ apr_pool_t *scratch_pool)
+{
+ const char *resolved_url;
+ const char *external_abspath;
+ const char *repos_relpath;
+ const char *repos_root_url;
+ const char *repos_uuid;
+ svn_node_kind_t external_kind;
+ svn_revnum_t peg_revision;
+ svn_revnum_t revision;
+ svn_error_t *err;
+
+ external_abspath = svn_dirent_join(externals_parent_abspath,
+ item->target_dir,
+ scratch_pool);
+
+ SVN_ERR(svn_wc__resolve_relative_external_url(
+ &resolved_url,
+ item,
+ externals_parent_repos_root_url,
+ externals_parent_url,
+ scratch_pool, scratch_pool));
+
+ /* This is a hack. We only need to call svn_wc_upgrade() on external
+ * dirs, as file externals are upgraded along with their defining
+ * WC. Reading the kind will throw an exception on an external dir,
+ * saying that the wc must be upgraded. If it's a file, the lookup
+ * is done in an adm_dir belonging to the defining wc (which has
+ * already been upgraded) and no error is returned. If it doesn't
+ * exist (external that isn't checked out yet), we'll just get
+ * svn_node_none. */
+ err = svn_wc_read_kind2(&external_kind, ctx->wc_ctx,
+ external_abspath, TRUE, FALSE, scratch_pool);
+ if (err && err->apr_err == SVN_ERR_WC_UPGRADE_REQUIRED)
+ {
+ svn_error_clear(err);
+
+ SVN_ERR(svn_client_upgrade(external_abspath, ctx, scratch_pool));
+ }
+ else if (err)
+ return svn_error_trace(err);
+
+ /* The upgrade of any dir should be done now, get the now reliable
+ * kind. */
+ SVN_ERR(svn_wc_read_kind2(&external_kind, ctx->wc_ctx, external_abspath,
+ TRUE, FALSE, scratch_pool));
+
+ /* Update the EXTERNALS table according to the root URL,
+ * relpath and uuid known in the upgraded external WC. */
+
+ /* We should probably have a function that provides all three
+ * of root URL, repos relpath and uuid at once, but here goes... */
+
+ /* First get the relpath, as that returns SVN_ERR_WC_PATH_NOT_FOUND
+ * when the node is not present in the file system.
+ * svn_wc__node_get_repos_info() would try to derive the URL. */
+ SVN_ERR(svn_wc__node_get_repos_info(NULL,
+ &repos_relpath,
+ &repos_root_url,
+ &repos_uuid,
+ ctx->wc_ctx,
+ external_abspath,
+ scratch_pool, scratch_pool));
+
+ /* If we haven't got any information from the checked out external,
+ * or if the URL information mismatches the external's definition,
+ * ask fetch_repos_info() to find out the repos root. */
+ if (0 != strcmp(resolved_url,
+ svn_path_url_add_component2(repos_root_url,
+ repos_relpath,
+ scratch_pool)))
+ {
+ SVN_ERR(fetch_repos_info(&repos_root_url, &repos_uuid, info_baton,
+ resolved_url, scratch_pool, scratch_pool));
+
+ repos_relpath = svn_uri_skip_ancestor(repos_root_url,
+ resolved_url,
+ scratch_pool);
+
+ /* There's just the URL, no idea what kind the external is.
+ * That's fine, as the external isn't even checked out yet.
+ * The kind will be set during the next 'update'. */
+ external_kind = svn_node_unknown;
+ }
+
+ peg_revision = (item->peg_revision.kind == svn_opt_revision_number
+ ? item->peg_revision.value.number
+ : SVN_INVALID_REVNUM);
+
+ revision = (item->revision.kind == svn_opt_revision_number
+ ? item->revision.value.number
+ : SVN_INVALID_REVNUM);
+
+ SVN_ERR(svn_wc__upgrade_add_external_info(ctx->wc_ctx,
+ external_abspath,
+ external_kind,
+ externals_parent,
+ repos_relpath,
+ repos_root_url,
+ repos_uuid,
+ peg_revision,
+ revision,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *
upgrade_externals_from_properties(svn_client_ctx_t *ctx,
const char *local_abspath,
@@ -265,130 +382,22 @@ upgrade_externals_from_properties(svn_cl
for (i = 0; i < externals_p->nelts; i++)
{
svn_wc_external_item2_t *item;
- const char *resolved_url;
- const char *external_abspath;
- const char *repos_relpath;
- const char *repos_root_url;
- const char *repos_uuid;
- svn_node_kind_t external_kind;
- svn_revnum_t peg_revision;
- svn_revnum_t revision;
item = APR_ARRAY_IDX(externals_p, i, svn_wc_external_item2_t*);
svn_pool_clear(iterpool2);
- external_abspath = svn_dirent_join(externals_parent_abspath,
- item->target_dir,
- iterpool2);
-
- err = svn_wc__resolve_relative_external_url(
- &resolved_url,
- item,
- externals_parent_repos_root_url,
- externals_parent_url,
- scratch_pool, scratch_pool);
- if (err)
- goto handle_error;
-
- /* This is a hack. We only need to call svn_wc_upgrade() on external
- * dirs, as file externals are upgraded along with their defining
- * WC. Reading the kind will throw an exception on an external dir,
- * saying that the wc must be upgraded. If it's a file, the lookup
- * is done in an adm_dir belonging to the defining wc (which has
- * already been upgraded) and no error is returned. If it doesn't
- * exist (external that isn't checked out yet), we'll just get
- * svn_node_none. */
- err = svn_wc_read_kind2(&external_kind, ctx->wc_ctx,
- external_abspath, TRUE, FALSE, iterpool2);
- if (err && err->apr_err == SVN_ERR_WC_UPGRADE_REQUIRED)
- {
- svn_error_clear(err);
-
- err = svn_client_upgrade(external_abspath, ctx, iterpool2);
- if (err)
- goto handle_error;
- }
- else if (err)
- goto handle_error;
-
- /* The upgrade of any dir should be done now, get the now reliable
- * kind. */
- err = svn_wc_read_kind2(&external_kind, ctx->wc_ctx, external_abspath,
- TRUE, FALSE, iterpool2);
- if (err)
- goto handle_error;
-
- /* Update the EXTERNALS table according to the root URL,
- * relpath and uuid known in the upgraded external WC. */
-
- /* We should probably have a function that provides all three
- * of root URL, repos relpath and uuid at once, but here goes... */
-
- /* First get the relpath, as that returns SVN_ERR_WC_PATH_NOT_FOUND
- * when the node is not present in the file system.
- * svn_wc__node_get_repos_info() would try to derive the URL. */
- err = svn_wc__node_get_repos_info(NULL,
- &repos_relpath,
- &repos_root_url,
- &repos_uuid,
- ctx->wc_ctx,
- external_abspath,
- iterpool2, iterpool2);
- if (err)
- goto handle_error;
-
- /* If we haven't got any information from the checked out external,
- * or if the URL information mismatches the external's definition,
- * ask fetch_repos_info() to find out the repos root. */
- if (0 != strcmp(resolved_url,
- svn_path_url_add_component2(repos_root_url,
- repos_relpath,
- scratch_pool)))
- {
- err = fetch_repos_info(&repos_root_url,
- &repos_uuid,
- info_baton,
- resolved_url,
- scratch_pool, scratch_pool);
- if (err)
- goto handle_error;
-
- repos_relpath = svn_uri_skip_ancestor(repos_root_url,
- resolved_url,
- iterpool2);
-
- /* There's just the URL, no idea what kind the external is.
- * That's fine, as the external isn't even checked out yet.
- * The kind will be set during the next 'update'. */
- external_kind = svn_node_unknown;
- }
-
- if (err)
- goto handle_error;
+ err = upgrade_external_item(ctx, externals_parent,
+ externals_parent_abspath,
+ externals_parent_url,
+ externals_parent_repos_root_url,
+ item, info_baton, iterpool2);
- peg_revision = (item->peg_revision.kind == svn_opt_revision_number
- ? item->peg_revision.value.number
- : SVN_INVALID_REVNUM);
-
- revision = (item->revision.kind == svn_opt_revision_number
- ? item->revision.value.number
- : SVN_INVALID_REVNUM);
-
- err = svn_wc__upgrade_add_external_info(ctx->wc_ctx,
- external_abspath,
- external_kind,
- externals_parent,
- repos_relpath,
- repos_root_url,
- repos_uuid,
- peg_revision,
- revision,
- iterpool2);
-handle_error:
if (err)
{
svn_wc_notify_t *notify =
- svn_wc_create_notify(external_abspath,
+ svn_wc_create_notify(svn_dirent_join(externals_parent,
+ item->target_dir,
+ iterpool2),
svn_wc_notify_failed_external,
scratch_pool);
notify->err = err;