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/29 22:12:38 UTC

svn commit: r1053735 [3/8] - in /subversion/branches/performance: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ contrib/client-side/svn_load_dirs/ notes/ subversion/bindings/javahl/native/ subversion/bindings/swig/ subversion/includ...

Modified: subversion/branches/performance/subversion/libsvn_subr/prompt.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/prompt.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/prompt.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/prompt.c Wed Dec 29 21:12:33 2010
@@ -418,12 +418,14 @@ plaintext_prompt_helper(svn_boolean_t *m
           else
             return err;
         }
-      if (apr_strnatcasecmp(answer, _("yes")) == 0)
+      if (apr_strnatcasecmp(answer, _("yes")) == 0 ||
+          apr_strnatcasecmp(answer, _("y")) == 0)
         {
           *may_save_plaintext = TRUE;
           answered = TRUE;
         }
-      else if (apr_strnatcasecmp(answer, _("no")) == 0)
+      else if (apr_strnatcasecmp(answer, _("no")) == 0 ||
+               apr_strnatcasecmp(answer, _("n")) == 0)
         {
           *may_save_plaintext = FALSE;
           answered = TRUE;

Modified: subversion/branches/performance/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/subst.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/subst.c Wed Dec 29 21:12:33 2010
@@ -606,11 +606,34 @@ translate_keyword(char *buf,
   return FALSE;
 }
 
+/* A boolean expression that evaluates to true if the first STR_LEN characters
+   of the string STR are one of the end-of-line strings LF, CR, or CRLF;
+   to false otherwise.  */
+#define STRING_IS_EOL(str, str_len) \
+  (((str_len) == 2 &&  (str)[0] == '\r' && (str)[1] == '\n') || \
+   ((str_len) == 1 && ((str)[0] == '\n' || (str)[0] == '\r')))
+
+/* A boolean expression that evaluates to true if the end-of-line string EOL1,
+   having length EOL1_LEN, and the end-of-line string EOL2, having length
+   EOL2_LEN, are different, assuming that EOL1 and EOL2 are both from the
+   set {"\n", "\r", "\r\n"};  to false otherwise.
+
+   Given that EOL1 and EOL2 are either "\n", "\r", or "\r\n", then if
+   EOL1_LEN is not the same as EOL2_LEN, then EOL1 and EOL2 are of course
+   different. If EOL1_LEN and EOL2_LEN are both 2 then EOL1 and EOL2 are both
+   "\r\n" and *EOL1 == *EOL2. Otherwise, EOL1_LEN and EOL2_LEN are both 1.
+   We need only check the one character for equality to determine whether
+   EOL1 and EOL2 are different in that case. */
+#define DIFFERENT_EOL_STRINGS(eol1, eol1_len, eol2, eol2_len) \
+  (((eol1_len) != (eol2_len)) || (*(eol1) != *(eol2)))
+
 
 /* Translate the newline string NEWLINE_BUF (of length NEWLINE_LEN) to
    the newline string EOL_STR (of length EOL_STR_LEN), writing the
    result (which is always EOL_STR) to the stream DST.
 
+   This function assumes that NEWLINE_BUF is either "\n", "\r", or "\r\n".
+
    Also check for consistency of the source newline strings across
    multiple calls, using SRC_FORMAT (length *SRC_FORMAT_LEN) as a cache
    of the first newline found.  If the current newline is not the same
@@ -620,6 +643,11 @@ translate_keyword(char *buf,
    newline in the file, and copy it to {SRC_FORMAT, *SRC_FORMAT_LEN} to
    use for later consistency checks.
 
+   If TRANSLATED_EOL is not NULL, then set *TRANSLATED_EOL to TRUE if the
+   newline string that was written (EOL_STR) is not the same as the newline
+   string that was translated (NEWLINE_BUF), otherwise leave *TRANSLATED_EOL
+   untouched.
+
    Note: all parameters are required even if REPAIR is TRUE.
    ### We could require that REPAIR must not change across a sequence of
        calls, and could then optimize by not using SRC_FORMAT at all if
@@ -633,17 +661,19 @@ translate_newline(const char *eol_str,
                   const char *newline_buf,
                   apr_size_t newline_len,
                   svn_stream_t *dst,
+                  svn_boolean_t *translated_eol,
                   svn_boolean_t repair)
 {
+  SVN_ERR_ASSERT(STRING_IS_EOL(newline_buf, newline_len));
+
   /* If we've seen a newline before, compare it with our cache to
      check for consistency, else cache it for future comparisons. */
   if (*src_format_len)
     {
       /* Comparing with cache.  If we are inconsistent and
          we are NOT repairing the file, generate an error! */
-      if ((! repair) &&
-          ((*src_format_len != newline_len) ||
-           (strncmp(src_format, newline_buf, newline_len))))
+      if ((! repair) && DIFFERENT_EOL_STRINGS(src_format, *src_format_len,
+                                              newline_buf, newline_len))
         return svn_error_create(SVN_ERR_IO_INCONSISTENT_EOL, NULL, NULL);
     }
   else
@@ -653,8 +683,18 @@ translate_newline(const char *eol_str,
       strncpy(src_format, newline_buf, newline_len);
       *src_format_len = newline_len;
     }
+
   /* Write the desired newline */
-  return translate_write(dst, eol_str, eol_str_len);
+  SVN_ERR(translate_write(dst, eol_str, eol_str_len));
+
+  /* Report whether we translated it.  Note: Not using DIFFERENT_EOL_STRINGS()
+   * because EOL_STR may not be a valid EOL sequence. */
+  if (translated_eol != NULL &&
+      (eol_str_len != newline_len ||
+       memcmp(eol_str, newline_buf, eol_str_len) != 0))
+    *translated_eol = TRUE;
+
+  return SVN_NO_ERROR;
 }
 
 
