subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ne...@apache.org
Subject svn commit: r1174139 - in /subversion/trunk/subversion: include/private/svn_wc_private.h libsvn_client/cleanup.c libsvn_wc/upgrade.c libsvn_wc/wc_db.c libsvn_wc/wc_db.h
Date Thu, 22 Sep 2011 13:51:13 GMT
Author: neels
Date: Thu Sep 22 13:51:12 2011
New Revision: 1174139

URL: http://svn.apache.org/viewvc?rev=1174139&view=rev
Log:
Try to find proper URL information on externals during upgrade. Do this only
after the existing prop upgrade ran through, as repository information is
easiest to obtain after all that. Issue #4016.

(This might obsolete some parts of the existing externals upgrade code. But
that is stuff for another patch, and might just be micro-optimization.)

* subversion/libsvn_client/cleanup.c
  (svn_client_upgrade): 
    Fetch all URL and revisions information from upgraded externals working
    copies, or from fetch_repos_info() if not checked out yet. This properly
    populates the EXTERNALS table rows for upgraded externals of all kinds.
    Furthermore, change error handling in the externals upgrade loop so that
    one externals failure does not abort upgrade of other externals.

* subversion/include/private/svn_wc_private.h,
* subversion/libsvn_wc/upgrade.c
  (svn_wc__upgrade_add_external_info): New function.

* subversion/libsvn_wc/wc_db.h,
* subversion/libsvn_wc/wc_db.c
  (svn_wc__db_upgrade_insert_external): New function.

Modified:
    subversion/trunk/subversion/include/private/svn_wc_private.h
    subversion/trunk/subversion/libsvn_client/cleanup.c
    subversion/trunk/subversion/libsvn_wc/upgrade.c
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h

Modified: subversion/trunk/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_wc_private.h?rev=1174139&r1=1174138&r2=1174139&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_wc_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_wc_private.h Thu Sep 22 13:51:12 2011
@@ -1169,6 +1169,21 @@ svn_wc__node_was_moved_here(const char *
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool);
 
+/* During an upgrade to wc-ng, supply known details about an existing
+ * external.  The working copy will suck in and store the information supplied
+ * about the existing external at @a local_abspath. */
+svn_error_t *
+svn_wc__upgrade_add_external_info(svn_wc_context_t *wc_ctx,
+                                  const char *local_abspath,
+                                  svn_node_kind_t kind,
+                                  const char *def_local_abspath,
+                                  const char *repos_relpath,
+                                  const char *repos_root_url,
+                                  const char *repos_uuid,
+                                  svn_revnum_t def_peg_revision,
+                                  svn_revnum_t def_revision,
+                                  apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/trunk/subversion/libsvn_client/cleanup.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/cleanup.c?rev=1174139&r1=1174138&r2=1174139&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/cleanup.c (original)
+++ subversion/trunk/subversion/libsvn_client/cleanup.c Thu Sep 22 13:51:12 2011
@@ -171,7 +171,12 @@ svn_client_upgrade(const char *path,
           svn_wc_external_item2_t *item;
           const char *external_abspath;
           const char *external_path;
+          const char *repos_relpath;
+          const char *repos_root_url;
+          const char *repos_uuid;
           svn_node_kind_t kind;
+          svn_revnum_t peg_revision;
+          svn_revnum_t revision;
           svn_error_t *err;
 
           item = APR_ARRAY_IDX(externals_p, i, svn_wc_external_item2_t*);
@@ -180,8 +185,10 @@ svn_client_upgrade(const char *path,
           external_path = svn_dirent_join(externals_parent, item->target_dir,
                                           iterpool2);
 
-          SVN_ERR(svn_dirent_get_absolute(&external_abspath, external_path,
-                                          iterpool2));
+          err = svn_dirent_get_absolute(&external_abspath, external_path,
+                                        iterpool2);
+          if (err)
+            goto handle_error;
 
           /* This is hack. We can only send dirs to svn_wc_upgrade(). This
              way we will get an exception saying that the wc must be
@@ -195,10 +202,106 @@ svn_client_upgrade(const char *path,
             {
               svn_error_clear(err);
 
-              SVN_ERR(svn_client_upgrade(external_abspath, ctx, iterpool2));
+              err = svn_client_upgrade(external_abspath, ctx, iterpool2);
+            }
+
+          if (err)
+            goto handle_error;
+
+          /* The upgrade of any dir should be done now, get the (supposedly
+           * now reliable) kind. */
+          err = svn_wc_read_kind(&kind, ctx->wc_ctx, external_abspath,
+                                 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_relpath(&repos_relpath,
+                                               ctx->wc_ctx,
+                                               external_abspath,
+                                               iterpool2, iterpool2);
+          if (! err)
+            {
+              /* We got a repos relpath from a WC. So also get the root. */
+              err = svn_wc__node_get_repos_info(&repos_root_url,
+                                                &repos_uuid,
+                                                ctx->wc_ctx,
+                                                external_abspath,
+                                                iterpool2, iterpool2);
+            }
+          else if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+            {
+              /* The external is not currently checked out. Try to figure out
+               * the URL parts via the defined URL and fetch_repos_info(). */
+              svn_error_clear(err);
+
+              /* The repos root / uuid from above get_repos_info() call, if it
+               * was successful, has returned the URL as derived from the WC's
+               * parent path, which is not what we want for the external. Only
+               * makes sense for added/deleted/not-present files. So make sure
+               * those values are not used. */
+              repos_root_url = NULL;
+              repos_relpath = NULL;
+
+              err = fetch_repos_info(&repos_root_url,
+                                     &repos_uuid,
+                                     &info_baton,
+                                     item->url,
+                                     scratch_pool, scratch_pool);
+              if (err)
+                goto handle_error;
+
+
+              repos_relpath = svn_uri_skip_ancestor(repos_root_url, item->url,
+                                                    iterpool2);
+
+              /* There's just this URL, no idea what kind it is. */
+              kind = svn_node_unknown;
+            }
+
+          if (err)
+            goto handle_error;
+
+          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,
+                                                  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_notify_failed_external,
+                                       scratch_pool);
+              notify->err = err;
+
+              ctx->notify_func2(ctx->notify_baton2,
+                                notify, scratch_pool);
+
+              svn_error_clear(err);
             }
-          else
-            SVN_ERR(err);
         }
     }
 

