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;