@@ -765,10 +805,12 @@ svn_subst_keywords_differ2(apr_hash_t *a
   return FALSE;
 }
 
+
 /* Baton for translate_chunk() to store its state in. */
 struct translation_baton
 {
   const char *eol_str;
+  svn_boolean_t *translated_eol;
   svn_boolean_t repair;
   apr_hash_t *keywords;
   svn_boolean_t expand;
@@ -813,6 +855,7 @@ struct translation_baton
  */
 static struct translation_baton *
 create_translation_baton(const char *eol_str,
+                         svn_boolean_t *translated_eol,
                          svn_boolean_t repair,
                          apr_hash_t *keywords,
                          svn_boolean_t expand,
@@ -826,6 +869,7 @@ create_translation_baton(const char *eol
 
   b->eol_str = eol_str;
   b->eol_str_len = eol_str ? strlen(eol_str) : 0;
+  b->translated_eol = translated_eol;
   b->repair = repair;
   b->keywords = keywords;
   b->expand = expand;
@@ -888,6 +932,9 @@ eol_unchanged(struct translation_baton *
  * To finish a series of chunk translations, flush all buffers by calling
  * this routine with a NULL value for BUF.
  *
+ * If B->translated_eol is not NULL, then set *B->translated_eol to TRUE if
+ * an end-of-line sequence was changed, otherwise leave it untouched.
+ *
  * Use POOL for temporary allocations.
  */
 static svn_error_t *
@@ -924,7 +971,8 @@ translate_chunk(svn_stream_t *dst,
               SVN_ERR(translate_newline(b->eol_str, b->eol_str_len,
                                         b->src_format,
                                         &b->src_format_len, b->newline_buf,
-                                        b->newline_off, dst, b->repair));
+                                        b->newline_off, dst, b->translated_eol,
+                                        b->repair));
 
               b->newline_off = 0;
             }
@@ -1070,7 +1118,8 @@ translate_chunk(svn_stream_t *dst,
                                             b->src_format,
                                             &b->src_format_len,
                                             b->newline_buf,
-                                            b->newline_off, dst, b->repair));
+                                            b->newline_off, dst,
+                                            b->translated_eol, b->repair));
 
                   b->newline_off = 0;
                   break;
@@ -1086,7 +1135,7 @@ translate_chunk(svn_stream_t *dst,
           SVN_ERR(translate_newline(b->eol_str, b->eol_str_len,
                                     b->src_format, &b->src_format_len,
                                     b->newline_buf, b->newline_off,
-                                    dst, b->repair));
+                                    dst, b->translated_eol, b->repair));
           b->newline_off = 0;
         }
 
@@ -1378,14 +1427,20 @@ svn_subst_read_specialfile(svn_stream_t 
   return SVN_NO_ERROR;
 }
 
