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 2011/12/19 19:49:43 UTC

svn commit: r1220893 [9/19] - in /subversion/branches/fs-py: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/server-side/mod_dontdothat/ notes/ subversion/bindings/javahl/native/ su...

Modified: subversion/branches/fs-py/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_local/ra_plugin.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_local/ra_plugin.c Mon Dec 19 18:49:34 2011
@@ -220,21 +220,21 @@ reporter_link_path(void *reporter_baton,
                    apr_pool_t *pool)
 {
   reporter_baton_t *rbaton = reporter_baton;
-  const char *fs_path = NULL;
   const char *repos_url = rbaton->sess->repos_url;
+  const char *relpath = svn_uri_skip_ancestor(repos_url, url, pool);
+  const char *fs_path;
 
-  if (!svn_uri__is_ancestor(repos_url, url))
+  if (!relpath)
     return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
                              _("'%s'\n"
                                "is not the same repository as\n"
                                "'%s'"), url, rbaton->sess->repos_url);
 
-  /* Skip the repos_url, but keep the last '/' to create an fspath */
-  fs_path = svn_uri_skip_ancestor(repos_url, url, pool);
-  if (fs_path[0] == '\0')
+  /* Convert the relpath to an fspath */
+  if (relpath[0] == '\0')
     fs_path = "/";
   else
-    fs_path = apr_pstrcat(pool, "/", fs_path, (char *)NULL);
+    fs_path = apr_pstrcat(pool, "/", relpath, (char *)NULL);
 
   return svn_repos_link_path3(rbaton->report_baton, path, fs_path, revision,
                               depth, start_empty, lock_token, pool);
