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 2012/05/07 22:24:51 UTC

svn commit: r1335238 - in /subversion/branches/ev2-export: ./ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_fs/ subversion/libsvn_ra_serf/ subversion/libsvn_wc/

Author: hwright
Date: Mon May  7 20:24:50 2012
New Revision: 1335238

URL: http://svn.apache.org/viewvc?rev=1335238&view=rev
Log:
On the ev2-export branch:
Bring up-to-date with trunk, which fixes a few errors.

Modified:
    subversion/branches/ev2-export/   (props changed)
    subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h
    subversion/branches/ev2-export/subversion/include/svn_ra.h
    subversion/branches/ev2-export/subversion/libsvn_client/ra.c
    subversion/branches/ev2-export/subversion/libsvn_fs/editor.c
    subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c
    subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c
    subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c

Propchange: subversion/branches/ev2-export/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1335172-1335224

Modified: subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h?rev=1335238&r1=1335237&r2=1335238&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h Mon May  7 20:24:50 2012
@@ -1089,13 +1089,12 @@ svn_wc__node_pristine_install(svn_wc_con
 
 /* Like svn_wc_get_pristine_contents2(), but keyed on the
    SHA1_CHECKSUM rather than on the local absolute path of the working
-   file.  WCROOT_ABSPATH is the absolute path of the root of the
-   working copy in whose pristine database we'll be looking for these
-   contents.  */
+   file.  WRI_ABSPATH is any versioned path of the working copy in
+   whose pristine database we'll be looking for these contents.  */
 svn_error_t *
 svn_wc__get_pristine_contents_by_checksum(svn_stream_t **contents,
                                           svn_wc_context_t *wc_ctx,
-                                          const char *wcroot_abspath,
+                                          const char *wri_abspath,
                                           const svn_checksum_t *sha1_checksum,
                                           apr_pool_t *result_pool,
                                           apr_pool_t *scratch_pool);

Modified: subversion/branches/ev2-export/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/svn_ra.h?rev=1335238&r1=1335237&r2=1335238&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/svn_ra.h (original)
+++ subversion/branches/ev2-export/subversion/include/svn_ra.h Mon May  7 20:24:50 2012
@@ -127,7 +127,7 @@ typedef svn_error_t *(*svn_ra_invalidate
  */
 typedef svn_error_t *(*svn_ra_get_wc_contents_func_t)(void *baton,
                                                       svn_stream_t **contents,
-                                                      svn_checksum_t *sha1_checksum,
+                                                      const svn_checksum_t *sha1_checksum,
                                                       apr_pool_t *pool);
 
 

Modified: subversion/branches/ev2-export/subversion/libsvn_client/ra.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/ra.c?rev=1335238&r1=1335237&r2=1335238&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/ra.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/ra.c Mon May  7 20:24:50 2012
@@ -52,9 +52,12 @@ typedef struct callback_baton_t
      this base directory. */
   const char *base_dir_abspath;
 
-  /* Holds the absolute path of the working copy root for the working
-     copy in which BASE_DIR_ABSPATH is found. */
-  const char *wcroot_abspath;
+  /* TEMPORARY: Is 'base_dir_abspath' a versioned path?  cmpilato
+     suspects that the commit-to-multiple-disjoint-working-copies
+     code is getting this all wrong, sometimes passing an unversioned
+     (or versioned in a foreign wc) path here which sorta kinda
+     happens to work most of the time but is ultimately incorrect.  */
+  svn_boolean_t base_dir_isversioned;
 
   /* An array of svn_client_commit_item3_t * structures, present only
      during working copy commits. */
@@ -242,12 +245,12 @@ invalidate_wc_props(void *baton,
 static svn_error_t *
 get_wc_contents(void *baton,
                 svn_stream_t **contents,
-                svn_checksum_t *sha1_checksum,
+                const svn_checksum_t *sha1_checksum,
                 apr_pool_t *pool)
 {
   callback_baton_t *cb = baton;
 
-  if (! cb->wcroot_abspath)
+  if (! (cb->base_dir_abspath && cb->base_dir_isversioned))
     {
       *contents = NULL;
       return SVN_NO_ERROR;
@@ -256,7 +259,7 @@ get_wc_contents(void *baton,
   return svn_error_trace(
              svn_wc__get_pristine_contents_by_checksum(contents,
                                                        cb->ctx->wc_ctx,
-                                                       cb->wcroot_abspath,
+                                                       cb->base_dir_abspath,
                                                        sha1_checksum,
                                                        pool, pool));
 }
@@ -320,7 +323,6 @@ svn_client__open_ra_session_internal(svn
 
   if (base_dir_abspath)
     {
-      const char *wcroot_abspath;
       svn_error_t *err = svn_wc__node_get_repos_info(NULL, &uuid, ctx->wc_ctx,
                                                      base_dir_abspath,
                                                      pool, pool);
@@ -335,25 +337,7 @@ svn_client__open_ra_session_internal(svn
       else
         {
           SVN_ERR(err);
-        }
-
-      err = svn_wc__get_wc_root(&wcroot_abspath, ctx->wc_ctx,
-                                base_dir_abspath, pool, pool);
-      if (err)
-        {
-          if (err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY)
-            {
-              svn_error_clear(err);
-              err = SVN_NO_ERROR;
-            }
-          else
-            {
-              return err;
-            }
-        }
-      else
-        {
-          cb->wcroot_abspath = wcroot_abspath;
+          cb->base_dir_isversioned = TRUE;
         }
     }
 

Modified: subversion/branches/ev2-export/subversion/libsvn_fs/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs/editor.c?rev=1335238&r1=1335237&r2=1335238&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs/editor.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs/editor.c Mon May  7 20:24:50 2012
@@ -168,17 +168,54 @@ can_modify(svn_fs_root_t *txn_root,
 {
   svn_revnum_t created_rev;
 
-  /* Out-of-dateness check:  compare the created-rev of the noden
+  /* Out-of-dateness check:  compare the created-rev of the node
      in the txn against the created-rev of FSPATH.  */
   SVN_ERR(svn_fs_node_created_rev(&created_rev, txn_root, fspath,
                                   scratch_pool));
 
-  /* If CREATED_REV is invalid, that means it's already mutable in the
+  /* Uncommitted nodes (eg. a descendent of a copy/move/rotate destination)
+     have no (committed) revision number. Let the caller go ahead and
+     modify these nodes.
+
+     Note: strictly speaking, they might be performing an "illegal" edit
+     in certain cases, but let's just assume they're Good Little Boys.
+
+     If CREATED_REV is invalid, that means it's already mutable in the
      txn, which means it has already passed this out-of-dateness check.
      (Usually, this happens when looking at a parent directory of an
      already-modified node)  */
-  if (SVN_IS_VALID_REVNUM(created_rev) && revision != created_rev)
-    {
+  if (!SVN_IS_VALID_REVNUM(created_rev))
+    return SVN_NO_ERROR;
+
+  /* If the node is immutable (has a revision), then the caller should
+     have supplied a valid revision number [that they expect to change].
+     The checks further below will determine the out-of-dateness of the
+     specified revision.  */
+  /* ### ugh. descendents of copy/move/rotate destinations carry along
+     ### their original immutable state and (thus) a valid CREATED_REV.
+     ### but they are logically uncommitted, so the caller will pass
+     ### SVN_INVALID_REVNUM. (technically, the caller could provide
+     ### ORIGINAL_REV, but that is semantically incorrect for the Ev2
+     ### API).
+     ###
+     ### for now, we will assume the caller knows what they are doing
+     ### and an invalid revision implies such a descendent. in the
+     ### future, we could examine the ancestor chain looking for a
+     ### copy/move/rotate-here node and allow the modification (and the
+     ### converse: if no such ancestor, the caller must specify the
+     ### correct/intended revision to modify).
+  */
+#if 1
+  if (!SVN_IS_VALID_REVNUM(revision))
+    return SVN_NO_ERROR;
+#else
+  if (!SVN_IS_VALID_REVNUM(revision))
+    /* ### use a custom error code?  */
+    return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+                             N_("Revision for modifying '%s' is required"),
+                             fspath);
+#endif
+
       if (revision < created_rev)
         {
           /* We asked to change a node that is *older* than what we found
@@ -188,7 +225,7 @@ can_modify(svn_fs_root_t *txn_root,
                                    fspath);
         }
 
-      /* revision > created_rev  */
+    if (revision > created_rev)
       {
         /* We asked to change a node that is *newer* than what we found
            in the transaction. Given that the transaction was based off
@@ -226,7 +263,6 @@ can_modify(svn_fs_root_t *txn_root,
                                      fspath);
           }
       }
-    }
 
   return SVN_NO_ERROR;
 }
@@ -370,13 +406,6 @@ alter_directory_cb(void *baton,
   /* Note: we ignore CHILDREN. We have no "incomplete" state to worry about,
      so we don't need to be aware of what children will be created.  */
 
-  if (!SVN_IS_VALID_REVNUM(revision))
-    /* ### use a custom error code?  */
-    return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
-                             N_("Revision for modification of '%s' "
-                                "is required"),
-                             fspath);
-
   SVN_ERR(get_root(&root, eb));
   SVN_ERR(can_modify(root, fspath, revision, scratch_pool));
 
@@ -400,13 +429,6 @@ alter_file_cb(void *baton,
   const char *fspath = FSPATH(relpath, scratch_pool);
   svn_fs_root_t *root;
 
-  if (!SVN_IS_VALID_REVNUM(revision))
-    /* ### use a custom error code?  */
-    return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
-                             N_("Revision for modification of '%s' "
-                                "is required"),
-                             fspath);
-
   SVN_ERR(get_root(&root, eb));
   SVN_ERR(can_modify(root, fspath, revision, scratch_pool));
 
@@ -452,13 +474,6 @@ delete_cb(void *baton,
   const char *fspath = FSPATH(relpath, scratch_pool);
   svn_fs_root_t *root;
 
-  if (!SVN_IS_VALID_REVNUM(revision))
-    /* ### use a custom error code?  */
-    return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
-                             N_("Revision for deletion of '%s' "
-                                "is required"),
-                             fspath);
-
   SVN_ERR(get_root(&root, eb));
   SVN_ERR(can_modify(root, fspath, revision, scratch_pool));
 
@@ -483,13 +498,6 @@ copy_cb(void *baton,
   svn_fs_root_t *root;
   svn_fs_root_t *src_root;
 
-  if (!SVN_IS_VALID_REVNUM(src_revision))
-    /* ### use a custom error code?  */
-    return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
-                             N_("Source revision for copy of '%s' "
-                                "is required"),
-                             src_fspath);
-
   SVN_ERR(get_root(&root, eb));
 
   /* Check if we can we replace the maybe-specified destination (revision).  */
@@ -523,13 +531,6 @@ move_cb(void *baton,
   svn_fs_root_t *root;
   svn_fs_root_t *src_root;
 
-  if (!SVN_IS_VALID_REVNUM(src_revision))
-    /* ### use a custom error code?  */
-    return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
-                             N_("Source revision for move of '%s' "
-                                "is required"),
-                             src_fspath);
-
   SVN_ERR(get_root(&root, eb));
 
   /* Check if we delete the specified source (revision), and can we replace

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c?rev=1335238&r1=1335237&r2=1335238&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c Mon May  7 20:24:50 2012
@@ -1241,10 +1241,6 @@ static svn_error_t *
 local_fetch(report_info_t *info)
 {
   const svn_delta_editor_t *update_editor = info->dir->update_editor;
-  svn_txdelta_window_t delta_window = { 0 };
-  svn_txdelta_op_t delta_op;
-  svn_string_t window_data;
-  char read_buf[SVN__STREAM_CHUNK_SIZE + 1];
 
   SVN_ERR(open_dir(info->dir));
   info->editor_pool = svn_pool_create(info->dir->dir_baton_pool);
@@ -1280,33 +1276,8 @@ local_fetch(report_info_t *info)
                                          &info->textdelta,
                                          &info->textdelta_baton));
   
-  while (1)
-    {
-      apr_size_t read_len = SVN__STREAM_CHUNK_SIZE;
-      
-      SVN_ERR(svn_stream_read(info->cached_contents, read_buf, &read_len));
-      if (read_len == 0)
-        break;
-      
-      window_data.data = read_buf;
-      window_data.len = read_len;
-      
-      delta_op.action_code = svn_txdelta_new;
-      delta_op.offset = 0;
-      delta_op.length = read_len;
-      
-      delta_window.tview_len = read_len;
-      delta_window.num_ops = 1;
-      delta_window.ops = &delta_op;
-      delta_window.new_data = &window_data;
-      
-      SVN_ERR(info->textdelta(&delta_window, info->textdelta_baton));
-      
-      if (read_len < SVN__STREAM_CHUNK_SIZE)
-        break;
-    }
-  
-  SVN_ERR(info->textdelta(NULL, info->textdelta_baton));
+  SVN_ERR(svn_txdelta_send_stream(info->cached_contents, info->textdelta,
+                                  info->textdelta_baton, NULL, info->pool));
 
   SVN_ERR(svn_stream_close(info->cached_contents));
   info->cached_contents = NULL;
@@ -1370,7 +1341,7 @@ handle_local_fetch(serf_request_t *reque
   if (sl.code != 200)
     {
       err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
-                              _("GET request failed: %d %s"),
+                              _("HEAD request failed: %d %s"),
                               sl.code, sl.reason);
       return error_fetch(request, fetch_ctx, err);
     }

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c?rev=1335238&r1=1335237&r2=1335238&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c Mon May  7 20:24:50 2012
@@ -1109,26 +1109,24 @@ svn_ra_serf__handle_multistatus_only(ser
 {
   svn_ra_serf__handler_t *handler = baton;
 
-  /* This response handler requires a pool for the server error.  */
-  SVN_ERR_ASSERT(handler->handler_pool);
+  /* We should see this just once, in order to initialize SERVER_ERROR.
+     At that point, the core error processing will take over. If we choose
+     not to parse an error, then we'll never return here (because we
+     change the response handler).  */
+  SVN_ERR_ASSERT(handler->server_error == NULL);
 
-  /* If necessary, initialize our XML parser. */
-  if (handler->server_error == NULL)
     {
-      svn_ra_serf__server_error_t *server_err;
       serf_bucket_t *hdrs;
       const char *val;
 
-      /* ### it would be nice to avoid allocating this every time. we
-         ### could potentially have a flag indicating we have examined
-         ### the Content-Type header already.  */
-      server_err = apr_pcalloc(handler->handler_pool, sizeof(*server_err));
-      server_err->init = TRUE;
-
       hdrs = serf_bucket_response_get_headers(response);
       val = serf_bucket_headers_get(hdrs, "Content-Type");
       if (val && strncasecmp(val, "text/xml", sizeof("text/xml") - 1) == 0)
         {
+          svn_ra_serf__server_error_t *server_err;
+
+          server_err = apr_pcalloc(handler->handler_pool, sizeof(*server_err));
+          server_err->init = TRUE;
           server_err->error = svn_error_create(APR_SUCCESS, NULL, NULL);
           server_err->has_xml_response = TRUE;
           server_err->contains_precondition_error = FALSE;
@@ -1143,6 +1141,8 @@ svn_ra_serf__handle_multistatus_only(ser
 
           /* Get the parser to set our DONE flag.  */
           server_err->parser.done = &handler->done;
+
+          handler->server_error = server_err;
         }
       else
         {
@@ -1150,53 +1150,18 @@ svn_ra_serf__handle_multistatus_only(ser
              ### caller thinks we are "done", then it may never call into
              ### serf_context_run() again to flush the response.  */
           handler->done = TRUE;
-          server_err->error = SVN_NO_ERROR;
-        }
-
-      handler->server_error = server_err;
-    }
-
-  /* If server_err->error still contains APR_SUCCESS, it means that we
-     have not successfully parsed the XML yet. */
-  if (handler->server_error
-      && handler->server_error->error
-      && handler->server_error->error->apr_err == APR_SUCCESS)
-    {
-      svn_error_t *err;
 
-      err = svn_ra_serf__handle_xml_parser(request, response,
-                                           &handler->server_error->parser,
-                                           scratch_pool);
-
-      /* APR_EOF will be returned when parsing is complete.  If we see
-         any other error, return it immediately.  In practice the only
-         other error we expect to see is APR_EAGAIN, which indicates that
-         we could not parse the XML because the contents are not yet
-         available to be read. */
-      if (!err || !APR_STATUS_IS_EOF(err->apr_err))
-        {
-          return svn_error_trace(err);
+          /* The body was not text/xml, so we don't know what to do with it.
+             Toss anything that arrives.  */
+          handler->response_handler = svn_ra_serf__handle_discard_body;
+          handler->response_baton = NULL;
         }
-      else if (handler->done
-               && handler->server_error->error->apr_err == APR_SUCCESS)
-        {
-          svn_error_clear(handler->server_error->error);
-          handler->server_error->error = SVN_NO_ERROR;
-
-          /* ### it would be nice to do this, but if we enter this response
-             ### handler again, it would be re-created. this throws back to
-             ### the idea of a flag determining whether we haved looked for
-             ### a server error.  */
-#if 0
-          handler->server_error = NULL;
-#endif
-        }
-
-      svn_error_clear(err);
     }
 
-  return svn_error_trace(svn_ra_serf__handle_discard_body(
-                           request, response, NULL, scratch_pool));
+  /* Returning SVN_NO_ERROR will return APR_SUCCESS to serf, which tells it
+     to call the response handler again. That will start up the XML parsing,
+     or it will be dropped on the floor (per the decision above).  */
+  return SVN_NO_ERROR;
 }
 
 
@@ -1674,40 +1639,52 @@ handle_response(serf_request_t *request,
                 serf_bucket_t *response,
                 svn_ra_serf__handler_t *handler,
                 apr_status_t *serf_status,
-                apr_pool_t *pool)
+                apr_pool_t *scratch_pool)
 {
-  serf_status_line sl;
   apr_status_t status;
   svn_error_t *err;
 
+  /* ### need to verify whether this already gets init'd on every
+     ### successful exit. for an error-exit, it will (properly) be
+     ### ignored by the caller.  */
+  *serf_status = APR_SUCCESS;
+
   if (!response)
     {
-      /* Uh-oh.  Our connection died.  Requeue. */
+      /* Uh-oh. Our connection died.  */
       if (handler->response_error)
         SVN_ERR(handler->response_error(request, response, 0,
                                         handler->response_error_baton));
 
+      /* Requeue another request for this handler.
+         ### how do we know if the handler can deal with this?!  */
       svn_ra_serf__request_create(handler);
 
-      return APR_SUCCESS;
+      return SVN_NO_ERROR;
     }
 
   /* If we're reading the body, then skip all this preparation.  */
   if (handler->reading_body)
     goto process_body;
 
-  status = serf_bucket_response_status(response, &sl);
-  if (SERF_BUCKET_READ_ERROR(status))
-    {
-      *serf_status = status;
-      return SVN_NO_ERROR; /* Handled by serf */
-    }
-  if (!sl.version && (APR_STATUS_IS_EOF(status) ||
-                      APR_STATUS_IS_EAGAIN(status)))
+  /* Copy the Status-Line info into HANDLER, if we don't yet have it.  */
+  if (handler->sline.version == 0)
     {
-      /* The response line is not (yet) ready.  */
-      *serf_status = status;
-      return SVN_NO_ERROR; /* Handled by serf */
+      serf_status_line sl;
+
+      status = serf_bucket_response_status(response, &sl);
+      if (status != APR_SUCCESS)
+        {
+          /* The response line is not (yet) ready, or some other error.  */
+          *serf_status = status;
+          return SVN_NO_ERROR; /* Handled by serf */
+        }
+
+      /* If we got APR_SUCCESS, then we should have Status-Line info.  */
+      SVN_ERR_ASSERT(sl.version != 0);
+
+      handler->sline = sl;
+      handler->sline.reason = apr_pstrdup(handler->handler_pool, sl.reason);
     }
 
   status = serf_bucket_response_wait_for_headers(response);
@@ -1715,10 +1692,20 @@ handle_response(serf_request_t *request,
     {
       if (!APR_STATUS_IS_EOF(status))
         {
+          /* Either the headers are not (yet) complete, or there really
+             was an error.  */
           *serf_status = status;
           return SVN_NO_ERROR;
         }
 
+      /* wait_for_headers() will return EOF if there is no body in this
+         response, or if we completely read the body. The latter is not
+         true since we would have set READING_BODY to get the body read,
+         and we would not be back to this code block.
+
+         It can also return EOF if we truly hit EOF while (say) processing
+         the headers. aka Badness.  */
+
       /* Cases where a lack of a response body (via EOF) is okay:
        *  - A HEAD request
        *  - 204/304 response
@@ -1728,21 +1715,24 @@ handle_response(serf_request_t *request,
        * scream loudly.
        */
       if (strcmp(handler->method, "HEAD") != 0
-          && sl.code != 204
-          && sl.code != 304)
+          && handler->sline.code != 204
+          && handler->sline.code != 304)
         {
           err = svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA,
                                   svn_error_wrap_apr(status, NULL),
                                   _("Premature EOF seen from server"
-                                    " (http status=%d)"), sl.code);
+                                    " (http status=%d)"),
+                                  handler->sline.code);
+
           /* This discard may be no-op, but let's preserve the algorithm
              used elsewhere in this function for clarity's sake. */
-          svn_ra_serf__response_discard_handler(request, response, NULL, pool);
+          svn_ra_serf__response_discard_handler(request, response, NULL,
+                                                scratch_pool);
           return err;
         }
     }
 
-  if (handler->conn->last_status_code == 401 && sl.code < 400)
+  if (handler->conn->last_status_code == 401 && handler->sline.code < 400)
     {
       SVN_ERR(svn_auth_save_credentials(handler->session->auth_state,
                                         handler->session->pool));
@@ -1750,14 +1740,20 @@ handle_response(serf_request_t *request,
       handler->session->auth_state = NULL;
     }
 
-  handler->conn->last_status_code = sl.code;
+  handler->conn->last_status_code = handler->sline.code;
 
-  if (sl.code == 405 || sl.code == 409 || sl.code >= 500)
+  if (handler->sline.code == 405
+      || handler->sline.code == 409
+      || handler->sline.code >= 500)
     {
       /* 405 Method Not allowed.
          409 Conflict: can indicate a hook error.
          5xx (Internal) Server error. */
-      SVN_ERR(svn_ra_serf__handle_server_error(request, response, pool));
+      /* ### this is completely wrong. it only catches the current network
+         ### packet. we need ongoing parsing. see SERVER_ERROR down below
+         ### in the process_body: area. we'll eventually move to that.  */
+      SVN_ERR(svn_ra_serf__handle_server_error(request, response,
+                                               scratch_pool));
 
       if (!handler->session->pending_error)
         {
@@ -1765,38 +1761,75 @@ handle_response(serf_request_t *request,
 
           /* 405 == Method Not Allowed (Occurs when trying to lock a working
              copy path which no longer exists at HEAD in the repository. */
-
-          if (sl.code == 405 && !strcmp(handler->method, "LOCK"))
+          if (handler->sline.code == 405
+              && strcmp(handler->method, "LOCK") == 0)
             apr_err = SVN_ERR_FS_OUT_OF_DATE;
 
-          return
-              svn_error_createf(apr_err, NULL,
-                                _("%s request on '%s' failed: %d %s"),
-                                handler->method, handler->path,
-                                sl.code, sl.reason);
+          return svn_error_createf(apr_err, NULL,
+                                   _("%s request on '%s' failed: %d %s"),
+                                   handler->method, handler->path,
+                                   handler->sline.code, handler->sline.reason);
         }
 
       return SVN_NO_ERROR; /* Error is set in caller */
     }
 
+  /* ... and set up the header fields in HANDLER.  */
+  handler->location = svn_ra_serf__response_get_location(
+                          response, handler->handler_pool);
+
   /* Stop processing the above, on every packet arrival.  */
   handler->reading_body = TRUE;
 
-  /* ... and set up the header fields in HANDLER if the caller is
-     interested.  */
-  if (handler->handler_pool != NULL)
+ process_body:
+
+  /* If we are supposed to parse the body as a server_error, then do
+     that now.  */
+  if (handler->server_error != NULL)
     {
-      handler->sline = sl;
-      handler->sline.reason = apr_pstrdup(handler->handler_pool,
-                                          handler->sline.reason);
-      handler->location = svn_ra_serf__response_get_location(
-                              response, handler->handler_pool);
+      err = svn_ra_serf__handle_xml_parser(request, response,
+                                           &handler->server_error->parser,
+                                           scratch_pool);
+
+      /* APR_EOF will be returned when parsing is complete.  If we see
+         any other error, return it immediately.
+
+         In practice the only other error we expect to see is APR_EAGAIN,
+         which indicates the network has no more data right now. This
+         svn_error_t will get unwrapped, and that APR_EAGAIN will be
+         returned to serf. We'll get called later, when more network data
+         is available.  */
+      if (!err || !APR_STATUS_IS_EOF(err->apr_err))
+        return svn_error_trace(err);
+
+      /* Clear the EOF. We don't need it.  */
+      svn_error_clear(err);
+
+      /* If the parsing is done, and we did not extract an error, then
+         simply toss everything, and anything else that might arrive.
+         The higher-level code will need to investigate HANDLER->SLINE,
+         as we have no further information for them.  */
+      if (handler->done
+          && handler->server_error->error->apr_err == APR_SUCCESS)
+        {
+          svn_error_clear(handler->server_error->error);
+
+          /* Stop parsing for a server error.  */
+          handler->server_error = NULL;
+
+          /* If anything arrives after this, then just discard it.  */
+          handler->response_handler = svn_ra_serf__handle_discard_body;
+          handler->response_baton = NULL;
+        }
+
+      *serf_status = APR_EOF;
+      return SVN_NO_ERROR;
     }
 
- process_body:
+  /* Pass the body along to the registered response handler.  */
   err = handler->response_handler(request, response,
                                   handler->response_baton,
-                                  pool);
+                                  scratch_pool);
 
   if (err
       && (!SERF_BUCKET_READ_ERROR(err->apr_err)
@@ -1917,6 +1950,20 @@ svn_ra_serf__request_create(svn_ra_serf_
 {
   SVN_ERR_ASSERT_NO_RETURN(handler->handler_pool != NULL);
 
+  /* In case HANDLER is re-queued, reset the various transient fields.
+
+     ### prior to recent changes, HANDLER was constant. maybe we should
+     ### break out these processing fields, apart from the request
+     ### definition.  */
+  handler->done = FALSE;
+  handler->server_error = NULL;
+  handler->sline.version = 0;
+  handler->location = NULL;
+  handler->reading_body = FALSE;
+
+  /* ### sometimes, we alter the >response_handler. how to reset that?
+     ### so far, that is just to discard the body. maybe a flag?  */
+
   /* ### do we need to hold onto the returned request object, or just
      ### not worry about it (the serf ctx will manage it).  */
   (void) serf_connection_request_create(handler->conn->conn,

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c?rev=1335238&r1=1335237&r2=1335238&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c Mon May  7 20:24:50 2012
@@ -2253,13 +2253,13 @@ svn_wc_get_pristine_contents2(svn_stream
 svn_error_t *
 svn_wc__get_pristine_contents_by_checksum(svn_stream_t **contents,
                                           svn_wc_context_t *wc_ctx,
-                                          const char *wcroot_abspath,
+                                          const char *wri_abspath,
                                           const svn_checksum_t *sha1_checksum,
                                           apr_pool_t *result_pool,
                                           apr_pool_t *scratch_pool)
 {
   return svn_error_trace(svn_wc__db_pristine_read(contents, NULL, wc_ctx->db,
-                                                  wcroot_abspath, sha1_checksum,
+                                                  wri_abspath, sha1_checksum,
                                                   result_pool, scratch_pool));
 }