-
-svn_stream_t *
-svn_subst_stream_translated(svn_stream_t *stream,
-                            const char *eol_str,
-                            svn_boolean_t repair,
-                            apr_hash_t *keywords,
-                            svn_boolean_t expand,
-                            apr_pool_t *result_pool)
+/* Same as svn_subst_stream_translated(), except for the following.
+ *
+ * If TRANSLATED_EOL is not NULL, then reading and/or writing to the stream
+ * will set *TRANSLATED_EOL to TRUE if an end-of-line sequence was changed,
+ * otherwise leave it untouched.
+ */
+static svn_stream_t *
+stream_translated(svn_stream_t *stream,
+                  const char *eol_str,
+                  svn_boolean_t *translated_eol,
+                  svn_boolean_t repair,
+                  apr_hash_t *keywords,
+                  svn_boolean_t expand,
+                  apr_pool_t *result_pool)
 {
   struct translated_stream_baton *baton
     = apr_palloc(result_pool, sizeof(*baton));
@@ -1427,9 +1482,11 @@ svn_subst_stream_translated(svn_stream_t
   /* Setup the baton fields */
   baton->stream = stream;
   baton->in_baton
-    = create_translation_baton(eol_str, repair, keywords, expand, result_pool);
+    = create_translation_baton(eol_str, translated_eol, repair, keywords,
+                               expand, result_pool);
   baton->out_baton
-    = create_translation_baton(eol_str, repair, keywords, expand, result_pool);
+    = create_translation_baton(eol_str, translated_eol, repair, keywords,
+                               expand, result_pool);
   baton->written = FALSE;
   baton->readbuf = svn_stringbuf_create("", result_pool);
   baton->readbuf_off = 0;
@@ -1448,15 +1505,32 @@ svn_subst_stream_translated(svn_stream_t
   return s;
 }
 
+svn_stream_t *
+svn_subst_stream_translated(svn_stream_t *stream,
+                            const char *eol_str,
+                            svn_boolean_t repair,
+                            apr_hash_t *keywords,
+                            svn_boolean_t expand,
+                            apr_pool_t *result_pool)
+{
+  return stream_translated(stream, eol_str, NULL, repair, keywords, expand,
+                           result_pool);
+}
 
-svn_error_t *
-svn_subst_translate_cstring2(const char *src,
-                             const char **dst,
-                             const char *eol_str,
-                             svn_boolean_t repair,
-                             apr_hash_t *keywords,
-                             svn_boolean_t expand,
-                             apr_pool_t *pool)
+/* Same as svn_subst_translate_cstring2(), except for the following.
+ *
+ * If TRANSLATED_EOL is not NULL, then set *TRANSLATED_EOL to TRUE if an
+ * end-of-line sequence was changed, or to FALSE otherwise.
+ */
+static svn_error_t *
+translate_cstring(const char **dst,
+                  svn_boolean_t *translated_eol,
+                  const char *src,
+                  const char *eol_str,
+                  svn_boolean_t repair,
+                  apr_hash_t *keywords,
+                  svn_boolean_t expand,
+                  apr_pool_t *pool)
 {
   svn_stringbuf_t *dst_stringbuf;
   svn_stream_t *dst_stream;
@@ -1473,9 +1547,12 @@ svn_subst_translate_cstring2(const char 
   dst_stringbuf = svn_stringbuf_create("", pool);
   dst_stream = svn_stream_from_stringbuf(dst_stringbuf, pool);
 
+  if (translated_eol)
+    *translated_eol = FALSE;
+
   /* Another wrapper to translate the content. */
-  dst_stream = svn_subst_stream_translated(dst_stream, eol_str, repair,
-                                           keywords, expand, pool);
+  dst_stream = stream_translated(dst_stream, eol_str, translated_eol, repair,
+                                 keywords, expand, pool);
 
   /* Jam the text into the destination stream (to translate it). */
   SVN_ERR(svn_stream_write(dst_stream, src, &len));
@@ -1487,6 +1564,19 @@ svn_subst_translate_cstring2(const char 
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_subst_translate_cstring2(const char *src,
+                             const char **dst,
+                             const char *eol_str,
+                             svn_boolean_t repair,
+                             apr_hash_t *keywords,
+                             svn_boolean_t expand,
+                             apr_pool_t *pool)
+{
+  return translate_cstring(dst, NULL, src, eol_str, repair, keywords, expand,
+                            pool);
+}
+
 /* Given a special file at SRC, generate a textual representation of
    it in a normal file at DST.  Perform all allocations in POOL. */
 /* ### this should be folded into svn_subst_copy_and_translate3 */
@@ -1799,14 +1889,16 @@ svn_subst_stream_from_specialfile(svn_st
 
 /*** String translation */
 svn_error_t *
-svn_subst_translate_string(svn_string_t **new_value,
-                           const svn_string_t *value,
-                           const char *encoding,
-                           apr_pool_t *pool)
+svn_subst_translate_string2(svn_string_t **new_value,
+                            svn_boolean_t *translated_to_utf8,
+                            svn_boolean_t *translated_line_endings,
+                            const svn_string_t *value,
+                            const char *encoding,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
 {
   const char *val_utf8;
   const char *val_utf8_lf;
-  apr_pool_t *scratch_pool = svn_pool_create(pool);
 
   if (value == NULL)
     {
@@ -1824,16 +1916,19 @@ svn_subst_translate_string(svn_string_t 
       SVN_ERR(svn_utf_cstring_to_utf8(&val_utf8, value->data, scratch_pool));
     }
 
-  SVN_ERR(svn_subst_translate_cstring2(val_utf8,
-                                       &val_utf8_lf,
-                                       "\n",  /* translate to LF */
-                                       FALSE, /* no repair */
-                                       NULL,  /* no keywords */
-                                       FALSE, /* no expansion */
-                                       scratch_pool));
+  if (translated_to_utf8)
+    *translated_to_utf8 = (strcmp(value->data, val_utf8) != 0);
+
+  SVN_ERR(translate_cstring(&val_utf8_lf,
+                            translated_line_endings,
+                            val_utf8,
+                            "\n",  /* translate to LF */
+                            FALSE, /* no repair */
+                            NULL,  /* no keywords */
+                            FALSE, /* no expansion */
+                            scratch_pool));
 
-  *new_value = svn_string_create(val_utf8_lf, pool);
-  svn_pool_destroy(scratch_pool);
+  *new_value = svn_string_create(val_utf8_lf, result_pool);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c Wed Dec 29 21:12:33 2010
@@ -709,7 +709,7 @@ find_base_rev(svn_revnum_t *base_rev,
   else if (status == svn_wc__db_status_deleted)
     {
       const char *work_del_abspath;
-       SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, NULL, &work_del_abspath,
+       SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, &work_del_abspath,
                                        db, local_abspath, pool, pool));
 
       if (work_del_abspath != NULL)

Modified: subversion/branches/performance/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/adm_ops.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/adm_ops.c Wed Dec 29 21:12:33 2010
@@ -510,7 +510,7 @@ svn_wc_process_committed_queue2(svn_wc_c
                              iterpool));
     }
 
-  svn_hash__clear(queue->queue, iterpool);
+  SVN_ERR(svn_hash__clear(queue->queue, iterpool));
 
   svn_pool_destroy(iterpool);
 

Modified: subversion/branches/performance/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/deprecated.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/deprecated.c Wed Dec 29 21:12:33 2010
@@ -3366,8 +3366,8 @@ svn_wc_relocate3(const char *path,
   svn_wc_context_t *wc_ctx;
 
   if (! recurse)
-    svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, 0,
-                     _("Non-recursive relocation not supported"));
+    SVN_ERR(svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                             _("Non-recursive relocation not supported")));
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,

Modified: subversion/branches/performance/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/entries.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/entries.c Wed Dec 29 21:12:33 2010
@@ -91,7 +91,6 @@ typedef struct {
   svn_depth_t depth;
   apr_time_t last_mod_time;
   apr_hash_t *properties;
-  svn_boolean_t keep_local;
 } db_working_node_t;
 
 typedef struct {
@@ -254,7 +253,6 @@ get_base_info_for_deleted(svn_wc_entry_t
 
       SVN_ERR(svn_wc__db_scan_deletion(NULL,
                                        NULL,
-                                       NULL,
                                        &work_del_abspath,
                                        db, entry_abspath,
                                        scratch_pool, scratch_pool));
@@ -534,7 +532,7 @@ read_one_entry(const svn_wc_entry_t **ne
       /* ### we don't have to worry about moves, so this is a delete. */
       entry->schedule = svn_wc_schedule_delete;
 
-      SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, NULL,
+      SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
                                        &work_del_abspath,
                                        db, entry_abspath,
                                        scratch_pool, scratch_pool));
@@ -1580,6 +1578,7 @@ write_entry(struct write_baton **entry_n
             apr_int64_t wc_id,
             apr_int64_t repos_id,
             const svn_wc_entry_t *entry,
+            const svn_wc__text_base_info_t *text_base_info,
             const char *local_relpath,
             const char *entry_abspath,
             const svn_wc_entry_t *this_dir,
@@ -1588,7 +1587,7 @@ write_entry(struct write_baton **entry_n
             apr_pool_t *scratch_pool)
 {
   db_base_node_t *base_node = NULL;
-  db_working_node_t *working_node = NULL;
+  db_working_node_t *working_node = NULL, *below_working_node = NULL;
   db_actual_node_t *actual_node = NULL;
   const char *parent_relpath;
 
@@ -1682,6 +1681,11 @@ write_entry(struct write_baton **entry_n
   switch (entry->schedule)
     {
       case svn_wc_schedule_normal:
+        SVN_ERR_ASSERT(!parent_node
+                       || (parent_node->base && !parent_node->work
+                           && !entry->copied)
+                       || (!parent_node->base && parent_node->work
+                           && entry->copied));
         if (entry->copied)
           working_node = MAYBE_ALLOC(working_node, result_pool);
         else
@@ -1689,26 +1693,26 @@ write_entry(struct write_baton **entry_n
         break;
 
       case svn_wc_schedule_add:
+        SVN_ERR_ASSERT((parent_node->base && !parent_node->work)
+                       || (parent_node->work && !parent_node->base));
         working_node = MAYBE_ALLOC(working_node, result_pool);
         break;
 
       case svn_wc_schedule_delete:
+        SVN_ERR_ASSERT(!entry->copied);
         working_node = MAYBE_ALLOC(working_node, result_pool);
-        /* If the entry is part of a REPLACED (not COPIED) subtree,
-           then it needs a BASE node. */
-        if (parent_node->base
-            && (! (entry->copied
-                   || (this_dir->copied
-                       && (this_dir->schedule == svn_wc_schedule_add ||
-                           this_dir->schedule == svn_wc_schedule_delete ||
-                           this_dir->schedule == svn_wc_schedule_replace)))))
+        if (parent_node->base)
           base_node = MAYBE_ALLOC(base_node, result_pool);
         break;
 
       case svn_wc_schedule_replace:
+        SVN_ERR_ASSERT((parent_node->base && !parent_node->work)
+                       || (parent_node->work && !parent_node->base));
         working_node = MAYBE_ALLOC(working_node, result_pool);
         if (parent_node->base)
           base_node = MAYBE_ALLOC(base_node, result_pool);
+        else
+          below_working_node = MAYBE_ALLOC(below_working_node, scratch_pool);
         break;
     }
 
@@ -1716,15 +1720,19 @@ write_entry(struct write_baton **entry_n
      BASE node to indicate the not-present node.  */
   if (entry->deleted)
     {
-      base_node = MAYBE_ALLOC(base_node, result_pool);
+      SVN_ERR_ASSERT(base_node && !working_node && !below_working_node);
+      SVN_ERR_ASSERT(!entry->incomplete);
+      base_node->presence = svn_wc__db_status_not_present;
     }
 
-  if (entry->copied)
+  if (entry->absent)
     {
-      /* Make sure we get a WORKING_NODE inserted. The copyfrom information
-         will occur here or on a parent, as appropriate.  */
-      working_node = MAYBE_ALLOC(working_node, result_pool);
+      SVN_ERR_ASSERT(base_node && !working_node);
+      base_node->presence = svn_wc__db_status_absent;
+    }
 
+  if (entry->copied)
+    {
       if (entry->copyfrom_url)
         {
           const char *relative_url;
@@ -1741,12 +1749,8 @@ write_entry(struct write_baton **entry_n
                 svn_path_uri_decode(relative_url, result_pool);
             }
           working_node->copyfrom_revnum = entry->copyfrom_rev;
-#ifdef SVN_WC__OP_DEPTH
           working_node->op_depth
             = svn_wc__db_op_depth_for_upgrade(local_relpath);
-#else
-          working_node->op_depth = 2; /* ### temporary op_depth */
-#endif
         }
       else if (parent_node->work && parent_node->work->copyfrom_repos_path)
         {
@@ -1765,20 +1769,6 @@ write_entry(struct write_baton **entry_n
                                                         scratch_pool));
     }
 
-  if (entry->keep_local)
-    {
-      SVN_ERR_ASSERT(working_node != NULL);
-      SVN_ERR_ASSERT(entry->schedule == svn_wc_schedule_delete);
-      working_node->keep_local = TRUE;
-    }
-
-  if (entry->absent)
-    {
-      SVN_ERR_ASSERT(working_node == NULL);
-      SVN_ERR_ASSERT(base_node != NULL);
-      base_node->presence = svn_wc__db_status_absent;
-    }
-
   if (entry->conflict_old)
     {
       actual_node = MAYBE_ALLOC(actual_node, scratch_pool);
@@ -1833,8 +1823,6 @@ write_entry(struct write_baton **entry_n
 
       if (entry->deleted)
         {
-          SVN_ERR_ASSERT(!entry->incomplete);
-
           base_node->presence = svn_wc__db_status_not_present;
           /* ### should be svn_node_unknown, but let's store what we have. */
           base_node->kind = entry->kind;
@@ -1867,8 +1855,40 @@ write_entry(struct write_baton **entry_n
       if (entry->kind == svn_node_dir)
         base_node->checksum = NULL;
       else
-        SVN_ERR(svn_checksum_parse_hex(&base_node->checksum, svn_checksum_md5,
-                                       entry->checksum, result_pool));
+        {
+          if (text_base_info && text_base_info->revert_base.sha1_checksum)
+            base_node->checksum = text_base_info->revert_base.sha1_checksum;
+          else if (text_base_info && text_base_info->normal_base.sha1_checksum)
+            base_node->checksum = text_base_info->normal_base.sha1_checksum;
+          else
+            base_node->checksum = NULL;
+
+          /* The base MD5 checksum is available in the entry, unless there
+           * is a copied WORKING node.  If possible, verify that the entry
+           * checksum matches the base file that we found. */
+#ifdef SVN_DEBUG
+          if (! (working_node && entry->copied))
+            {
+              svn_checksum_t *entry_md5_checksum, *found_md5_checksum;
+              SVN_ERR(svn_checksum_parse_hex(&entry_md5_checksum, svn_checksum_md5,
+                                             entry->checksum, scratch_pool));
+              if (text_base_info && text_base_info->revert_base.md5_checksum)
+                found_md5_checksum = text_base_info->revert_base.md5_checksum;
+              else if (text_base_info && text_base_info->normal_base.md5_checksum)
+                found_md5_checksum = text_base_info->normal_base.md5_checksum;
+              else
+                found_md5_checksum = NULL;
+              if (entry_md5_checksum && found_md5_checksum)
+                SVN_ERR_ASSERT(svn_checksum_match(entry_md5_checksum,
+                                                  found_md5_checksum));
+              else
+                {
+                  /* ### Not sure what conditions this should cover. */
+                  /* SVN_ERR_ASSERT(entry->deleted || ...); */
+                }
+            }
+#endif
+        }
 
       if (this_dir->repos)
         {
@@ -1952,6 +1972,37 @@ write_entry(struct write_baton **entry_n
         }
     }
 
+  if (below_working_node)
+    {
+      below_working_node->wc_id = wc_id;
+      below_working_node->local_relpath = local_relpath;
+      below_working_node->op_depth = parent_node->work->op_depth;
+      below_working_node->parent_relpath = parent_relpath;
+      below_working_node->presence = svn_wc__db_status_normal;
+      below_working_node->kind = svn_node_file;
+      below_working_node->copyfrom_repos_id
+        = parent_node->work->copyfrom_repos_id;
+      below_working_node->copyfrom_repos_path
+        = svn_relpath_join(parent_node->work->copyfrom_repos_path, entry->name,
+                           scratch_pool);
+      below_working_node->copyfrom_revnum
+        = parent_node->work->copyfrom_revnum;
+      below_working_node->moved_here = FALSE;
+      below_working_node->moved_to = FALSE;
+
+      /* The revert_base checksum isn't available in the entry structure,
+         so the caller provides it. */
+      below_working_node->checksum = text_base_info->revert_base.sha1_checksum;
+      below_working_node->translated_size = 0;
+      below_working_node->changed_rev = SVN_INVALID_REVNUM;
+      below_working_node->changed_date = 0;
+      below_working_node->changed_author = NULL;
+      below_working_node->depth = svn_depth_infinity;
+      below_working_node->last_mod_time = 0;
+      below_working_node->properties = NULL;
+      SVN_ERR(insert_working_node(sdb, below_working_node, scratch_pool));
+    }
+
   /* Insert the working node. */
   if (working_node)
     {
@@ -1973,9 +2024,24 @@ write_entry(struct write_baton **entry_n
       if (entry->kind == svn_node_dir)
         working_node->checksum = NULL;
       else
-        SVN_ERR(svn_checksum_parse_hex(&working_node->checksum,
-                                       svn_checksum_md5,
-                                       entry->checksum, result_pool));
+        {
+          working_node->checksum = text_base_info->normal_base.sha1_checksum;
+
+          /* If an MD5 checksum is present in the entry, we can verify that
+           * it matches the MD5 of the base file we found earlier. */
+#ifdef SVN_DEBUG
+          if (entry->checksum)
+          {
+            svn_checksum_t *md5_checksum;
+            SVN_ERR(svn_checksum_parse_hex(&md5_checksum, svn_checksum_md5,
+                                           entry->checksum, result_pool));
+            SVN_ERR_ASSERT(
+              md5_checksum && text_base_info->normal_base.md5_checksum);
+            SVN_ERR_ASSERT(svn_checksum_match(
+              md5_checksum, text_base_info->normal_base.md5_checksum));
+          }
+#endif
+        }
 
       /* All subdirs start of incomplete, and stop being incomplete
          when the entries file in the subdir is upgraded. */
@@ -2039,15 +2105,8 @@ write_entry(struct write_baton **entry_n
 
       if (!entry->copied)
         {
-          if (parent_node->work)
-            working_node->op_depth = parent_node->work->op_depth;
-          else
-#ifdef SVN_WC__OP_DEPTH
-            working_node->op_depth
-              = svn_wc__db_op_depth_for_upgrade(local_relpath);
-#else
-            working_node->op_depth = 2; /* ### temporary op_depth */
-#endif
+          working_node->op_depth
+            = svn_wc__db_op_depth_for_upgrade(local_relpath);
         }
 
       SVN_ERR(insert_working_node(sdb, working_node, scratch_pool));
@@ -2067,7 +2126,7 @@ write_entry(struct write_baton **entry_n
 
   if (entry_node)
     {
-      *entry_node = apr_palloc(result_pool, sizeof(*entry_node));
+      *entry_node = apr_palloc(result_pool, sizeof(**entry_node));
       (*entry_node)->base = base_node;
       (*entry_node)->work = working_node;
     }
@@ -2083,6 +2142,7 @@ struct entries_write_baton
   const char *dir_abspath;
   const char *new_root_abspath;
   apr_hash_t *entries;
+  apr_hash_t *text_bases_info;
   struct write_baton *parent_node;
   struct write_baton *dir_node;
   apr_pool_t *result_pool;
@@ -2124,7 +2184,7 @@ entries_write_new_cb(void *baton,
 
   /* Write out "this dir" */
   SVN_ERR(write_entry(&ewb->dir_node, ewb->parent_node, db, sdb,
-                      ewb->wc_id, ewb->repos_id, this_dir, dir_relpath,
+                      ewb->wc_id, ewb->repos_id, this_dir, NULL, dir_relpath,
                       svn_dirent_join(new_root_abspath, dir_relpath,
                                       scratch_pool),
                       this_dir, FALSE, ewb->result_pool, iterpool));
@@ -2135,6 +2195,8 @@ entries_write_new_cb(void *baton,
       const char *name = svn__apr_hash_index_key(hi);
       const svn_wc_entry_t *this_entry = svn__apr_hash_index_val(hi);
       const char *child_abspath, *child_relpath;
+      svn_wc__text_base_info_t *text_base_info
+        = apr_hash_get(ewb->text_bases_info, name, APR_HASH_KEY_STRING);
 
       svn_pool_clear(iterpool);
 
@@ -2148,7 +2210,7 @@ entries_write_new_cb(void *baton,
       child_relpath = svn_dirent_skip_ancestor(old_root_abspath, child_abspath);
       SVN_ERR(write_entry(NULL, ewb->dir_node, db, sdb,
                           ewb->wc_id, ewb->repos_id,
-                          this_entry, child_relpath,
+                          this_entry, text_base_info, child_relpath,
                           svn_dirent_join(new_root_abspath, child_relpath,
                                           scratch_pool),
                           this_dir, TRUE, iterpool, iterpool));
@@ -2169,6 +2231,7 @@ svn_wc__write_upgraded_entries(void **di
                                const char *dir_abspath,
                                const char *new_root_abspath,
                                apr_hash_t *entries,
+                               apr_hash_t *text_bases_info,
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool)
 {
@@ -2180,6 +2243,7 @@ svn_wc__write_upgraded_entries(void **di
   ewb.dir_abspath = dir_abspath;
   ewb.new_root_abspath = new_root_abspath;
   ewb.entries = entries;
+  ewb.text_bases_info = text_bases_info;
   ewb.parent_node = parent_baton;
   ewb.result_pool = result_pool;
 

Modified: subversion/branches/performance/subversion/libsvn_wc/entries.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/entries.h?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/entries.h (original)
+++ subversion/branches/performance/subversion/libsvn_wc/entries.h Wed Dec 29 21:12:33 2010
@@ -80,17 +80,30 @@ svn_error_t *
 svn_wc__entry_is_hidden(svn_boolean_t *hidden, const svn_wc_entry_t *entry);
 
 
-/* For internal use by entries.c to read/write old-format working copies. */
-svn_error_t *
-svn_wc__read_entries_old(apr_hash_t **entries,
-                         const char *dir_abspath,
-                         apr_pool_t *result_pool,
-                         apr_pool_t *scratch_pool);
+/* The checksums of one pre-1.7 text-base file.  If the text-base file
+ * exists, both checksums are filled in, otherwise both fields are NULL. */
+typedef struct svn_wc__text_base_file_info_t
+{
+  svn_checksum_t *sha1_checksum;
+  svn_checksum_t *md5_checksum;
+} svn_wc__text_base_file_info_t;
+
+/* The text-base checksums of the normal base and/or the revert-base of one
+ * pre-1.7 versioned text file. */
+typedef struct svn_wc__text_base_info_t
+{
+  svn_wc__text_base_file_info_t normal_base;
+  svn_wc__text_base_file_info_t revert_base;
+} svn_wc__text_base_info_t;
 
 /* For internal use by upgrade.c to write entries in the wc-ng format.
    Return in DIR_BATON the baton to be passed as PARENT_BATON when
    upgrading child directories. Pass a NULL PARENT_BATON when upgrading
-   the root directory. */
+   the root directory.
+
+   TEXT_BASES_INFO is a hash of information about all the text bases found
+   in this directory's admin area, keyed on (const char *) name of the
+   versioned file, with (svn_wc__text_base_info_t *) values. */
 svn_error_t *
 svn_wc__write_upgraded_entries(void **dir_baton,
                                void *parent_baton,
@@ -101,6 +114,7 @@ svn_wc__write_upgraded_entries(void **di
                                const char *dir_abspath,
                                const char *new_root_abspath,
                                apr_hash_t *entries,
+                               apr_hash_t *text_bases_info,
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool);
 

Modified: subversion/branches/performance/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/lock.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/lock.c Wed Dec 29 21:12:33 2010
@@ -543,18 +543,8 @@ open_single(svn_wc_adm_access_t **adm_ac
 
   /* The format version must match exactly. Note that wc_db will perform
      an auto-upgrade if allowed. If it does *not*, then it has decided a
-     manual upgrade is required.
-
-     Note: if it decided on a manual upgrade, then we "should" never even
-     reach this code. An error should have been raised earlier.  */
-  if (wc_format != SVN_WC__VERSION)
-    {
-      return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL,
-                               _("Working copy format of '%s' is too old (%d); "
-                                 "please run 'svn upgrade'"),
-                               svn_dirent_local_style(path, scratch_pool),
-                               wc_format);
-    }
+     manual upgrade is required and it should have raised an error.  */
+  SVN_ERR_ASSERT(wc_format == SVN_WC__VERSION);
 
   /* Need to create a new lock */
   SVN_ERR(adm_access_alloc(&lock, path, db, db_provided, write_lock,

Modified: subversion/branches/performance/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/node.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/node.c Wed Dec 29 21:12:33 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;
 }
@@ -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,
@@ -984,7 +1007,7 @@ svn_wc__node_get_working_rev_info(svn_re
       const char *base_del_abspath;
 
       SVN_ERR(svn_wc__db_scan_deletion(&base_del_abspath, NULL,
-                                       NULL, &work_del_abspath, wc_ctx->db,
+                                       &work_del_abspath, wc_ctx->db,
                                        local_abspath, scratch_pool,
                                        scratch_pool));
       if (work_del_abspath)
@@ -1075,7 +1098,7 @@ svn_wc__node_get_commit_base_rev(svn_rev
       const char *parent_abspath;
       svn_wc__db_status_t parent_status;
 
-      SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, NULL,
+      SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
                                        &work_del_abspath,
                                        wc_ctx->db, local_abspath,
                                        scratch_pool, scratch_pool));
@@ -1263,9 +1286,7 @@ svn_wc__internal_node_get_schedule(svn_w
             break;
 
           /* Find out details of our deletion.  */
-          SVN_ERR(svn_wc__db_scan_deletion(NULL,
-                                           NULL,
-                                           NULL,
+          SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
                                            &work_del_abspath,
                                            db, local_abspath,
                                            scratch_pool, scratch_pool));
@@ -1319,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/performance/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/props.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/props.c Wed Dec 29 21:12:33 2010
@@ -836,7 +836,7 @@ maybe_generate_propconflict(svn_boolean_
                   (mergestream, diff, the_val, working_val, new_val,
                    NULL, NULL, NULL, NULL,
                    svn_diff_conflict_display_modified_latest, filepool));
-          svn_stream_close(mergestream);
+          SVN_ERR(svn_stream_close(mergestream));
         }
     }
 

Modified: subversion/branches/performance/subversion/libsvn_wc/revision_status.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/revision_status.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/revision_status.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/revision_status.c Wed Dec 29 21:12:33 2010
@@ -52,6 +52,7 @@ 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)
 {

Modified: subversion/branches/performance/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/status.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/status.c Wed Dec 29 21:12:33 2010
@@ -1632,10 +1632,15 @@ make_file_baton(struct dir_baton *parent
 }
 
 
-svn_boolean_t
-svn_wc__is_sendable_status(const svn_wc_status3_t *status,
-                           svn_boolean_t no_ignore,
-                           svn_boolean_t get_all)
+/**
+ * Return a boolean answer to the question "Is @a status something that
+ * should be reported?".  @a no_ignore and @a get_all are the same as
+ * svn_wc_get_status_editor4().
+ */
+static svn_boolean_t
+is_sendable_status(const svn_wc_status3_t *status,
+                   svn_boolean_t no_ignore,
+                   svn_boolean_t get_all)
 {
   /* If the repository status was touched at all, it's interesting. */
   if (status->repos_node_status != svn_wc_status_none)
@@ -1764,7 +1769,7 @@ handle_statii(struct edit_baton *eb,
         }
       if (dir_was_deleted)
         status->repos_node_status = svn_wc_status_deleted;
-      if (svn_wc__is_sendable_status(status, eb->no_ignore, eb->get_all))
+      if (is_sendable_status(status, eb->no_ignore, eb->get_all))
         SVN_ERR((eb->status_func)(eb->status_baton, local_abspath, status,
                                   iterpool));
     }
@@ -2001,8 +2006,8 @@ close_directory(void *dir_baton,
                             dir_status ? dir_status->repos_root_url : NULL,
                             dir_status ? dir_status->repos_relpath : NULL,
                             db->statii, was_deleted, db->depth, pool));
-      if (dir_status && svn_wc__is_sendable_status(dir_status, eb->no_ignore,
-                                                   eb->get_all))
+      if (dir_status && is_sendable_status(dir_status, eb->no_ignore,
+                                           eb->get_all))
         SVN_ERR((eb->status_func)(eb->status_baton, db->local_abspath,
                                   dir_status, pool));
       apr_hash_set(pb->statii, db->local_abspath, APR_HASH_KEY_STRING, NULL);
@@ -2032,8 +2037,7 @@ close_directory(void *dir_baton,
                                          eb->cancel_func, eb->cancel_baton,
                                          pool));
                 }
-              if (svn_wc__is_sendable_status(tgt_status, eb->no_ignore,
-                                             eb->get_all))
+              if (is_sendable_status(tgt_status, eb->no_ignore, eb->get_all))
                 SVN_ERR((eb->status_func)(eb->status_baton, eb->target_abspath,
                                           tgt_status, pool));
             }
@@ -2047,8 +2051,8 @@ close_directory(void *dir_baton,
                                 eb->anchor_status->repos_root_url,
                                 eb->anchor_status->repos_relpath,
                                 db->statii, FALSE, eb->default_depth, pool));
-          if (svn_wc__is_sendable_status(eb->anchor_status, eb->no_ignore,
-                                         eb->get_all))
+          if (is_sendable_status(eb->anchor_status, eb->no_ignore,
+                                 eb->get_all))
             SVN_ERR((eb->status_func)(eb->status_baton, db->local_abspath,
                                       eb->anchor_status, pool));
           eb->anchor_status = NULL;
@@ -2305,7 +2309,7 @@ svn_wc_get_status_editor5(const svn_delt
     {
       apr_array_header_t *ignores;
 
-      svn_wc_get_default_ignores(&ignores, NULL, result_pool);
+      SVN_ERR(svn_wc_get_default_ignores(&ignores, NULL, result_pool));
       eb->ignores = ignores;
     }
 
@@ -2375,7 +2379,7 @@ svn_wc_walk_status(svn_wc_context_t *wc_
     {
       apr_array_header_t *ignores;
 
-      svn_wc_get_default_ignores(&ignores, NULL, scratch_pool);
+      SVN_ERR(svn_wc_get_default_ignores(&ignores, NULL, scratch_pool));
       ignore_patterns = ignores;
     }
 

Modified: subversion/branches/performance/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/update_editor.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/update_editor.c Wed Dec 29 21:12:33 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;
 
@@ -1318,18 +1297,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 +1324,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)
     {
@@ -3496,13 +3478,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 +3680,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 +3688,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 +3824,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 +3855,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 +3882,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 +3902,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 +3919,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 +4037,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 +4066,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)
@@ -4226,15 +4148,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 +4182,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 +4252,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 +4281,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 +4295,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 +4312,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 +4337,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 +4348,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.