You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/12/30 22:27:54 UTC

svn commit: r1054005 [6/11] - in /subversion/branches/ignore-mergeinfo: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ contrib/client-side/svn_load_dirs/ contrib/server-side/ contrib/server-side/mod_dontdothat/ contrib/server-side/sv...

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/node.c?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/node.c Thu Dec 30 21:27:46 2010
@@ -165,6 +165,55 @@ svn_wc__node_get_repos_info(const char *
   return SVN_NO_ERROR;
 }
 
+/* Convert DB_KIND into the appropriate NODE_KIND value.
+ * If SHOW_HIDDEN is TRUE, report the node kind as found in the DB
+ * even if DB_STATUS indicates that the node is hidden.
+ * Else, return svn_kind_none for such nodes.
+ *
+ * ### This is a bit ugly. We should consider promoting svn_wc__db_kind_t
+ * ### to the de-facto node kind type instead of converting between them
+ * ### in non-backwards compat code.
+ * ### See also comments at the definition of svn_wc__db_kind_t. */
+static svn_error_t *
+convert_db_kind_to_node_kind(svn_node_kind_t *node_kind,
+                             svn_wc__db_kind_t db_kind,
+                             svn_wc__db_status_t db_status,
+                             svn_boolean_t show_hidden)
+{
+  switch (db_kind)
+    {
+      case svn_wc__db_kind_file:
+        *node_kind = svn_node_file;
+        break;
+      case svn_wc__db_kind_dir:
+        *node_kind = svn_node_dir;
+        break;
+      case svn_wc__db_kind_symlink:
+        *node_kind = svn_node_file;
+        break;
+      case svn_wc__db_kind_unknown:
+        *node_kind = svn_node_unknown;
+        break;
+      default:
+        SVN_ERR_MALFUNCTION();
+    }
+
+  /* Make sure hidden nodes return svn_node_none. */
+  if (! show_hidden)
+    switch (db_status)
+      {
+        case svn_wc__db_status_not_present:
+        case svn_wc__db_status_absent:
+        case svn_wc__db_status_excluded:
+          *node_kind = svn_node_none;
+
+        default:
+          break;
+      }
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_wc_read_kind(svn_node_kind_t *kind,
                  svn_wc_context_t *wc_ctx,
@@ -192,36 +241,7 @@ svn_wc_read_kind(svn_node_kind_t *kind,
   else
     SVN_ERR(err);
 
-  switch (db_kind)
-    {
-      case svn_wc__db_kind_file:
-        *kind = svn_node_file;
-        break;
-      case svn_wc__db_kind_dir:
-        *kind = svn_node_dir;
-        break;
-      case svn_wc__db_kind_symlink:
-        *kind = svn_node_file;
-        break;
-      case svn_wc__db_kind_unknown:
-        *kind = svn_node_unknown;
-        break;
-      default:
-        SVN_ERR_MALFUNCTION();
-    }
-
-  /* Make sure hidden nodes return svn_node_none. */
-  if (! show_hidden)
-    switch (db_status)
-      {
-        case svn_wc__db_status_not_present:
-        case svn_wc__db_status_absent:
-        case svn_wc__db_status_excluded:
-          *kind = svn_node_none;
-
-        default:
-          break;
-      }
+  SVN_ERR(convert_db_kind_to_node_kind(kind, db_kind, db_status, show_hidden));
 
   return SVN_NO_ERROR;
 }
@@ -401,7 +421,7 @@ svn_wc__node_get_url(const char **url,
                             result_pool, scratch_pool));
 }
 
-/* ### This is essentially a copy-paste of svn_wc__internal_get_url(). 
+/* ### This is essentially a copy-paste of svn_wc__internal_get_url().
  * ### If we decide to keep this one, then it should be rewritten to avoid
  * ### code duplication.*/
 svn_error_t *