@@ -541,12 +541,10 @@ svn_ra_local__reparent(svn_ra_session_t 
                        apr_pool_t *pool)
 {
   svn_ra_local__session_baton_t *sess = session->priv;
-  const char *relpath = "";
+  const char *relpath = svn_uri_skip_ancestor(sess->repos_url, url, pool);
 
   /* If the new URL isn't the same as our repository root URL, then
      let's ensure that it's some child of it. */
-  if (strcmp(url, sess->repos_url) != 0)
-    relpath = svn_uri__is_child(sess->repos_url, url, pool);
   if (! relpath)
     return svn_error_createf
       (SVN_ERR_RA_ILLEGAL_URL, NULL,

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/commit.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/commit.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/commit.c Mon Dec 19 18:49:34 2011
@@ -87,7 +87,7 @@ typedef struct commit_ctx_t
   apr_hash_t *revprop_table;
 
   /* A hash mapping svn_string_t * paths (those which are valid as
-     target in the MERGE response) to svn_node_kind_t kinds. */
+     target in the MERGE response) to (void*)svn_recurse_kind. */
   apr_hash_t *valid_targets;
 
   /* The (potential) author of this commit. */
@@ -633,22 +633,20 @@ static apr_hash_t *get_child_tokens(apr_
 {
   apr_hash_index_t *hi;
   apr_hash_t *tokens = apr_hash_make(pool);
-  apr_pool_t *subpool = svn_pool_create(pool);
 
   for (hi = apr_hash_first(pool, lock_tokens); hi; hi = apr_hash_next(hi))
     {
       const void *key;
       apr_ssize_t klen;
       void *val;
+      const char *child_relpath;
 
-      svn_pool_clear(subpool);
       apr_hash_this(hi, &key, &klen, &val);
-
-      if (svn_relpath__is_child(dir, key, subpool))
+      child_relpath = svn_relpath_skip_ancestor(dir, key);
+      if (child_relpath && *child_relpath)
         apr_hash_set(tokens, key, klen, val);
     }
 
-  svn_pool_destroy(subpool);
   return tokens;
 }
 
@@ -1572,6 +1570,8 @@ svn_error_t * svn_ra_neon__get_commit_ed
   svn_delta_editor_t *commit_editor;
   commit_ctx_t *cc;
   apr_hash_index_t *hi;
+  svn_delta_shim_callbacks_t *shim_callbacks =
+                                svn_delta_shim_callbacks_default(pool);
 
   /* Build the main commit editor's baton. */
   cc = apr_pcalloc(pool, sizeof(*cc));
@@ -1622,7 +1622,7 @@ svn_error_t * svn_ra_neon__get_commit_ed
   *edit_baton = cc;
 
   SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
-                                   NULL, NULL, NULL, NULL, pool, pool));
+                                   shim_callbacks, pool, pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/fetch.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/fetch.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/fetch.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/fetch.c Mon Dec 19 18:49:34 2011
@@ -1487,7 +1487,7 @@ start_element(int *elem, void *userdata,
       if (DIR_DEPTH(rb) == 0)
         {
           /* pathbuf has to live for the whole edit! */
-          pathbuf = svn_stringbuf_create("", rb->pool);
+          pathbuf = svn_stringbuf_create_empty(rb->pool);
 
           /* During switch operations, we need to invalidate the
              tree's version resource URLs in case something goes
@@ -2544,7 +2544,7 @@ make_reporter(svn_ra_session_t *session,
   rb->edit_baton = edit_baton;
   rb->fetch_content = fetch_content;
   rb->in_resource = FALSE;
-  rb->current_wcprop_path = svn_stringbuf_create("", pool);
+  rb->current_wcprop_path = svn_stringbuf_create_empty(pool);
   rb->is_switch = dst_path != NULL;
   rb->target = target;
   rb->receiving_all = FALSE;
@@ -2553,7 +2553,7 @@ make_reporter(svn_ra_session_t *session,
   rb->whandler_baton = NULL;
   rb->svndiff_decoder = NULL;
   rb->base64_decoder = NULL;
-  rb->cdata_accum = svn_stringbuf_create("", pool);
+  rb->cdata_accum = svn_stringbuf_create_empty(pool);
   rb->send_copyfrom_args = send_copyfrom_args;
   rb->lock_tokens = apr_hash_make(pool);
 

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/file_revs.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/file_revs.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/file_revs.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/file_revs.c Mon Dec 19 18:49:34 2011
@@ -307,7 +307,7 @@ svn_ra_neon__get_file_revs(svn_ra_sessio
                            apr_pool_t *pool)
 {
   svn_ra_neon__session_t *ras = session->priv;
-  svn_stringbuf_t *request_body = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *request_body = svn_stringbuf_create_empty(pool);
   const char *bc_url;
   const char *bc_relative;
   const char *final_bc_url;
@@ -349,7 +349,7 @@ svn_ra_neon__get_file_revs(svn_ra_sessio
   /* Initialize the baton. */
   rb.handler = handler;
   rb.handler_baton = handler_baton;
-  rb.cdata_accum = svn_stringbuf_create("", pool);
+  rb.cdata_accum = svn_stringbuf_create_empty(pool);
   rb.subpool = svn_pool_create(pool);
   reset_file_rev(&rb);
 

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/get_dated_rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/get_dated_rev.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/get_dated_rev.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/get_dated_rev.c Mon Dec 19 18:49:34 2011
@@ -93,7 +93,7 @@ drev_start_element(int *elem, void *bato
     return SVN_NO_ERROR;
 
   if (elm->id == ELEM_version_name)
-    b->cdata = svn_stringbuf_create("", b->pool);
+    b->cdata = svn_stringbuf_create_empty(b->pool);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/get_deleted_rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/get_deleted_rev.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/get_deleted_rev.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/get_deleted_rev.c Mon Dec 19 18:49:34 2011
@@ -89,7 +89,7 @@ drev_start_element(int *elem, void *bato
     return SVN_NO_ERROR;
 
   if (elm->id == ELEM_version_name)
-    b->cdata = svn_stringbuf_create("", b->pool);
+    b->cdata = svn_stringbuf_create_empty(b->pool);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/get_location_segments.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/get_location_segments.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/get_location_segments.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/get_location_segments.c Mon Dec 19 18:49:34 2011
@@ -150,7 +150,7 @@ svn_ra_neon__get_location_segments(svn_r
   apr_pool_t *subpool = svn_pool_create(pool);
 
   /* Build the request body. */
-  request_body = svn_stringbuf_create("", subpool);
+  request_body = svn_stringbuf_create_empty(subpool);
   svn_stringbuf_appendcstr(request_body,
                            "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                            DEBUG_CR "<S:get-location-segments xmlns:S=\""

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/get_locations.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/get_locations.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/get_locations.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/get_locations.c Mon Dec 19 18:49:34 2011
@@ -138,7 +138,7 @@ svn_ra_neon__get_locations(svn_ra_sessio
 
   *locations = apr_hash_make(pool);
 
-  request_body = svn_stringbuf_create("", pool);
+  request_body = svn_stringbuf_create_empty(pool);
   svn_stringbuf_appendcstr(request_body,
                            "<?xml version=\"1.0\" encoding=\"utf-8\"?>" DEBUG_CR
                            "<S:get-locations xmlns:S=\"" SVN_XML_NAMESPACE

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/get_locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/get_locks.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/get_locks.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/get_locks.c Mon Dec 19 18:49:34 2011
@@ -257,13 +257,11 @@ getlocks_end_element(void *userdata, int
       else if ((baton->requested_depth == svn_depth_files) ||
                (baton->requested_depth == svn_depth_immediates))
         {
-          const char *rel_uri = svn_fspath__is_child(baton->path,
-                                                     baton->current_lock->path,
-                                                     baton->scratchpool);
+          const char *rel_uri = svn_fspath__skip_ancestor(
+                                  baton->path, baton->current_lock->path);
           if (rel_uri && (svn_path_component_count(rel_uri) == 1))
             apr_hash_set(baton->lock_hash, baton->current_lock->path,
                          APR_HASH_KEY_STRING, baton->current_lock);
-          svn_pool_clear(baton->scratchpool);
         }
       break;
 
@@ -389,7 +387,7 @@ svn_ra_neon__get_locks(svn_ra_session_t 
   baton.scratchpool = svn_pool_create(pool);
   baton.current_lock = NULL;
   baton.encoding = NULL;
-  baton.cdata_accum = svn_stringbuf_create("", pool);
+  baton.cdata_accum = svn_stringbuf_create_empty(pool);
 
   body = apr_psprintf(pool,
                       "<?xml version=\"1.0\" encoding=\"utf-8\"?>"

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/lock.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/lock.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/lock.c Mon Dec 19 18:49:34 2011
@@ -105,13 +105,13 @@ lock_start_element(int *elem, void *bato
     case ELEM_lock_timeout:
     case ELEM_lock_depth:
     case ELEM_status:
-      b->cdata = svn_stringbuf_create("", b->pool);
+      b->cdata = svn_stringbuf_create_empty(b->pool);
       break;
 
     case ELEM_href:
       if (parent == ELEM_lock_token
           || parent == ELEM_response)
-        b->cdata = svn_stringbuf_create("", b->pool);
+        b->cdata = svn_stringbuf_create_empty(b->pool);
       break;
 
     default:

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/log.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/log.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/log.c Mon Dec 19 18:49:34 2011
@@ -32,6 +32,7 @@
 #include "svn_error.h"
 #include "svn_pools.h"
 #include "svn_path.h"
+#include "svn_base64.h"
 #include "svn_xml.h"
 #include "svn_props.h"
 
@@ -52,6 +53,8 @@ struct log_baton
   */
   svn_stringbuf_t *want_cdata;
   svn_stringbuf_t *cdata;
+  const char *cdata_encoding; /* encoding of CDATA (NULL or "base64") */
+
   /* Allocate log message information.
    * NOTE: this pool may be cleared multiple times as log messages are
    * received.
@@ -162,14 +165,27 @@ log_start_element(int *elem, void *baton
     case ELEM_comment:
       lb->want_cdata = lb->cdata;
       svn_stringbuf_setempty(lb->cdata);
+      lb->cdata_encoding = NULL;
+          
+      /* Some tags might contain encoded CDATA. */
+      if ((elm->id == ELEM_comment) ||
+          (elm->id == ELEM_creator_displayname) ||
+          (elm->id == ELEM_log_date) ||
+          (elm->id == ELEM_rev_prop))
+        {
+          lb->cdata_encoding = svn_xml_get_attr_value("encoding", atts);
+          if (lb->cdata_encoding)
+            lb->cdata_encoding = apr_pstrdup(lb->subpool, lb->cdata_encoding);
+        }
+
+      /* revprop tags have names. */
       if (elm->id == ELEM_revprop)
         {
-          lb->revprop_name = apr_pstrdup(lb->subpool,
-                                         svn_xml_get_attr_value("name",
-                                                                atts));
+          const char *revprop_name = svn_xml_get_attr_value("name", atts);
           if (lb->revprop_name == NULL)
             return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                      _("Missing name attr in revprop element"));
+          lb->revprop_name = apr_pstrdup(lb->subpool, revprop_name);
         }
       break;
     case ELEM_has_children:
@@ -235,6 +251,36 @@ log_start_element(int *elem, void *baton
   return SVN_NO_ERROR;
 }
 
+/*
+ * Set *DECODED_CDATA to a copy of current CDATA being tracked in LB,
+ * decoded as necessary, and allocated from LB->subpool.
+ */
+static svn_error_t *
+maybe_decode_log_cdata(const svn_string_t **decoded_cdata,
+                       struct log_baton *lb)
+{
+  if (lb->cdata_encoding)
+    {
+      svn_string_t in;
+      in.data = lb->cdata->data;
+      in.len = lb->cdata->len;
+
+      /* Check for a known encoding type.  This is easy -- there's
+         only one.  */
+      if (strcmp(lb->cdata_encoding, "base64") != 0)
+        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
+
+      *decoded_cdata = svn_base64_decode_string(&in, lb->subpool);
+    }
+  else
+    {
+      *decoded_cdata = svn_string_create_from_buf(lb->cdata, lb->subpool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+                       
 
 /*
  * This implements the `svn_ra_neon__xml_endelm_cb' prototype.
@@ -244,6 +290,10 @@ log_end_element(void *baton, int state,
                 const char *nspace, const char *name)
 {
   struct log_baton *lb = baton;
+  const svn_string_t *decoded_cdata;
+
+  if (lb->want_cdata)
+    SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, lb));
 
   switch (state)
     {
@@ -256,8 +306,7 @@ log_end_element(void *baton, int state,
           if (! lb->log_entry->revprops)
             lb->log_entry->revprops = apr_hash_make(lb->subpool);
           apr_hash_set(lb->log_entry->revprops, SVN_PROP_REVISION_AUTHOR,
-                       APR_HASH_KEY_STRING,
-                       svn_string_create_from_buf(lb->cdata, lb->subpool));
+                       APR_HASH_KEY_STRING, decoded_cdata);
         }
       break;
     case ELEM_log_date:
@@ -266,8 +315,7 @@ log_end_element(void *baton, int state,
           if (! lb->log_entry->revprops)
             lb->log_entry->revprops = apr_hash_make(lb->subpool);
           apr_hash_set(lb->log_entry->revprops, SVN_PROP_REVISION_DATE,
-                       APR_HASH_KEY_STRING,
-                       svn_string_create_from_buf(lb->cdata, lb->subpool));
+                       APR_HASH_KEY_STRING, decoded_cdata);
         }
       break;
     case ELEM_added_path:
@@ -289,8 +337,7 @@ log_end_element(void *baton, int state,
       if (! lb->log_entry->revprops)
         lb->log_entry->revprops = apr_hash_make(lb->subpool);
       apr_hash_set(lb->log_entry->revprops, lb->revprop_name,
-                   APR_HASH_KEY_STRING,
-                   svn_string_create_from_buf(lb->cdata, lb->subpool));
+                   APR_HASH_KEY_STRING, decoded_cdata);
       break;
     case ELEM_comment:
       if (lb->want_message)
@@ -298,8 +345,7 @@ log_end_element(void *baton, int state,
           if (! lb->log_entry->revprops)
             lb->log_entry->revprops = apr_hash_make(lb->subpool);
           apr_hash_set(lb->log_entry->revprops, SVN_PROP_REVISION_LOG,
-                       APR_HASH_KEY_STRING,
-                       svn_string_create_from_buf(lb->cdata, lb->subpool));
+                       APR_HASH_KEY_STRING, decoded_cdata);
         }
       break;
     case ELEM_log_item:
@@ -365,7 +411,7 @@ svn_error_t * svn_ra_neon__get_log(svn_r
 
   int i;
   svn_ra_neon__session_t *ras = session->priv;
-  svn_stringbuf_t *request_body = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *request_body = svn_stringbuf_create_empty(pool);
   svn_boolean_t want_custom_revprops;
   struct log_baton lb;
   const char *bc_url;
@@ -380,8 +426,8 @@ svn_error_t * svn_ra_neon__get_log(svn_r
      Maybe Greg can explain?  Meanwhile, I'm tentatively using
      "request_*" for my local vars below. */
 
-  static const char log_request_head[]
-    = "<S:log-report xmlns:S=\"" SVN_XML_NAMESPACE "\">" DEBUG_CR;
+  static const char log_request_head[] = "<S:log-report xmlns:S=\""
+    SVN_XML_NAMESPACE "\">" DEBUG_CR "<S:encode-binary-props/>";
 
   static const char log_request_tail[] = "</S:log-report>" DEBUG_CR;
 
@@ -404,23 +450,17 @@ svn_error_t * svn_ra_neon__get_log(svn_r
 
   if (discover_changed_paths)
     {
-      svn_stringbuf_appendcstr(request_body,
-                               apr_psprintf(pool,
-                                            "<S:discover-changed-paths/>"));
+      svn_stringbuf_appendcstr(request_body, "<S:discover-changed-paths/>");
     }
 
   if (strict_node_history)
     {
-      svn_stringbuf_appendcstr(request_body,
-                               apr_psprintf(pool,
-                                            "<S:strict-node-history/>"));
+      svn_stringbuf_appendcstr(request_body, "<S:strict-node-history/>");
     }
 
   if (include_merged_revisions)
     {
-      svn_stringbuf_appendcstr(request_body,
-                               apr_psprintf(pool,
-                                            "<S:include-merged-revisions/>"));
+      svn_stringbuf_appendcstr(request_body, "<S:include-merged-revisions/>");
     }
 
   if (revprops)
@@ -449,9 +489,7 @@ svn_error_t * svn_ra_neon__get_log(svn_r
     }
   else
     {
-      svn_stringbuf_appendcstr(request_body,
-                               apr_psprintf(pool,
-                                            "<S:all-revprops/>"));
+      svn_stringbuf_appendcstr(request_body, "<S:all-revprops/>");
       lb.want_author = lb.want_date = lb.want_message = TRUE;
       want_custom_revprops = TRUE;
     }
@@ -491,9 +529,10 @@ svn_error_t * svn_ra_neon__get_log(svn_r
   lb.count = 0;
   lb.nest_level = 0;
   lb.limit_compat_bailout = FALSE;
-  lb.cdata = svn_stringbuf_create("", pool);
+  lb.cdata = svn_stringbuf_create_empty(pool);
   lb.log_entry = svn_log_entry_create(pool);
   lb.want_cdata = NULL;
+  lb.cdata_encoding = NULL;
   reset_log_item(&lb);
 
   /* ras's URL may not exist in HEAD, and thus it's not safe to send

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/merge.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/merge.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/merge.c Mon Dec 19 18:49:34 2011
@@ -259,7 +259,7 @@ static svn_error_t * handle_resource(mer
     }
 
   /* a collection or regular resource */
-  if (! svn_urlpath__is_ancestor(mc->base_href, mc->href->data))
+  if (! svn_urlpath__skip_ancestor(mc->base_href, mc->href->data))
     {
       /* ### need something better than APR_EGENERAL */
       return svn_error_createf(APR_EGENERAL, NULL,
@@ -269,9 +269,7 @@ static svn_error_t * handle_resource(mer
     }
 
   /* given HREF of the form: BASE "/" RELATIVE, extract the relative portion */
-  relative = svn_urlpath__is_child(mc->base_href, mc->href->data, NULL);
-  if (! relative) /* the paths are equal */
-    relative = "";
+  relative = svn_urlpath__skip_ancestor(mc->base_href, mc->href->data);
 
   /* bump the resource */
   relative = svn_path_uri_decode(relative, pool);
@@ -704,9 +702,9 @@ svn_error_t * svn_ra_neon__merge_activit
   merge_ctx_t mc = { 0 };
   const char *body;
   apr_hash_t *extra_headers = NULL;
-  svn_stringbuf_t *lockbuf = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *lockbuf = svn_stringbuf_create_empty(pool);
 
-  mc.cdata = svn_stringbuf_create("", pool);
+  mc.cdata = svn_stringbuf_create_empty(pool);
   mc.pool = pool;
   mc.scratchpool = svn_pool_create(pool);
   mc.base_href = repos_url;

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/mergeinfo.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/mergeinfo.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/mergeinfo.c Mon Dec 19 18:49:34 2011
@@ -167,7 +167,7 @@ svn_ra_neon__get_mergeinfo(svn_ra_sessio
                            apr_pool_t *pool)
 {
   svn_ra_neon__session_t *ras = session->priv;
-  svn_stringbuf_t *request_body = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *request_body = svn_stringbuf_create_empty(pool);
   struct mergeinfo_baton mb;
   const char *bc_url;
   const char *bc_relative;
@@ -221,8 +221,8 @@ svn_ra_neon__get_mergeinfo(svn_ra_sessio
   svn_stringbuf_appendcstr(request_body, minfo_report_tail);
 
   mb.pool = pool;
-  mb.curr_path = svn_stringbuf_create("", pool);
-  mb.curr_info = svn_stringbuf_create("", pool);
+  mb.curr_path = svn_stringbuf_create_empty(pool);
+  mb.curr_info = svn_stringbuf_create_empty(pool);
   mb.catalog = apr_hash_make(pool);
   mb.err = SVN_NO_ERROR;
 

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/options.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/options.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/options.c Mon Dec 19 18:49:34 2011
@@ -288,7 +288,7 @@ svn_ra_neon__exchange_capabilities(svn_r
   int status_code;
 
   oc.pool = pool;
-  oc.cdata = svn_stringbuf_create("", pool);
+  oc.cdata = svn_stringbuf_create_empty(pool);
 
   if (youngest_rev)
     *youngest_rev = SVN_INVALID_REVNUM;

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/props.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/props.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/props.c Mon Dec 19 18:49:34 2011
@@ -547,7 +547,7 @@ svn_error_t * svn_ra_neon__get_props(apr
   pc.pool = pool;
   pc.propbuffer = apr_hash_make(pool);
   pc.props = apr_hash_make(pool);
-  pc.cdata = svn_stringbuf_create("", pool);
+  pc.cdata = svn_stringbuf_create_empty(pool);
 
   /* Create and dispatch the request! */
   SVN_ERR(svn_ra_neon__parsed_request(sess, "PROPFIND", url,

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/replay.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/replay.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/replay.c Mon Dec 19 18:49:34 2011
@@ -345,7 +345,7 @@ start_element(int *elem, void *baton, in
             if (svn_xml_get_attr_value("del", atts))
               rb->prop_accum = NULL;
             else
-              rb->prop_accum = svn_stringbuf_create("", rb->prop_pool);
+              rb->prop_accum = svn_stringbuf_create_empty(rb->prop_pool);
 
             rb->prop_name = apr_pstrdup(rb->prop_pool, name);
           }
@@ -479,7 +479,7 @@ svn_ra_neon__replay(svn_ra_session_t *se
   rb.pool = pool;
   rb.dirs = apr_array_make(pool, 5, sizeof(dir_item_t));
   rb.prop_pool = svn_pool_create(pool);
-  rb.prop_accum = svn_stringbuf_create("", rb.prop_pool);
+  rb.prop_accum = svn_stringbuf_create_empty(rb.prop_pool);
 
   return svn_ra_neon__parsed_request(ras, "REPORT", ras->url->data, body,
                                      NULL, NULL,

Modified: subversion/branches/fs-py/subversion/libsvn_ra_neon/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/util.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/util.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/util.c Mon Dec 19 18:49:34 2011
@@ -313,12 +313,12 @@ multistatus_parser_create(svn_ra_neon__r
                                  start_207_element,
                                  svn_ra_neon__xml_collect_cdata,
                                  end_207_element, b);
-  b->cdata = svn_stringbuf_create("", req->pool);
-  b->description = svn_stringbuf_create("", req->pool);
+  b->cdata = svn_stringbuf_create_empty(req->pool);
+  b->description = svn_stringbuf_create_empty(req->pool);
   b->req = req;
 
-  b->propname = svn_stringbuf_create("", req->pool);
-  b->propstat_description = svn_stringbuf_create("", req->pool);
+  b->propname = svn_stringbuf_create_empty(req->pool);
+  b->propstat_description = svn_stringbuf_create_empty(req->pool);
 }
 
 
@@ -895,7 +895,7 @@ error_parser_create(svn_ra_neon__request
   b->tmp_err = NULL;
 
   b->want_cdata = NULL;
-  b->cdata = svn_stringbuf_create("", req->pool);
+  b->cdata = svn_stringbuf_create_empty(req->pool);
 
   /* attach a standard <D:error> body parser to the request */
   error_parser = xml_parser_create(req);

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/blame.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/blame.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/blame.c Mon Dec 19 18:49:34 2011
@@ -54,7 +54,7 @@ typedef enum blame_state_e {
   SET_PROP,
   REMOVE_PROP,
   MERGED_REVISION,
-  TXDELTA,
+  TXDELTA
 } blame_state_e;
 
 typedef struct blame_info_t {
@@ -151,7 +151,7 @@ create_propval(blame_info_t *info)
 
   if (!info->prop_attr)
     {
-      return svn_string_create("", info->pool);
+      return svn_string_create_empty(info->pool);
     }
   else
     {

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/commit.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/commit.c Mon Dec 19 18:49:34 2011
@@ -527,9 +527,8 @@ checkout_file(file_context_t *file)
           file->checkout->activity_url = file->commit->activity_url;
           file->checkout->resource_url =
             svn_path_url_add_component2(parent_dir->checkout->resource_url,
-                                        svn_relpath__is_child(parent_dir->relpath,
-                                                              file->relpath,
-                                                              file->pool),
+                                        svn_relpath_skip_ancestor(
+                                          parent_dir->relpath, file->relpath),
                                         file->pool);
           return SVN_NO_ERROR;
         }
@@ -1800,7 +1799,7 @@ change_dir_prop(void *dir_baton,
     }
   else
     {
-      value = svn_string_create("", dir->pool);
+      value = svn_string_create_empty(dir->pool);
       svn_ra_serf__set_prop(dir->removed_props, proppatch_target,
                             ns, name, value, dir->pool);
     }
@@ -2048,7 +2047,7 @@ change_file_prop(void *file_baton,
     }
   else
     {
-      value = svn_string_create("", file->pool);
+      value = svn_string_create_empty(file->pool);
 
       svn_ra_serf__set_prop(file->removed_props, file->url,
                             ns, name, value, file->pool);
@@ -2320,6 +2319,8 @@ svn_ra_serf__get_commit_editor(svn_ra_se
   svn_delta_editor_t *editor;
   commit_context_t *ctx;
   apr_hash_index_t *hi;
+  svn_delta_shim_callbacks_t *shim_callbacks =
+                                    svn_delta_shim_callbacks_default(pool);
 
   ctx = apr_pcalloc(pool, sizeof(*ctx));
 
@@ -2367,8 +2368,7 @@ svn_ra_serf__get_commit_editor(svn_ra_se
   *edit_baton = ctx;
 
   SVN_ERR(svn_editor__insert_shims(ret_editor, edit_baton, *ret_editor,
-                                   *edit_baton, NULL, NULL, NULL, NULL,
-                                   pool, pool));
+                                   *edit_baton, shim_callbacks, pool, pool));
 
   return SVN_NO_ERROR;
 }
@@ -2462,7 +2462,7 @@ svn_ra_serf__change_rev_prop(svn_ra_sess
     }
   else if (old_value_p)
     {
-      svn_string_t *dummy_value = svn_string_create("", proppatch_ctx->pool);
+      svn_string_t *dummy_value = svn_string_create_empty(proppatch_ctx->pool);
 
       svn_ra_serf__set_prop(proppatch_ctx->previous_removed_props,
                             proppatch_ctx->path,
@@ -2476,7 +2476,7 @@ svn_ra_serf__change_rev_prop(svn_ra_sess
     }
   else
     {
-      value = svn_string_create("", proppatch_ctx->pool);
+      value = svn_string_create_empty(proppatch_ctx->pool);
 
       svn_ra_serf__set_prop(proppatch_ctx->removed_props, proppatch_ctx->path,
                             ns, name, value, proppatch_ctx->pool);

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/get_deleted_rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/get_deleted_rev.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/get_deleted_rev.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/get_deleted_rev.c Mon Dec 19 18:49:34 2011
@@ -37,7 +37,7 @@
  */
 typedef enum drev_state_e {
   NONE = 0,
-  VERSION_NAME,
+  VERSION_NAME
 } drev_state_e;
 
 typedef struct drev_context_t {

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/getdate.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/getdate.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/getdate.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/getdate.c Mon Dec 19 18:49:34 2011
@@ -48,7 +48,7 @@
  */
 typedef enum date_state_e {
   NONE = 0,
-  VERSION_NAME,
+  VERSION_NAME
 } date_state_e;
 
 typedef struct date_info_t {

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/getlocations.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/getlocations.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/getlocations.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/getlocations.c Mon Dec 19 18:49:34 2011
@@ -43,7 +43,7 @@
  */
 typedef enum loc_state_e {
   REPORT,
-  LOCATION,
+  LOCATION
 } loc_state_e;
 
 typedef struct loc_state_list_t {

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/getlocks.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/getlocks.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/getlocks.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/getlocks.c Mon Dec 19 18:49:34 2011
@@ -55,7 +55,7 @@ typedef enum lock_state_e {
   OWNER,
   COMMENT,
   CREATION_DATE,
-  EXPIRATION_DATE,
+  EXPIRATION_DATE
 } lock_state_e;
 
 typedef struct lock_info_t {
@@ -200,9 +200,8 @@ end_getlocks(svn_ra_serf__xml_parser_t *
       else if ((lock_ctx->requested_depth == svn_depth_files) ||
                (lock_ctx->requested_depth == svn_depth_immediates))
         {
-          const char *rel_path = svn_fspath__is_child(lock_ctx->path,
-                                                      info->lock->path,
-                                                      info->pool);
+          const char *rel_path = svn_fspath__skip_ancestor(lock_ctx->path,
+                                                           info->lock->path);
           if (rel_path && (svn_path_component_count(rel_path) == 1))
             apr_hash_set(lock_ctx->hash, info->lock->path,
                          APR_HASH_KEY_STRING, info->lock);

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/locks.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/locks.c Mon Dec 19 18:49:34 2011
@@ -55,7 +55,7 @@ typedef enum lock_state_e {
   DEPTH,
   TIMEOUT,
   LOCK_TOKEN,
-  COMMENT,
+  COMMENT
 } lock_state_e;
 
 typedef struct lock_prop_info_t {

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/log.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/log.c Mon Dec 19 18:49:34 2011
@@ -32,6 +32,7 @@
 #include "svn_pools.h"
 #include "svn_ra.h"
 #include "svn_dav.h"
+#include "svn_base64.h"
 #include "svn_xml.h"
 #include "svn_config.h"
 #include "svn_path.h"
@@ -61,15 +62,18 @@ typedef enum log_state_e {
   REPLACED_PATH,
   DELETED_PATH,
   MODIFIED_PATH,
-  SUBTRACTIVE_MERGE,
+  SUBTRACTIVE_MERGE
 } log_state_e;
 
 typedef struct log_info_t {
   apr_pool_t *pool;
 
-  /* The currently collected value as we build it up */
+  /* The currently collected value as we build it up, and its wire
+   * encoding (if any).
+   */
   const char *tmp;
   apr_size_t tmp_len;
+  const char *tmp_encoding;
 
   /* Temporary change path - ultimately inserted into changed_paths hash. */
   svn_log_changed_path2_t *tmp_path;
@@ -114,7 +118,8 @@ typedef struct log_context_t {
 static log_info_t *
 push_state(svn_ra_serf__xml_parser_t *parser,
            log_context_t *log_ctx,
-           log_state_e state)
+           log_state_e state,
+           const char **attrs)
 {
   svn_ra_serf__xml_push_state(parser, state);
 
@@ -152,6 +157,10 @@ push_state(svn_ra_serf__xml_parser_t *pa
     {
       log_info_t *info = parser->state->private;
 
+      info->tmp_encoding = svn_xml_get_attr_value("encoding", attrs);
+      if (info->tmp_encoding)
+        info->tmp_encoding = apr_pstrdup(info->pool, info->tmp_encoding);
+
       if (!info->log_entry->revprops)
         {
           info->log_entry->revprops = apr_hash_make(info->pool);
@@ -192,12 +201,12 @@ start_log(svn_ra_serf__xml_parser_t *par
   if (state == NONE &&
       strcmp(name.name, "log-report") == 0)
     {
-      push_state(parser, log_ctx, REPORT);
+      push_state(parser, log_ctx, REPORT, attrs);
     }
   else if (state == REPORT &&
            strcmp(name.name, "log-item") == 0)
     {
-      push_state(parser, log_ctx, ITEM);
+      push_state(parser, log_ctx, ITEM, attrs);
     }
   else if (state == ITEM)
     {
@@ -205,44 +214,43 @@ start_log(svn_ra_serf__xml_parser_t *par
 
       if (strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
         {
-          push_state(parser, log_ctx, VERSION);
+          push_state(parser, log_ctx, VERSION, attrs);
         }
       else if (strcmp(name.name, "creator-displayname") == 0)
         {
-          push_state(parser, log_ctx, CREATOR);
+          info = push_state(parser, log_ctx, CREATOR, attrs);
         }
       else if (strcmp(name.name, "date") == 0)
         {
-          push_state(parser, log_ctx, DATE);
+          info = push_state(parser, log_ctx, DATE, attrs);
         }
       else if (strcmp(name.name, "comment") == 0)
         {
-          push_state(parser, log_ctx, COMMENT);
+          info = push_state(parser, log_ctx, COMMENT, attrs);
         }
       else if (strcmp(name.name, "revprop") == 0)
         {
-          const char *revprop_name;
-          info = push_state(parser, log_ctx, REVPROP);
-          revprop_name = svn_xml_get_attr_value("name", attrs);
+          const char *revprop_name =
+            svn_xml_get_attr_value("name", attrs);
           if (revprop_name == NULL)
             return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                      _("Missing name attr in revprop element"));
-
+          info = push_state(parser, log_ctx, REVPROP, attrs);
           info->revprop_name = apr_pstrdup(info->pool, revprop_name);
         }
       else if (strcmp(name.name, "has-children") == 0)
         {
-          push_state(parser, log_ctx, HAS_CHILDREN);
+          push_state(parser, log_ctx, HAS_CHILDREN, attrs);
         }
       else if (strcmp(name.name, "subtractive-merge") == 0)
         {
-          push_state(parser, log_ctx, SUBTRACTIVE_MERGE);
+          push_state(parser, log_ctx, SUBTRACTIVE_MERGE, attrs);
         }
       else if (strcmp(name.name, "added-path") == 0)
         {
           const char *copy_path, *copy_rev_str;
 
-          info = push_state(parser, log_ctx, ADDED_PATH);
+          info = push_state(parser, log_ctx, ADDED_PATH, attrs);
           info->tmp_path->action = 'A';
 
           copy_path = svn_xml_get_attr_value("copyfrom-path", attrs);
@@ -266,7 +274,7 @@ start_log(svn_ra_serf__xml_parser_t *par
         {
           const char *copy_path, *copy_rev_str;
 
-          info = push_state(parser, log_ctx, REPLACED_PATH);
+          info = push_state(parser, log_ctx, REPLACED_PATH, attrs);
           info->tmp_path->action = 'R';
 
           copy_path = svn_xml_get_attr_value("copyfrom-path", attrs);
@@ -288,14 +296,14 @@ start_log(svn_ra_serf__xml_parser_t *par
         }
       else if (strcmp(name.name, "deleted-path") == 0)
         {
-          info = push_state(parser, log_ctx, DELETED_PATH);
+          info = push_state(parser, log_ctx, DELETED_PATH, attrs);
           info->tmp_path->action = 'D';
 
           SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
         }
       else if (strcmp(name.name, "modified-path") == 0)
         {
-          info = push_state(parser, log_ctx, MODIFIED_PATH);
+          info = push_state(parser, log_ctx, MODIFIED_PATH, attrs);
           info->tmp_path->action = 'M';
 
           SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
@@ -305,6 +313,39 @@ start_log(svn_ra_serf__xml_parser_t *par
   return SVN_NO_ERROR;
 }
 
+/*
+ * Set *DECODED_CDATA to a copy of current CDATA being tracked in INFO,
+ * decoded as necessary, and allocated from INFO->pool..
+ */
+static svn_error_t *
+maybe_decode_log_cdata(const svn_string_t **decoded_cdata,
+                       log_info_t *info)
+{
+  if (info->tmp_encoding)
+    {
+      svn_string_t in;
+      in.data = info->tmp;
+      in.len = info->tmp_len;
+
+      /* Check for a known encoding type.  This is easy -- there's
+         only one.  */
+      if (strcmp(info->tmp_encoding, "base64") != 0)
+        {
+          return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+                                   _("Unsupported encoding '%s'"),
+                                   info->tmp_encoding);
+        }
+
+      *decoded_cdata = svn_base64_decode_string(&in, info->pool);
+    }
+  else
+    {
+      *decoded_cdata = svn_string_ncreate(info->tmp, info->tmp_len,
+                                          info->pool);
+    }
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 end_log(svn_ra_serf__xml_parser_t *parser,
         void *userData,
@@ -361,10 +402,10 @@ end_log(svn_ra_serf__xml_parser_t *parse
     {
       if (log_ctx->want_author)
         {
+          const svn_string_t *decoded_cdata;
+          SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
           apr_hash_set(info->log_entry->revprops, SVN_PROP_REVISION_AUTHOR,
-                       APR_HASH_KEY_STRING,
-                       svn_string_ncreate(info->tmp, info->tmp_len,
-                                          info->pool));
+                       APR_HASH_KEY_STRING, decoded_cdata);
         }
       info->tmp_len = 0;
       svn_ra_serf__xml_pop_state(parser);
@@ -374,10 +415,10 @@ end_log(svn_ra_serf__xml_parser_t *parse
     {
       if (log_ctx->want_date)
         {
+          const svn_string_t *decoded_cdata;
+          SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
           apr_hash_set(info->log_entry->revprops, SVN_PROP_REVISION_DATE,
-                       APR_HASH_KEY_STRING,
-                       svn_string_ncreate(info->tmp, info->tmp_len,
-                                          info->pool));
+                       APR_HASH_KEY_STRING, decoded_cdata);
         }
       info->tmp_len = 0;
       svn_ra_serf__xml_pop_state(parser);
@@ -387,19 +428,20 @@ end_log(svn_ra_serf__xml_parser_t *parse
     {
       if (log_ctx->want_message)
         {
+          const svn_string_t *decoded_cdata;
+          SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
           apr_hash_set(info->log_entry->revprops, SVN_PROP_REVISION_LOG,
-                       APR_HASH_KEY_STRING,
-                       svn_string_ncreate(info->tmp, info->tmp_len,
-                                          info->pool));
+                       APR_HASH_KEY_STRING, decoded_cdata);
         }
       info->tmp_len = 0;
       svn_ra_serf__xml_pop_state(parser);
     }
   else if (state == REVPROP)
     {
+      const svn_string_t *decoded_cdata;
+      SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
       apr_hash_set(info->log_entry->revprops, info->revprop_name,
-                   APR_HASH_KEY_STRING,
-                   svn_string_ncreate(info->tmp, info->tmp_len, info->pool));
+                   APR_HASH_KEY_STRING, decoded_cdata);
       info->tmp_len = 0;
       svn_ra_serf__xml_pop_state(parser);
     }
@@ -562,6 +604,10 @@ create_log_body(serf_bucket_t **body_bkt
         }
     }
 
+  svn_ra_serf__add_tag_buckets(buckets,
+                               "S:encode-binary-props", NULL,
+                               alloc);
+
   svn_ra_serf__add_close_tag_buckets(buckets, alloc,
                                      "S:log-report");
 

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/merge.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/merge.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/merge.c Mon Dec 19 18:49:34 2011
@@ -60,14 +60,14 @@ typedef enum merge_state_e {
   DATE,
   IGNORE_PROP_NAME,
   NEED_PROP_NAME,
-  PROP_VAL,
+  PROP_VAL
 } merge_state_e;
 
 typedef enum resource_type_e {
   UNSET,
   BASELINE,
   COLLECTION,
-  CHECKED_IN,
+  CHECKED_IN
 } resource_type_e;
 
 typedef struct merge_info_t {
@@ -292,7 +292,7 @@ end_merge(svn_ra_serf__xml_parser_t *par
           const char *href;
 
           href = apr_hash_get(info->props, "href", APR_HASH_KEY_STRING);
-          if (! svn_urlpath__is_ancestor(ctx->merge_url, href))
+          if (! svn_urlpath__skip_ancestor(ctx->merge_url, href))
             {
               return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                                        _("A MERGE response for '%s' is not "
@@ -311,11 +311,9 @@ end_merge(svn_ra_serf__xml_parser_t *par
 
               /* From the above check, we know that CTX->MERGE_URL is
                  an ancestor of HREF.  All that remains is to
-                 determine of HREF is the same as CTX->MERGE_URL, or --
-                 if not -- is relative value as a child thereof. */
-              href = svn_urlpath__is_child(ctx->merge_url, href, NULL);
-              if (! href)
-                href = "";
+                 determine if HREF is the same as CTX->MERGE_URL, or --
+                 if not -- its relative value as a child thereof. */
+              href = svn_urlpath__skip_ancestor(ctx->merge_url, href);
 
               checked_in = apr_hash_get(info->props, "checked-in",
                                         APR_HASH_KEY_STRING);
@@ -447,7 +445,7 @@ svn_ra_serf__merge_lock_token_list(apr_h
       path.data = key;
       path.len = klen;
 
-      if (parent && !svn_relpath__is_ancestor(parent, key))
+      if (parent && !svn_relpath_skip_ancestor(parent, key))
         continue;
 
       svn_ra_serf__add_open_tag_buckets(body, alloc, "S:lock", NULL);

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/mergeinfo.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/mergeinfo.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/mergeinfo.c Mon Dec 19 18:49:34 2011
@@ -256,8 +256,8 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
 
   mergeinfo_ctx = apr_pcalloc(pool, sizeof(*mergeinfo_ctx));
   mergeinfo_ctx->pool = pool;
-  mergeinfo_ctx->curr_path = svn_stringbuf_create("", pool);
-  mergeinfo_ctx->curr_info = svn_stringbuf_create("", pool);
+  mergeinfo_ctx->curr_path = svn_stringbuf_create_empty(pool);
+  mergeinfo_ctx->curr_info = svn_stringbuf_create_empty(pool);
   mergeinfo_ctx->done = FALSE;
   mergeinfo_ctx->result_catalog = apr_hash_make(pool);
   mergeinfo_ctx->paths = paths;

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/options.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/options.c Mon Dec 19 18:49:34 2011
@@ -51,7 +51,7 @@
 typedef enum options_state_e {
   OPTIONS,
   ACTIVITY_COLLECTION,
-  HREF,
+  HREF
 } options_state_e;
 
 typedef struct options_state_list_t {

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/property.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/property.c Mon Dec 19 18:49:34 2011
@@ -43,7 +43,7 @@ typedef enum prop_state_e {
   NONE = 0,
   RESPONSE,
   PROP,
-  PROPVAL,
+  PROPVAL
 } prop_state_e;
 
 typedef struct prop_info_t {

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/replay.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/replay.c Mon Dec 19 18:49:34 2011
@@ -55,7 +55,7 @@ typedef enum replay_state_e {
   ADD_FILE,
   DELETE_ENTRY,
   APPLY_TEXTDELTA,
-  CHANGE_PROP,
+  CHANGE_PROP
 } replay_state_e;
 
 typedef struct replay_info_t replay_info_t;

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/update.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/update.c Mon Dec 19 18:49:34 2011
@@ -68,7 +68,7 @@ typedef enum report_state_e {
     ADD_FILE,
     PROP,
     IGNORE_PROP_NAME,
-    NEED_PROP_NAME,
+    NEED_PROP_NAME
 } report_state_e;
 
 

Modified: subversion/branches/fs-py/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/util.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/util.c Mon Dec 19 18:49:34 2011
@@ -914,7 +914,7 @@ svn_ra_serf__handle_discard_body(serf_re
               server_err->error = svn_error_create(APR_SUCCESS, NULL, NULL);
               server_err->has_xml_response = TRUE;
               server_err->contains_precondition_error = FALSE;
-              server_err->cdata = svn_stringbuf_create("", pool);
+              server_err->cdata = svn_stringbuf_create_empty(pool);
               server_err->collect_cdata = FALSE;
               server_err->parser.pool = server_err->error->pool;
               server_err->parser.user_data = server_err;
@@ -1182,7 +1182,7 @@ svn_ra_serf__handle_multistatus_only(ser
           server_err->error = svn_error_create(APR_SUCCESS, NULL, NULL);
           server_err->has_xml_response = TRUE;
           server_err->contains_precondition_error = FALSE;
-          server_err->cdata = svn_stringbuf_create("", server_err->error->pool);
+          server_err->cdata = svn_stringbuf_create_empty(server_err->error->pool);
           server_err->collect_cdata = FALSE;
           server_err->parser.pool = server_err->error->pool;
           server_err->parser.user_data = server_err;
@@ -2408,15 +2408,8 @@ svn_ra_serf__get_relative_path(const cha
 
   decoded_root = svn_path_uri_decode(session->repos_root.path, pool);
   decoded_orig = svn_path_uri_decode(orig_path, pool);
-  if (strcmp(decoded_root, decoded_orig) == 0)
-    {
-      *rel_path = "";
-    }
-  else
-    {
-      *rel_path = svn_urlpath__is_child(decoded_root, decoded_orig, pool);
-      SVN_ERR_ASSERT(*rel_path != NULL);
-    }
+  *rel_path = svn_urlpath__skip_ancestor(decoded_root, decoded_orig);
+  SVN_ERR_ASSERT(*rel_path != NULL);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/fs-py/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_svn/client.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_svn/client.c Mon Dec 19 18:49:34 2011
@@ -1166,15 +1166,12 @@ static svn_error_t *ra_svn_get_dir(svn_r
 static svn_tristate_t
 optbool_to_tristate(apr_uint64_t v)
 {
-  switch (v)
-  {
-    case TRUE:
-      return svn_tristate_true;
-    case FALSE:
-      return svn_tristate_false;
-    default: /* Contains SVN_RA_SVN_UNSPECIFIED_NUMBER */
-      return svn_tristate_unknown;
-  }
+  if (v == TRUE)
+    return svn_tristate_true;
+  if (v == FALSE)
+    return svn_tristate_false;
+
+  return svn_tristate_unknown; /* Contains SVN_RA_SVN_UNSPECIFIED_NUMBER */
 }
 
 /* If REVISION is SVN_INVALID_REVNUM, no value is sent to the
@@ -2340,7 +2337,7 @@ static svn_error_t *ra_svn_get_locks(svn
         }
       else if ((depth == svn_depth_files) || (depth == svn_depth_immediates))
         {
-          const char *relpath = svn_fspath__is_child(abs_path, lock->path, pool);
+          const char *relpath = svn_fspath__skip_ancestor(abs_path, lock->path);
           if (relpath && (svn_path_component_count(relpath) == 1))
             apr_hash_set(*locks, lock->path, APR_HASH_KEY_STRING, lock);
         }

Modified: subversion/branches/fs-py/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_svn/editorp.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_svn/editorp.c Mon Dec 19 18:49:34 2011
@@ -408,6 +408,8 @@ void svn_ra_svn_get_editor(const svn_del
 {
   svn_delta_editor_t *ra_svn_editor = svn_delta_default_editor(pool);
   ra_svn_edit_baton_t *eb;
+  svn_delta_shim_callbacks_t *shim_callbacks =
+                                    svn_delta_shim_callbacks_default(pool);
 
   eb = apr_palloc(pool, sizeof(*eb));
   eb->conn = conn;
@@ -437,8 +439,8 @@ void svn_ra_svn_get_editor(const svn_del
   *edit_baton = eb;
 
   svn_error_clear(svn_editor__insert_shims(editor, edit_baton, *editor,
-                                           *edit_baton, NULL, NULL,
-                                           NULL, NULL, pool, pool));
+                                           *edit_baton, shim_callbacks,
+                                           pool, pool));
 }
 
 /* --- DRIVING AN EDITOR --- */

Modified: subversion/branches/fs-py/subversion/libsvn_repos/authz.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_repos/authz.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_repos/authz.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_repos/authz.c Mon Dec 19 18:49:34 2011
@@ -785,6 +785,9 @@ svn_repos_authz_check_access(svn_authz_t
 {
   const char *current_path;
 
+  if (!repos_name)
+    repos_name = "";
+
   /* If PATH is NULL, check if the user has *any* access. */
   if (!path)
     {

Modified: subversion/branches/fs-py/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_repos/commit.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_repos/commit.c Mon Dec 19 18:49:34 2011
@@ -782,6 +782,86 @@ abort_edit(void *edit_baton,
 }
 
 
+static svn_error_t *
+prop_fetch_func(apr_hash_t **props,
+                void *baton,
+                const char *path,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
+{
+  struct edit_baton *eb = baton;
+  svn_fs_root_t *fs_root;
+  svn_error_t *err;
+
+  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs,
+                               svn_fs_txn_base_revision(eb->txn),
+                               scratch_pool));
+  err = svn_fs_node_proplist(props, fs_root, path, result_pool);
+  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
+    {
+      svn_error_clear(err);
+      *props = apr_hash_make(result_pool);
+      return SVN_NO_ERROR;
+    }
+  else if (err)
+    return svn_error_trace(err);
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+kind_fetch_func(svn_kind_t *kind,
+                void *baton,
+                const char *path,
+                apr_pool_t *scratch_pool)
+{
+  struct edit_baton *eb = baton;
+  svn_node_kind_t node_kind;
+
+  SVN_ERR(svn_fs_check_path(&node_kind, eb->txn_root, path, scratch_pool));
+  *kind = svn__kind_from_node_kind(node_kind, FALSE);
+
+  return SVN_NO_ERROR;
+} 
+
+static svn_error_t *
+fetch_base_func(const char **filename,
+                void *baton,
+                const char *path,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
+{
+  struct edit_baton *eb = baton;
+  svn_stream_t *contents;
+  svn_stream_t *file_stream;
+  const char *tmp_filename;
+  svn_fs_root_t *fs_root;
+  svn_error_t *err;
+
+  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs,
+                               svn_fs_txn_base_revision(eb->txn),
+                               scratch_pool));
+
+  err = svn_fs_file_contents(&contents, fs_root, path, scratch_pool);
+  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
+    {
+      svn_error_clear(err);
+      *filename = NULL;
+      return SVN_NO_ERROR;
+    }
+  else if (err)
+    return svn_error_trace(err);
+  SVN_ERR(svn_stream_open_unique(&file_stream, &tmp_filename, NULL,
+                                 svn_io_file_del_on_pool_cleanup,
+                                 scratch_pool, scratch_pool));
+  SVN_ERR(svn_stream_copy3(contents, file_stream, NULL, NULL, scratch_pool));
+
+  *filename = apr_pstrdup(result_pool, tmp_filename);
+
+  return SVN_NO_ERROR;
+}
+
+
 
 /*** Public interfaces. ***/
 
@@ -802,6 +882,8 @@ svn_repos_get_commit_editor5(const svn_d
   svn_delta_editor_t *e;
   apr_pool_t *subpool = svn_pool_create(pool);
   struct edit_baton *eb;
+  svn_delta_shim_callbacks_t *shim_callbacks =
+                                    svn_delta_shim_callbacks_default(pool);
 
   /* Do a global authz access lookup.  Users with no write access
      whatsoever to the repository don't get a commit editor. */
@@ -853,8 +935,15 @@ svn_repos_get_commit_editor5(const svn_d
   *edit_baton = eb;
   *editor = e;
 
+  shim_callbacks->fetch_props_func = prop_fetch_func;
+  shim_callbacks->fetch_props_baton = eb;
+  shim_callbacks->fetch_kind_func = kind_fetch_func;
+  shim_callbacks->fetch_kind_baton = eb;
+  shim_callbacks->fetch_base_func = fetch_base_func;
+  shim_callbacks->fetch_base_baton = eb;
+
   SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
-                                   NULL, NULL, NULL, NULL, pool, pool));
+                                   shim_callbacks, pool, pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/fs-py/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_repos/deprecated.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_repos/deprecated.c Mon Dec 19 18:49:34 2011
@@ -715,6 +715,28 @@ svn_repos_verify_fs(svn_repos_t *repos,
 /*** From load.c ***/
 
 svn_error_t *
+svn_repos_load_fs3(svn_repos_t *repos,
+                   svn_stream_t *dumpstream,
+                   enum svn_repos_load_uuid uuid_action,
+                   const char *parent_dir,
+                   svn_boolean_t use_pre_commit_hook,
+                   svn_boolean_t use_post_commit_hook,
+                   svn_boolean_t validate_props,
+                   svn_repos_notify_func_t notify_func,
+                   void *notify_baton,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
+                   apr_pool_t *pool)
+{
+  return svn_repos_load_fs4(repos, dumpstream,
+                            SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
+                            uuid_action, parent_dir,
+                            use_pre_commit_hook, use_post_commit_hook,
+                            validate_props, notify_func, notify_baton,
+                            cancel_func, cancel_baton, pool);
+}
+
+svn_error_t *
 svn_repos_load_fs2(svn_repos_t *repos,
                    svn_stream_t *dumpstream,
                    svn_stream_t *feedback_stream,
@@ -803,6 +825,25 @@ svn_repos_load_fs(svn_repos_t *repos,
 }
 
 svn_error_t *
+svn_repos_get_fs_build_parser3(const svn_repos_parse_fns2_t **callbacks,
+                               void **parse_baton,
+                               svn_repos_t *repos,
+                               svn_boolean_t use_history,
+                               svn_boolean_t validate_props,
+                               enum svn_repos_load_uuid uuid_action,
+                               const char *parent_dir,
+                               svn_repos_notify_func_t notify_func,
+                               void *notify_baton,
+                               apr_pool_t *pool)
+{
+  return svn_repos_get_fs_build_parser4(callbacks, parse_baton, repos,
+                                        SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
+                                        use_history, validate_props,
+                                        uuid_action, parent_dir,
+                                        notify_func, notify_baton, pool);
+}
+
+svn_error_t *
 svn_repos_get_fs_build_parser2(const svn_repos_parse_fns2_t **parser,
                                void **parse_baton,
                                svn_repos_t *repos,

Modified: subversion/branches/fs-py/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_repos/dump.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_repos/dump.c Mon Dec 19 18:49:34 2011
@@ -849,6 +849,37 @@ change_dir_prop(void *parent_baton,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+fetch_base_func(const char **filename,
+                void *baton,
+                const char *path,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
+{
+  struct edit_baton *eb = baton;
+  svn_stream_t *contents;
+  svn_stream_t *file_stream;
+  const char *tmp_filename;
+  svn_error_t *err;
+
+  err = svn_fs_file_contents(&contents, eb->fs_root, path, scratch_pool);
+  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
+    {
+      svn_error_clear(err);
+      *filename = NULL;
+      return SVN_NO_ERROR;
+    }
+  else if (err)
+    return svn_error_trace(err);
+  SVN_ERR(svn_stream_open_unique(&file_stream, &tmp_filename, NULL,
+                                 svn_io_file_del_on_pool_cleanup,
+                                 scratch_pool, scratch_pool));
+  SVN_ERR(svn_stream_copy3(contents, file_stream, NULL, NULL, scratch_pool));
+
+  *filename = apr_pstrdup(result_pool, tmp_filename);
+
+  return SVN_NO_ERROR;
+}
 
 
 static svn_error_t *
@@ -870,6 +901,8 @@ get_dump_editor(const svn_delta_editor_t
      root baton. */
   struct edit_baton *eb = apr_pcalloc(pool, sizeof(*eb));
   svn_delta_editor_t *dump_editor = svn_delta_default_editor(pool);
+  svn_delta_shim_callbacks_t *shim_callbacks =
+                                svn_delta_shim_callbacks_default(pool);
 
   /* Set up the edit baton. */
   eb->stream = stream;
@@ -896,8 +929,11 @@ get_dump_editor(const svn_delta_editor_t
   *edit_baton = eb;
   *editor = dump_editor;
 
+  shim_callbacks->fetch_base_func = fetch_base_func;
+  shim_callbacks->fetch_base_baton = eb;
+
   SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
-                                   NULL, NULL, NULL, NULL, pool, pool));
+                                   shim_callbacks, pool, pool));
 
   return SVN_NO_ERROR;
 }
@@ -1127,6 +1163,10 @@ svn_repos_dump_fs3(svn_repos_t *repos,
                                     NULL, NULL, subpool));
         }
 
+      /* While our editor close_edit implementation is a no-op, we still
+         do this for completeness. */
+      SVN_ERR(dump_editor->close_edit(dump_edit_baton, subpool));
+
     loop_end:
       if (notify_func)
         {

Modified: subversion/branches/fs-py/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_repos/load-fs-vtable.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_repos/load-fs-vtable.c Mon Dec 19 18:49:34 2011
@@ -63,6 +63,12 @@ struct parse_baton
   svn_repos_notify_t *notify;
   apr_pool_t *pool;
 
+  /* Start and end (inclusive) of revision range we'll pay attention
+     to, or a pair of SVN_INVALID_REVNUMs if we're not filtering by
+     revisions. */
+  svn_revnum_t start_rev;
+  svn_revnum_t end_rev;
+
   /* A hash mapping copy-from revisions and mergeinfo range revisions
      (svn_revnum_t *) in the dump stream to their corresponding revisions
      (svn_revnum_t *) in the loaded repository.  The hash and its
@@ -84,13 +90,13 @@ struct parse_baton
 struct revision_baton
 {
   svn_revnum_t rev;
-
   svn_fs_txn_t *txn;
   svn_fs_root_t *txn_root;
 
   const svn_string_t *datestamp;
 
   apr_int32_t rev_offset;
+  svn_boolean_t skipped;
 
   struct parse_baton *pb;
   apr_pool_t *pool;
@@ -320,8 +326,8 @@ renumber_mergeinfo_revs(svn_string_t **f
     }
 
   if (predates_stream_mergeinfo)
-      SVN_ERR(svn_mergeinfo_merge(final_mergeinfo, predates_stream_mergeinfo,
-                                  subpool));
+      SVN_ERR(svn_mergeinfo_merge2(final_mergeinfo, predates_stream_mergeinfo,
+                                   subpool, subpool));
 
   SVN_ERR(svn_mergeinfo_sort(final_mergeinfo, subpool));
 
@@ -451,7 +457,14 @@ make_revision_baton(apr_hash_t *headers,
 
   if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_REVISION_NUMBER,
                           APR_HASH_KEY_STRING)))
-    rb->rev = SVN_STR_TO_REV(val);
+    {
+      rb->rev = SVN_STR_TO_REV(val);
+
+      /* If we're filtering revisions, is this one we'll skip? */
+      rb->skipped = (SVN_IS_VALID_REVNUM(pb->start_rev)
+                     && ((rb->rev < pb->start_rev) ||
+                         (rb->rev > pb->end_rev)));
+    }
 
   return rb;
 }
@@ -476,7 +489,7 @@ new_revision_record(void **revision_bato
      It might be positive or negative. */
   rb->rev_offset = (apr_int32_t) (rb->rev) - (head_rev + 1);
 
-  if (rb->rev > 0)
+  if ((rb->rev > 0) && (! rb->skipped))
     {
       /* Create a new fs txn. */
       SVN_ERR(svn_fs_begin_txn2(&(rb->txn), pb->fs, head_rev, 0, pool));
@@ -493,6 +506,14 @@ new_revision_record(void **revision_bato
       if (!SVN_IS_VALID_REVNUM(pb->oldest_old_rev))
         pb->oldest_old_rev = rb->rev;
     }
+  
+  /* If we're skipping this revision, try to notify someone. */
+  if (rb->skipped && pb->notify_func)
+    {
+      pb->notify->action = svn_repos_notify_load_skipped_rev;
+      pb->notify->old_revision = rb->rev;
+      pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
+    }
 
   /* If we're parsing revision 0, only the revision are (possibly)
      interesting to us: when loading the stream into an empty
@@ -607,6 +628,13 @@ new_node_record(void **node_baton,
 
   SVN_ERR(make_node_baton(&nb, headers, rb, pool));
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    {
+      *node_baton = nb;
+      return SVN_NO_ERROR;
+    }
+
   /* Make sure we have an action we recognize. */
   if (nb->action < svn_node_action_change
         || nb->action > svn_node_action_replace)
@@ -652,6 +680,10 @@ set_revision_property(void *baton,
 {
   struct revision_baton *rb = baton;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    return SVN_NO_ERROR;
+
   if (rb->rev > 0)
     {
       if (rb->pb->validate_props)
@@ -691,6 +723,10 @@ set_node_property(void *baton,
   struct revision_baton *rb = nb->rb;
   struct parse_baton *pb = rb->pb;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    return SVN_NO_ERROR;
+
   if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
     {
       svn_string_t *renumbered_mergeinfo;
@@ -751,6 +787,10 @@ delete_node_property(void *baton,
   struct node_baton *nb = baton;
   struct revision_baton *rb = nb->rb;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    return SVN_NO_ERROR;
+
   return change_node_prop(rb->txn_root, nb->path, name, NULL,
                           rb->pb->validate_props, nb->pool);
 }
@@ -764,6 +804,10 @@ remove_node_props(void *baton)
   apr_hash_t *proplist;
   apr_hash_index_t *hi;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    return SVN_NO_ERROR;
+
   SVN_ERR(svn_fs_node_proplist(&proplist,
                                rb->txn_root, nb->path, nb->pool));
 
@@ -788,6 +832,13 @@ apply_textdelta(svn_txdelta_window_handl
   struct node_baton *nb = node_baton;
   struct revision_baton *rb = nb->rb;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    {
+      *handler = NULL;
+      return SVN_NO_ERROR;
+    }
+
   return svn_fs_apply_textdelta(handler, handler_baton,
                                 rb->txn_root, nb->path,
                                 svn_checksum_to_cstring(nb->base_checksum,
@@ -805,6 +856,13 @@ set_fulltext(svn_stream_t **stream,
   struct node_baton *nb = node_baton;
   struct revision_baton *rb = nb->rb;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    {
+      *stream = NULL;
+      return SVN_NO_ERROR;
+    }
+
   return svn_fs_apply_text(stream,
                            rb->txn_root, nb->path,
                            svn_checksum_to_cstring(nb->result_checksum,
@@ -820,6 +878,10 @@ close_node(void *baton)
   struct revision_baton *rb = nb->rb;
   struct parse_baton *pb = rb->pb;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    return SVN_NO_ERROR;
+
   if (pb->notify_func)
     {
       pb->notify->action = svn_repos_notify_load_node_done;
@@ -839,7 +901,9 @@ close_revision(void *baton)
   svn_revnum_t committed_rev;
   svn_error_t *err;
 
-  if (rb->rev <= 0)
+  /* If we're skipping this revision or it has an invalid revision
+     number, we're done here. */
+  if (rb->skipped || (rb->rev <= 0))
     return SVN_NO_ERROR;
 
   /* Run the pre-commit hook, if so commanded. */
@@ -943,9 +1007,11 @@ close_revision(void *baton)
 
 
 svn_error_t *
-svn_repos_get_fs_build_parser3(const svn_repos_parse_fns2_t **callbacks,
+svn_repos_get_fs_build_parser4(const svn_repos_parse_fns2_t **callbacks,
                                void **parse_baton,
                                svn_repos_t *repos,
+                               svn_revnum_t start_rev,
+                               svn_revnum_t end_rev,
                                svn_boolean_t use_history,
                                svn_boolean_t validate_props,
                                enum svn_repos_load_uuid uuid_action,
@@ -960,6 +1026,13 @@ svn_repos_get_fs_build_parser3(const svn
   if (parent_dir)
     parent_dir = svn_relpath_canonicalize(parent_dir, pool);
 
+  SVN_ERR_ASSERT((SVN_IS_VALID_REVNUM(start_rev) &&
+                  SVN_IS_VALID_REVNUM(end_rev))
+                 || ((! SVN_IS_VALID_REVNUM(start_rev)) &&
+                     (! SVN_IS_VALID_REVNUM(end_rev))));
+  if (SVN_IS_VALID_REVNUM(start_rev))
+    SVN_ERR_ASSERT(start_rev <= end_rev);
+
   parser->new_revision_record = new_revision_record;
   parser->new_node_record = new_node_record;
   parser->uuid_record = uuid_record;
@@ -985,6 +1058,8 @@ svn_repos_get_fs_build_parser3(const svn
   pb->rev_map = apr_hash_make(pool);
   pb->oldest_old_rev = SVN_INVALID_REVNUM;
   pb->last_rev_mapped = SVN_INVALID_REVNUM;
+  pb->start_rev = start_rev;
+  pb->end_rev = end_rev;
 
   *callbacks = parser;
   *parse_baton = pb;
@@ -994,8 +1069,10 @@ svn_repos_get_fs_build_parser3(const svn
 
 
 svn_error_t *
-svn_repos_load_fs3(svn_repos_t *repos,
+svn_repos_load_fs4(svn_repos_t *repos,
                    svn_stream_t *dumpstream,
+                   svn_revnum_t start_rev,
+                   svn_revnum_t end_rev,
                    enum svn_repos_load_uuid uuid_action,
                    const char *parent_dir,
                    svn_boolean_t use_pre_commit_hook,
@@ -1013,8 +1090,9 @@ svn_repos_load_fs3(svn_repos_t *repos,
 
   /* This is really simple. */
 
-  SVN_ERR(svn_repos_get_fs_build_parser3(&parser, &parse_baton,
+  SVN_ERR(svn_repos_get_fs_build_parser4(&parser, &parse_baton,
                                          repos,
+                                         start_rev, end_rev,
                                          TRUE, /* look for copyfrom revs */
                                          validate_props,
                                          uuid_action,

Modified: subversion/branches/fs-py/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_repos/log.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_repos/log.c Mon Dec 19 18:49:34 2011
@@ -663,9 +663,9 @@ fs_mergeinfo_changed(svn_mergeinfo_catal
           svn_mergeinfo_catalog_t tmp_catalog;
 
           APR_ARRAY_PUSH(query_paths, const char *) = changed_path;
-          SVN_ERR(svn_fs_get_mergeinfo(&tmp_catalog, root,
-                                       query_paths, svn_mergeinfo_inherited,
-                                       FALSE, iterpool));
+          SVN_ERR(svn_fs_get_mergeinfo2(&tmp_catalog, root,
+                                        query_paths, svn_mergeinfo_inherited,
+                                        FALSE, TRUE, iterpool, iterpool));
           tmp_mergeinfo = apr_hash_get(tmp_catalog, changed_path,
                                         APR_HASH_KEY_STRING);
           if (tmp_mergeinfo)
@@ -682,9 +682,9 @@ fs_mergeinfo_changed(svn_mergeinfo_catal
           svn_mergeinfo_catalog_t tmp_catalog;
 
           APR_ARRAY_PUSH(query_paths, const char *) = base_path;
-          SVN_ERR(svn_fs_get_mergeinfo(&tmp_catalog, base_root,
-                                       query_paths, svn_mergeinfo_inherited,
-                                       FALSE, iterpool));
+          SVN_ERR(svn_fs_get_mergeinfo2(&tmp_catalog, base_root,
+                                        query_paths, svn_mergeinfo_inherited,
+                                        FALSE, TRUE, iterpool, iterpool));
           tmp_mergeinfo = apr_hash_get(tmp_catalog, base_path,
                                         APR_HASH_KEY_STRING);
           if (tmp_mergeinfo)
@@ -711,17 +711,16 @@ fs_mergeinfo_changed(svn_mergeinfo_catal
           if (prev_mergeinfo_value)
             SVN_ERR(svn_mergeinfo_parse(&prev_mergeinfo,
                                         prev_mergeinfo_value->data, iterpool));
-          SVN_ERR(svn_mergeinfo_diff(&deleted, &added, prev_mergeinfo,
-                                     mergeinfo, FALSE, iterpool));
+          SVN_ERR(svn_mergeinfo_diff2(&deleted, &added, prev_mergeinfo,
+                                      mergeinfo, FALSE, result_pool,
+                                      iterpool));
 
           /* Toss interesting stuff into our return catalogs. */
           hash_path = apr_pstrdup(result_pool, changed_path);
           apr_hash_set(*deleted_mergeinfo_catalog, hash_path,
-                       APR_HASH_KEY_STRING, svn_mergeinfo_dup(deleted,
-                                                              result_pool));
+                       APR_HASH_KEY_STRING, deleted);
           apr_hash_set(*added_mergeinfo_catalog, hash_path,
-                       APR_HASH_KEY_STRING, svn_mergeinfo_dup(added,
-                                                              result_pool));
+                       APR_HASH_KEY_STRING, added);
         }
     }
 
@@ -795,8 +794,9 @@ get_combined_mergeinfo_changes(svn_merge
       const char *prev_path;
       svn_revnum_t appeared_rev, prev_rev;
       svn_fs_root_t *prev_root;
-      svn_mergeinfo_catalog_t catalog;
-      svn_mergeinfo_t prev_mergeinfo, mergeinfo, deleted, added;
+      svn_mergeinfo_catalog_t catalog, inherited_catalog;
+      svn_mergeinfo_t prev_mergeinfo, mergeinfo, deleted, added,
+        prev_inherited_mergeinfo, inherited_mergeinfo;
       apr_array_header_t *query_paths;
 
       svn_pool_clear(iterpool);
@@ -835,8 +835,9 @@ get_combined_mergeinfo_changes(svn_merge
       SVN_ERR(svn_fs_revision_root(&prev_root, fs, prev_rev, iterpool));
       query_paths = apr_array_make(iterpool, 1, sizeof(const char *));
       APR_ARRAY_PUSH(query_paths, const char *) = prev_path;
-      err = svn_fs_get_mergeinfo(&catalog, prev_root, query_paths,
-                                 svn_mergeinfo_inherited, FALSE, iterpool);
+      err = svn_fs_get_mergeinfo2(&catalog, prev_root, query_paths,
+                                  svn_mergeinfo_inherited, FALSE, TRUE,
+                                  iterpool, iterpool);
       if (err && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
                   err->apr_err == SVN_ERR_FS_NOT_DIRECTORY ||
                   err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR))
@@ -846,26 +847,64 @@ get_combined_mergeinfo_changes(svn_merge
           continue;
         }
       SVN_ERR(err);
+
+      /* Issue #4022 'svn log -g interprets change in inherited mergeinfo due
+         to move as a merge': A copy where the source and destination inherit
+         mergeinfo from the same parent means the inherited mergeinfo of the
+         source and destination will differ, but this diffrence is not
+         indicative of a merge unless the mergeinfo on the inherited parent
+         has actually changed.
+
+         To check for this we must fetch the "raw" previous inherited
+         mergeinfo and the "raw" mergeinfo @REV then compare these. */
+      SVN_ERR(svn_fs_get_mergeinfo2(&inherited_catalog, prev_root, query_paths,
+                                    svn_mergeinfo_nearest_ancestor, FALSE,
+                                    FALSE, /* adjust_inherited_mergeinfo */
+                                    iterpool, iterpool));
+
       prev_mergeinfo = apr_hash_get(catalog, prev_path, APR_HASH_KEY_STRING);
+      prev_inherited_mergeinfo = apr_hash_get(inherited_catalog, prev_path, APR_HASH_KEY_STRING);
 
       /* Fetch the current mergeinfo (as of REV, and including
          inherited stuff) for this path. */
       APR_ARRAY_IDX(query_paths, 0, const char *) = path;
-      SVN_ERR(svn_fs_get_mergeinfo(&catalog, root, query_paths,
-                                   svn_mergeinfo_inherited, FALSE, iterpool));
+      SVN_ERR(svn_fs_get_mergeinfo2(&catalog, root, query_paths,
+                                    svn_mergeinfo_inherited, FALSE, TRUE,
+                                    iterpool, iterpool));
+
+      /* Issue #4022 again, fetch the raw inherited mergeinfo. */
+      SVN_ERR(svn_fs_get_mergeinfo2(&inherited_catalog, root, query_paths,
+                                    svn_mergeinfo_nearest_ancestor, FALSE,
+                                    FALSE, /* adjust_inherited_mergeinfo */
+                                    iterpool, iterpool));
+
       mergeinfo = apr_hash_get(catalog, path, APR_HASH_KEY_STRING);
+      inherited_mergeinfo = apr_hash_get(inherited_catalog, path, APR_HASH_KEY_STRING);
 
       if (!prev_mergeinfo && !mergeinfo)
         continue;
 
+      /* Last bit of issue #4022 checking. */
+      if (prev_inherited_mergeinfo && inherited_mergeinfo)
+        {
+          svn_boolean_t inherits_same_mergeinfo;
+
+          SVN_ERR(svn_mergeinfo__equals(&inherits_same_mergeinfo,
+                                        prev_inherited_mergeinfo,
+                                        inherited_mergeinfo,
+                                        TRUE, iterpool));
+          /* If a copy rather than an actual merge brought about an
+             inherited mergeinfo change then we are finished. */
+          if (inherits_same_mergeinfo)
+            continue;
+        }
+
       /* Compare, constrast, and combine the results. */
-      SVN_ERR(svn_mergeinfo_diff(&deleted, &added, prev_mergeinfo,
-                                 mergeinfo, FALSE, iterpool));
-      SVN_ERR(svn_mergeinfo_merge2(*deleted_mergeinfo,
-                                   svn_mergeinfo_dup(deleted, result_pool),
+      SVN_ERR(svn_mergeinfo_diff2(&deleted, &added, prev_mergeinfo,
+                                  mergeinfo, FALSE, result_pool, iterpool));
+      SVN_ERR(svn_mergeinfo_merge2(*deleted_mergeinfo, deleted,
                                    result_pool, iterpool));
-      SVN_ERR(svn_mergeinfo_merge2(*added_mergeinfo,
-                                   svn_mergeinfo_dup(added, result_pool),
+      SVN_ERR(svn_mergeinfo_merge2(*added_mergeinfo, added,
                                    result_pool, iterpool));
      }
 
@@ -888,7 +927,7 @@ get_combined_mergeinfo_changes(svn_merge
       for (i = 0; i < paths->nelts; i++)
         {
           const char *path = APR_ARRAY_IDX(paths, i, const char *);
-          if (! svn_dirent_is_ancestor(path, changed_path))
+          if (! svn_fspath__skip_ancestor(path, changed_path))
             continue;
           svn_pool_clear(iterpool);
           deleted = apr_hash_get(deleted_mergeinfo_catalog, key, klen);
@@ -1103,8 +1142,7 @@ send_log(svn_revnum_t rev,
               apr_array_header_t *rangelist =
                 svn__apr_hash_index_val(hi2);
 
-              if (svn_fspath__is_ancestor(mergeinfo_path,
-                                          changed_path))
+              if (svn_fspath__skip_ancestor(mergeinfo_path, changed_path))
                 {
                   int i;
 

Modified: subversion/branches/fs-py/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_repos/replay.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_repos/replay.c Mon Dec 19 18:49:34 2011
@@ -573,8 +573,9 @@ path_driver_cb_func(void **dir_baton,
                                                   struct copy_info);
           if (info->copyfrom_path)
             {
-              const char *relpath = svn_relpath__is_child(info->path,
-                                                          edit_path, pool);
+              const char *relpath = svn_relpath_skip_ancestor(info->path,
+                                                              edit_path);
+              SVN_ERR_ASSERT(relpath && *relpath);
               SVN_ERR(svn_fs_revision_root(&source_root,
                                            svn_fs_root_fs(root),
                                            info->copyfrom_rev, pool));