Modified: subversion/trunk/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/upgrade.c?rev=1174139&r1=1174138&r2=1174139&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_wc/upgrade.c Thu Sep 22 13:51:12 2011
@@ -1985,3 +1985,44 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_wc__upgrade_add_external_info(svn_wc_context_t *wc_ctx,
+                                  const char *local_abspath,
+                                  svn_node_kind_t kind,
+                                  const char *def_local_abspath,
+                                  const char *repos_relpath,
+                                  const char *repos_root_url,
+                                  const char *repos_uuid,
+                                  svn_revnum_t def_peg_revision,
+                                  svn_revnum_t def_revision,
+                                  apr_pool_t *scratch_pool)
+{
+  svn_wc__db_kind_t db_kind;
+  switch (kind)
+    {
+      case svn_node_dir:
+        db_kind = svn_wc__db_kind_dir;
+        break;
+
+      case svn_node_file:
+        db_kind = svn_wc__db_kind_file;
+        break;
+
+      case svn_node_unknown:
+        db_kind = svn_wc__db_kind_unknown;
+        break;
+
+      default:
+        SVN_ERR_MALFUNCTION();
+    }
+
+  SVN_ERR(svn_wc__db_upgrade_insert_external(wc_ctx->db, local_abspath,
+                                             db_kind,
+                                             svn_dirent_dirname(local_abspath,
+                                                                scratch_pool),
+                                             def_local_abspath, repos_relpath,
+                                             repos_root_url, repos_uuid,
+                                             def_peg_revision, def_revision,
+                                             scratch_pool));
+  return SVN_NO_ERROR;
+}

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1174139&r1=1174138&r2=1174139&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Sep 22 13:51:12 2011
@@ -10413,6 +10413,77 @@ svn_wc__db_upgrade_apply_props(svn_sqlit
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_wc__db_upgrade_insert_external(svn_wc__db_t *db,
+                                   const char *local_abspath,
+                                   svn_wc__db_kind_t kind,
+                                   const char *parent_abspath,
+                                   const char *def_local_abspath,
+                                   const char *repos_relpath,
+                                   const char *repos_root_url,
+                                   const char *repos_uuid,
+                                   svn_revnum_t def_peg_revision,
+                                   svn_revnum_t def_revision,
+                                   apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *parent_local_relpath;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+  apr_int64_t repos_id;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot,
+                                                &parent_local_relpath, db,
+                                                parent_abspath, scratch_pool,
+                                                scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_SELECT_REPOSITORY));
+  SVN_ERR(svn_sqlite__bindf(stmt, "s", repos_root_url));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+  if (have_row)
+    repos_id = svn_sqlite__column_int64(stmt, 0);
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  if (!have_row)
+    {
+      /* Need to set up a new repository row. */
+      SVN_ERR(create_repos_id(&repos_id, repos_root_url, repos_uuid,
+                              wcroot->sdb, scratch_pool));
+    }
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_INSERT_EXTERNAL));
+
+  /* wc_id, local_relpath, parent_relpath, presence, kind, def_local_relpath,
+   * repos_id, def_repos_relpath, def_operational_revision, def_revision */
+  SVN_ERR(svn_sqlite__bindf(stmt, "issstsis",
+                            wcroot->wc_id,
+                            svn_dirent_skip_ancestor(wcroot->abspath,
+                                                     local_abspath),
+                            parent_local_relpath,
+                            "normal",
+                            kind_map, kind,
+                            svn_dirent_skip_ancestor(wcroot->abspath,
+                                                     def_local_abspath),
+                            repos_id,
+                            repos_relpath));
+
+  if (SVN_IS_VALID_REVNUM(def_peg_revision))
+    SVN_ERR(svn_sqlite__bind_revnum(stmt, 9, def_peg_revision));
+
+  if (SVN_IS_VALID_REVNUM(def_revision))
+    SVN_ERR(svn_sqlite__bind_revnum(stmt, 10, def_revision));
+
+  SVN_ERR(svn_sqlite__insert(NULL, stmt));
+
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_wc__db_upgrade_get_repos_id(apr_int64_t *repos_id,

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1174139&r1=1174138&r2=1174139&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Thu Sep 22 13:51:12 2011
@@ -2652,6 +2652,19 @@ svn_wc__db_upgrade_apply_props(svn_sqlit
                                apr_int64_t wc_id,
                                apr_pool_t *scratch_pool);
 
+/* Simply insert (or replace) one row in the EXTERNALS table. */
+svn_error_t *
+svn_wc__db_upgrade_insert_external(svn_wc__db_t *db,
+                                   const char *local_abspath,
+                                   svn_wc__db_kind_t kind,
+                                   const char *parent_abspath,
+                                   const char *def_local_abspath,
+                                   const char *repos_relpath,
+                                   const char *repos_root_url,
+                                   const char *repos_uuid,
+                                   svn_revnum_t def_peg_revision,
+                                   svn_revnum_t def_revision,
+                                   apr_pool_t *scratch_pool);
 
 /* Get the repository identifier corresponding to REPOS_ROOT_URL from the
    database in SDB. The value is returned in *REPOS_ID. All allocations



Mime
View raw message