@@ -648,22 +668,28 @@ walker_helper(svn_wc__db_t *db,
               void *cancel_baton,
               apr_pool_t *scratch_pool)
 {
-  const apr_array_header_t *rel_children;
+  apr_hash_t *rel_children_info;
+  apr_hash_index_t *hi;
   apr_pool_t *iterpool;
-  int i;
 
   if (depth == svn_depth_empty)
     return SVN_NO_ERROR;
 
-  SVN_ERR(svn_wc__db_read_children(&rel_children, db, dir_abspath,
-                                   scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__db_read_children_walker_info(&rel_children_info, db,
+                                               dir_abspath, scratch_pool,
+                                               scratch_pool));
+
 
   iterpool = svn_pool_create(scratch_pool);
-  for (i = 0; i < rel_children->nelts; i++)
+  for (hi = apr_hash_first(scratch_pool, rel_children_info);
+       hi;
+       hi = apr_hash_next(hi))
     {
+      const char *child_name = svn__apr_hash_index_key(hi);
+      struct svn_wc__db_walker_info_t *wi = svn__apr_hash_index_val(hi);
+      svn_wc__db_kind_t child_kind = wi->kind;
+      svn_wc__db_status_t child_status = wi->status;
       const char *child_abspath;
-      svn_wc__db_kind_t child_kind;
-      svn_wc__db_status_t child_status;
 
       svn_pool_clear(iterpool);
 
@@ -671,17 +697,7 @@ walker_helper(svn_wc__db_t *db,
       if (cancel_func)
         SVN_ERR(cancel_func(cancel_baton));
 
-      child_abspath = svn_dirent_join(dir_abspath,
-                                      APR_ARRAY_IDX(rel_children, i,
-                                                    const char *),
-                                      iterpool);
-
-      SVN_ERR(svn_wc__db_read_info(&child_status, &child_kind, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL,
-                                   db, child_abspath, iterpool, iterpool));
+      child_abspath = svn_dirent_join(dir_abspath, child_name, iterpool);
 
       if (!show_hidden)
         switch (child_status)
@@ -699,9 +715,14 @@ walker_helper(svn_wc__db_t *db,
       if (child_kind == svn_wc__db_kind_file
             || depth >= svn_depth_immediates)
         {
-          /* ### Maybe we should pass kind to the callback?.
-             ### almost every callee starts by asking for this */
-          SVN_ERR(walk_callback(child_abspath, walk_baton, iterpool));
+          svn_node_kind_t kind;
+
+          SVN_ERR(convert_db_kind_to_node_kind(&kind, child_kind,
+                                               child_status, show_hidden));
+          /* ### We might want to pass child_status as well because at least
+           * ### one callee is asking for it.
+           * ### But is it OK to use an svn_wc__db type in this API? */
+          SVN_ERR(walk_callback(child_abspath, kind, walk_baton, iterpool));
         }
 
       /* Recurse into this directory, if appropriate. */
@@ -737,28 +758,30 @@ svn_wc__internal_walk_children(svn_wc__d
                                void *cancel_baton,
                                apr_pool_t *scratch_pool)
 {
-  svn_wc__db_kind_t kind;
+  svn_wc__db_kind_t db_kind;
+  svn_node_kind_t kind;
   svn_wc__db_status_t status;
 
   SVN_ERR_ASSERT(walk_depth >= svn_depth_empty
                  && walk_depth <= svn_depth_infinity);
 
   /* Check if the node exists before the first callback */
-  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL,
+  SVN_ERR(svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL,
                                db, local_abspath, scratch_pool, scratch_pool));
 
-  SVN_ERR(walk_callback(local_abspath, walk_baton, scratch_pool));
+  SVN_ERR(convert_db_kind_to_node_kind(&kind, db_kind, status, show_hidden));
+  SVN_ERR(walk_callback(local_abspath, kind, walk_baton, scratch_pool));
 
-  if (kind == svn_wc__db_kind_file
+  if (db_kind == svn_wc__db_kind_file
       || status == svn_wc__db_status_not_present
       || status == svn_wc__db_status_excluded
       || status == svn_wc__db_status_absent)
     return SVN_NO_ERROR;
 
-  if (kind == svn_wc__db_kind_dir)
+  if (db_kind == svn_wc__db_kind_dir)
     {
       return svn_error_return(
         walker_helper(db, local_abspath, show_hidden, walk_callback, walk_baton,
@@ -957,11 +980,11 @@ svn_wc__node_get_base_rev(svn_revnum_t *
 
 svn_error_t *
 svn_wc__node_get_working_rev_info(svn_revnum_t *revision,
-                                  svn_revnum_t *changed_rev, 
-                                  apr_time_t *changed_date, 
+                                  svn_revnum_t *changed_rev,
+                                  apr_time_t *changed_date,
                                   const char **changed_author,
-                                  svn_wc_context_t *wc_ctx, 
-                                  const char *local_abspath, 
+                                  svn_wc_context_t *wc_ctx,
+                                  const char *local_abspath,
                                   apr_pool_t *scratch_pool,
                                   apr_pool_t *result_pool)
 {
@@ -993,7 +1016,7 @@ svn_wc__node_get_working_rev_info(svn_re
                                        NULL, changed_rev, changed_date,
                                        changed_author, NULL, NULL, NULL,
                                        NULL, NULL, NULL, NULL, NULL, NULL,
-                                       NULL, NULL, NULL, NULL, 
+                                       NULL, NULL, NULL, NULL,
                                        NULL, NULL, wc_ctx->db, work_del_abspath,
                                        result_pool, scratch_pool));
         }
@@ -1146,7 +1169,7 @@ svn_wc__node_get_lock_info(const char **
     *lock_comment = lock ? lock->comment : NULL;
   if (lock_date)
     *lock_date = lock ? lock->date : 0;
-      
+
   return SVN_NO_ERROR;
 }
 
@@ -1317,6 +1340,19 @@ svn_wc__internal_node_get_schedule(svn_w
               if (base_status != svn_wc__db_status_not_present)
                 *schedule = svn_wc_schedule_replace;
             }
+          else
+            {
+              svn_boolean_t below_work;
+
+              SVN_ERR(svn_wc__db_temp_below_work(&below_work,
+                                                 db, local_abspath,
+                                                 scratch_pool));
+              /* Unlike base nodes above, not-present is considered a
+                 replace since working not-present represents a delete
+                 to be committed */
+              if (below_work)
+                *schedule = svn_wc_schedule_replace;
+            }
 
           if (status == svn_wc__db_status_added)
             break; /* Local addition */

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/props.c?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/props.c Thu Dec 30 21:27:46 2010
@@ -480,7 +480,7 @@ generate_conflict_message(const char *pr
                                       "value '%s',\nbut property with value "
                                       "'%s' is locally deleted."),
                                     propname, incoming_base->data,
-                                    original->data);          
+                                    original->data);
         }
 
       /* We were trying to delete INCOMING_BASE but our ORIGINAL is
@@ -535,7 +535,7 @@ generate_conflict_message(const char *pr
                                 "added with value '%s'."),
                               propname, incoming_base->data, incoming->data,
                               mine->data);
-  
+
   return svn_string_createf(result_pool,
                             _("Trying to change property '%s' from '%s' to "
                               "'%s',\nbut the property does not exist."),

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/relocate.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/relocate.c?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/relocate.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/relocate.c Thu Dec 30 21:27:46 2010
@@ -136,7 +136,7 @@ svn_wc_relocate4(svn_wc_context_t *wc_ct
                              _("Invalid source URL prefix: '%s' (does not "
                                "overlap target's URL '%s')"),
                              from, old_url);
-  
+
   if (old_url_len == from_len)
     new_url = to;
   else

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/revision_status.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/revision_status.c?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/revision_status.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/revision_status.c Thu Dec 30 21:27:46 2010
@@ -52,18 +52,19 @@ struct walk_baton
  * Temporary allocations are made in SCRATCH_POOL. */
 static svn_error_t *
 analyze_status(const char *local_abspath,
+               svn_node_kind_t kind,
                void *baton,
                apr_pool_t *scratch_pool)
 {
   struct walk_baton *wb = baton;
   svn_revnum_t changed_rev;
   svn_revnum_t revision;
-  svn_revnum_t item_rev; 
+  svn_revnum_t item_rev;
   svn_depth_t depth;
   svn_wc__db_status_t status;
 
-  SVN_ERR(svn_wc__db_read_info(&status, NULL, &revision, NULL, 
-                               NULL, NULL, &changed_rev, 
+  SVN_ERR(svn_wc__db_read_info(&status, NULL, &revision, NULL,
+                               NULL, NULL, &changed_rev,
                                NULL, NULL, NULL, &depth, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, wb->db,
@@ -72,7 +73,7 @@ analyze_status(const char *local_abspath
   /* We need the excluded and absent paths when checking for sparse
    * checkouts. But only for that. To collect those we're walking all the
    * hidden nodes. */
-  if (status == svn_wc__db_status_excluded 
+  if (status == svn_wc__db_status_excluded
       || status == svn_wc__db_status_absent)
     {
       wb->result->sparse_checkout = TRUE;
@@ -85,7 +86,7 @@ analyze_status(const char *local_abspath
   else if (status == svn_wc__db_status_added
            || status == svn_wc__db_status_deleted)
     {
-      wb->result->modified = TRUE; 
+      wb->result->modified = TRUE;
     }
 
   if (! wb->result->switched)
@@ -134,10 +135,10 @@ analyze_status(const char *local_abspath
                                                FALSE,
                                                TRUE,
                                                scratch_pool));
-      wb->result->modified |= text_mod; 
+      wb->result->modified |= text_mod;
     }
 
-  wb->result->sparse_checkout |= (depth != svn_depth_infinity 
+  wb->result->sparse_checkout |= (depth != svn_depth_infinity
                                   && depth != svn_depth_unknown);
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/status.c?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/status.c Thu Dec 30 21:27:46 2010
@@ -187,7 +187,7 @@ struct dir_baton
   /* out-of-date info corresponding to ood_* fields in svn_wc_status3_t. */
   svn_node_kind_t ood_kind;
   svn_revnum_t ood_changed_rev;
-  apr_time_t ood_changed_date;  
+  apr_time_t ood_changed_date;
   const char *ood_changed_author;
 };
 
@@ -243,7 +243,7 @@ read_info(const struct svn_wc__db_info_t
           apr_pool_t *result_pool,
           apr_pool_t *scratch_pool)
 {
-  struct svn_wc__db_info_t *mutable 
+  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,
@@ -560,7 +560,7 @@ assemble_status(svn_wc_status3_t **statu
                                             db, local_abspath, scratch_pool));
 
       if (!text_conflicted && !prop_conflicted && !tree_conflicted)
-        conflicted = FALSE; 
+        conflicted = FALSE;
     }
 
   if (node_status == svn_wc_status_normal)
@@ -586,7 +586,7 @@ assemble_status(svn_wc_status3_t **statu
 
   if (node_status == svn_wc_status_normal)
     node_status = text_status;
-  
+
   if (node_status == svn_wc_status_normal
       && prop_status != svn_wc_status_none)
     node_status = prop_status;
@@ -599,7 +599,7 @@ assemble_status(svn_wc_status3_t **statu
          || (node_status == svn_wc_status_normal))
 
         && (! switched_p)
-        && (! info->lock) 
+        && (! info->lock)
         && (! repos_lock)
         && (! info->changelist)
         && (! conflicted))
@@ -2530,8 +2530,8 @@ internal_status(svn_wc_status3_t **statu
       else if (err)
         return svn_error_return(err);
 
-      if (!err 
-          && parent_repos_relpath == NULL 
+      if (!err
+          && parent_repos_relpath == NULL
           && parent_status != svn_wc__db_status_added
           && parent_status != svn_wc__db_status_deleted)
         SVN_ERR(svn_wc__db_scan_base_repos(&parent_repos_relpath,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/update_editor.c?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/update_editor.c Thu Dec 30 21:27:46 2010
@@ -908,9 +908,6 @@ struct file_baton
   /* Set if this file is new. */
   svn_boolean_t adding_file;
 
-  /* Set if this file is new with history. */
-  svn_boolean_t added_with_history;
-
   /* Set if an unversioned file of the same name already existed in
      this directory. */
   svn_boolean_t obstruction_found;
@@ -928,24 +925,6 @@ struct file_baton
   svn_checksum_t *new_text_base_md5_checksum;
   svn_checksum_t *new_text_base_sha1_checksum;
 
-  /* If this file was added with history, these are the checksums of the
-     copy-from text base, which is in the pristine store, else NULL. */
-  svn_checksum_t *copied_text_base_md5_checksum;
-  svn_checksum_t *copied_text_base_sha1_checksum;
-
-  /* If this file was added with history, and the copyfrom had local
-     mods, this is the path to a copy of the user's version with local
-     mods (in the temporary area). */
-  const char *copied_working_text;
-
-  /* If this file was added with history, this hash contains the base
-     properties of the copied file. */
-  apr_hash_t *copied_base_props;
-
-  /* If this file was added with history, this hash contains the working
-     properties of the copied file. */
-  apr_hash_t *copied_working_props;
-
   /* Set if we've received an apply_textdelta for this file. */
   svn_boolean_t received_textdelta;
 
@@ -956,7 +935,7 @@ struct file_baton
 
   /* The last-changed-date of the file.  This is actually a property
      that comes through as an 'entry prop', and will be used to set
-     the working file's timestamp if it's added. 
+     the working file's timestamp if it's added.
 
      Will be NULL unless eb->use_commit_times is TRUE. */
   const char *last_changed_date;
@@ -1102,8 +1081,6 @@ static svn_error_t *
 accumulate_last_change(svn_revnum_t *changed_rev,
                        apr_time_t *changed_date,
                        const char **changed_author,
-                       svn_wc__db_t *db,
-                       const char *local_abspath,
                        const apr_array_header_t *entry_props,
                        apr_pool_t *scratch_pool,
                        apr_pool_t *result_pool)
@@ -1318,18 +1295,21 @@ typedef struct modcheck_baton_t {
                                           then this field has no meaning. */
 } modcheck_baton_t;
 
-/* */
+/* An implementation of svn_wc__node_found_func_t. */
 static svn_error_t *
 modcheck_found_node(const char *local_abspath,
+                    svn_node_kind_t kind,
                     void *walk_baton,
                     apr_pool_t *scratch_pool)
 {
   modcheck_baton_t *baton = walk_baton;
-  svn_wc__db_kind_t kind;
+  svn_wc__db_kind_t db_kind;
   svn_wc__db_status_t status;
   svn_boolean_t modified;
 
-  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
+  /* ### The walker could in theory pass status and db kind as arguments.
+   * ### So this read_info call is probably redundant. */
+  SVN_ERR(svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL,
@@ -1342,7 +1322,7 @@ modcheck_found_node(const char *local_ab
      modification */
   else if (!baton->found_mod || baton->all_edits_are_deletes)
     SVN_ERR(entry_has_local_mods(&modified, baton->db, local_abspath,
-                                 kind, scratch_pool));
+                                 db_kind, scratch_pool));
 
   if (modified)
     {
@@ -1965,7 +1945,7 @@ 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.  */
@@ -2042,7 +2022,7 @@ do_entry_deletion(struct edit_baton *eb,
           /* The item was locally replaced with something else. We should
            * remove the BASE node below the new working node, which turns
            * the replacement in an addition. */
-           
+
            /* Fall through to the normal "delete" code path. */
         }
       else
@@ -2815,7 +2795,7 @@ close_directory(void *dir_baton,
       SVN_ERR(accumulate_last_change(&new_changed_rev,
                                      &new_changed_date,
                                      &new_changed_author,
-                                     eb->db, db->local_abspath, entry_props,
+                                     entry_props,
                                      pool, pool));
     }
 
@@ -3496,13 +3476,7 @@ apply_textdelta(void *file_baton,
     }
   else
     {
-      if (fb->copied_text_base_sha1_checksum)
-        SVN_ERR(svn_wc__db_pristine_read(&source, fb->edit_baton->db,
-                                         fb->local_abspath,
-                                         fb->copied_text_base_sha1_checksum,
-                                         handler_pool, handler_pool));
-      else
-        source = svn_stream_empty(handler_pool);
+      source = svn_stream_empty(handler_pool);
     }
 
   /* If we don't have a recorded checksum, use the ra provided checksum */
@@ -3704,8 +3678,7 @@ merge_file(svn_skel_t **work_items,
      Note that this compares to the current pristine file, which is
      different from fb->old_text_base_path if we have a replaced-with-history
      file.  However, in the case we had an obstruction, we check against the
-     new text base. (And if we're doing an add-with-history and we've already
-     saved a copy of a locally-modified file, then there certainly are mods.)
+     new text base.
 
      Special case: The working file is referring to a file external? If so
                    then we must mark it as unmodified in order to avoid bogus
@@ -3713,17 +3686,7 @@ merge_file(svn_skel_t **work_items,
                    merge externals item from the repository.
 
      ### Newly added file externals have a svn_wc_schedule_add here. */
-  if (fb->copied_working_text)
-    {
-      /* The file was copied here, and it came with both a (new) pristine
-         and a working file. Presumably, the working file is modified
-         relative to the new pristine.
-
-         The new pristine is in NEW_TEXT_BASE_TMP_ABSPATH, which should also
-         be FB->COPIED_TEXT_BASE_ABSPATH.  */
-      is_locally_modified = TRUE;
-    }
-  else if (file_external &&
+  if (file_external &&
            status ==svn_wc__db_status_added)
     {
       is_locally_modified = FALSE; /* ### Or a conflict will be raised */
@@ -3859,7 +3822,7 @@ merge_file(svn_skel_t **work_items,
           svn_node_kind_t wfile_kind;
 
           SVN_ERR(svn_io_check_path(fb->local_abspath, &wfile_kind, pool));
-          if (wfile_kind == svn_node_none && ! fb->added_with_history)
+          if (wfile_kind == svn_node_none)
             {
               /* working file is missing?!
                  Just copy the new text-base to the file. */
@@ -3890,26 +3853,18 @@ merge_file(svn_skel_t **work_items,
                     path_ext = "";
                 }
 
-              /* Create strings representing the revisions of the
-                 old and new text-bases. */
-              /* Either an old version, or an add-with-history */
-              if (fb->added_with_history)
-                oldrev_str = apr_psprintf(pool, ".copied%s%s",
+              {
+                svn_revnum_t old_rev = revision;
+
+                /* ### BH: Why is this necessary? */
+                if (!SVN_IS_VALID_REVNUM(old_rev))
+                  old_rev = 0;
+
+                oldrev_str = apr_psprintf(pool, ".r%ld%s%s",
+                                          old_rev,
                                           *path_ext ? "." : "",
                                           *path_ext ? path_ext : "");
-              else
-                {
-                  svn_revnum_t old_rev = revision;
-
-                  /* ### BH: Why is this necessary? */
-                  if (!SVN_IS_VALID_REVNUM(old_rev))
-                    old_rev = 0;
-
-                  oldrev_str = apr_psprintf(pool, ".r%ld%s%s",
-                                            old_rev,
-                                            *path_ext ? "." : "",
-                                            *path_ext ? path_ext : "");
-                }
+              }
               newrev_str = apr_psprintf(pool, ".r%ld%s%s",
                                         *eb->target_revision,
                                         *path_ext ? "." : "",
@@ -3925,11 +3880,6 @@ merge_file(svn_skel_t **work_items,
                                              pool, pool));
                   delete_left = TRUE;
                 }
-              else if (fb->copied_text_base_sha1_checksum)
-                SVN_ERR(svn_wc__db_pristine_get_path(&merge_left, eb->db,
-                                                     fb->local_abspath,
-                                                     fb->copied_text_base_sha1_checksum,
-                                                     pool, pool));
               else
                 SVN_ERR(svn_wc__ultimate_base_text_path_to_read(
                   &merge_left, eb->db, fb->local_abspath, pool, pool));
@@ -3950,7 +3900,7 @@ merge_file(svn_skel_t **work_items,
                         merge_left, NULL,
                         new_text_base_tmp_abspath, NULL,
                         fb->local_abspath,
-                        fb->copied_working_text,
+                        NULL /* copyfrom_abspath */,
                         oldrev_str, newrev_str, mine_str,
                         FALSE /* dry_run */,
                         eb->diff3_cmd, NULL, fb->propchanges,
@@ -3967,16 +3917,6 @@ merge_file(svn_skel_t **work_items,
                                                        pool, pool));
                   *work_items = svn_wc__wq_merge(*work_items, work_item, pool);
                 }
-
-              /* And clean up add-with-history-related temp file too. */
-              if (fb->copied_working_text)
-                {
-                  SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
-                                                       eb->db,
-                                                       fb->copied_working_text,
-                                                       pool, pool));
-                  *work_items = svn_wc__wq_merge(*work_items, work_item, pool);
-                }
             } /* end: working file exists and has mods */
         } /* end: working file has mods */
     } /* end: "textual" merging process */
@@ -4095,8 +4035,6 @@ close_file(void *file_baton,
   svn_wc_notify_state_t content_state, prop_state;
   svn_wc_notify_lock_state_t lock_state;
   svn_checksum_t *expected_md5_checksum = NULL;
-  svn_checksum_t *new_text_base_md5_checksum;
-  svn_checksum_t *new_text_base_sha1_checksum;
   apr_hash_t *new_base_props = NULL;
   apr_hash_t *new_actual_props = NULL;
   apr_array_header_t *entry_props;
@@ -4126,42 +4064,24 @@ close_file(void *file_baton,
     SVN_ERR(svn_checksum_parse_hex(&expected_md5_checksum, svn_checksum_md5,
                                    expected_md5_digest, pool));
 
-  /* Retrieve the new text-base file's path and checksums.  If it was an
-   * add-with-history, with no apply_textdelta, then that means the text-base
-   * of the copied file, else the new text-base created by apply_textdelta(),
-   * if any. */
   if (fb->received_textdelta)
-    {
-      new_text_base_md5_checksum = fb->new_text_base_md5_checksum;
-      new_text_base_sha1_checksum = fb->new_text_base_sha1_checksum;
-      SVN_ERR_ASSERT(new_text_base_md5_checksum &&
-                     new_text_base_sha1_checksum);
-    }
-  else if (fb->added_with_history)
-    {
-      SVN_ERR_ASSERT(! fb->new_text_base_sha1_checksum);
-      new_text_base_md5_checksum = fb->copied_text_base_md5_checksum;
-      new_text_base_sha1_checksum = fb->copied_text_base_sha1_checksum;
-      SVN_ERR_ASSERT(new_text_base_md5_checksum &&
-                     new_text_base_sha1_checksum);
-    }
+    SVN_ERR_ASSERT(fb->new_text_base_sha1_checksum
+                   && fb->new_text_base_md5_checksum);
   else
-    {
-      SVN_ERR_ASSERT(! fb->new_text_base_sha1_checksum
-                     && ! fb->copied_text_base_sha1_checksum);
-      new_text_base_md5_checksum = NULL;
-      new_text_base_sha1_checksum = NULL;
-    }
+    SVN_ERR_ASSERT(! fb->new_text_base_sha1_checksum
+                   && ! fb->new_text_base_md5_checksum);
 
-  if (new_text_base_md5_checksum && expected_md5_checksum
-      && !svn_checksum_match(expected_md5_checksum, new_text_base_md5_checksum))
+  if (fb->new_text_base_md5_checksum && expected_md5_checksum
+      && !svn_checksum_match(expected_md5_checksum,
+                             fb->new_text_base_md5_checksum))
     return svn_error_createf(SVN_ERR_CHECKSUM_MISMATCH, NULL,
             _("Checksum mismatch for '%s':\n"
               "   expected:  %s\n"
               "     actual:  %s\n"),
             svn_dirent_local_style(fb->local_abspath, pool),
             expected_md5_digest,
-            svn_checksum_to_cstring_display(new_text_base_md5_checksum, pool));
+            svn_checksum_to_cstring_display(fb->new_text_base_md5_checksum,
+                                            pool));
 
   SVN_ERR(svn_wc_read_kind(&kind, eb->wc_ctx, fb->local_abspath, TRUE, pool));
   if (kind == svn_node_none && ! fb->adding_file)
@@ -4177,7 +4097,6 @@ close_file(void *file_baton,
   SVN_ERR(accumulate_last_change(&new_changed_rev,
                                  &new_changed_date,
                                  &new_changed_author,
-                                 eb->db, fb->local_abspath,
                                  entry_props,
                                  pool, pool));
 
@@ -4226,15 +4145,7 @@ close_file(void *file_baton,
     local_actual_props = apr_hash_make(pool);
 
 
-  if (fb->copied_base_props)
-    {
-      /* The BASE props are given by the source of the copy. We may also
-         have some ACTUAL props if the server directed us to copy a path
-         located in our WC which had some ACTUAL changes.  */
-      current_base_props = fb->copied_base_props;
-      current_actual_props = fb->copied_working_props;
-    }
-  else if (kind != svn_node_none)
+  if (kind != svn_node_none)
     {
       /* This node already exists. Grab its properties. */
       SVN_ERR(svn_wc__get_pristine_props(&current_base_props,
@@ -4268,30 +4179,20 @@ close_file(void *file_baton,
                                 SVN_PROP_SPECIAL,
                                 APR_HASH_KEY_STRING) != NULL;
 
-      /* Jump through hoops to get the proper props in case of
-       * a copy. (see the fb->copied_base_props condition above) */
-      if (fb->copied_base_props)
-        {
-          incoming_is_link = fb->copied_working_props
-                             && apr_hash_get(fb->copied_working_props,
-                                             SVN_PROP_SPECIAL,
-                                             APR_HASH_KEY_STRING) != NULL;
-        }
-      else
-        {
-          int i;
+      {
+        int i;
 
-          for (i = 0; i < regular_props->nelts; ++i)
-            {
-              const svn_prop_t *prop = &APR_ARRAY_IDX(regular_props, i,
-                                                      svn_prop_t);
+        for (i = 0; i < regular_props->nelts; ++i)
+          {
+            const svn_prop_t *prop = &APR_ARRAY_IDX(regular_props, i,
+                                                    svn_prop_t);
 
-              if (strcmp(prop->name, SVN_PROP_SPECIAL) == 0)
-                {
-                  incoming_is_link = TRUE;
-                }
-            }
-        }
+            if (strcmp(prop->name, SVN_PROP_SPECIAL) == 0)
+              {
+                incoming_is_link = TRUE;
+              }
+          }
+      }
 
 
       if (local_is_link != incoming_is_link)
@@ -4348,7 +4249,7 @@ close_file(void *file_baton,
 
       /* 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,
+                         &content_state, fb, fb->new_text_base_sha1_checksum,
                          pool, scratch_pool));
 
       if (install_pristine)
@@ -4377,15 +4278,9 @@ close_file(void *file_baton,
       /* Adding a BASE node under a locally added node.
        * The incoming add becomes the revert-base! */
       svn_wc_notify_state_t no_prop_state;
-      apr_hash_t *copied_base_props;
       apr_hash_t *no_new_actual_props = NULL;
       apr_hash_t *no_working_props = apr_hash_make(pool);
 
-      copied_base_props = fb->copied_base_props;
-      if (! copied_base_props)
-        copied_base_props = apr_hash_make(pool);
-
-
       /* Store the incoming props (sent as propchanges) in new_base_props.
        * Keep the actual props unchanged. */
       SVN_ERR(svn_wc__merge_props(&no_prop_state,
@@ -4397,7 +4292,7 @@ close_file(void *file_baton,
                                   NULL /* left_version */,
                                   NULL /* right_version */,
                                   NULL /* server_baseprops (update, not merge)  */,
-                                  copied_base_props,
+                                  apr_hash_make(pool),
                                   no_working_props,
                                   regular_props, /* propchanges */
                                   TRUE /* base_merge */,
@@ -4414,7 +4309,7 @@ close_file(void *file_baton,
   /* Now that all the state has settled, should we update the readonly
      status of the working file? The LOCK_STATE will signal what we should
      do for this node.  */
-  if (new_text_base_sha1_checksum == NULL
+  if (fb->new_text_base_sha1_checksum == NULL
       && lock_state == svn_wc_notify_lock_state_unlocked)
     {
       /* If a lock was removed and we didn't update the text contents, we
@@ -4439,18 +4334,6 @@ close_file(void *file_baton,
       all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
     }
 
-  /* Remove the copied text base file if we're no longer using it. */
-  if (fb->copied_text_base_sha1_checksum)
-    {
-      /* ### TODO: Add a WQ item to remove this pristine if unreferenced:
-         svn_wc__wq_build_pristine_remove(&work_item,
-                                          eb->db, fb->local_abspath,
-                                          fb->copied_text_base_sha1_checksum,
-                                          pool);
-         all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
-      */
-    }
-
   /* ### NOTE: from this point onwards, we make several changes to the
      ### database in a non-transactional way. we also queue additional
      ### work after these changes. some revamps need to be performed to
@@ -4462,7 +4345,7 @@ close_file(void *file_baton,
       /* Set the 'checksum' column of the file's BASE_NODE row to
        * NEW_TEXT_BASE_SHA1_CHECKSUM.  The pristine text identified by that
        * checksum is already in the pristine store. */
-    const svn_checksum_t *new_checksum = new_text_base_sha1_checksum;
+    const svn_checksum_t *new_checksum = fb->new_text_base_sha1_checksum;
     const char *serialised;
 
     /* If we don't have a NEW checksum, then the base must not have changed.
@@ -5664,7 +5547,6 @@ svn_wc_add_repos_file4(svn_wc_context_t 
     SVN_ERR(accumulate_last_change(&changed_rev,
                                    &changed_date,
                                    &changed_author,
-                                   db, local_abspath,
                                    entry_props, pool, pool));
   }
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/upgrade.c?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/upgrade.c Thu Dec 30 21:27:46 2010
@@ -937,14 +937,36 @@ migrate_props(const char *dir_abspath,
 }
 
 
-/* If DIR_RELPATH is set then any .svn-revert files will trigger an
-   attempt to update the checksum in a NODES row below the top WORKING
-   node. */
+/* If STR ends with SUFFIX and is longer than SUFFIX, return the part of
+ * STR that comes before SUFFIX; else return NULL. */
+static char *
+remove_suffix(const char *str, const char *suffix, apr_pool_t *result_pool)
+{
+  int str_len = strlen(str);
+  int suffix_len = strlen(suffix);
+
+  if (str_len > suffix_len
+      && strcmp(str + str_len - suffix_len, suffix) == 0)
+    {
+      return apr_pstrmemdup(result_pool, str, str_len - suffix_len);
+    }
+
+  return NULL;
+}
+
+/* Copy all the text-base files from the administrative area of WC directory
+   DIR_ABSPATH into the pristine store of SDB which is located in directory
+   NEW_WCROOT_ABSPATH.
+
+   Set *TEXT_BASES_INFO to a new hash, allocated in RESULT_POOL, that maps
+   (const char *) name of the versioned file to (svn_wc__text_base_info_t *)
+   information about the pristine text. */
 static svn_error_t *
-migrate_text_bases(const char *dir_abspath,
+migrate_text_bases(apr_hash_t **text_bases_info,
+                   const char *dir_abspath,
                    const char *new_wcroot_abspath,
-                   const char *dir_relpath,
                    svn_sqlite__db_t *sdb,
+                   apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
 {
   apr_hash_t *dirents;
@@ -954,110 +976,108 @@ migrate_text_bases(const char *dir_abspa
                                                 TEXT_BASE_SUBDIR,
                                                 scratch_pool);
 
+  *text_bases_info = apr_hash_make(result_pool);
+
+  /* Iterate over the text-base files */
   SVN_ERR(svn_io_get_dirents3(&dirents, text_base_dir, TRUE,
                               scratch_pool, scratch_pool));
   for (hi = apr_hash_first(scratch_pool, dirents); hi;
-            hi = apr_hash_next(hi))
+       hi = apr_hash_next(hi))
     {
       const char *text_base_basename = svn__apr_hash_index_key(hi);
-      const char *pristine_path;
-      const char *text_base_path;
       svn_checksum_t *md5_checksum;
       svn_checksum_t *sha1_checksum;
-      svn_sqlite__stmt_t *stmt;
-      apr_finfo_t finfo;
 
       svn_pool_clear(iterpool);
-      text_base_path = svn_dirent_join(text_base_dir, text_base_basename,
-                                       iterpool);
-
-      /* ### This code could be a bit smarter: we could chain checksum
-             streams instead of reading the file twice; we could check to
-             see if a pristine row exists before attempting to insert one;
-             we could check and see if a pristine file exists before
-             attempting to copy a new one over it.
-             
-             However, I think simplicity is the big win here, especially since
-             this is code that runs exactly once on a user's machine: when
-             doing the upgrade.  If you disagree, feel free to add the
-             complexity. :)  */
-
-      /* Gather the two checksums. */
-      SVN_ERR(svn_io_file_checksum2(&md5_checksum, text_base_path,
-                                    svn_checksum_md5, iterpool));
-      SVN_ERR(svn_io_file_checksum2(&sha1_checksum, text_base_path,
-                                    svn_checksum_sha1, iterpool));
-
-      SVN_ERR(svn_io_stat(&finfo, text_base_path, APR_FINFO_SIZE, iterpool));
-
-      /* Insert a row into the pristine table. */
-      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_PRISTINE));
-      SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, iterpool));
-      SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, iterpool));
-      SVN_ERR(svn_sqlite__bind_int64(stmt, 3, finfo.size));
-      SVN_ERR(svn_sqlite__insert(NULL, stmt));
-
-      SVN_ERR(svn_wc__db_pristine_get_future_path(&pristine_path,
-                                                  new_wcroot_abspath,
-                                                  sha1_checksum,
-                                                  iterpool, iterpool));
-
-      /* Ensure any sharding directories exist. */
-      SVN_ERR(svn_wc__ensure_directory(svn_dirent_dirname(pristine_path,
-                                                          iterpool),
-                                       iterpool));
-
-      /* Copy, rather than move, so that the upgrade can be restarted.
-         It could be moved if upgrades scanned for files in the
-         pristine directory as well as the text-base directory. */
-      SVN_ERR(svn_io_copy_file(text_base_path, pristine_path, TRUE,
-                               iterpool));
 
-      if (dir_relpath)
-        {
-          apr_size_t len = strlen(text_base_basename);
-          if (len >= sizeof(SVN_WC__REVERT_EXT)
-              && strcmp(text_base_basename
-                        + len - sizeof(SVN_WC__REVERT_EXT) - 1,
-                        SVN_WC__REVERT_EXT))
-            {
-              /* Assumming this revert-base is not an orphan, the
-                 upgrade process will have inserted a NODES row with a
-                 null checksum below the top-level working node.
-                 Update that checksum now. */
-              apr_int64_t op_depth = -1, wc_id = 1;
-              const char *name
-                = apr_pstrndup(iterpool, text_base_basename,
-                               len - sizeof(SVN_WC__REVERT_EXT) + 1);
-              const char *local_relpath = svn_relpath_join(dir_relpath, name,
-                                                           iterpool);
-              svn_boolean_t have_row;
-
-              SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                                STMT_SELECT_NODE_INFO));
-              SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
-              SVN_ERR(svn_sqlite__step(&have_row, stmt));
-              if (have_row)
-                {
-                  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-                  if (have_row && svn_sqlite__column_is_null(stmt, 6)
-                      && !strcmp(svn_sqlite__column_text(stmt, 4, NULL),
-                                 "file"))
-                    op_depth = svn_sqlite__column_int64(stmt, 0);
-                }
-              SVN_ERR(svn_sqlite__reset(stmt));
-              if (op_depth != -1)
-                {
-                  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                                    STMT_UPDATE_CHECKSUM));
-                  SVN_ERR(svn_sqlite__bindf(stmt, "isi", wc_id, local_relpath,
-                                            op_depth));
-                  SVN_ERR(svn_sqlite__bind_checksum(stmt, 4, sha1_checksum,
-                                                    iterpool));
-                  SVN_ERR(svn_sqlite__update(NULL, stmt));
-                }
-            }
-        }
+      /* Calculate its checksums and copy it to the pristine store */
+      {
+        const char *pristine_path;
+        const char *text_base_path;
+        svn_sqlite__stmt_t *stmt;
+        apr_finfo_t finfo;
+
+        text_base_path = svn_dirent_join(text_base_dir, text_base_basename,
+                                         iterpool);
+
+        /* ### This code could be a bit smarter: we could chain checksum
+               streams instead of reading the file twice; we could check to
+               see if a pristine row exists before attempting to insert one;
+               we could check and see if a pristine file exists before
+               attempting to copy a new one over it.
+
+               However, I think simplicity is the big win here, especially since
+               this is code that runs exactly once on a user's machine: when
+               doing the upgrade.  If you disagree, feel free to add the
+               complexity. :)  */
+
+        /* Gather the two checksums. */
+        SVN_ERR(svn_io_file_checksum2(&md5_checksum, text_base_path,
+                                      svn_checksum_md5, iterpool));
+        SVN_ERR(svn_io_file_checksum2(&sha1_checksum, text_base_path,
+                                      svn_checksum_sha1, iterpool));
+
+        SVN_ERR(svn_io_stat(&finfo, text_base_path, APR_FINFO_SIZE, iterpool));
+
+        /* Insert a row into the pristine table. */
+        SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_PRISTINE));
+        SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, iterpool));
+        SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, iterpool));
+        SVN_ERR(svn_sqlite__bind_int64(stmt, 3, finfo.size));
+        SVN_ERR(svn_sqlite__insert(NULL, stmt));
+
+        SVN_ERR(svn_wc__db_pristine_get_future_path(&pristine_path,
+                                                    new_wcroot_abspath,
+                                                    sha1_checksum,
+                                                    iterpool, iterpool));
+
+        /* Ensure any sharding directories exist. */
+        SVN_ERR(svn_wc__ensure_directory(svn_dirent_dirname(pristine_path,
+                                                            iterpool),
+                                         iterpool));
+
+        /* Copy, rather than move, so that the upgrade can be restarted.
+           It could be moved if upgrades scanned for files in the
+           pristine directory as well as the text-base directory. */
+        SVN_ERR(svn_io_copy_file(text_base_path, pristine_path, TRUE,
+                                 iterpool));
+      }
+
+      /* Add the checksums for this text-base to *TEXT_BASES_INFO. */
+      {
+        const char *versioned_file_name;
+        svn_boolean_t is_revert_base;
+        svn_wc__text_base_info_t *info;
+        svn_wc__text_base_file_info_t *file_info;
+
+        /* Determine the versioned file name and whether this is a normal base
+         * or a revert base. */
+        versioned_file_name = remove_suffix(text_base_basename,
+                                            SVN_WC__REVERT_EXT, result_pool);
+        if (versioned_file_name)
+          {
+            is_revert_base = TRUE;
+          }
+        else
+          {
+            versioned_file_name = remove_suffix(text_base_basename,
+                                                SVN_WC__BASE_EXT, result_pool);
+            is_revert_base = FALSE;
+          }
+
+        /* Create a new info struct for this versioned file, or fill in the
+         * existing one if this is the second text-base we've found for it. */
+        info = apr_hash_get(*text_bases_info, versioned_file_name,
+                            APR_HASH_KEY_STRING);
+        if (info == NULL)
+          info = apr_pcalloc(result_pool, sizeof (*info));
+        file_info = (is_revert_base ? &info->revert_base : &info->normal_base);
+
+        file_info->sha1_checksum = svn_checksum_dup(sha1_checksum, result_pool);
+        file_info->md5_checksum = svn_checksum_dup(md5_checksum, result_pool);
+        apr_hash_set(*text_bases_info, versioned_file_name, APR_HASH_KEY_STRING,
+                     info);
+      }
     }
 
   svn_pool_destroy(iterpool);
@@ -1149,6 +1169,7 @@ upgrade_to_wcng(void **dir_baton,
   apr_hash_t *entries;
   svn_wc_entry_t *this_dir;
   const char *old_wcroot_abspath, *dir_relpath;
+  apr_hash_t *text_bases_info;
 
   /* Don't try to mess with the WC if there are old log files left. */
 
@@ -1170,18 +1191,21 @@ upgrade_to_wcng(void **dir_baton,
    * The semantics and storage mechanisms between the two are vastly different,
    * so it's going to be a bit painful.  Here's a plan for the operation:
    *
-   * 1) The 'entries' file needs to be moved to the new format. We read it
-   *    using the old-format reader, and then use our compatibility code
-   *    for writing entries to fill out the (new) wc_db state.
+   * 1) Read the old 'entries' using the old-format reader.
    *
-   * 2) Convert wcprop to the wc-ng format
+   * 2) Create the new DB if it hasn't already been created.
    *
-   * 3) Trash old, unused files and subdirs
+   * 3) Use our compatibility code for writing entries to fill out the (new)
+   *    DB state.  Use the remembered checksums, since an entry has only the
+   *    MD5 not the SHA1 checksum, and in the case of a revert-base doesn't
+   *    even have that.
    *
-   * ### (fill in other bits as they are implemented)
+   * 4) Convert wcprop to the wc-ng format
+   *
+   * 5) Migrate regular properties to the WC-NG DB.
    */
 
-  /***** ENTRIES *****/
+  /***** ENTRIES - READ *****/
   SVN_ERR(svn_wc__read_entries_old(&entries, dir_abspath,
                                    scratch_pool, scratch_pool));
 
@@ -1202,6 +1226,7 @@ upgrade_to_wcng(void **dir_baton,
                    apr_pstrdup(hash_pool, this_dir->uuid));
     }
 
+  /* Create the new DB if it hasn't already been created. */
   if (!data->sdb)
     {
       const char *root_adm_abspath;
@@ -1235,20 +1260,25 @@ upgrade_to_wcng(void **dir_baton,
       SVN_ERR(svn_wc__db_wclock_obtain(db, data->root_abspath, 0, FALSE,
                                        scratch_pool));
     }
- 
+
+  old_wcroot_abspath = svn_dirent_get_longest_ancestor(dir_abspath,
+                                                       data->root_abspath,
+                                                       scratch_pool);
+  dir_relpath = svn_dirent_skip_ancestor(old_wcroot_abspath, dir_abspath);
+
+  /***** TEXT BASES *****/
+  SVN_ERR(migrate_text_bases(&text_bases_info, dir_abspath, data->root_abspath,
+                             data->sdb, scratch_pool, scratch_pool));
+
+  /***** ENTRIES - WRITE *****/
   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,
+                                         entries, text_bases_info,
                                          result_pool, scratch_pool));
 
   /***** WC PROPS *****/
-
-  /* Ugh. We don't know precisely where the wcprops are. Ignore them.  */
-  old_wcroot_abspath = svn_dirent_get_longest_ancestor(dir_abspath,
-                                                       data->root_abspath,
-                                                       scratch_pool);
-  dir_relpath = svn_dirent_skip_ancestor(old_wcroot_abspath, dir_abspath);
+  /* If we don't know precisely where the wcprops are, ignore them.  */
   if (old_format != SVN_WC__WCPROPS_LOST)
     {
       apr_hash_t *all_wcprops;
@@ -1264,9 +1294,6 @@ upgrade_to_wcng(void **dir_baton,
                                                  all_wcprops, scratch_pool));
     }
 
-  SVN_ERR(migrate_text_bases(dir_abspath, data->root_abspath, dir_relpath,
-                             data->sdb, scratch_pool));
-
   /* Upgrade all the properties (including "this dir").
 
      Note: this must come AFTER the entries have been migrated into the
@@ -1282,6 +1309,25 @@ upgrade_to_wcng(void **dir_baton,
 }
 
 
+/* Return a string indicating the released version (or versions) of
+ * Subversion that used WC format number WC_FORMAT, or some other
+ * suitable string if no released version used WC_FORMAT.
+ *
+ * ### It's not ideal to encode this sort of knowledge in this low-level
+ * library.  On the other hand, it doesn't need to be updated often and
+ * should be easily found when it does need to be updated.  */
+static const char *
+version_string_from_format(int wc_format)
+{
+  switch (wc_format)
+    {
+      case 4: return "<=1.3";
+      case 8: return "1.4";
+      case 9: return "1.5";
+      case 10: return "1.6";
+    }
+  return _("(unreleased development version)");
+}
 
 svn_error_t *
 svn_wc__upgrade_sdb(int *result_format,
@@ -1294,16 +1340,18 @@ svn_wc__upgrade_sdb(int *result_format,
 
   if (start_format < SVN_WC__WC_NG_VERSION /* 12 */)
     return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL,
-                             _("Working copy format of '%s' is too old (%d); "
-                               "please run 'svn upgrade'"),
+                             _("Working copy '%s' is too old (format %d, "
+                               "created by Subversion %s)"),
                              svn_dirent_local_style(wcroot_abspath,
                                                     scratch_pool),
-                             start_format);
+                             start_format,
+                             version_string_from_format(start_format));
 
   /* Early WCNG formats no longer supported. */
   if (start_format < 19)
     return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL,
-                             _("Working copy format of '%s' is too old (%d); "
+                             _("Working copy '%s' is an old development "
+                               "version (format %d); to upgrade it, "
                                "use a format 18 client, then "
                                "use 'tools/dev/wc-ng/bump-to-19.py', then "
                                "use the current client"),

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/util.c?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/util.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/util.c Thu Dec 30 21:27:46 2010
@@ -642,7 +642,7 @@ svn_wc__status2_from_3(svn_wc_status2_t 
   if (old_status->versioned
       && old_status->conflicted
       && old_status->node_status != svn_wc_status_obstructed
-      && (old_status->kind == svn_node_file 
+      && (old_status->kind == svn_node_file
           || old_status->node_status != svn_wc_status_missing))
     {
       svn_boolean_t text_conflict_p, prop_conflict_p;

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc-metadata.sql?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc-metadata.sql Thu Dec 30 21:27:46 2010
@@ -167,9 +167,9 @@ CREATE TABLE ACTUAL_NODE (
            conflicts? Why do we need these in a column to refer to the
            pristine store? Can't we just parse the checksums from
            conflict_data as well? */
-  older_checksum  TEXT,
-  left_checksum  TEXT,
-  right_checksum  TEXT,
+  older_checksum  TEXT REFERENCES PRISTINE (checksum),
+  left_checksum  TEXT REFERENCES PRISTINE (checksum),
+  right_checksum  TEXT REFERENCES PRISTINE (checksum),
 
   PRIMARY KEY (wc_id, local_relpath)
   );
@@ -415,7 +415,7 @@ CREATE TABLE NODES (
 
   /* The SHA-1 checksum of the pristine text, if this node is a file and was
      moved here or copied here, else NULL. */
-  checksum  TEXT,
+  checksum  TEXT REFERENCES PRISTINE (checksum),
 
   /* for kind==symlink, this specifies the target. */
   symlink_target  TEXT,
@@ -610,8 +610,15 @@ FROM ACTUAL_NODE_BACKUP;
 
 DROP TABLE ACTUAL_NODE_BACKUP;
 
-/* Note: One difference remains between the schemas of an upgraded and a
- * fresh WC.  While format 22 was current, "NOT NULL" was added to the
+/* Note: Other differences between the schemas of an upgraded and a
+ * fresh WC.
+ *
+ * While format 22 was current, "NOT NULL" was added to the
  * columns PRISTINE.size and PRISTINE.md5_checksum.  The format was not
- * bumped because it is a forward- and backward-compatible change. */
+ * bumped because it is a forward- and backward-compatible change.
+ *
+ * While format 23 was current, "REFERENCES PRISTINE" was added to the
+ * columns ACTUAL_NODE.older_checksum, ACTUAL_NODE.left_checksum,
+ * ACTUAL_NODE.right_checksum, NODES.checksum.
+ */
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc-queries.sql?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc-queries.sql Thu Dec 30 21:27:46 2010
@@ -104,6 +104,15 @@ LEFT OUTER JOIN lock ON nodes.repos_id =
   AND nodes.repos_path = lock.repos_relpath
 WHERE wc_id = ?1 AND parent_relpath = ?2;
 
+-- STMT_SELECT_NODE_CHILDREN_WALKER_INFO
+/* ### See comment at STMT_SELECT_NODE_CHILDREN_INFO.
+   ### Should C code handle GROUP BY local_relpath ORDER BY op_depths DESC? */
+SELECT local_relpath, op_depth, presence, kind
+FROM nodes
+WHERE wc_id = ?1 AND parent_relpath = ?2
+GROUP BY local_relpath
+ORDER BY op_depth DESC;
+
 -- STMT_SELECT_ACTUAL_CHILDREN_INFO
 SELECT prop_reject, changelist, conflict_old, conflict_new,
 conflict_working, tree_conflict_data, properties, local_relpath,
@@ -712,14 +721,15 @@ UPDATE actual_node SET tree_conflict_dat
 SELECT DISTINCT local_relpath FROM nodes
 WHERE kind = 'file' AND parent_relpath = ?1;
 
--- STMT_PLAN_PROP_UPGRADE
-SELECT 0, nodes_base.presence, nodes_base.wc_id FROM nodes nodes_base
-WHERE nodes_base.local_relpath = ?1 AND nodes_base.op_depth = 0
-UNION ALL
-SELECT 1, nodes_work.presence, nodes_work.wc_id FROM nodes nodes_work
-WHERE nodes_work.local_relpath = ?1
-  AND nodes_work.op_depth = (SELECT MAX(op_depth) FROM nodes
-                             WHERE local_relpath = ?1 AND op_depth > 0);
+-- STMT_SELECT_NODE_UPGRADE
+SELECT op_depth, presence, wc_id
+FROM nodes
+WHERE local_relpath = ?1
+ORDER BY op_depth DESC;
+
+-- STMT_UPDATE_NODE_PROPS
+UPDATE nodes SET properties = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3;
 
 -- STMT_HAS_WORKING_NODES
 SELECT 1 FROM nodes WHERE op_depth > 0;

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc.h?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc.h Thu Dec 30 21:27:46 2010
@@ -122,7 +122,7 @@ extern "C" {
  * the working copy.
  *
  * The change from 19 to 20 introduces NODES and drops BASE_NODE and
- * WORKING_NODE, op_depth is always 0 or 2. 
+ * WORKING_NODE, op_depth is always 0 or 2.
  *
  * The change from 20 to 21 moved tree conflict storage from the
  * parent to the conflicted node.

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db.c?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db.c Thu Dec 30 21:27:46 2010
@@ -170,7 +170,7 @@ typedef struct insert_base_baton_t {
 } insert_base_baton_t;
 
 
-typedef struct {
+typedef struct insert_working_baton_t {
   /* common to all insertions into WORKING (including NODE_DATA) */
   svn_wc__db_status_t presence;
   svn_wc__db_kind_t kind;
@@ -303,6 +303,14 @@ static svn_error_t *
 convert_to_working_status(svn_wc__db_status_t *working_status,
                           svn_wc__db_status_t status);
 
+static svn_error_t *
+wclock_owns_lock(svn_boolean_t *own_lock,
+                 svn_wc__db_pdh_t *pdh,
+                 const char *local_relpath,
+                 svn_boolean_t exact,
+                 apr_pool_t *scratch_pool);
+
+
 /* Return the absolute path, in local path style, of LOCAL_RELPATH in WCROOT. */
 static const char *
 path_for_error_message(const svn_wc__db_wcroot_t *wcroot,
@@ -715,7 +723,7 @@ blank_ibb(insert_base_baton_t *pibb)
 
               0         1         2         3         4
               normal
-   A          normal          
+   A          normal
    A/B        normal              normal
    A/B/C                          not-pres  normal
    A/B/C/D                                            normal
@@ -725,7 +733,7 @@ blank_ibb(insert_base_baton_t *pibb)
 
    Now an update that adds base nodes for A/B/C, A/B/C/D and A/B/C/D/E
    must extend the A/B deletion:
-   
+
               0         1         2         3         4
               normal
    A          normal
@@ -1244,73 +1252,6 @@ which_trees_exist(svn_boolean_t *base_ex
 }
 
 
-/* Determine which trees' nodes exist for a given LOCAL_RELPATH in the
-   specified SDB.
-
-   Note: this is VERY similar to the above which_trees_exist() except that
-   we return a WC_ID and verify some additional constraints.  */
-static svn_error_t *
-prop_upgrade_trees(svn_boolean_t *base_exists,
-                   svn_wc__db_status_t *base_presence,
-                   svn_boolean_t *working_exists,
-                   svn_wc__db_status_t *work_presence,
-                   apr_int64_t *wc_id,
-                   svn_sqlite__db_t *sdb,
-                   const char *local_relpath)
-{
-  svn_sqlite__stmt_t *stmt;
-  svn_boolean_t have_row;
-
-  *base_exists = FALSE;
-  *working_exists = FALSE;
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_PLAN_PROP_UPGRADE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "s", local_relpath));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
-  /* During a property upgrade, there better be a row corresponding to
-     the provided LOCAL_RELPATH. We shouldn't even be here without a
-     query for available rows.  */
-  SVN_ERR_ASSERT(have_row);
-
-  /* Use the first column to detect which table this row came from.  */
-  if (svn_sqlite__column_int(stmt, 0))
-    {
-      *working_exists = TRUE;  /* value == 1  */
-      *work_presence = svn_sqlite__column_token(stmt, 1, presence_map);
-    }
-  else
-    {
-      *base_exists = TRUE;  /* value == 0  */
-      *base_presence = svn_sqlite__column_token(stmt, 1, presence_map);
-    }
-
-  /* Return the WC_ID that was assigned.  */
-  *wc_id = svn_sqlite__column_int64(stmt, 2);
-
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  if (have_row)
-    {
-      /* If both rows, then both tables.  */
-      *base_exists = TRUE;
-      *working_exists = TRUE;
-
-      /* If the second row came from WORKING_NODE, then we should also
-         fetch the 'presence' column value.  */
-      if (svn_sqlite__column_int(stmt, 0))
-        *work_presence = svn_sqlite__column_token(stmt, 1, presence_map);
-      else
-        *base_presence = svn_sqlite__column_token(stmt, 1, presence_map);
-
-      /* During an upgrade, there should be just one working copy, so both
-         rows should refer to the same value.  */
-      SVN_ERR_ASSERT(*wc_id == svn_sqlite__column_int64(stmt, 2));
-    }
-
-  return svn_error_return(svn_sqlite__reset(stmt));
-}
-
-
 /* */
 static svn_error_t *
 create_db(svn_sqlite__db_t **sdb,
@@ -3280,7 +3221,7 @@ op_depth_for_copy(apr_int64_t *op_depth,
         }
     }
   SVN_ERR(svn_sqlite__reset(stmt));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -4168,7 +4109,7 @@ read_all_tree_conflicts(apr_hash_t **tre
       const char *conflict_data;
       const svn_skel_t *skel;
       const svn_wc_conflict_description2_t *conflict;
-      
+
       svn_pool_clear(iterpool);
 
       child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
@@ -4787,7 +4728,7 @@ info_below_working(svn_boolean_t *have_b
             *have_work = TRUE;
           else
             *have_base = TRUE;
-              
+
           *status = svn_sqlite__column_token(stmt, 3, presence_map);
           if (op_depth > 0)
             SVN_ERR(convert_to_working_status(status, *status));
@@ -4914,7 +4855,7 @@ svn_wc__db_temp_op_delete(svn_wc__db_t *
   VERIFY_USABLE_PDH(b.pdh);
 
   /* These two for svn_wc__db_temp_forget_directory */
-  b.db = db; 
+  b.db = db;
   b.local_abspath = local_abspath;
 
   SVN_ERR(svn_sqlite__with_transaction(b.pdh->wcroot->sdb, temp_op_delete_txn,
@@ -5161,8 +5102,7 @@ read_info(svn_wc__db_status_t *status,
               op_depth = svn_sqlite__column_int64(stmt_info, 0);
             }
 
-          if (have_base)
-            *have_base = (op_depth == 0);
+          *have_base = (op_depth == 0);
         }
     }
   else if (have_act)
@@ -5513,6 +5453,61 @@ svn_wc__db_read_children_info(apr_hash_t
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_wc__db_read_children_walker_info(apr_hash_t **nodes,
+                                     svn_wc__db_t *db,
+                                     const char *dir_abspath,
+                                     apr_pool_t *result_pool,
+                                     apr_pool_t *scratch_pool)
+{
+  svn_wc__db_pdh_t *pdh;
+  const char *dir_relpath;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+  apr_int64_t op_depth;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
+
+  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &dir_relpath, db,
+                                             dir_abspath,
+                                             svn_sqlite__mode_readonly,
+                                             scratch_pool, scratch_pool));
+  VERIFY_USABLE_PDH(pdh);
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_SELECT_NODE_CHILDREN_WALKER_INFO));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, dir_relpath));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+  *nodes = apr_hash_make(result_pool);
+  while (have_row)
+    {
+      struct svn_wc__db_walker_info_t *child;
+      const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+      const char *name = svn_relpath_basename(child_relpath, NULL);
+      svn_error_t *err;
+
+      child = apr_hash_get(*nodes, name, APR_HASH_KEY_STRING);
+      if (child == NULL)
+        child = apr_palloc(result_pool, sizeof(*child));
+
+      op_depth = svn_sqlite__column_int(stmt, 1);
+      child->status = svn_sqlite__column_token(stmt, 2, presence_map);
+      if (op_depth > 0)
+        SVN_ERR(convert_to_working_status(&child->status, child->status));
+      child->kind = svn_sqlite__column_token(stmt, 3, kind_map);
+      apr_hash_set(*nodes, apr_pstrdup(result_pool, name),
+                   APR_HASH_KEY_STRING, child);
+
+      err = svn_sqlite__step(&have_row, stmt);
+      if (err)
+        SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+    }
+
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_wc__db_read_prop(const svn_string_t **propval,
@@ -6181,7 +6176,7 @@ svn_wc__db_global_commit(svn_wc__db_t *d
 
   cb.new_revision = new_revision;
 
-  cb.changed_rev = changed_revision; 
+  cb.changed_rev = changed_revision;
   cb.changed_date = changed_date;
   cb.changed_author = changed_author;
   cb.new_checksum = new_checksum;
@@ -7095,12 +7090,10 @@ svn_wc__db_upgrade_apply_props(svn_sqlit
                                int original_format,
                                apr_pool_t *scratch_pool)
 {
-  svn_boolean_t have_base;
-  svn_wc__db_status_t base_presence;
-  svn_boolean_t have_work;
-  svn_wc__db_status_t work_presence;
-  apr_int64_t wc_id;
   svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+  apr_int64_t wc_id, top_op_depth = -1, below_op_depth = -1;
+  svn_wc__db_status_t top_presence, below_presence;
   int affected_rows;
 
   /* ### working_props: use set_props_txn.
@@ -7130,19 +7123,31 @@ svn_wc__db_upgrade_apply_props(svn_sqlit
      the handling of our inputs, relative to the state of this node.
   */
 
-  /* Collect information about this node.  */
-  SVN_ERR(prop_upgrade_trees(&have_base, &base_presence,
-                             &have_work, &work_presence,
-                             &wc_id, sdb, local_relpath));
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_NODE_UPGRADE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "s", local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  if (have_row)
+    {
+      top_op_depth = svn_sqlite__column_int64(stmt, 0);
+      top_presence = svn_sqlite__column_token(stmt, 1, presence_map);
+      wc_id = svn_sqlite__column_int64(stmt, 2);
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      if (have_row)
+        {
+          below_op_depth = svn_sqlite__column_int64(stmt, 0);
+          below_presence = svn_sqlite__column_token(stmt, 1, presence_map);
+        }
+    }
+  SVN_ERR(svn_sqlite__reset(stmt));
 
   /* Detect the buggy scenario described above. We cannot upgrade this
      working copy if we have no idea where BASE_PROPS should go.  */
   if (original_format > SVN_WC__NO_REVERT_FILES
       && revert_props == NULL
-      && have_work
-      && work_presence == svn_wc__db_status_normal
-      && have_base
-      && base_presence != svn_wc__db_status_not_present)
+      && top_op_depth != -1
+      && top_presence == svn_wc__db_status_normal
+      && below_op_depth != -1
+      && below_presence != svn_wc__db_status_not_present)
     {
       /* There should be REVERT_PROPS, so it appears that we just ran into
          the described bug. Sigh.  */
@@ -7155,48 +7160,45 @@ svn_wc__db_upgrade_apply_props(svn_sqlit
                                                  scratch_pool), scratch_pool));
     }
 
-  if (have_base
-      && (base_presence == svn_wc__db_status_normal
-          || base_presence == svn_wc__db_status_incomplete))
-    {
-      apr_hash_t *props = revert_props ? revert_props : base_props;
+  /* Need at least one row, or two rows if there are revert props */
+  if (top_op_depth == -1
+      || (below_op_depth == -1 && revert_props))
+    return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
+                             _("Insufficient NODES rows for '%s'"),
+                             svn_dirent_local_style(
+                               svn_dirent_join(dir_abspath, local_relpath,
+                                               scratch_pool), scratch_pool));
+
+  /* one row, base props only: upper row gets base props
+     two rows, base props only: lower row gets base props
+     two rows, revert props only: lower row gets revert props
+     two rows, base and revert props: upper row gets base, lower gets revert */
+
 
+  if (revert_props || below_op_depth == -1)
+    {
       SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                        STMT_UPDATE_NODE_BASE_PROPS));
-      SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
-      SVN_ERR(svn_sqlite__bind_properties(stmt, 3, props, scratch_pool));
+                                        STMT_UPDATE_NODE_PROPS));
+      SVN_ERR(svn_sqlite__bindf(stmt, "isi",
+                                wc_id, local_relpath, top_op_depth));
+      SVN_ERR(svn_sqlite__bind_properties(stmt, 4, base_props, scratch_pool));
       SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
 
-      /* ### should we provide a nicer error message?  */
       SVN_ERR_ASSERT(affected_rows == 1);
     }
 
-  if (have_work)
+  if (below_op_depth != -1)
     {
-      /* WORKING_NODE has very limited 'presence' values.  */
-      SVN_ERR_ASSERT(work_presence == svn_wc__db_status_normal
-                     || work_presence == svn_wc__db_status_not_present
-                     || work_presence == svn_wc__db_status_base_deleted
-                     || work_presence == svn_wc__db_status_incomplete);
+      apr_hash_t *props = revert_props ? revert_props : base_props;
 
-      /* Do we have a replaced node? It has properties: an empty set for
-         adds, and a non-empty set for copies/moves.  */
-      if (original_format > SVN_WC__NO_REVERT_FILES
-          && (work_presence == svn_wc__db_status_normal
-              || work_presence == svn_wc__db_status_incomplete))
-        {
-          SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                            STMT_UPDATE_NODE_WORKING_PROPS));
-          SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
-          SVN_ERR(svn_sqlite__bind_properties(stmt, 3, base_props,
-                                              scratch_pool));
-          SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                        STMT_UPDATE_NODE_PROPS));
+      SVN_ERR(svn_sqlite__bindf(stmt, "isi",
+                                wc_id, local_relpath, below_op_depth));
+      SVN_ERR(svn_sqlite__bind_properties(stmt, 4, props, scratch_pool));
+      SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
 
-          /* ### should we provide a nicer error message?  */
-          SVN_ERR_ASSERT(affected_rows == 1);
-        }
-      /* else other states should have no properties.  */
-      /* ### should we insert empty props for <= SVN_WC__NO_REVERT_FILES?  */
+      SVN_ERR_ASSERT(affected_rows == 1);
     }
 
   /* If there are WORKING_PROPS, then they always go into ACTUAL_NODE.  */
@@ -7950,7 +7952,6 @@ svn_wc__db_temp_wcroot_tempdir(const cha
 /* Baton for wclock_obtain_cb() */
 struct wclock_obtain_baton
 {
-  svn_wc__db_t *db;
   svn_wc__db_pdh_t *pdh;
   const char *local_relpath;
   int levels_to_lock;
@@ -8024,7 +8025,6 @@ wclock_obtain_cb(void *baton,
 
   while (got_row)
     {
-      const char *lock_abspath;
       svn_boolean_t own_lock;
 
       lock_relpath = svn_sqlite__column_text(stmt, 0, scratch_pool);
@@ -8038,13 +8038,10 @@ wclock_obtain_cb(void *baton,
           continue;
         }
 
-      lock_abspath = svn_dirent_join(wcroot->abspath,
-                                     lock_relpath, scratch_pool);
-
       /* Check if we are the lock owner, because we should be able to
          extend our lock. */
-      err = svn_wc__db_wclock_owns_lock(&own_lock, bt->db, lock_abspath,
-                                        TRUE, scratch_pool);
+      err = wclock_owns_lock(&own_lock, bt->pdh, lock_relpath,
+                             TRUE, scratch_pool);
 
       if (err)
         SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
@@ -8054,7 +8051,7 @@ wclock_obtain_cb(void *baton,
           SVN_ERR(svn_sqlite__reset(stmt));
           err = svn_error_createf(SVN_ERR_WC_LOCKED, NULL,
                                    _("'%s' is already locked."),
-                                   svn_dirent_local_style(lock_abspath,
+                                   path_for_error_message(wcroot, lock_relpath,
                                                           scratch_pool));
           return svn_error_createf(SVN_ERR_WC_LOCKED, err,
                                    _("Working copy '%s' locked."),
@@ -8181,22 +8178,16 @@ svn_wc__db_wclock_obtain(svn_wc__db_t *d
                   || (lock->levels + relpath_depth(lock->local_relpath))
                             >= depth))
             {
-              const char *lock_abspath
-                  = svn_dirent_join(baton.pdh->wcroot->abspath,
-                                    lock->local_relpath,
-                                    scratch_pool);
-
-              return svn_error_createf(SVN_ERR_WC_LOCKED, NULL,
-                                       _("'%s' is already locked via '%s'."),
-                                       svn_dirent_local_style(local_abspath,
-                                                              scratch_pool),
-                                       svn_dirent_local_style(lock_abspath,
-                                                              scratch_pool));
+              return svn_error_createf(
+                SVN_ERR_WC_LOCKED, NULL,
+                _("'%s' is already locked via '%s'."),
+                svn_dirent_local_style(local_abspath, scratch_pool),
+                path_for_error_message(baton.pdh->wcroot, lock->local_relpath,
+                                       scratch_pool));
             }
         }
     }
 
-  baton.db = db;
   baton.steal_lock = steal_lock;
   baton.levels_to_lock = levels_to_lock;
 
@@ -8325,29 +8316,18 @@ svn_wc__db_wclock_release(svn_wc__db_t *
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_wc__db_wclock_owns_lock(svn_boolean_t *own_lock,
-                            svn_wc__db_t *db,
-                            const char *local_abspath,
-                            svn_boolean_t exact,
-                            apr_pool_t *scratch_pool)
+/* Like svn_wc__db_wclock_owns_lock() but taking PDH+LOCAL_RELPATH instead
+ * of DB+LOCAL_ABSPATH. */
+static svn_error_t *
+wclock_owns_lock(svn_boolean_t *own_lock,
+                 svn_wc__db_pdh_t *pdh,
+                 const char *local_relpath,
+                 svn_boolean_t exact,
+                 apr_pool_t *scratch_pool)
 {
-  svn_wc__db_pdh_t *pdh;
-  const char *local_relpath;
   apr_array_header_t *owned_locks;
   int lock_level, i;
 
-  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &local_relpath, db,
-                              local_abspath, svn_sqlite__mode_readwrite,
-                              scratch_pool, scratch_pool));
-
-  if (!pdh->wcroot)
-    return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
-                             _("The node '%s' was not found."),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-
-  VERIFY_USABLE_PDH(pdh);
   *own_lock = FALSE;
   owned_locks = pdh->wcroot->owned_locks;
   lock_level = relpath_depth(local_relpath);
@@ -8384,6 +8364,33 @@ svn_wc__db_wclock_owns_lock(svn_boolean_
 }
 
 svn_error_t *
+svn_wc__db_wclock_owns_lock(svn_boolean_t *own_lock,
+                            svn_wc__db_t *db,
+                            const char *local_abspath,
+                            svn_boolean_t exact,
+                            apr_pool_t *scratch_pool)
+{
+  svn_wc__db_pdh_t *pdh;
+  const char *local_relpath;
+
+  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &local_relpath, db,
+                              local_abspath, svn_sqlite__mode_readwrite,
+                              scratch_pool, scratch_pool));
+
+  if (!pdh->wcroot)
+    return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
+                             _("The node '%s' was not found."),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+  VERIFY_USABLE_PDH(pdh);
+
+  SVN_ERR(wclock_owns_lock(own_lock, pdh, local_relpath, exact, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_wc__db_temp_op_set_base_incomplete(svn_wc__db_t *db,
                                        const char *local_dir_abspath,
                                        svn_boolean_t incomplete,
@@ -8744,7 +8751,7 @@ svn_wc__db_temp_op_set_file_external(svn
   svn_boolean_t got_row;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-  SVN_ERR_ASSERT(!repos_relpath 
+  SVN_ERR_ASSERT(!repos_relpath
                  || svn_relpath_is_canonical(repos_relpath, scratch_pool));
 
   SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &local_relpath, db,
@@ -9115,3 +9122,25 @@ svn_wc__db_temp_op_set_new_dir_to_incomp
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_wc__db_temp_below_work(svn_boolean_t *have_work,
+                           svn_wc__db_t *db,
+                           const char *local_abspath,
+                           apr_pool_t *scratch_pool)
+{
+  svn_boolean_t have_base;
+  svn_wc__db_status_t status;
+  svn_wc__db_pdh_t *pdh;
+  const char *local_relpath;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &local_relpath, db,
+                              local_abspath, svn_sqlite__mode_readwrite,
+                              scratch_pool, scratch_pool));
+  VERIFY_USABLE_PDH(pdh);
+  SVN_ERR(info_below_working(&have_base, have_work, &status,
+                             pdh, local_relpath, scratch_pool));
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db.h?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/wc_db.h Thu Dec 30 21:27:46 2010
@@ -972,7 +972,7 @@ svn_wc__db_pristine_remove(svn_wc__db_t 
                            apr_pool_t *scratch_pool);
 
 
-/* Remove all unreferenced pristines belonging to WRI_ABSPATH in DB. */
+/* Remove all unreferenced pristines in the WC of WRI_ABSPATH in DB. */
 svn_error_t *
 svn_wc__db_pristine_cleanup(svn_wc__db_t *db,
                             const char *wri_abspath,
@@ -1518,6 +1518,25 @@ svn_wc__db_read_children_info(apr_hash_t
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool);
 
+
+/* Structure returned by svn_wc__db_read_walker_info.  Only has the
+   fields needed by svn_wc__internal_walk_children(). */
+struct svn_wc__db_walker_info_t {
+  svn_wc__db_status_t status;
+  svn_wc__db_kind_t kind;
+};
+
+/* Return in *NODES a hash mapping name->struct svn_wc__db_walker_info_t for
+   the children of DIR_ABSPATH. "name" is the child's name relatve to
+   DIR_ABSPATH, not an absolute path. */
+svn_error_t *
+svn_wc__db_read_children_walker_info(apr_hash_t **nodes,
+                                     svn_wc__db_t *db,
+                                     const char *dir_abspath,
+                                     apr_pool_t *result_pool,
+                                     apr_pool_t *scratch_pool);
+
+
 /* Set *PROPVAL to the value of the property named PROPNAME of the node
    LOCAL_ABSPATH in the ACTUAL tree (looking through to the WORKING or BASE
    tree as required).
@@ -2336,16 +2355,6 @@ svn_wc__db_temp_op_make_copy(svn_wc__db_
                              apr_pool_t *scratch_pool);
 
 
-#ifndef SVN_WC__OP_DEPTH
-/* Elide the copyfrom information for LOCAL_ABSPATH if it can be derived
-   from the parent node.  */
-svn_error_t *
-svn_wc__db_temp_elide_copyfrom(svn_wc__db_t *db,
-                               const char *local_abspath,
-                               apr_pool_t *scratch_pool);
-#endif
-
-
 /* Return the serialized file external info (from BASE) for LOCAL_ABSPATH.
    Stores NULL into SERIALIZED_FILE_EXTERNAL if this node is NOT a file
    external. If a BASE node does not exist: SVN_ERR_WC_PATH_NOT_FOUND.  */
@@ -2405,7 +2414,7 @@ svn_wc__db_temp_op_set_rev_and_repos_rel
    REPOS_RELPATH is not NULL, apply REPOS_RELPATH, REPOS_ROOT_URL and
    REPOS_UUID.
    Perform all temporary allocations in SCRATCH_POOL.
-   
+
    ### For 1.7 this should probably become a proper tree conflict and
    ### just handled by putting a base directory below the existing
    ### working node.
@@ -2430,6 +2439,14 @@ svn_wc__db_drop_root(svn_wc__db_t *db,
 /* Return the OP_DEPTH for LOCAL_RELPATH. */
 int svn_wc__db_op_depth_for_upgrade(const char *local_relpath);
 
+/* Set *HAVE_WORK TRUE if there is a working layer below the top layer */
+svn_error_t *
+svn_wc__db_temp_below_work(svn_boolean_t *have_work,
+                           svn_wc__db_t *db,
+                           const char *local_abspath,
+                           apr_pool_t *scratch_pool);
+
+
 /* @} */
 
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.c?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/workqueue.c Thu Dec 30 21:27:46 2010
@@ -480,8 +480,8 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
 
 /* Removes a BASE_NODE and all it's data, leaving any adds and copies as is.
    Do this as a depth first traversal to make sure than any parent still exists
-   on error conditions. 
-   
+   on error conditions.
+
    ### This function needs review for 4th tree behavior.*/
 static svn_error_t *
 remove_base_node(svn_wc__db_t *db,
@@ -712,7 +712,7 @@ run_deletion_postcommit(svn_wc__db_t *db
                 db, local_abspath,
                 FALSE, FALSE, cancel_func, cancel_baton, scratch_pool));
 
-      /* If the parent entry's working rev 'lags' behind new_rev... 
+      /* If the parent entry's working rev 'lags' behind new_rev...
          ### Maybe we should also add a not-present node if the
          ### deleted node was switched? */
       if (new_revision > parent_revision)

Modified: subversion/branches/ignore-mergeinfo/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/mod_authz_svn/mod_authz_svn.c?rev=1054005&r1=1054004&r2=1054005&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/mod_authz_svn/mod_authz_svn.c Thu Dec 30 21:27:46 2010
@@ -46,7 +46,7 @@
 
 extern module AP_MODULE_DECLARE_DATA authz_svn_module;
 
-typedef struct {
+typedef struct authz_svn_config_rec {
   int authoritative;
   int anonymous;
   int no_auth_when_anon_ok;
@@ -166,22 +166,22 @@ get_access_conf(request_rec *r, authz_sv
   dav_error *dav_err;
   char errbuf[256];
 
-  if (conf->repo_relative_access_file) 
+  if (conf->repo_relative_access_file)
     {
       dav_err = dav_svn_get_repos_path(r, conf->base_path, &repos_path);
       if (dav_err) {
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, dav_err->desc);
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "%s", dav_err->desc);
         return NULL;
       }
       access_file = svn_dirent_join_many(r->pool, repos_path, "conf",
                                          conf->repo_relative_access_file,
                                          NULL);
-    } 
+    }
   else
     {
       access_file = conf->access_file;
     }
-  
+
   ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                 "Path to authz file is %s", access_file);