You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/12/02 21:55:18 UTC

svn commit: r1041580 [11/35] - in /subversion/branches/gpg-agent-password-store: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/hook-scripts/ contrib/server-side/ notes/http-and-webdav/ notes/wc-ng/ subversi...

Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/status.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/status.c Thu Dec  2 20:55:08 2010
@@ -233,6 +233,115 @@ struct file_baton
 
 
 /** Code **/
+
+/* Fill in *INFO with the information it would contain if it were
+   obtained from svn_wc__db_read_children_info. */
+static svn_error_t *
+read_info(const struct svn_wc__db_info_t **info,
+          const char *local_abspath,
+          svn_wc__db_t *db,
+          apr_pool_t *result_pool,
+          apr_pool_t *scratch_pool)
+{
+  struct svn_wc__db_info_t *mutable 
+    = apr_palloc(scratch_pool, sizeof(struct svn_wc__db_info_t));
+
+  SVN_ERR(svn_wc__db_read_info(&mutable->status, &mutable->kind,
+                               &mutable->revnum, &mutable->repos_relpath,
+                               &mutable->repos_root_url, NULL,
+                               &mutable->changed_rev,
+                               &mutable->changed_date,
+                               &mutable->changed_author,
+                               &mutable->last_mod_time,
+                               &mutable->depth, NULL,
+                               &mutable->translated_size, NULL,
+                               &mutable->changelist, NULL, NULL, NULL, NULL,
+                               &mutable->props_mod,
+                               &mutable->have_base, NULL,
+                               &mutable->conflicted, &mutable->lock,
+                               db, local_abspath,
+                               result_pool, scratch_pool));
+
+  if (mutable->status == svn_wc__db_status_deleted)
+    mutable->has_props = FALSE;
+  else if (mutable->props_mod)
+    {
+      mutable->has_props = TRUE;
+#ifdef HAVE_SYMLINK
+      SVN_ERR(svn_wc__get_translate_info(NULL, NULL, NULL, &mutable->special,
+                                         db, local_abspath,
+                                         scratch_pool, scratch_pool));
+#endif
+    }
+  else
+    {
+      apr_hash_t *properties;
+
+      SVN_ERR(svn_wc__db_read_pristine_props(&properties, db, local_abspath,
+                                             scratch_pool, scratch_pool));
+      mutable->has_props = (properties && !!apr_hash_count(properties));
+#ifdef HAVE_SYMLINK
+      mutable->special = (mutable->has_props
+                          && apr_hash_get(properties, SVN_PROP_SPECIAL,
+                                          APR_HASH_KEY_STRING));
+#endif
+    }
+
+  *info = mutable;
+
+  return SVN_NO_ERROR;
+}
+
+/* Return *REPOS_RELPATH and *REPOS_ROOT_URL for LOCAL_ABSPATH using
+   information in INFO if available, falling back on
+   PARENT_REPOS_RELPATH and PARENT_REPOS_ROOT_URL if available, and
+   finally falling back on querying DB. */
+static svn_error_t *
+get_repos_root_url_relpath(const char **repos_relpath,
+                           const char **repos_root_url,
+                           const struct svn_wc__db_info_t *info,
+                           const char *parent_repos_relpath,
+                           const char *parent_repos_root_url,
+                           svn_wc__db_t *db,
+                           const char *local_abspath,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
+{
+  if (info->repos_relpath && info->repos_root_url)
+    {
+      *repos_relpath = info->repos_relpath;
+      *repos_root_url = info->repos_root_url;
+    }
+  else if (parent_repos_relpath && parent_repos_root_url)
+    {
+      *repos_relpath = svn_relpath_join(parent_repos_relpath,
+                                        svn_dirent_basename(local_abspath,
+                                                            NULL),
+                                        scratch_pool);
+      *repos_root_url = parent_repos_root_url;
+    }
+  else if (info->status == svn_wc__db_status_added)
+    {
+      SVN_ERR(svn_wc__db_scan_addition(NULL, NULL,
+                                       repos_relpath, repos_root_url,
+                                       NULL, NULL, NULL, NULL, NULL,
+                                       db, local_abspath,
+                                       result_pool, scratch_pool));
+    }
+  else if (info->have_base)
+    {
+      SVN_ERR(svn_wc__db_scan_base_repos(repos_relpath, repos_root_url, NULL,
+                                         db, local_abspath,
+                                         result_pool, scratch_pool));
+    }
+  else
+    {
+      *repos_relpath = NULL;
+      *repos_root_url = NULL;
+    }
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 internal_status(svn_wc_status3_t **status,
                 svn_wc__db_t *db,
@@ -262,6 +371,7 @@ assemble_status(svn_wc_status3_t **statu
                 const char *local_abspath,
                 const char *parent_repos_root_url,
                 const char *parent_repos_relpath,
+                const struct svn_wc__db_info_t *info,
                 const svn_io_dirent2_t *dirent,
                 svn_boolean_t get_all,
                 const svn_lock_t *repos_lock,
@@ -269,76 +379,32 @@ assemble_status(svn_wc_status3_t **statu
                 apr_pool_t *scratch_pool)
 {
   svn_wc_status3_t *stat;
-  svn_wc__db_status_t db_status;
-  svn_wc__db_kind_t db_kind;
-  const char *repos_relpath;
-  const char *repos_root_url;
   svn_boolean_t switched_p = FALSE;
-  svn_boolean_t prop_modified_p;
-  svn_wc__db_lock_t *lock;
-  svn_revnum_t revision;
-  svn_revnum_t changed_rev;
-  const char *changed_author;
-  apr_time_t changed_date;
-  const char *changelist;
-  svn_boolean_t have_base;
-  svn_boolean_t conflicted;
   svn_boolean_t copied = FALSE;
-  svn_filesize_t translated_size;
-  apr_time_t last_mod_time;
-  svn_depth_t depth;
+  svn_boolean_t conflicted;
   svn_error_t *err;
+  const char *repos_relpath;
+  const char *repos_root_url;
 
   /* Defaults for two main variables. */
   enum svn_wc_status_kind node_status = svn_wc_status_normal;
   enum svn_wc_status_kind text_status = svn_wc_status_normal;
   enum svn_wc_status_kind prop_status = svn_wc_status_none;
 
-  SVN_ERR(svn_wc__db_read_info(&db_status, &db_kind, &revision,
-                               &repos_relpath, &repos_root_url, NULL,
-                               &changed_rev, &changed_date,
-                               &changed_author, &last_mod_time, &depth, NULL,
-                               &translated_size, NULL, &changelist, NULL, NULL,
-                               NULL, NULL, &prop_modified_p, &have_base, NULL,
-                               &conflicted, &lock, db, local_abspath,
-                               result_pool, scratch_pool));
 
-  if (!repos_relpath)
-    {
-      /* The node is not switched, so imply from parent if possible */
-
-      if (parent_repos_relpath != NULL)
-        repos_relpath = svn_relpath_join(parent_repos_relpath,
-                                         svn_dirent_basename(local_abspath,
-                                                             NULL),
-                                         result_pool);
-      else if (db_status == svn_wc__db_status_added)
-        SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath,
-                                         &repos_root_url, NULL, NULL, NULL,
-                                         NULL, NULL,
-                                         db, local_abspath,
-                                         result_pool, scratch_pool));
-      else if (have_base)
-        SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath,
-                                           &repos_root_url, NULL,
-                                           db, local_abspath,
-                                           result_pool, scratch_pool));
+  if (!info)
+    SVN_ERR(read_info(&info, local_abspath, db, result_pool, scratch_pool));
 
-      switched_p = FALSE;
-    }
-  else if (!parent_repos_relpath)
+  if (!info->repos_relpath || !parent_repos_relpath)
     switched_p = FALSE;
   else
     {
       /* A node is switched if it doesn't have the implied repos_relpath */
-
-      const char *name = svn_relpath_is_child(parent_repos_relpath, repos_relpath, NULL);
+      const char *name = svn_relpath_is_child(parent_repos_relpath,
+                                              info->repos_relpath, NULL);
       switched_p = !name || (strcmp(name, svn_dirent_basename(local_abspath, NULL)) != 0);
     }
 
-  if (!repos_root_url && parent_repos_root_url)
-    repos_root_url = apr_pstrdup(result_pool, parent_repos_root_url);
-
   /* Examine whether our target is missing or obstructed or missing.
 
      While we are not completely in single-db mode yet, data about
@@ -347,14 +413,14 @@ assemble_status(svn_wc_status3_t **statu
      mode these obstructions are no longer reported and we have
      to detect obstructions by looking at the on disk status in DIRENT.
      */
-  if (db_kind == svn_wc__db_kind_dir)
+  if (info->kind == svn_wc__db_kind_dir)
     {
-      if (db_status == svn_wc__db_status_incomplete)
+      if (info->status == svn_wc__db_status_incomplete)
         {
           /* Highest precedence.  */
           node_status = svn_wc_status_incomplete;
         }
-      else if (db_status == svn_wc__db_status_deleted)
+      else if (info->status == svn_wc__db_status_deleted)
         {
           node_status = svn_wc_status_deleted;
 
@@ -374,7 +440,7 @@ assemble_status(svn_wc_status3_t **statu
     }
   else
     {
-      if (db_status == svn_wc__db_status_deleted)
+      if (info->status == svn_wc__db_status_deleted)
         {
           node_status = svn_wc_status_deleted;
 
@@ -400,13 +466,11 @@ assemble_status(svn_wc_status3_t **statu
      It means that no further information is available, and we should skip
      all this work.  */
   if (node_status == svn_wc_status_normal
-      || (node_status == svn_wc_status_missing && db_kind != svn_wc__db_kind_dir))
+      || (node_status == svn_wc_status_missing
+          && info->kind != svn_wc__db_kind_dir))
     {
       svn_boolean_t has_props;
       svn_boolean_t text_modified_p = FALSE;
-#ifdef HAVE_SYMLINK
-      svn_boolean_t wc_special;
-#endif /* HAVE_SYMLINK */
 
       /* Implement predecence rules: */
 
@@ -415,43 +479,30 @@ assemble_status(svn_wc_status3_t **statu
             precedence over M. */
 
       /* Does the node have props? */
-      if (db_status == svn_wc__db_status_deleted)
+      if (info->status == svn_wc__db_status_deleted)
         has_props = FALSE; /* Not interesting */
-      else if (prop_modified_p)
+      else if (info->props_mod)
         has_props = TRUE;
       else
-        {
-          apr_hash_t *props;
-        
-          SVN_ERR(svn_wc__db_read_pristine_props(&props, db, local_abspath,
-                                                 scratch_pool, scratch_pool));
+        has_props = info->has_props;
 
-          has_props = (props != NULL && apr_hash_count(props) > 0);
-        }
       if (has_props)
         prop_status = svn_wc_status_normal;
 
       /* If the entry has a properties, see if it has local changes. */
       if (has_props)
-        prop_status = prop_modified_p ? svn_wc_status_modified
+        prop_status = info->props_mod ? svn_wc_status_modified
                                       : svn_wc_status_normal;
 
-#ifdef HAVE_SYMLINK
-      if (has_props)
-        SVN_ERR(svn_wc__get_translate_info(NULL, NULL, NULL,
-                                           &wc_special,
-                                           db, local_abspath,
-                                           scratch_pool, scratch_pool));
-      else
-        wc_special = FALSE;
-#endif /* HAVE_SYMLINK */
+      /* ### Don't read properties twice!  Cache wc_special in
+             svn_wc__db_read_children_info. */
 
       /* If the entry is a file, check for textual modifications */
       if (node_status != svn_wc_status_missing
-          && (db_kind == svn_wc__db_kind_file
-              || db_kind == svn_wc__db_kind_symlink)
+          && (info->kind == svn_wc__db_kind_file
+              || info->kind == svn_wc__db_kind_symlink)
 #ifdef HAVE_SYMLINK
-             && (wc_special == (dirent && dirent->special))
+             && (info->special == (dirent && dirent->special))
 #endif /* HAVE_SYMLINK */
           )
         {
@@ -463,8 +514,8 @@ assemble_status(svn_wc_status3_t **statu
           if (dirent
               && dirent->filesize != SVN_INVALID_FILESIZE
               && dirent->mtime != 0
-              && translated_size == dirent->filesize
-              && last_mod_time == dirent->mtime)
+              && info->translated_size == dirent->filesize
+              && info->last_mod_time == dirent->mtime)
             text_modified_p = FALSE;
           else
             {
@@ -488,14 +539,16 @@ assemble_status(svn_wc_status3_t **statu
             }
         }
 #ifdef HAVE_SYMLINK
-      else if (wc_special != (dirent && dirent->special))
+      else if (info->special != (dirent && dirent->special))
         node_status = svn_wc_status_obstructed;
 #endif /* HAVE_SYMLINK */
 
+
       if (text_modified_p)
         text_status = svn_wc_status_modified;
     }
 
+  conflicted = info->conflicted;
   if (conflicted)
     {
       svn_boolean_t text_conflicted, prop_conflicted, tree_conflicted;
@@ -517,7 +570,7 @@ assemble_status(svn_wc_status3_t **statu
             of medium precedence.  They also override any C or M that may
             be in the prop_status field at this point, although they do not
             override a C text status.*/
-      if (db_status == svn_wc__db_status_added)
+      if (info->status == svn_wc__db_status_added)
         {
           svn_wc_schedule_t schedule;
           SVN_ERR(svn_wc__internal_node_get_schedule(&schedule, &copied,
@@ -546,21 +599,26 @@ assemble_status(svn_wc_status3_t **statu
          || (node_status == svn_wc_status_normal))
 
         && (! switched_p)
-        && (! lock) 
+        && (! info->lock) 
         && (! repos_lock)
-        && (! changelist)
+        && (! info->changelist)
         && (! conflicted))
       {
         *status = NULL;
         return SVN_NO_ERROR;
       }
 
+  SVN_ERR(get_repos_root_url_relpath(&repos_relpath, &repos_root_url, info,
+                                     parent_repos_relpath,
+                                     parent_repos_root_url,
+                                     db, local_abspath,
+                                     scratch_pool, scratch_pool));
 
   /* 6. Build and return a status structure. */
 
   stat = apr_pcalloc(result_pool, sizeof(**status));
 
-  switch (db_kind)
+  switch (info->kind)
     {
       case svn_wc__db_kind_dir:
         stat->kind = svn_node_dir;
@@ -573,7 +631,7 @@ assemble_status(svn_wc_status3_t **statu
       default:
         stat->kind = svn_node_unknown;
     }
-  stat->depth = depth;
+  stat->depth = info->depth;
   stat->node_status = node_status;
   stat->text_status = text_status;
   stat->prop_status = prop_status;
@@ -583,24 +641,24 @@ assemble_status(svn_wc_status3_t **statu
   stat->switched = switched_p;
   stat->copied = copied;
   stat->repos_lock = repos_lock;
-  stat->revision = revision;
-  stat->changed_rev = changed_rev;
-  stat->changed_author = changed_author;
-  stat->changed_date = changed_date;
+  stat->revision = info->revnum;
+  stat->changed_rev = info->changed_rev;
+  stat->changed_author = info->changed_author;
+  stat->changed_date = info->changed_date;
 
   stat->ood_kind = svn_node_none;
   stat->ood_changed_rev = SVN_INVALID_REVNUM;
   stat->ood_changed_date = 0;
   stat->ood_changed_author = NULL;
 
-  if (lock)
+  if (info->lock)
     {
       svn_lock_t *lck = apr_pcalloc(result_pool, sizeof(*lck));
       lck->path = repos_relpath;
-      lck->token = lock->token;
-      lck->owner = lock->owner;
-      lck->comment = lock->comment;
-      lck->creation_date = lock->date;
+      lck->token = info->lock->token;
+      lck->owner = info->lock->owner;
+      lck->comment = info->lock->comment;
+      lck->creation_date = info->lock->date;
       stat->lock = lck;
     }
   else
@@ -608,7 +666,7 @@ assemble_status(svn_wc_status3_t **statu
 
   stat->conflicted = conflicted;
   stat->versioned = TRUE;
-  stat->changelist = changelist;
+  stat->changelist = info->changelist;
   stat->repos_root_url = repos_root_url;
   stat->repos_relpath = repos_relpath;
 
@@ -699,6 +757,7 @@ send_status_structure(const struct walk_
                       const char *local_abspath,
                       const char *parent_repos_root_url,
                       const char *parent_repos_relpath,
+                      const struct svn_wc__db_info_t *info,
                       const svn_io_dirent2_t *dirent,
                       svn_boolean_t get_all,
                       svn_wc_status_func4_t status_func,
@@ -711,44 +770,27 @@ send_status_structure(const struct walk_
   /* Check for a repository lock. */
   if (wb->repos_locks)
     {
-      const char *repos_relpath;
-      svn_wc__db_status_t status;
-      svn_boolean_t have_base;
-
-      SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, &repos_relpath, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, &have_base, NULL, NULL, NULL, 
-                                   wb->db, local_abspath,
-                                   scratch_pool, scratch_pool));
-
-      /* A switched path can be deleted: check the right relpath */
-      if (status == svn_wc__db_status_deleted && have_base)
-        SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, NULL,
-                                           NULL, wb->db, local_abspath,
-                                           scratch_pool, scratch_pool));
-
-      if (!repos_relpath && parent_repos_relpath)
-        repos_relpath = svn_relpath_join(parent_repos_relpath,
-                                         svn_dirent_basename(local_abspath,
-                                                             NULL),
-                                         scratch_pool);
-
+      const char *repos_relpath, *repos_root_url;
 
+      SVN_ERR(get_repos_root_url_relpath(&repos_relpath, &repos_root_url,
+                                         info, parent_repos_relpath,
+                                         parent_repos_root_url,
+                                         wb->db, local_abspath,
+                                         scratch_pool, scratch_pool));
       if (repos_relpath)
         {
           /* repos_lock still uses the deprecated filesystem absolute path
              format */
           repos_lock = apr_hash_get(wb->repos_locks,
-                                    svn_uri_join("/", repos_relpath,
-                                                 scratch_pool),
+                                    svn_fspath__join("/", repos_relpath,
+                                                     scratch_pool),
                                     APR_HASH_KEY_STRING);
         }
     }
 
   SVN_ERR(assemble_status(&statstruct, wb->db, local_abspath,
                           parent_repos_root_url, parent_repos_relpath,
-                          dirent, get_all,
+                          info, dirent, get_all,
                           repos_lock, scratch_pool, scratch_pool));
 
   if (statstruct && status_func)
@@ -910,6 +952,7 @@ get_dir_status(const struct walk_status_
                svn_boolean_t skip_this_dir,
                const char *parent_repos_root_url,
                const char *parent_repos_relpath,
+               const struct svn_wc__db_info_t *dir_info,
                const svn_io_dirent2_t *dirent,
                const apr_array_header_t *ignores,
                svn_depth_t depth,
@@ -931,6 +974,7 @@ handle_dir_entry(const struct walk_statu
                  svn_wc__db_kind_t db_kind,
                  const char *dir_repos_root_url,
                  const char *dir_repos_relpath,
+                 const struct svn_wc__db_info_t *entry_info,
                  svn_io_dirent2_t *dirent,
                  const apr_array_header_t *ignores,
                  svn_depth_t depth,
@@ -963,6 +1007,7 @@ handle_dir_entry(const struct walk_statu
         {
           SVN_ERR(get_dir_status(wb, local_abspath, NULL, FALSE,
                                  dir_repos_root_url, dir_repos_relpath,
+                                 entry_info,
                                  dirent, ignores, depth, get_all, no_ignore,
                                  status_func, status_baton, cancel_func,
                                  cancel_baton,
@@ -975,7 +1020,7 @@ handle_dir_entry(const struct walk_statu
           SVN_ERR(send_status_structure(wb, local_abspath,
                                         dir_repos_root_url,
                                         dir_repos_relpath,
-                                        dirent, get_all,
+                                        entry_info, dirent, get_all,
                                         status_func, status_baton, pool));
         }
     }
@@ -985,7 +1030,7 @@ handle_dir_entry(const struct walk_statu
       SVN_ERR(send_status_structure(wb, local_abspath,
                                     dir_repos_root_url,
                                     dir_repos_relpath,
-                                    dirent, get_all,
+                                    entry_info, dirent, get_all,
                                     status_func, status_baton, pool));
     }
 
@@ -1067,6 +1112,7 @@ get_dir_status(const struct walk_status_
                svn_boolean_t skip_this_dir,
                const char *parent_repos_root_url,
                const char *parent_repos_relpath,
+               const struct svn_wc__db_info_t *dir_info,
                const svn_io_dirent2_t *dirent,
                const apr_array_header_t *ignore_patterns,
                svn_depth_t depth,
@@ -1083,29 +1129,20 @@ get_dir_status(const struct walk_status_
   const char *dir_repos_relpath;
   apr_hash_t *dirents, *nodes, *conflicts, *all_children;
   apr_array_header_t *patterns = NULL;
-  svn_wc__db_status_t dir_status;
-  svn_depth_t dir_depth;
   apr_pool_t *iterpool, *subpool = svn_pool_create(scratch_pool);
   svn_error_t *err;
 
-  /* See if someone wants to cancel this operation. */
   if (cancel_func)
     SVN_ERR(cancel_func(cancel_baton));
 
   if (depth == svn_depth_unknown)
     depth = svn_depth_infinity;
 
-  /* Make our iteration pool. */
   iterpool = svn_pool_create(subpool);
 
-  /* Load list of childnodes. */
-  {
-    const apr_array_header_t *child_nodes;
-
-    SVN_ERR(svn_wc__db_read_children(&child_nodes, wb->db, local_abspath,
-                                     iterpool, iterpool));
-    SVN_ERR(svn_hash_from_cstring_keys(&nodes, child_nodes, subpool));
-  }
+  SVN_ERR(svn_wc__db_read_children_info(&nodes, &conflicts,
+                                        wb->db, local_abspath,
+                                        subpool, iterpool));
 
   err = svn_io_get_dirents3(&dirents, local_abspath, FALSE, subpool, subpool);
   if (err
@@ -1118,77 +1155,36 @@ get_dir_status(const struct walk_status_
   else
     SVN_ERR(err);
 
-  SVN_ERR(svn_wc__db_read_info(&dir_status, NULL, NULL, &dir_repos_relpath,
-                               &dir_repos_root_url, NULL, NULL, NULL, NULL,
-                               NULL, &dir_depth, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, wb->db, local_abspath, scratch_pool,
-                               scratch_pool));
-
-  if (dir_repos_relpath == NULL)
-    {
-      if (parent_repos_root_url != NULL)
-        {
-          dir_repos_root_url = parent_repos_root_url;
-          dir_repos_relpath = svn_relpath_join(
-                                    parent_repos_relpath,
-                                    svn_dirent_basename(local_abspath, NULL),
-                                    scratch_pool);
-        }
-      else if (dir_status != svn_wc__db_status_deleted
-               && dir_status != svn_wc__db_status_added)
-        SVN_ERR(svn_wc__db_scan_base_repos(&dir_repos_relpath,
-                                           &dir_repos_root_url,
-                                           NULL, wb->db, local_abspath,
-                                           scratch_pool, scratch_pool));
-      else
-        {
-          dir_repos_relpath = NULL;
-          dir_repos_root_url = NULL;
-        }
-    }
-
+  if (!dir_info)
+    SVN_ERR(read_info(&dir_info, local_abspath, wb->db,
+                      scratch_pool, scratch_pool));
+
+  SVN_ERR(get_repos_root_url_relpath(&dir_repos_relpath, &dir_repos_root_url,
+                                     dir_info, parent_repos_relpath,
+                                     parent_repos_root_url,
+                                     wb->db, local_abspath,
+                                     scratch_pool, scratch_pool));
   if (selected == NULL)
     {
-      const apr_array_header_t *victims;
-      /* Create a hash containing all children */
+      /* Create a hash containing all children.  The source hashes
+         don't all map the same types, but only the keys of the result
+         hash are subsequently used. */
       all_children = apr_hash_overlay(subpool, nodes, dirents);
-
-      SVN_ERR(svn_wc__db_read_conflict_victims(&victims,
-                                               wb->db, local_abspath,
-                                               iterpool, iterpool));
-
-      SVN_ERR(svn_hash_from_cstring_keys(&conflicts, victims, subpool));
-
-      /* Optimize for the no-tree-conflict case */
       if (apr_hash_count(conflicts) > 0)
         all_children = apr_hash_overlay(subpool, conflicts, all_children);
     }
   else
     {
-      const svn_wc_conflict_description2_t *tc;
-      const char *selected_abspath;
-
-      conflicts = apr_hash_make(subpool);
+      /* Create a hash containing just selected */
       all_children = apr_hash_make(subpool);
-
       apr_hash_set(all_children, selected, APR_HASH_KEY_STRING, selected);
-
-      selected_abspath = svn_dirent_join(local_abspath, selected, iterpool);
-
-      SVN_ERR(svn_wc__db_op_read_tree_conflict(&tc, wb->db, selected_abspath,
-                                               iterpool, iterpool));
-
-      /* Note this path if a tree conflict is present.  */
-      if (tc != NULL)
-        apr_hash_set(conflicts, selected, APR_HASH_KEY_STRING, "");
     }
 
   /* If "this dir" has "svn:externals" property set on it, send the name and
      value to wc->external_func along with this directory's depth. (Also,
      we want to track the externals internally so we can report status more
      accurately.) */
-  SVN_ERR(handle_externals(wb, local_abspath, dir_depth, iterpool));
+  SVN_ERR(handle_externals(wb, local_abspath, dir_info->depth, iterpool));
 
   if (!selected)
     {
@@ -1197,7 +1193,7 @@ get_dir_status(const struct walk_status_
         SVN_ERR(send_status_structure(wb, local_abspath,
                                       parent_repos_root_url,
                                       parent_repos_relpath,
-                                      dirent, get_all,
+                                      dir_info, dirent, get_all,
                                       status_func, status_baton,
                                       iterpool));
 
@@ -1215,6 +1211,7 @@ get_dir_status(const struct walk_status_
       apr_ssize_t klen;
       const char *node_abspath;
       svn_io_dirent2_t *dirent_p;
+      const struct svn_wc__db_info_t *info;
 
       svn_pool_clear(iterpool);
 
@@ -1224,32 +1221,24 @@ get_dir_status(const struct walk_status_
 
       dirent_p = apr_hash_get(dirents, key, klen);
 
-      if (apr_hash_get(nodes, key, klen))
+      info = apr_hash_get(nodes, key, klen);
+      if (info)
         {
-          /* Versioned node */
-          svn_wc__db_status_t node_status;
-          svn_wc__db_kind_t node_kind;
-
-          SVN_ERR(svn_wc__db_read_info(&node_status, &node_kind, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL,
-                                   wb->db, node_abspath, iterpool, iterpool));
-
-          if (node_status != svn_wc__db_status_not_present
-              && node_status != svn_wc__db_status_excluded
-              && node_status != svn_wc__db_status_absent)
+          if (info->status != svn_wc__db_status_not_present
+              && info->status != svn_wc__db_status_excluded
+              && info->status != svn_wc__db_status_absent)
             {
-              if (depth == svn_depth_files && node_kind == svn_wc__db_kind_dir)
+              if (depth == svn_depth_files && info->kind == svn_wc__db_kind_dir)
                 continue;
 
               /* Handle this entry (possibly recursing). */
               SVN_ERR(handle_dir_entry(wb,
                                        node_abspath,
-                                       node_status,
-                                       node_kind,
+                                       info->status,
+                                       info->kind,
                                        dir_repos_root_url,
                                        dir_repos_relpath,
+                                       info,
                                        dirent_p,
                                        ignore_patterns,
                                        depth == svn_depth_infinity
@@ -1592,6 +1581,7 @@ make_dir_baton(void **dir_baton,
       SVN_ERR(get_dir_status(&eb->wb, local_abspath, NULL, TRUE,
                              status_in_parent->repos_root_url,
                              status_in_parent->repos_relpath,
+                             NULL,
                              NULL /* dirent */, ignores,
                              d->depth == svn_depth_files
                                       ? svn_depth_files
@@ -1765,6 +1755,7 @@ handle_statii(struct edit_baton *eb,
           SVN_ERR(get_dir_status(&eb->wb,
                                  local_abspath, NULL, TRUE,
                                  dir_repos_root_url, dir_repos_relpath,
+                                 NULL,
                                  NULL /* dirent */,
                                  ignores, depth, eb->get_all, eb->no_ignore,
                                  status_func, status_baton,
@@ -2033,7 +2024,7 @@ close_directory(void *dir_baton,
                 {
                   SVN_ERR(get_dir_status(&eb->wb,
                                          eb->target_abspath, NULL, TRUE,
-                                         NULL, NULL, NULL /* dirent */,
+                                         NULL, NULL, NULL, NULL /* dirent */,
                                          eb->ignores,
                                          eb->default_depth,
                                          eb->get_all, eb->no_ignore,
@@ -2196,10 +2187,10 @@ close_file(void *file_baton,
               const char *repos_relpath = svn_relpath_join(dir_repos_relpath,
                                                            fb->name, pool);
 
-               repos_lock = apr_hash_get(fb->edit_baton->wb.repos_locks,
-                                         svn_uri_join("/", repos_relpath,
-                                                      pool),
-                                         APR_HASH_KEY_STRING);
+              repos_lock = apr_hash_get(fb->edit_baton->wb.repos_locks,
+                                        svn_fspath__join("/", repos_relpath,
+                                                         pool),
+                                        APR_HASH_KEY_STRING);
             }
         }
     }
@@ -2415,7 +2406,7 @@ svn_wc_walk_status(svn_wc_context_t *wc_
                          anchor_abspath,
                          target_name,
                          skip_root,
-                         NULL, NULL, /* parent info */
+                         NULL, NULL, NULL, /* parent info */
                          dirent,
                          ignore_patterns,
                          depth,
@@ -2553,6 +2544,7 @@ internal_status(svn_wc_status3_t **statu
   return svn_error_return(assemble_status(status, db, local_abspath,
                                           parent_repos_root_url,
                                           parent_repos_relpath,
+                                          NULL,
                                           dirent,
                                           TRUE /* get_all */,
                                           NULL /* repos_lock */,

Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/translate.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/translate.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/translate.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/translate.c Thu Dec  2 20:55:08 2010
@@ -376,6 +376,7 @@ svn_wc__maybe_set_read_only(svn_boolean_
                             apr_pool_t *scratch_pool)
 {
   const svn_string_t *needs_lock;
+  svn_wc__db_status_t status;
   svn_wc__db_lock_t *lock;
   svn_error_t *err;
 
@@ -384,7 +385,7 @@ svn_wc__maybe_set_read_only(svn_boolean_
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  err = svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL,
+  err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL,
@@ -399,6 +400,11 @@ svn_wc__maybe_set_read_only(svn_boolean_
   else if (err)
     return svn_error_return(err);
   else if (lock)
+    /* ### Is this "we have the lock?" */
+    return SVN_NO_ERROR;
+
+  /* Files that aren't in the repository yet should be left writable. */
+  if (status == svn_wc__db_status_added)
     return SVN_NO_ERROR;
 
   SVN_ERR(svn_wc__internal_propget(&needs_lock, db, local_abspath,

Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/tree_conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/tree_conflicts.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/tree_conflicts.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/tree_conflicts.c Thu Dec  2 20:55:08 2010
@@ -267,47 +267,6 @@ svn_wc__deserialize_conflict(const svn_w
 }
 
 
-/* ### this is BAD. the CONFLICTS structure should not be dependent upon
-   ### DIR_PATH. each conflict should be labeled with an entry name, not
-   ### a whole path. (and a path which happens to vary based upon invocation
-   ### of the user client and these APIs)  */
-svn_error_t *
-svn_wc__read_tree_conflicts(apr_hash_t **conflicts,
-                            const char *conflict_data,
-                            const char *dir_path,
-                            apr_pool_t *pool)
-{
-  const svn_skel_t *skel;
-  apr_pool_t *iterpool;
-
-  *conflicts = apr_hash_make(pool);
-
-  if (conflict_data == NULL)
-    return SVN_NO_ERROR;
-
-  skel = svn_skel__parse(conflict_data, strlen(conflict_data), pool);
-  if (skel == NULL)
-    return svn_error_create(SVN_ERR_WC_CORRUPT, NULL,
-                            _("Error parsing tree conflict skel"));
-
-  iterpool = svn_pool_create(pool);
-  for (skel = skel->children; skel != NULL; skel = skel->next)
-    {
-      const svn_wc_conflict_description2_t *conflict;
-
-      svn_pool_clear(iterpool);
-      SVN_ERR(svn_wc__deserialize_conflict(&conflict, skel, dir_path,
-                                           pool, iterpool));
-      if (conflict != NULL)
-        apr_hash_set(*conflicts, svn_dirent_basename(conflict->local_abspath,
-                                                     pool),
-                     APR_HASH_KEY_STRING, conflict);
-    }
-  svn_pool_destroy(iterpool);
-
-  return SVN_NO_ERROR;
-}
-
 /* Prepend to SKEL the string corresponding to enumeration value N, as found
  * in MAP. */
 static svn_error_t *
@@ -417,29 +376,6 @@ svn_wc__serialize_conflict(svn_skel_t **
 
 
 svn_error_t *
-svn_wc__write_tree_conflicts(const char **conflict_data,
-                             apr_hash_t *conflicts,
-                             apr_pool_t *pool)
-{
-  svn_skel_t *skel = svn_skel__make_empty_list(pool);
-  apr_hash_index_t *hi;
-
-  for (hi = apr_hash_first(pool, conflicts); hi; hi = apr_hash_next(hi))
-    {
-      svn_skel_t *c_skel;
-
-      SVN_ERR(svn_wc__serialize_conflict(&c_skel, svn__apr_hash_index_val(hi),
-                                         pool, pool));
-      svn_skel__prepend(c_skel, skel);
-    }
-
-  *conflict_data = svn_skel__unparse(skel, pool)->data;
-
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
 svn_wc__del_tree_conflict(svn_wc_context_t *wc_ctx,
                           const char *victim_abspath,
                           apr_pool_t *scratch_pool)

Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/tree_conflicts.h
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/tree_conflicts.h?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/tree_conflicts.h (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/tree_conflicts.h Thu Dec  2 20:55:08 2010
@@ -74,37 +74,6 @@ svn_wc__deserialize_conflict(const svn_w
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool);
 
-/*
- * Encode tree conflict descriptions into a single string.
- *
- * Set *CONFLICT_DATA to a string, allocated in POOL, that encodes the tree
- * conflicts in CONFLICTS in a form suitable for storage in a single string
- * field in a WC entry. CONFLICTS is a hash of zero or more pointers to
- * svn_wc_conflict_description2_t objects, index by their basenames. All of the
- * conflict victim paths must be siblings.
- *
- * Do all allocations in POOL.
- *
- * @see svn_wc__read_tree_conflicts()
- */
-svn_error_t *
-svn_wc__write_tree_conflicts(const char **conflict_data,
-                             apr_hash_t *conflicts,
-                             apr_pool_t *pool);
-
-/*
- * Read tree conflict descriptions from @a conflict_data.  Set @a *conflicts
- * to a hash of pointers to svn_wc_conflict_description2_t objects indexed by
- * svn_wc_conflict_description2_t.local_abspath, all newly allocated in @a
- * pool.  @a dir_path is the path to the working copy directory whose conflicts
- * are being read.  The conflicts read are the tree conflicts on the immediate
- * child nodes of @a dir_path.  Do all allocations in @a pool.
- */
-svn_error_t *
-svn_wc__read_tree_conflicts(apr_hash_t **conflicts,
-                            const char *conflict_data,
-                            const char *dir_path,
-                            apr_pool_t *pool);
 
 /* Token mapping tables.  */
 extern const svn_token_map_t svn_wc__operation_map[];

Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/update_editor.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/update_editor.c Thu Dec  2 20:55:08 2010
@@ -1091,29 +1091,6 @@ window_handler(svn_txdelta_window_t *win
 }
 
 
-/* Prepare directory for dir_baton DB for updating or checking out.
- * Give it depth DEPTH.
- *
- * If the path already exists, but is not a working copy for
- * ANCESTOR_URL and ANCESTOR_REVISION, then an error will be returned.
- */
-static svn_error_t *
-prep_directory(struct dir_baton *db,
-               const char *ancestor_url,
-               svn_revnum_t ancestor_revision,
-               apr_pool_t *pool)
-{
-  const char *dir_abspath;
-
-  dir_abspath = db->local_abspath;
-
-  /* Make sure the directory exists. */
-  SVN_ERR(svn_wc__ensure_directory(dir_abspath, pool));
-
-  return SVN_NO_ERROR;
-}
-
-
 /* Find the last-change info within ENTRY_PROPS, and return then in the
    CHANGED_* parameters. Each parameter will be initialized to its "none"
    value, and will contain the relavent info if found.
@@ -1988,7 +1965,10 @@ do_entry_deletion(struct edit_baton *eb,
     }
 
     /* Receive the remote removal of excluded/absent/not present node.
-       Do not notify. */
+       Do not notify. 
+
+       ### This is wrong if svn_wc__db_status_excluded refers to a
+           working node replacing the base node.  */
   if (status == svn_wc__db_status_not_present
       || status == svn_wc__db_status_excluded
       || status == svn_wc__db_status_absent)
@@ -2043,8 +2023,7 @@ do_entry_deletion(struct edit_baton *eb,
            * we must schedule the existing content for re-addition as a copy
            * of what it was, but with its local modifications preserved. */
 
-          SVN_ERR(svn_wc__db_temp_op_make_copy(eb->db, local_abspath, FALSE,
-                                               pool));
+          SVN_ERR(svn_wc__db_temp_op_make_copy(eb->db, local_abspath, pool));
 
           /* Fall through to remove the BASE_NODEs properly, with potentially
              keeping a not-present marker */
@@ -2473,21 +2452,12 @@ add_directory(const char *path,
                                                        db->ambient_depth,
                                                        pool));
 
-  SVN_ERR(prep_directory(db,
-                         svn_path_url_add_component2(eb->repos_root,
-                                                     db->new_relpath, pool),
-                         *(eb->target_revision),
-                         db->pool));
-
-  /* If PATH is within a locally deleted tree then make it also
-     scheduled for deletion.  We must do this after the call to
-     prep_directory() otherwise the administrative area for DB->PATH
-     is not present, nor is there an entry for DB->PATH in DB->PATH's
-     entries. */
-  if (pb->in_deleted_and_tree_conflicted_subtree)
-    {
-      SVN_ERR(svn_wc__db_temp_op_delete(eb->db, db->local_abspath, pool));
-    }
+  SVN_ERR(svn_wc__ensure_directory(db->local_abspath, pool));
+
+  if (!pb->in_deleted_and_tree_conflicted_subtree
+      && status == svn_wc__db_status_added)
+    /* If there is no conflict we take over any added directory */
+    SVN_ERR(svn_wc__db_temp_op_remove_working(eb->db, db->local_abspath, pool));
 
   /* If this add was obstructed by dir scheduled for addition without
      history let close_file() handle the notification because there
@@ -2925,22 +2895,10 @@ close_directory(void *dir_baton,
          item to write out an old-style props file.  */
       if (new_base_props != NULL)
         {
-          apr_array_header_t *prop_diffs;
-
           SVN_ERR_ASSERT(new_actual_props != NULL);
 
-          /* If the ACTUAL props are the same as the BASE props, then we
-             should "write" a NULL. This will remove the props from the
-             ACTUAL_NODE row, and remove the old-style props file, indicating
-             "no change".  */
-          props = new_actual_props;
-          SVN_ERR(svn_prop_diffs(&prop_diffs, new_actual_props, new_base_props,
-                                 pool));
-          if (prop_diffs->nelts == 0)
-            props = NULL;
-
           SVN_ERR(svn_wc__db_op_set_props(eb->db, db->local_abspath,
-                                          props,
+                                          new_actual_props,
                                           NULL /* conflict */,
                                           NULL /* work_items */,
                                           pool));
@@ -4389,32 +4347,31 @@ close_file(void *file_baton,
       /* We will ALWAYS have properties to save (after a not-dry-run merge).  */
       SVN_ERR_ASSERT(new_base_props != NULL && new_actual_props != NULL);
 
-    /* Merge the text. This will queue some additional work.  */
-    SVN_ERR(merge_file(&all_work_items, &install_pristine, &install_from,
-                       &content_state, fb, new_text_base_sha1_checksum,
-                       pool, scratch_pool));
-
-    if (install_pristine)
-      {
-        svn_boolean_t record_fileinfo;
+      /* Merge the text. This will queue some additional work.  */
+      SVN_ERR(merge_file(&all_work_items, &install_pristine, &install_from,
+                         &content_state, fb, new_text_base_sha1_checksum,
+                         pool, scratch_pool));
 
-        /* If we are installing from the pristine contents, then go ahead and
-           record the fileinfo. That will be the "proper" values. Installing
-           from some random file means the fileinfo does NOT correspond to
-           the pristine (in which case, the fileinfo will be cleared for
-           safety's sake).  */
-        record_fileinfo = install_from == NULL;
+      if (install_pristine)
+        {
+          svn_boolean_t record_fileinfo;
 
-        SVN_ERR(svn_wc__wq_build_file_install(&work_item,
-                                              eb->db,
-                                              fb->local_abspath,
-                                              install_from,
-                                              eb->use_commit_times,
-                                              record_fileinfo,
-                                              pool, pool));
-        all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
-      }
+          /* If we are installing from the pristine contents, then go ahead and
+             record the fileinfo. That will be the "proper" values. Installing
+             from some random file means the fileinfo does NOT correspond to
+             the pristine (in which case, the fileinfo will be cleared for
+             safety's sake).  */
+          record_fileinfo = install_from == NULL;
 
+          SVN_ERR(svn_wc__wq_build_file_install(&work_item,
+                                                eb->db,
+                                                fb->local_abspath,
+                                                install_from,
+                                                eb->use_commit_times,
+                                                record_fileinfo,
+                                                pool, pool));
+          all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
+        }
     }
   else
     {
@@ -4568,13 +4525,6 @@ close_file(void *file_baton,
 
   /* Deal with the WORKING tree, based on updates to the BASE tree.  */
 
-  /* An ancestor was locally-deleted. This file is being added within
-     that tree. We need to schedule this file for deletion.  */
-  if (fb->dir_baton->in_deleted_and_tree_conflicted_subtree && fb->adding_file)
-    {
-      SVN_ERR(svn_wc__db_temp_op_delete(eb->db, fb->local_abspath, pool));
-    }
-
   /* If this file was locally-added and is now being added by the update, we
      can toss the local-add, turning this into a local-edit.  */
   if (fb->add_existed && fb->adding_file)
@@ -4587,23 +4537,10 @@ close_file(void *file_baton,
      properties merge. */
   if (! fb->adding_base_under_local_add)
     {
-      apr_hash_t *props;
-      apr_array_header_t *prop_diffs;
-
       SVN_ERR_ASSERT(new_actual_props != NULL);
 
-      /* If the ACTUAL props are the same as the BASE props, then we
-         should "write" a NULL. This will remove the props from the
-         ACTUAL_NODE row, and remove the old-style props file, indicating
-         "no change".  */
-      props = new_actual_props;
-      SVN_ERR(svn_prop_diffs(&prop_diffs, new_actual_props, new_base_props,
-                             pool));
-      if (prop_diffs->nelts == 0)
-        props = NULL;
-
       SVN_ERR(svn_wc__db_op_set_props(eb->db, fb->local_abspath,
-                                      props,
+                                      new_actual_props,
                                       NULL /* conflict */,
                                       NULL /* work_item */,
                                       pool));
@@ -4808,7 +4745,7 @@ tweak_entries(svn_wc__db_t *db,
       svn_wc__db_status_t status;
 
       const char *child_repos_relpath = NULL;
-      svn_boolean_t excluded;
+      svn_boolean_t excluded, is_file_external;
 
       svn_pool_clear(iterpool);
 
@@ -4818,12 +4755,21 @@ tweak_entries(svn_wc__db_t *db,
                                                child_basename, iterpool);
 
       child_abspath = svn_dirent_join(dir_abspath, child_basename, iterpool);
+
+      /* Skip stuff we've already decided to exclude. */
       excluded = (apr_hash_get(exclude_paths, child_abspath,
                                APR_HASH_KEY_STRING) != NULL);
-
       if (excluded)
         continue;
 
+      /* Skip stuff we've identified as file externals.  (If we're
+         here, we were doing an update of a directory, not the actual
+         switch handling of a file external itself.) */
+      SVN_ERR(svn_wc__internal_is_file_external(&is_file_external, db,
+                                                child_abspath, iterpool));
+      if (is_file_external)
+        continue;
+
       SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL,
                                    NULL, NULL, NULL, NULL, NULL, NULL,
                                    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -5512,6 +5458,18 @@ svn_wc__strictly_is_wc_root(svn_boolean_
 
 
 svn_error_t *
+svn_wc_get_wc_root(const char **wcroot_abspath,
+                   svn_wc_context_t *wc_ctx,
+                   const char *local_abspath,
+                   apr_pool_t *scratch_pool,
+                   apr_pool_t *result_pool)
+{
+  return svn_wc__db_get_wcroot(wcroot_abspath, wc_ctx->db,
+                               local_abspath, scratch_pool, result_pool);
+}
+
+
+svn_error_t *
 svn_wc_get_actual_target2(const char **anchor,
                           const char **target,
                           svn_wc_context_t *wc_ctx,
@@ -5575,8 +5533,6 @@ svn_wc_add_repos_file4(svn_wc_context_t 
                        svn_revnum_t copyfrom_rev,
                        svn_cancel_func_t cancel_func,
                        void *cancel_baton,
-                       svn_wc_notify_func2_t notify_func,
-                       void *notify_baton,
                        apr_pool_t *scratch_pool)
 {
   svn_wc__db_t *db = wc_ctx->db;
@@ -5592,7 +5548,6 @@ svn_wc_add_repos_file4(svn_wc_context_t 
   const char *original_root_url;
   const char *original_repos_relpath;
   const char *original_uuid;
-  apr_hash_t *actual_props;
   svn_revnum_t changed_rev;
   apr_time_t changed_date;
   const char *changed_author;
@@ -5714,25 +5669,6 @@ svn_wc_add_repos_file4(svn_wc_context_t 
                                    entry_props, pool, pool));
   }
 
-  /* Add some work items to install the properties.  */
-  {
-    if (new_props == NULL)
-      {
-        actual_props = NULL;
-      }
-    else
-      {
-        apr_array_header_t *prop_diffs;
-
-        SVN_ERR(svn_prop_diffs(&prop_diffs, new_props, new_base_props,
-                               pool));
-        if (prop_diffs->nelts == 0)
-          actual_props = NULL;
-        else
-          actual_props = new_props;
-      }
-  }
-
   /* Copy NEW_BASE_CONTENTS into a temporary file so our log can refer to
      it, and set TMP_TEXT_BASE_ABSPATH to its path.  Compute its
      NEW_TEXT_BASE_MD5_CHECKSUM and NEW_TEXT_BASE_SHA1_CHECKSUM as we copy. */
@@ -5857,7 +5793,7 @@ svn_wc_add_repos_file4(svn_wc_context_t 
   /* ### if below fails, then the above db change would remain :-(  */
 
   SVN_ERR(svn_wc__db_op_set_props(db, local_abspath,
-                                  actual_props,
+                                  new_props,
                                   NULL /* conflict */,
                                   all_work_items,
                                   pool));

Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/upgrade.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_wc/upgrade.c Thu Dec  2 20:55:08 2010
@@ -346,11 +346,7 @@ get_versioned_files(const apr_array_head
   svn_boolean_t have_row;
 
   /* ### just select 'file' children. do we need 'symlink' in the future?  */
-#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_ALL_FILES));
-#else
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_ALL_FILES_1));
-#endif
   SVN_ERR(svn_sqlite__bindf(stmt, "s", parent_relpath));
 
   /* ### 10 is based on Subversion's average of 8.5 files per versioned
@@ -376,14 +372,15 @@ get_versioned_files(const apr_array_head
 }
 
 
-/* */
+/* Return the path of the old-school administrative lock file
+   associated with LOCAL_DIR_ABSPATH, allocated from RESULT_POOL. */
 static const char *
 build_lockfile_path(const char *local_dir_abspath,
                     apr_pool_t *result_pool)
 {
   return svn_dirent_join_many(result_pool,
                               local_dir_abspath,
-                              ".svn", /* ### switch to dynamic?  */
+                              svn_wc_get_adm_dir(result_pool),
                               ADM_LOCK,
                               NULL);
 }
@@ -634,110 +631,75 @@ bump_to_13(void *baton, svn_sqlite__db_t
   return SVN_NO_ERROR;
 }
 
-
-#if 0 /* ### no tree conflict migration yet */
-
-/* ### duplicated from wc_db.c  */
-static const char *
-kind_to_word(svn_wc__db_kind_t kind)
-{
-  switch (kind)
-    {
-    case svn_wc__db_kind_dir:
-      return "dir";
-    case svn_wc__db_kind_file:
-      return "file";
-    case svn_wc__db_kind_symlink:
-      return "symlink";
-    case svn_wc__db_kind_unknown:
-      return "unknown";
-    case svn_wc__db_kind_subdir:
-      return "subdir";
-    default:
-      SVN_ERR_MALFUNCTION_NO_RETURN();
-    }
-}
-
-
-/* */
-static const char *
-conflict_kind_to_word(svn_wc_conflict_kind_t conflict_kind)
-{
-  switch (conflict_kind)
-    {
-    case svn_wc_conflict_kind_text:
-      return "text";
-    case svn_wc_conflict_kind_property:
-      return "property";
-    case svn_wc_conflict_kind_tree:
-      return "tree";
-    default:
-      SVN_ERR_MALFUNCTION_NO_RETURN();
-    }
-}
-
-
-/* */
-static const char *
-conflict_action_to_word(svn_wc_conflict_action_t action)
-{
-  return svn_token__to_word(svn_wc__conflict_action_map, action);
-}
-
-
-/* */
-static const char *
-conflict_reason_to_word(svn_wc_conflict_reason_t reason)
+/*
+ * Read tree conflict descriptions from @a conflict_data.  Set @a *conflicts
+ * to a hash of pointers to svn_wc_conflict_description2_t objects indexed by
+ * svn_wc_conflict_description2_t.local_abspath, all newly allocated in @a
+ * pool.  @a dir_path is the path to the working copy directory whose conflicts
+ * are being read.  The conflicts read are the tree conflicts on the immediate
+ * child nodes of @a dir_path.  Do all allocations in @a pool.
+ *
+ * Note: There were some concerns about this function:
+ *
+ * ### this is BAD. the CONFLICTS structure should not be dependent upon
+ * ### DIR_PATH. each conflict should be labeled with an entry name, not
+ * ### a whole path. (and a path which happens to vary based upon invocation
+ * ### of the user client and these APIs)
+ *
+ * those assumptions were baked into former versions of the data model, so
+ * they have to stick around here.  But they have been removed from the
+ * New Way. */
+static svn_error_t *
+read_tree_conflicts(apr_hash_t **conflicts,
+                    const char *conflict_data,
+                    const char *dir_path,
+                    apr_pool_t *pool)
 {
-  return svn_token__to_word(svn_wc__conflict_reason_map, reason);
-}
+  const svn_skel_t *skel;
+  apr_pool_t *iterpool;
 
+  *conflicts = apr_hash_make(pool);
 
-/* */
-static const char *
-wc_operation_to_word(svn_wc_operation_t operation)
-{
-  return svn_token__to_word(svn_wc__operation_map, operation);
-}
+  if (conflict_data == NULL)
+    return SVN_NO_ERROR;
 
+  skel = svn_skel__parse(conflict_data, strlen(conflict_data), pool);
+  if (skel == NULL)
+    return svn_error_create(SVN_ERR_WC_CORRUPT, NULL,
+                            _("Error parsing tree conflict skel"));
 
-/* */
-static svn_wc__db_kind_t
-db_kind_from_node_kind(svn_node_kind_t node_kind)
-{
-  switch (node_kind)
+  iterpool = svn_pool_create(pool);
+  for (skel = skel->children; skel != NULL; skel = skel->next)
     {
-    case svn_node_file:
-      return svn_wc__db_kind_file;
-    case svn_node_dir:
-      return svn_wc__db_kind_dir;
-    case svn_node_unknown:
-    case svn_node_none:
-      return svn_wc__db_kind_unknown;
-    default:
-      SVN_ERR_MALFUNCTION_NO_RETURN();
+      const svn_wc_conflict_description2_t *conflict;
+
+      svn_pool_clear(iterpool);
+      SVN_ERR(svn_wc__deserialize_conflict(&conflict, skel, dir_path,
+                                           pool, iterpool));
+      if (conflict != NULL)
+        apr_hash_set(*conflicts, svn_dirent_basename(conflict->local_abspath,
+                                                     pool),
+                     APR_HASH_KEY_STRING, conflict);
     }
-}
+  svn_pool_destroy(iterpool);
 
+  return SVN_NO_ERROR;
+}
 
 /* */
 static svn_error_t *
 migrate_single_tree_conflict_data(svn_sqlite__db_t *sdb,
                                   const char *tree_conflict_data,
-                                  apr_uint64_t wc_id,
+                                  apr_int64_t wc_id,
                                   const char *local_relpath,
                                   apr_pool_t *scratch_pool)
 {
-  svn_sqlite__stmt_t *insert_stmt;
   apr_hash_t *conflicts;
   apr_hash_index_t *hi;
   apr_pool_t *iterpool;
 
-  SVN_ERR(svn_sqlite__get_statement(&insert_stmt, sdb,
-                                    STMT_INSERT_NEW_CONFLICT));
-
-  SVN_ERR(svn_wc__read_tree_conflicts(&conflicts, tree_conflict_data,
-                                      local_relpath, scratch_pool));
+  SVN_ERR(read_tree_conflicts(&conflicts, tree_conflict_data, local_relpath,
+                              scratch_pool));
 
   iterpool = svn_pool_create(scratch_pool);
   for (hi = apr_hash_first(scratch_pool, conflicts);
@@ -747,8 +709,10 @@ migrate_single_tree_conflict_data(svn_sq
       const svn_wc_conflict_description2_t *conflict =
           svn__apr_hash_index_val(hi);
       const char *conflict_relpath;
-      apr_int64_t left_repos_id;
-      apr_int64_t right_repos_id;
+      const char *conflict_data;
+      svn_sqlite__stmt_t *stmt;
+      svn_boolean_t have_row;
+      svn_skel_t *skel;
 
       svn_pool_clear(iterpool);
 
@@ -757,72 +721,34 @@ migrate_single_tree_conflict_data(svn_sq
                                            conflict->local_abspath, iterpool),
                                          iterpool);
 
-      /* Optionally get the right repos ids. */
-      if (conflict->src_left_version)
-        {
-          SVN_ERR(svn_wc__db_upgrade_get_repos_id(
-                    &left_repos_id,
-                    sdb,
-                    conflict->src_left_version->repos_url,
-                    iterpool));
-        }
+      SVN_ERR(svn_wc__serialize_conflict(&skel, conflict, iterpool, iterpool));
+      conflict_data = svn_skel__unparse(skel, iterpool)->data;
 
-      if (conflict->src_right_version)
-        {
-          SVN_ERR(svn_wc__db_upgrade_get_repos_id(
-                    &right_repos_id,
-                    sdb,
-                    conflict->src_right_version->repos_url,
-                    iterpool));
-        }
-
-      SVN_ERR(svn_sqlite__bindf(insert_stmt, "is", wc_id, conflict_relpath));
-
-      SVN_ERR(svn_sqlite__bind_text(insert_stmt, 3,
-                                    svn_dirent_dirname(conflict_relpath,
-                                                       iterpool)));
-      SVN_ERR(svn_sqlite__bind_text(insert_stmt, 4,
-                                    kind_to_word(db_kind_from_node_kind(
-                                                        conflict->node_kind))));
-      SVN_ERR(svn_sqlite__bind_text(insert_stmt, 5,
-                                    conflict_kind_to_word(conflict->kind)));
-
-      if (conflict->property_name)
-        SVN_ERR(svn_sqlite__bind_text(insert_stmt, 6,
-                                      conflict->property_name));
-
-      SVN_ERR(svn_sqlite__bind_text(insert_stmt, 7,
-                              conflict_action_to_word(conflict->action)));
-      SVN_ERR(svn_sqlite__bind_text(insert_stmt, 8,
-                              conflict_reason_to_word(conflict->reason)));
-      SVN_ERR(svn_sqlite__bind_text(insert_stmt, 9,
-                              wc_operation_to_word(conflict->operation)));
+      /* See if we need to update or insert an ACTUAL node. */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_ACTUAL_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, conflict_relpath));
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      SVN_ERR(svn_sqlite__reset(stmt));
 
-      if (conflict->src_left_version)
+      if (have_row)
         {
-          SVN_ERR(svn_sqlite__bind_int64(insert_stmt, 10, left_repos_id));
-          SVN_ERR(svn_sqlite__bind_text(insert_stmt, 11,
-                                   conflict->src_left_version->path_in_repos));
-          SVN_ERR(svn_sqlite__bind_int64(insert_stmt, 12,
-                                       conflict->src_left_version->peg_rev));
-          SVN_ERR(svn_sqlite__bind_text(insert_stmt, 13,
-                                        kind_to_word(db_kind_from_node_kind(
-                                    conflict->src_left_version->node_kind))));
+          /* There is an existing ACTUAL row, so just update it. */
+          SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                            STMT_UPDATE_ACTUAL_CONFLICT_DATA));
         }
-
-      if (conflict->src_right_version)
+      else
         {
-          SVN_ERR(svn_sqlite__bind_int64(insert_stmt, 14, right_repos_id));
-          SVN_ERR(svn_sqlite__bind_text(insert_stmt, 15,
-                                 conflict->src_right_version->path_in_repos));
-          SVN_ERR(svn_sqlite__bind_int64(insert_stmt, 16,
-                                       conflict->src_right_version->peg_rev));
-          SVN_ERR(svn_sqlite__bind_text(insert_stmt, 17,
-                                        kind_to_word(db_kind_from_node_kind(
-                                    conflict->src_right_version->node_kind))));
+          /* We need to insert an ACTUAL row with the tree conflict data. */
+          SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                            STMT_INSERT_ACTUAL_CONFLICT_DATA));
         }
 
-      SVN_ERR(svn_sqlite__insert(NULL, insert_stmt));
+      SVN_ERR(svn_sqlite__bindf(stmt, "iss", wc_id, conflict_relpath,
+                                conflict_data));
+      if (!have_row)
+        SVN_ERR(svn_sqlite__bind_text(stmt, 4, local_relpath));
+
+      SVN_ERR(svn_sqlite__step_done(stmt));
     }
 
   svn_pool_destroy(iterpool);
@@ -833,57 +759,50 @@ migrate_single_tree_conflict_data(svn_sq
 
 /* */
 static svn_error_t *
-migrate_tree_conflicts(svn_sqlite__db_t *sdb,
-                       apr_pool_t *scratch_pool)
+migrate_tree_conflict_data(svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
 {
-  svn_sqlite__stmt_t *select_stmt;
-  svn_sqlite__stmt_t *erase_stmt;
+  svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
   /* Iterate over each node which has a set of tree conflicts, then insert
      all of them into the new schema.  */
 
-  SVN_ERR(svn_sqlite__get_statement(&select_stmt, sdb,
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                     STMT_SELECT_OLD_TREE_CONFLICT));
 
   /* Get all the existing tree conflict data. */
-  SVN_ERR(svn_sqlite__step(&have_row, select_stmt));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
   while (have_row)
     {
-      apr_uint64_t wc_id;
+      apr_int64_t wc_id;
       const char *local_relpath;
       const char *tree_conflict_data;
 
       svn_pool_clear(iterpool);
 
-      wc_id = svn_sqlite__column_int64(select_stmt, 0);
-      local_relpath = svn_sqlite__column_text(select_stmt, 1, iterpool);
-      tree_conflict_data = svn_sqlite__column_text(select_stmt, 2,
-                                                   iterpool);
+      wc_id = svn_sqlite__column_int64(stmt, 0);
+      local_relpath = svn_sqlite__column_text(stmt, 1, iterpool);
+      tree_conflict_data = svn_sqlite__column_text(stmt, 2, iterpool);
 
-      SVN_ERR(migrate_single_tree_conflict_data(sdb,
-                                                tree_conflict_data,
+      SVN_ERR(migrate_single_tree_conflict_data(sdb, tree_conflict_data,
                                                 wc_id, local_relpath,
                                                 iterpool));
 
       /* We don't need to do anything but step over the previously
          prepared statement. */
-      SVN_ERR(svn_sqlite__step(&have_row, select_stmt));
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
     }
-  SVN_ERR(svn_sqlite__reset(select_stmt));
+  SVN_ERR(svn_sqlite__reset(stmt));
 
   /* Erase all the old tree conflict data.  */
-  SVN_ERR(svn_sqlite__get_statement(&erase_stmt, sdb,
-                                    STMT_ERASE_OLD_CONFLICTS));
-  SVN_ERR(svn_sqlite__step_done(erase_stmt));
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_ERASE_OLD_CONFLICTS));
+  SVN_ERR(svn_sqlite__step_done(stmt));
 
   svn_pool_destroy(iterpool);
   return SVN_NO_ERROR;
 }
 
-#endif /* ### no tree conflict migration yet */
-
 
 /* */
 static svn_error_t *
@@ -1199,7 +1118,6 @@ bump_to_17(void *baton, svn_sqlite__db_t
   return SVN_NO_ERROR;
 }
 
-#if (SVN_WC__VERSION > 19)
 static svn_error_t *
 bump_to_20(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
 {
@@ -1207,25 +1125,22 @@ bump_to_20(void *baton, svn_sqlite__db_t
   SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_20));
   return SVN_NO_ERROR;
 }
-#endif
-
 
-#if 0 /* ### no tree conflict migration yet */
-
-/* */
 static svn_error_t *
-bump_to_XXX(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
+bump_to_21(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
 {
-  const char *wcroot_abspath = ((struct bump_baton *)baton)->wcroot_abspath;
-
-  SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_XXX));
-
-  SVN_ERR(migrate_tree_conflicts(sdb, scratch_pool));
+  SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_21));
+  SVN_ERR(migrate_tree_conflict_data(sdb, scratch_pool));
+  return SVN_NO_ERROR;
+}
 
+static svn_error_t *
+bump_to_22(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_22));
   return SVN_NO_ERROR;
 }
 
-#endif /* ### no tree conflict migration yet */
 
 struct upgrade_data_t {
   svn_sqlite__db_t *sdb;
@@ -1248,7 +1163,9 @@ struct upgrade_data_t {
 
    Uses SCRATCH_POOL for all temporary allocation.  */
 static svn_error_t *
-upgrade_to_wcng(svn_wc__db_t *db,
+upgrade_to_wcng(void **dir_baton,
+                void *parent_baton,
+                svn_wc__db_t *db,
                 const char *dir_abspath,
                 int old_format,
                 svn_wc_upgrade_get_repos_info_t repos_info_func,
@@ -1350,11 +1267,11 @@ upgrade_to_wcng(svn_wc__db_t *db,
                                        scratch_pool));
     }
  
-  SVN_ERR(svn_wc__write_upgraded_entries(db, data->sdb,
+  SVN_ERR(svn_wc__write_upgraded_entries(dir_baton, parent_baton, db, data->sdb,
                                          data->repos_id, data->wc_id,
                                          dir_abspath, data->root_abspath,
                                          entries,
-                                         scratch_pool));
+                                         result_pool, scratch_pool));
 
   /***** WC PROPS *****/
 
@@ -1502,13 +1419,23 @@ svn_wc__upgrade_sdb(int *result_format,
                                    "use 'tools/dev/wc-ng/bump-to-19.py' to "
                                    "upgrade it"), wcroot_abspath);
 
-#if (SVN_WC__VERSION > 19)
       case 19:
         SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_20, &bb,
                                              scratch_pool));
         *result_format = 20;
         /* FALLTHROUGH  */
-#endif
+
+      case 20:
+        SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_21, &bb,
+                                             scratch_pool));
+        *result_format = 21;
+        /* FALLTHROUGH  */
+
+      case 21:
+        SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_22, &bb,
+                                             scratch_pool));
+        *result_format = 22;
+        /* FALLTHROUGH  */
 
       /* ### future bumps go here.  */
 #if 0
@@ -1541,7 +1468,8 @@ svn_wc__upgrade_sdb(int *result_format,
 
 /* */
 static svn_error_t *
-upgrade_working_copy(svn_wc__db_t *db,
+upgrade_working_copy(void *parent_baton,
+                     svn_wc__db_t *db,
                      const char *dir_abspath,
                      svn_wc_upgrade_get_repos_info_t repos_info_func,
                      void *repos_info_baton,
@@ -1551,8 +1479,10 @@ upgrade_working_copy(svn_wc__db_t *db,
                      void *cancel_baton,
                      svn_wc_notify_func2_t notify_func,
                      void *notify_baton,
+                     apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
 {
+  void *dir_baton;
   int old_format;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   apr_array_header_t *subdirs;
@@ -1595,7 +1525,7 @@ upgrade_working_copy(svn_wc__db_t *db,
     }
 
 
-  SVN_ERR(upgrade_to_wcng(db, dir_abspath, old_format,
+  SVN_ERR(upgrade_to_wcng(&dir_baton, parent_baton, db, dir_abspath, old_format,
                           repos_info_func, repos_info_baton,
                           repos_cache, data, scratch_pool, iterpool));
 
@@ -1611,12 +1541,12 @@ upgrade_working_copy(svn_wc__db_t *db,
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(upgrade_working_copy(db, child_abspath,
+      SVN_ERR(upgrade_working_copy(dir_baton, db, child_abspath,
                                    repos_info_func, repos_info_baton,
                                    repos_cache, data,
                                    cancel_func, cancel_baton,
                                    notify_func, notify_baton,
-                                   iterpool));
+                                   iterpool, iterpool));
     }
 
   svn_pool_destroy(iterpool);
@@ -1699,18 +1629,19 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
                           scratch_pool, scratch_pool));
 
   /* Upgrade the pre-wcng into a wcng in a temporary location. */
-  SVN_ERR(upgrade_working_copy(db, local_abspath,
+  SVN_ERR(upgrade_working_copy(NULL, db, local_abspath,
                                repos_info_func, repos_info_baton,
                                apr_hash_make(scratch_pool), &data,
                                cancel_func, cancel_baton,
                                notify_func, notify_baton,
-                               scratch_pool));
+                               scratch_pool, scratch_pool));
 
   /* A workqueue item to move the pristine dir into place */
   pristine_from = svn_wc__adm_child(data.root_abspath, PRISTINE_STORAGE_RELPATH,
                                     scratch_pool);
   pristine_to = svn_wc__adm_child(local_abspath, PRISTINE_STORAGE_RELPATH,
                                   scratch_pool);
+  SVN_ERR(svn_wc__ensure_directory(pristine_from, scratch_pool));
   SVN_ERR(svn_wc__wq_build_file_move(&work_item, db,
                                      pristine_from, pristine_to,
                                      scratch_pool, scratch_pool));