You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by sv...@apache.org on 2012/09/29 06:02:06 UTC

svn commit: r1391743 - in /subversion/branches/1.7.x: ./ STATUS subversion/include/private/svn_wc_private.h subversion/libsvn_client/cleanup.c subversion/libsvn_wc/upgrade.c subversion/libsvn_wc/wc_db.c subversion/libsvn_wc/wc_db.h

Author: svn-role
Date: Sat Sep 29 04:02:05 2012
New Revision: 1391743

URL: http://svn.apache.org/viewvc?rev=1391743&view=rev
Log:
Merge r1174342 from trunk:

 * r1174342
   Fix issue 4016, make status descend into dir externals after upgrade.
   Justification:
     Status doesn't work properly after upgrade.
   Votes:
     +1: philip, cmpilato, rhuijben

Modified:
    subversion/branches/1.7.x/   (props changed)
    subversion/branches/1.7.x/STATUS
    subversion/branches/1.7.x/subversion/include/private/svn_wc_private.h
    subversion/branches/1.7.x/subversion/libsvn_client/cleanup.c
    subversion/branches/1.7.x/subversion/libsvn_wc/upgrade.c
    subversion/branches/1.7.x/subversion/libsvn_wc/wc_db.c
    subversion/branches/1.7.x/subversion/libsvn_wc/wc_db.h

Propchange: subversion/branches/1.7.x/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1174342

Modified: subversion/branches/1.7.x/STATUS
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/STATUS?rev=1391743&r1=1391742&r2=1391743&view=diff
==============================================================================
--- subversion/branches/1.7.x/STATUS (original)
+++ subversion/branches/1.7.x/STATUS Sat Sep 29 04:02:05 2012
@@ -146,13 +146,6 @@ Veto-blocked changes:
 Approved changes:
 =================
 
- * r1174342
-   Fix issue 4016, make status descend into dir externals after upgrade.
-   Justification:
-     Status doesn't work properly after upgrade.
-   Votes:
-     +1: philip, cmpilato, rhuijben
-
  * r1374800, r1374802, r1389364
    Fix issues with applying Git patch files.
    Justification:

Modified: subversion/branches/1.7.x/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/include/private/svn_wc_private.h?rev=1391743&r1=1391742&r2=1391743&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/1.7.x/subversion/include/private/svn_wc_private.h Sat Sep 29 04:02:05 2012
@@ -1112,6 +1112,21 @@ svn_wc__get_info(svn_wc_context_t *wc_ct
                  void *cancel_baton,
                  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/branches/1.7.x/subversion/libsvn_client/cleanup.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_client/cleanup.c?rev=1391743&r1=1391742&r2=1391743&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_client/cleanup.c (original)
+++ subversion/branches/1.7.x/subversion/libsvn_client/cleanup.c Sat Sep 29 04:02:05 2012
@@ -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/branches/1.7.x/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_wc/upgrade.c?rev=1391743&r1=1391742&r2=1391743&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/1.7.x/subversion/libsvn_wc/upgrade.c Sat Sep 29 04:02:05 2012
@@ -1994,3 +1994,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/branches/1.7.x/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_wc/wc_db.c?rev=1391743&r1=1391742&r2=1391743&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/1.7.x/subversion/libsvn_wc/wc_db.c Sat Sep 29 04:02:05 2012
@@ -9980,6 +9980,79 @@ 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 *def_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));
+
+  /* We know only of DEF_LOCAL_ABSPATH that it definitely belongs to "this"
+   * WC, i.e. where the svn:externals prop is set. The external target path
+   * itself may be "hidden behind" other working copies. */
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &def_local_relpath,
+                                                db, def_local_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),
+                            svn_dirent_skip_ancestor(wcroot->abspath,
+                                                     parent_abspath),
+                            "normal",
+                            kind_map, kind,
+                            def_local_relpath,
+                            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/branches/1.7.x/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_wc/wc_db.h?rev=1391743&r1=1391742&r2=1391743&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/1.7.x/subversion/libsvn_wc/wc_db.h Sat Sep 29 04:02:05 2012
@@ -2635,6 +2635,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