subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hwri...@apache.org
Subject svn commit: r1339210 [3/3] - in /subversion/branches/ev2-export: ./ build/generator/templates/ contrib/server-side/ subversion/include/ subversion/libsvn_client/ subversion/libsvn_ra/ subversion/libsvn_ra_serf/ subversion/libsvn_repos/ subversion/libsv...
Date Wed, 16 May 2012 14:57:42 GMT
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c?rev=1339210&r1=1339209&r2=1339210&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c Wed May 16 14:57:41 2012
@@ -37,6 +37,7 @@
 
 #include "private/svn_dav_protocol.h"
 #include "private/svn_string_private.h"
+#include "private/svn_subr_private.h"
 #include "svn_private_config.h"
 
 #include "ra_serf.h"
@@ -46,8 +47,8 @@
 /*
  * This enum represents the current state of our XML parsing for a REPORT.
  */
-typedef enum log_state_e {
-  NONE = 0,
+enum {
+  INITIAL = 0,
   REPORT,
   ITEM,
   VERSION,
@@ -61,26 +62,7 @@ typedef enum log_state_e {
   DELETED_PATH,
   MODIFIED_PATH,
   SUBTRACTIVE_MERGE
-} log_state_e;
-
-typedef struct log_info_t {
-  apr_pool_t *pool;
-
-  /* The currently collected value as we build it up, and its wire
-   * encoding (if any).
-   */
-  svn_stringbuf_t *tmp;
-  const char *tmp_encoding;
-
-  /* Temporary change path - ultimately inserted into changed_paths hash. */
-  svn_log_changed_path2_t *tmp_path;
-
-  /* Log information */
-  svn_log_entry_t *log_entry;
-
-  /* Place to hold revprop name. */
-  const char *revprop_name;
-} log_info_t;
+};
 
 typedef struct log_context_t {
   apr_pool_t *pool;
@@ -97,8 +79,11 @@ typedef struct log_context_t {
   int nest_level; /* used to track mergeinfo nesting levels */
   int count; /* only incremented when nest_level == 0 */
 
-  /* are we done? */
-  svn_boolean_t done;
+  /* Collect information for storage into a log entry. Most of the entry
+     members are collected by individual states. revprops and paths are
+     N datapoints per entry.  */
+  apr_hash_t *collect_revprops;
+  apr_hash_t *collect_paths;
 
   /* log receiver function and baton */
   svn_log_entry_receiver_t receiver;
@@ -110,411 +95,312 @@ typedef struct log_context_t {
   svn_boolean_t want_message;
 } 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,
-           const char **attrs)
-{
-  svn_ra_serf__xml_push_state(parser, state);
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t log_ttable[] = {
+  { INITIAL, S_, "log-report", REPORT,
+    FALSE, { NULL }, FALSE, FALSE },
 
-  if (state == ITEM)
-    {
-      log_info_t *info;
-      apr_pool_t *info_pool = svn_pool_create(parser->state->pool);
+  /* Note that we have an opener here. We need to construct a new LOG_ENTRY
+     to record multiple paths.  */
+  { REPORT, S_, "log-item", ITEM,
+    FALSE, { NULL }, TRUE, TRUE },
 
-      info = apr_pcalloc(info_pool, sizeof(*info));
-      info->pool = info_pool;
-      info->tmp = svn_stringbuf_create_empty(info_pool);
-      info->log_entry = svn_log_entry_create(info_pool);
+  { ITEM, D_, SVN_DAV__VERSION_NAME, VERSION,
+    TRUE, { NULL }, FALSE, TRUE },
 
-      info->log_entry->revision = SVN_INVALID_REVNUM;
+  { ITEM, D_, "creator-displayname", CREATOR,
+    TRUE, { "?encoding", NULL }, FALSE, TRUE },
 
-      parser->state->private = info;
-    }
+  { ITEM, S_, "date", DATE,
+    TRUE, { "?encoding", NULL }, FALSE, TRUE },
 
-  if (state == ADDED_PATH || state == REPLACED_PATH ||
-      state == DELETED_PATH || state == MODIFIED_PATH)
-    {
-      log_info_t *info = parser->state->private;
+  { ITEM, D_, "comment", COMMENT,
+    TRUE, { "?encoding", NULL }, FALSE, TRUE },
 
-      if (!info->log_entry->changed_paths2)
-        {
-          info->log_entry->changed_paths2 = apr_hash_make(info->pool);
-          info->log_entry->changed_paths = info->log_entry->changed_paths2;
-        }
+  { ITEM, S_, "revprop", REVPROP,
+    TRUE, { "name", "?encoding", NULL }, FALSE, TRUE },
 
-      info->tmp_path = svn_log_changed_path2_create(info->pool);
-      info->tmp_path->copyfrom_rev = SVN_INVALID_REVNUM;
-    }
+  { ITEM, S_, "has-children", HAS_CHILDREN,
+    FALSE, { NULL }, FALSE, TRUE },
 
-  if (state == CREATOR || state == DATE || state == COMMENT
-      || state == REVPROP)
-    {
-      log_info_t *info = parser->state->private;
+  { ITEM, S_, "subtractive-merge", SUBTRACTIVE_MERGE,
+    FALSE, { NULL }, FALSE, TRUE },
 
-      info->tmp_encoding = svn_xml_get_attr_value("encoding", attrs);
-      if (info->tmp_encoding)
-        info->tmp_encoding = apr_pstrdup(info->pool, info->tmp_encoding);
+  { ITEM, S_, "added-path", ADDED_PATH,
+    TRUE, { "?node-kind", "?text-mods", "?prop-mods",
+            "?copyfrom-path", "?copyfrom-rev", NULL }, FALSE, TRUE },
 
-      if (!info->log_entry->revprops)
-        {
-          info->log_entry->revprops = apr_hash_make(info->pool);
-        }
-    }
+  { ITEM, S_, "replaced-path", REPLACED_PATH,
+    TRUE, { "?node-kind", "?text-mods", "?prop-mods",
+            "?copyfrom-path", "?copyfrom-rev", NULL }, FALSE, TRUE },
 
-  return parser->state->private;
-}
+  { ITEM, S_, "deleted-path", DELETED_PATH,
+    TRUE, { "?node-kind", "?text-mods", "?prop-mods", NULL }, FALSE, TRUE },
 
-/* Helper function to parse the common arguments availabe in ATTRS into CHANGE. */
-static svn_error_t *
-read_changed_path_attributes(svn_log_changed_path2_t *change, const char **attrs)
-{
-  /* All these arguments are optional. The *_from_word() functions can handle
-     them for us */
+  { ITEM, S_, "modified-path", MODIFIED_PATH,
+    TRUE, { "?node-kind", "?text-mods", "?prop-mods", NULL }, FALSE, TRUE },
 
-  change->node_kind = svn_node_kind_from_word(
-                           svn_xml_get_attr_value("node-kind", attrs));
-  change->text_modified = svn_tristate__from_word(
-                           svn_xml_get_attr_value("text-mods", attrs));
-  change->props_modified = svn_tristate__from_word(
-                           svn_xml_get_attr_value("prop-mods", attrs));
+  { 0 }
+};
 
-  return SVN_NO_ERROR;
-}
+
+/* Store CDATA into REVPROPS, associated with PROPNAME. If ENCODING is not
+   NULL, then it must base "base64" and CDATA will be decoded first.
 
+   NOTE: PROPNAME must live longer than REVPROPS.  */
 static svn_error_t *
-start_log(svn_ra_serf__xml_parser_t *parser,
-          svn_ra_serf__dav_props_t name,
-          const char **attrs,
-          apr_pool_t *scratch_pool)
+collect_revprop(apr_hash_t *revprops,
+                const char *propname,
+                const svn_string_t *cdata,
+                const char *encoding)
 {
-  log_context_t *log_ctx = parser->user_data;
-  log_state_e state;
+  apr_pool_t *result_pool = apr_hash_pool_get(revprops);
+  const svn_string_t *decoded;
 
-  state = parser->state->current_state;
-
-  if (state == NONE &&
-      strcmp(name.name, "log-report") == 0)
-    {
-      push_state(parser, log_ctx, REPORT, attrs);
-    }
-  else if (state == REPORT &&
-           strcmp(name.name, "log-item") == 0)
+  if (encoding)
     {
-      push_state(parser, log_ctx, ITEM, attrs);
-    }
-  else if (state == ITEM)
-    {
-      log_info_t *info;
-
-      if (strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
-        {
-          push_state(parser, log_ctx, VERSION, attrs);
-        }
-      else if (strcmp(name.name, "creator-displayname") == 0)
-        {
-          push_state(parser, log_ctx, CREATOR, attrs);
-        }
-      else if (strcmp(name.name, "date") == 0)
-        {
-          push_state(parser, log_ctx, DATE, attrs);
-        }
-      else if (strcmp(name.name, "comment") == 0)
-        {
-          push_state(parser, log_ctx, COMMENT, attrs);
-        }
-      else if (strcmp(name.name, "revprop") == 0)
-        {
-          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, attrs);
-        }
-      else if (strcmp(name.name, "subtractive-merge") == 0)
+      /* Check for a known encoding type.  This is easy -- there's
+         only one.  */
+      if (strcmp(encoding, "base64") != 0)
         {
-          push_state(parser, log_ctx, SUBTRACTIVE_MERGE, attrs);
+          return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+                                   _("Unsupported encoding '%s'"),
+                                   encoding);
         }
-      else if (strcmp(name.name, "added-path") == 0)
-        {
-          const char *copy_path, *copy_rev_str;
-
-          info = push_state(parser, log_ctx, ADDED_PATH, attrs);
-          info->tmp_path->action = 'A';
 
-          copy_path = svn_xml_get_attr_value("copyfrom-path", attrs);
-          copy_rev_str = svn_xml_get_attr_value("copyfrom-rev", attrs);
-          if (copy_path && copy_rev_str)
-            {
-              svn_revnum_t copy_rev;
-
-              copy_rev = SVN_STR_TO_REV(copy_rev_str);
-              if (SVN_IS_VALID_REVNUM(copy_rev))
-                {
-                  info->tmp_path->copyfrom_path = apr_pstrdup(info->pool,
-                                                              copy_path);
-                  info->tmp_path->copyfrom_rev = copy_rev;
-                }
-            }
-
-          SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
-        }
-      else if (strcmp(name.name, "replaced-path") == 0)
-        {
-          const char *copy_path, *copy_rev_str;
+      decoded = svn_base64_decode_string(cdata, result_pool);
+    }
+  else
+    {
+      decoded = svn_string_dup(cdata, result_pool);
+    }
 
-          info = push_state(parser, log_ctx, REPLACED_PATH, attrs);
-          info->tmp_path->action = 'R';
+  /* Caller has ensured PROPNAME has sufficient lifetime.  */
+  apr_hash_set(revprops, propname, APR_HASH_KEY_STRING, decoded);
 
-          copy_path = svn_xml_get_attr_value("copyfrom-path", attrs);
-          copy_rev_str = svn_xml_get_attr_value("copyfrom-rev", attrs);
-          if (copy_path && copy_rev_str)
-            {
-              svn_revnum_t copy_rev;
+  return SVN_NO_ERROR;
+}
 
-              copy_rev = SVN_STR_TO_REV(copy_rev_str);
-              if (SVN_IS_VALID_REVNUM(copy_rev))
-                {
-                  info->tmp_path->copyfrom_path = apr_pstrdup(info->pool,
-                                                              copy_path);
-                  info->tmp_path->copyfrom_rev = copy_rev;
-                }
-            }
 
-          SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
+/* Record ACTION on the path in CDATA into PATHS. Other properties about
+   the action are pulled from ATTRS.  */
+static svn_error_t *
+collect_path(apr_hash_t *paths,
+             char action,
+             const svn_string_t *cdata,
+             apr_hash_t *attrs)
+{
+  apr_pool_t *result_pool = apr_hash_pool_get(paths);
+  svn_log_changed_path2_t *lcp;
+  const char *copyfrom_path;
+  const char *copyfrom_rev;
+  const char *path;
+
+  lcp = svn_log_changed_path2_create(result_pool);
+  lcp->action = action;
+  lcp->copyfrom_rev = SVN_INVALID_REVNUM;
+
+  /* COPYFROM_* are only recorded for ADDED_PATH and REPLACED_PATH.  */
+  copyfrom_path = apr_hash_get(attrs, "copyfrom-path", APR_HASH_KEY_STRING);
+  copyfrom_rev = apr_hash_get(attrs, "copyfrom-rev", APR_HASH_KEY_STRING);
+  if (copyfrom_path && copyfrom_rev)
+    {
+      svn_revnum_t rev = SVN_STR_TO_REV(copyfrom_rev);
+
+      if (SVN_IS_VALID_REVNUM(rev))
+        {
+          lcp->copyfrom_path = apr_pstrdup(result_pool, copyfrom_path);
+          lcp->copyfrom_rev = rev;
         }
-      else if (strcmp(name.name, "deleted-path") == 0)
-        {
-          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, attrs);
-          info->tmp_path->action = 'M';
+  lcp->node_kind = svn_node_kind_from_word(apr_hash_get(
+                                             attrs, "node-kind",
+                                             APR_HASH_KEY_STRING));
+  lcp->text_modified = svn_tristate__from_word(apr_hash_get(
+                                                 attrs, "text-mods",
+                                                 APR_HASH_KEY_STRING));
+  lcp->props_modified = svn_tristate__from_word(apr_hash_get(
+                                                  attrs, "prop-mods",
+                                                  APR_HASH_KEY_STRING));
 
-          SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
-        }
-    }
+  path = apr_pstrmemdup(result_pool, cdata->data, cdata->len);
+  apr_hash_set(paths, path, APR_HASH_KEY_STRING, lcp);
 
   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..
- */
+
+/* Conforms to svn_ra_serf__xml_opened_t  */
 static svn_error_t *
-maybe_decode_log_cdata(const svn_string_t **decoded_cdata,
-                       log_info_t *info)
+log_opened(svn_ra_serf__xml_estate_t *xes,
+           void *baton,
+           int entered_state,
+           apr_pool_t *scratch_pool)
 {
+  log_context_t *log_ctx = baton;
+  apr_pool_t *state_pool = svn_ra_serf__xml_state_pool(xes);
 
-  if (info->tmp_encoding)
-    {
-      svn_string_t tmp;
-
-      /* Don't use morph_info_string cuz we need info->tmp to
-         remain usable.  */
-      tmp.data = info->tmp->data;
-      tmp.len = info->tmp->len;
+  SVN_ERR_ASSERT(entered_state == ITEM);
 
-      /* 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);
-        }
+  log_ctx->collect_revprops = apr_hash_make(state_pool);
+  log_ctx->collect_paths = apr_hash_make(state_pool);
 
-      *decoded_cdata = svn_base64_decode_string(&tmp, info->pool);
-    }
-  else
-    {
-      *decoded_cdata = svn_string_create_from_buf(info->tmp, info->pool);
-    }
   return SVN_NO_ERROR;
 }
 
+
+/* Conforms to svn_ra_serf__xml_closed_t  */
 static svn_error_t *
-end_log(svn_ra_serf__xml_parser_t *parser,
-        svn_ra_serf__dav_props_t name,
-        apr_pool_t *scratch_pool)
+log_closed(svn_ra_serf__xml_estate_t *xes,
+           void *baton,
+           int leaving_state,
+           const svn_string_t *cdata,
+           apr_hash_t *attrs,
+           apr_pool_t *scratch_pool)
 {
-  log_context_t *log_ctx = parser->user_data;
-  log_state_e state;
-  log_info_t *info;
-
-  state = parser->state->current_state;
-  info = parser->state->private;
+  log_context_t *log_ctx = baton;
 
-  if (state == REPORT &&
-      strcmp(name.name, "log-report") == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == ITEM &&
-           strcmp(name.name, "log-item") == 0)
+  if (leaving_state == ITEM)
     {
+      svn_log_entry_t *log_entry;
+      const char *rev_str;
+
       if (log_ctx->limit && (log_ctx->nest_level == 0)
           && (++log_ctx->count > log_ctx->limit))
         {
           return SVN_NO_ERROR;
         }
 
+      log_entry = svn_log_entry_create(scratch_pool);
+
+      /* Pick up the paths from the context. These have the same lifetime
+         as this state. That is long enough for us to pass the paths to
+         the receiver callback.  */
+      if (apr_hash_count(log_ctx->collect_paths) > 0)
+        {
+          log_entry->changed_paths = log_ctx->collect_paths;
+          log_entry->changed_paths2 = log_ctx->collect_paths;
+        }
+
+      /* ... and same story for the collected revprops.  */
+      log_entry->revprops = log_ctx->collect_revprops;
+
+      log_entry->has_children = svn_hash__get_bool(attrs,
+                                                   "has-children",
+                                                   FALSE);
+      log_entry->subtractive_merge = svn_hash__get_bool(attrs,
+                                                        "subtractive-merge",
+                                                        FALSE);
+
+      rev_str = apr_hash_get(attrs, "revision", APR_HASH_KEY_STRING);
+      if (rev_str)
+        log_entry->revision = SVN_STR_TO_REV(rev_str);
+      else
+        log_entry->revision = SVN_INVALID_REVNUM;
+
       /* Give the info to the reporter */
       SVN_ERR(log_ctx->receiver(log_ctx->receiver_baton,
-                                info->log_entry,
-                                info->pool));
+                                log_entry,
+                                scratch_pool));
 
-      if (info->log_entry->has_children)
+      if (log_entry->has_children)
         {
           log_ctx->nest_level++;
         }
-      if (! SVN_IS_VALID_REVNUM(info->log_entry->revision))
+      if (! SVN_IS_VALID_REVNUM(log_entry->revision))
         {
           SVN_ERR_ASSERT(log_ctx->nest_level);
           log_ctx->nest_level--;
         }
 
-      svn_pool_destroy(info->pool);
-      svn_ra_serf__xml_pop_state(parser);
+      /* These hash tables are going to be unusable once this state's
+         pool is destroyed. But let's not leave stale pointers in
+         structures that have a longer life.  */
+      log_ctx->collect_revprops = NULL;
+      log_ctx->collect_paths = NULL;
     }
-  else if (state == VERSION &&
-           strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
+  else if (leaving_state == VERSION)
     {
-      info->log_entry->revision = SVN_STR_TO_REV(info->tmp->data);
-      svn_stringbuf_setempty(info->tmp);
-      svn_ra_serf__xml_pop_state(parser);
+      svn_ra_serf__xml_note(xes, ITEM, "revision", cdata->data);
     }
-  else if (state == CREATOR &&
-           strcmp(name.name, "creator-displayname") == 0)
+  else if (leaving_state == CREATOR)
     {
       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, decoded_cdata);
+          SVN_ERR(collect_revprop(log_ctx->collect_revprops,
+                                  SVN_PROP_REVISION_AUTHOR,
+                                  cdata,
+                                  apr_hash_get(attrs, "encoding",
+                                               APR_HASH_KEY_STRING)));
         }
-      svn_stringbuf_setempty(info->tmp);
-      svn_ra_serf__xml_pop_state(parser);
     }
-  else if (state == DATE &&
-           strcmp(name.name, "date") == 0)
+  else if (leaving_state == DATE)
     {
       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, decoded_cdata);
+          SVN_ERR(collect_revprop(log_ctx->collect_revprops,
+                                  SVN_PROP_REVISION_DATE,
+                                  cdata,
+                                  apr_hash_get(attrs, "encoding",
+                                               APR_HASH_KEY_STRING)));
         }
-      svn_stringbuf_setempty(info->tmp);
-      svn_ra_serf__xml_pop_state(parser);
     }
-  else if (state == COMMENT &&
-           strcmp(name.name, "comment") == 0)
+  else if (leaving_state == COMMENT)
     {
       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, decoded_cdata);
-        }
-      svn_stringbuf_setempty(info->tmp);
-      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, decoded_cdata);
-      svn_stringbuf_setempty(info->tmp);
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == HAS_CHILDREN &&
-           strcmp(name.name, "has-children") == 0)
-    {
-      info->log_entry->has_children = TRUE;
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == SUBTRACTIVE_MERGE &&
-           strcmp(name.name, "subtractive-merge") == 0)
-    {
-      info->log_entry->subtractive_merge = TRUE;
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if ((state == ADDED_PATH &&
-            strcmp(name.name, "added-path") == 0) ||
-           (state == DELETED_PATH &&
-            strcmp(name.name, "deleted-path") == 0) ||
-           (state == MODIFIED_PATH &&
-            strcmp(name.name, "modified-path") == 0) ||
-           (state == REPLACED_PATH &&
-            strcmp(name.name, "replaced-path") == 0))
-    {
-      char *path;
-
-      path = apr_pstrmemdup(info->pool, info->tmp->data, info->tmp->len);
-      svn_stringbuf_setempty(info->tmp);
-
-      apr_hash_set(info->log_entry->changed_paths2, path, APR_HASH_KEY_STRING,
-                   info->tmp_path);
-      svn_ra_serf__xml_pop_state(parser);
+          SVN_ERR(collect_revprop(log_ctx->collect_revprops,
+                                  SVN_PROP_REVISION_LOG,
+                                  cdata,
+                                  apr_hash_get(attrs, "encoding",
+                                               APR_HASH_KEY_STRING)));
+        }
     }
+  else if (leaving_state == REVPROP)
+    {
+      apr_pool_t *result_pool = apr_hash_pool_get(log_ctx->collect_revprops);
 
-  return SVN_NO_ERROR;
-}
+      SVN_ERR(collect_revprop(
+                log_ctx->collect_revprops,
+                apr_pstrdup(result_pool,
+                            apr_hash_get(attrs, "name", APR_HASH_KEY_STRING)),
+                cdata,
+                apr_hash_get(attrs, "encoding", APR_HASH_KEY_STRING)
+                ));
+    }
+  else if (leaving_state == HAS_CHILDREN)
+    {
+      svn_ra_serf__xml_note(xes, ITEM, "has-children", "yes");
+    }
+  else if (leaving_state == SUBTRACTIVE_MERGE)
+    {
+      svn_ra_serf__xml_note(xes, ITEM, "subtractive-merge", "yes");
+    }
+  else
+    {
+      char action;
 
-static svn_error_t *
-cdata_log(svn_ra_serf__xml_parser_t *parser,
-          const char *data,
-          apr_size_t len,
-          apr_pool_t *scratch_pool)
-{
-  log_context_t *log_ctx = parser->user_data;
-  log_state_e state;
-  log_info_t *info;
-
-  UNUSED_CTX(log_ctx);
-
-  state = parser->state->current_state;
-  info = parser->state->private;
-
-  switch (state)
-    {
-      case VERSION:
-      case CREATOR:
-      case DATE:
-      case COMMENT:
-      case REVPROP:
-      case ADDED_PATH:
-      case REPLACED_PATH:
-      case DELETED_PATH:
-      case MODIFIED_PATH:
-        svn_stringbuf_appendbytes(info->tmp, data, len);
-        break;
+      if (leaving_state == ADDED_PATH)
+        action = 'A';
+      else if (leaving_state == REPLACED_PATH)
+        action = 'R';
+      else if (leaving_state == DELETED_PATH)
+        action = 'D';
+      else
+        {
+          SVN_ERR_ASSERT(leaving_state == MODIFIED_PATH);
+          action = 'M';
+        }
 
-      default:
-        break;
+      SVN_ERR(collect_path(log_ctx->collect_paths, action, cdata, attrs));
     }
 
   return SVN_NO_ERROR;
 }
 
+
 static svn_error_t *
 create_log_body(serf_bucket_t **body_bkt,
                 void *baton,
@@ -632,7 +518,7 @@ svn_ra_serf__get_log(svn_ra_session_t *r
   log_context_t *log_ctx;
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__xml_parser_t *parser_ctx;
+  svn_ra_serf__xml_context_t *xmlctx;
   svn_boolean_t want_custom_revprops;
   svn_revnum_t peg_rev;
   svn_error_t *err;
@@ -651,7 +537,6 @@ svn_ra_serf__get_log(svn_ra_session_t *r
   log_ctx->include_merged_revisions = include_merged_revisions;
   log_ctx->revprops = revprops;
   log_ctx->nest_level = 0;
-  log_ctx->done = FALSE;
 
   want_custom_revprops = FALSE;
   if (revprops)
@@ -696,9 +581,11 @@ svn_ra_serf__get_log(svn_ra_session_t *r
                                       NULL /* url */, peg_rev,
                                       pool, pool));
 
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  xmlctx = svn_ra_serf__xml_context_create(log_ttable,
+                                           log_opened, log_closed, log_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
-  handler->handler_pool = pool;
   handler->method = "REPORT";
   handler->path = req_url;
   handler->body_delegate = create_log_body;
@@ -707,21 +594,7 @@ svn_ra_serf__get_log(svn_ra_session_t *r
   handler->conn = session->conns[0];
   handler->session = session;
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = log_ctx;
-  parser_ctx->start = start_log;
-  parser_ctx->end = end_log;
-  parser_ctx->cdata = cdata_log;
-  parser_ctx->done = &log_ctx->done;
-
-  handler->response_handler = svn_ra_serf__handle_xml_parser;
-  handler->response_baton = parser_ctx;
-
-  svn_ra_serf__request_create(handler);
-
-  err = svn_ra_serf__context_run_wait(&log_ctx->done, session, pool);
+  err = svn_ra_serf__context_run_one(handler, pool);
 
   SVN_ERR(svn_error_compose_create(
               svn_ra_serf__error_on_status(handler->sline.code,

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/replay.c?rev=1339210&r1=1339209&r2=1339210&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/replay.c Wed May 16 14:57:41 2012
@@ -415,7 +415,12 @@ was_readable(svn_boolean_t *readable,
    revision root, fspath, and revnum of the copyfrom of CHANGE, which
    corresponds to PATH under ROOT.  If the copyfrom info is valid
    (i.e., is not (NULL, SVN_INVALID_REVNUM)), then initialize SRC_READABLE
-   too, consulting AUTHZ_READ_FUNC and AUTHZ_READ_BATON if provided. */
+   too, consulting AUTHZ_READ_FUNC and AUTHZ_READ_BATON if provided.
+
+   NOTE: If the copyfrom information in CHANGE is marked as unknown
+   (meaning, its ->copyfrom_rev and ->copyfrom_path cannot be
+   trusted), this function will also update those members of the
+   CHANGE structure to carry accurate copyfrom information.  */
 static svn_error_t *
 fill_copyfrom(svn_fs_root_t **copyfrom_root,
               const char **copyfrom_path,
@@ -698,10 +703,18 @@ path_driver_cb_func(void **dir_baton,
         }
     }
 
-  /* Handle property modifications. */
   if (! do_delete || do_add)
     {
-      if (change->prop_mod)
+      /* Is this a copy that was downgraded to a raw add?  (If so,
+         we'll need to transmit properties and file contents and such
+         for it regardless of what the CHANGE structure's text_mod
+         and prop_mod flags say.)  */
+      svn_boolean_t downgraded_copy = (change->copyfrom_known
+                                       && change->copyfrom_path
+                                       && (! copyfrom_path));
+
+      /* Handle property modifications. */
+      if (change->prop_mod || downgraded_copy)
         {
           apr_array_header_t *prop_diffs;
           apr_hash_t *old_props;
@@ -731,14 +744,9 @@ path_driver_cb_func(void **dir_baton,
             }
         }
 
-      /* Handle textual modifications.
-
-         Note that this needs to happen in the "copy from a file we
-         aren't allowed to see" case since otherwise the caller will
-         have no way to actually get the new file's contents, which
-         they are apparently allowed to see. */
+      /* Handle textual modifications. */
       if (change->node_kind == svn_node_file
-          && (change->text_mod || (change->copyfrom_path && ! copyfrom_path)))
+          && (change->text_mod || downgraded_copy))
         {
           svn_txdelta_window_handler_t delta_handler;
           void *delta_handler_baton;

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/io.c?rev=1339210&r1=1339209&r2=1339210&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/io.c Wed May 16 14:57:41 2012
@@ -65,6 +65,7 @@
 
 #include "private/svn_atomic.h"
 #include "private/svn_io_private.h"
+#include "private/svn_subr_private.h"
 
 #define SVN_SLEEP_ENV_VAR "SVN_I_LOVE_CORRUPTED_WORKING_COPIES_SO_DISABLE_SLEEP_FOR_TIMESTAMPS"
 
@@ -2389,7 +2390,7 @@ svn_io_get_dirents3(apr_hash_t **dirents
   if (!only_check_type)
     flags |= APR_FINFO_SIZE | APR_FINFO_MTIME;
 
-  *dirents = apr_hash_make(result_pool);
+  *dirents = svn_hash__make(result_pool);
 
   SVN_ERR(svn_io_dir_open(&this_dir, path, scratch_pool));
 

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/skel.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/skel.c?rev=1339210&r1=1339209&r2=1339210&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/skel.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/skel.c Wed May 16 14:57:41 2012
@@ -25,6 +25,7 @@
 #include "svn_error.h"
 #include "private/svn_skel.h"
 #include "private/svn_string_private.h"
+#include "private/svn_subr_private.h"
 
 
 /* Parsing skeletons.  */
@@ -680,7 +681,7 @@ svn_skel__parse_proplist(apr_hash_t **pr
     return skel_err("proplist");
 
   /* Create the returned structure */
-  proplist = apr_hash_make(pool);
+  proplist = svn_hash__make(pool);
   for (elt = skel->children; elt; elt = elt->next->next)
     {
       svn_string_t *value = svn_string_ncreate(elt->next->data,

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/stream.c?rev=1339210&r1=1339209&r2=1339210&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/stream.c Wed May 16 14:57:41 2012
@@ -140,7 +140,7 @@ svn_error_t *
 svn_stream_read(svn_stream_t *stream, char *buffer, apr_size_t *len)
 {
   SVN_ERR_ASSERT(stream->read_fn != NULL);
-  return stream->read_fn(stream->baton, buffer, len);
+  return svn_error_trace(stream->read_fn(stream->baton, buffer, len));
 }
 
 
@@ -148,9 +148,10 @@ svn_error_t *
 svn_stream_skip(svn_stream_t *stream, apr_size_t len)
 {
   if (stream->skip_fn == NULL)
-    return skip_default_handler(stream->baton, len, stream->read_fn);
+    return svn_error_trace(
+            skip_default_handler(stream->baton, len, stream->read_fn));
 
-  return stream->skip_fn(stream->baton, len);
+  return svn_error_trace(stream->skip_fn(stream->baton, len));
 }
 
 
@@ -158,7 +159,7 @@ svn_error_t *
 svn_stream_write(svn_stream_t *stream, const char *data, apr_size_t *len)
 {
   SVN_ERR_ASSERT(stream->write_fn != NULL);
-  return stream->write_fn(stream->baton, data, len);
+  return svn_error_trace(stream->write_fn(stream->baton, data, len));
 }
 
 
@@ -182,7 +183,7 @@ svn_stream_mark(svn_stream_t *stream, sv
   if (stream->mark_fn == NULL)
     return svn_error_create(SVN_ERR_STREAM_SEEK_NOT_SUPPORTED, NULL, NULL);
 
-  return stream->mark_fn(stream->baton, mark, pool);
+  return svn_error_trace(stream->mark_fn(stream->baton, mark, pool));
 }
 
 svn_error_t *
@@ -191,7 +192,7 @@ svn_stream_seek(svn_stream_t *stream, co
   if (stream->seek_fn == NULL)
     return svn_error_create(SVN_ERR_STREAM_SEEK_NOT_SUPPORTED, NULL, NULL);
 
-  return stream->seek_fn(stream->baton, mark);
+  return svn_error_trace(stream->seek_fn(stream->baton, mark));
 }
 
 svn_boolean_t
@@ -208,7 +209,7 @@ svn_stream_close(svn_stream_t *stream)
 {
   if (stream->close_fn == NULL)
     return SVN_NO_ERROR;
-  return stream->close_fn(stream->baton);
+  return svn_error_trace(stream->close_fn(stream->baton));
 }
 
 svn_error_t *
@@ -217,7 +218,7 @@ svn_stream_puts(svn_stream_t *stream,
 {
   apr_size_t len;
   len = strlen(str);
-  return svn_stream_write(stream, str, &len);
+  return svn_error_trace(svn_stream_write(stream, str, &len));
 }
 
 svn_error_t *
@@ -233,7 +234,7 @@ svn_stream_printf(svn_stream_t *stream,
   message = apr_pvsprintf(pool, fmt, ap);
   va_end(ap);
 
-  return svn_stream_puts(stream, message);
+  return svn_error_trace(svn_stream_puts(stream, message));
 }
 
 
@@ -254,7 +255,7 @@ svn_stream_printf_from_utf8(svn_stream_t
   SVN_ERR(svn_utf_cstring_from_utf8_ex2(&translated, message, encoding,
                                         pool));
 
-  return svn_stream_puts(stream, translated);
+  return svn_error_trace(svn_stream_puts(stream, translated));
 }
 
 /* Size that 90% of the lines we encounter will be not longer than.
@@ -414,7 +415,7 @@ stream_readline_chunky(svn_stringbuf_t *
   /* Move the stream read pointer to the first position behind the EOL.
    */
   SVN_ERR(svn_stream_seek(stream, mark));
-  return svn_stream_skip(stream, total_parsed);
+  return svn_error_trace(svn_stream_skip(stream, total_parsed));
 }
 
 /* Guts of svn_stream_readline().
@@ -683,31 +684,31 @@ svn_stream_tee(svn_stream_t *out1,
 static svn_error_t *
 read_handler_disown(void *baton, char *buffer, apr_size_t *len)
 {
-  return svn_stream_read(baton, buffer, len);
+  return svn_error_trace(svn_stream_read(baton, buffer, len));
 }
 
 static svn_error_t *
 skip_handler_disown(void *baton, apr_size_t len)
 {
-  return svn_stream_skip(baton, len);
+  return svn_error_trace(svn_stream_skip(baton, len));
 }
 
 static svn_error_t *
 write_handler_disown(void *baton, const char *buffer, apr_size_t *len)
 {
-  return svn_stream_write(baton, buffer, len);
+  return svn_error_trace(svn_stream_write(baton, buffer, len));
 }
 
 static svn_error_t *
 mark_handler_disown(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
 {
-  return svn_stream_mark(baton, mark, pool);
+  return svn_error_trace(svn_stream_mark(baton, mark, pool));
 }
 
 static svn_error_t *
 seek_handler_disown(void *baton, const svn_stream_mark_t *mark)
 {
-  return svn_stream_seek(baton, mark);
+  return svn_error_trace(svn_stream_seek(baton, mark));
 }
 
 static svn_boolean_t
@@ -768,7 +769,7 @@ read_handler_apr(void *baton, char *buff
     err = svn_io_file_read_full2(btn->file, buffer, *len, len,
                                  &eof, btn->pool);
 
-  return err;
+  return svn_error_trace(err);
 }
 
 static svn_error_t *
@@ -777,7 +778,8 @@ skip_handler_apr(void *baton, apr_size_t
   struct baton_apr *btn = baton;
   apr_off_t offset = len;
 
-  return svn_io_file_seek(btn->file, APR_CUR, &offset, btn->pool);
+  return svn_error_trace(
+            svn_io_file_seek(btn->file, APR_CUR, &offset, btn->pool));
 }
 
 static svn_error_t *
@@ -795,7 +797,7 @@ write_handler_apr(void *baton, const cha
   else
     err = svn_io_file_write_full(btn->file, data, *len, len, btn->pool);
 
-  return err;
+  return svn_error_trace(err);
 }
 
 static svn_error_t *
@@ -803,7 +805,7 @@ close_handler_apr(void *baton)
 {
   struct baton_apr *btn = baton;
 
-  return svn_io_file_close(btn->file, btn->pool);
+  return svn_error_trace(svn_io_file_close(btn->file, btn->pool));
 }
 
 static svn_error_t *
@@ -1130,7 +1132,7 @@ close_handler_gz(void *baton)
     }
 
   if (btn->close != NULL)
-    return btn->close(btn->subbaton);
+    return svn_error_trace(btn->close(btn->subbaton));
   else
     return SVN_NO_ERROR;
 }
@@ -1205,7 +1207,7 @@ write_handler_checksum(void *baton, cons
   if (btn->write_checksum && *len > 0)
     SVN_ERR(svn_checksum_update(btn->write_ctx, buffer, *len));
 
-  return svn_stream_write(btn->proxy, buffer, len);
+  return svn_error_trace(svn_stream_write(btn->proxy, buffer, len));
 }
 
 
@@ -1234,7 +1236,7 @@ close_handler_checksum(void *baton)
   if (btn->write_ctx)
     SVN_ERR(svn_checksum_final(btn->write_checksum, btn->write_ctx, btn->pool));
 
-  return svn_stream_close(btn->proxy);
+  return svn_error_trace(svn_stream_close(btn->proxy));
 }
 
 
@@ -1290,21 +1292,21 @@ static svn_error_t *
 read_handler_md5(void *baton, char *buffer, apr_size_t *len)
 {
   struct md5_stream_baton *btn = baton;
-  return svn_stream_read(btn->proxy, buffer, len);
+  return svn_error_trace(svn_stream_read(btn->proxy, buffer, len));
 }
 
 static svn_error_t *
 skip_handler_md5(void *baton, apr_size_t len)
 {
   struct md5_stream_baton *btn = baton;
-  return svn_stream_skip(btn->proxy, len);
+  return svn_error_trace(svn_stream_skip(btn->proxy, len));
 }
 
 static svn_error_t *
 write_handler_md5(void *baton, const char *buffer, apr_size_t *len)
 {
   struct md5_stream_baton *btn = baton;
-  return svn_stream_write(btn->proxy, buffer, len);
+  return svn_error_trace(svn_stream_write(btn->proxy, buffer, len));
 }
 
 static svn_error_t *

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c?rev=1339210&r1=1339209&r2=1339210&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c Wed May 16 14:57:41 2012
@@ -51,6 +51,7 @@
 #include "private/svn_skel.h"
 #include "private/svn_wc_private.h"
 #include "private/svn_token.h"
+#include "private/svn_subr_private.h"
 
 
 #define NOT_IMPLEMENTED() SVN__NOT_IMPLEMENTED()
@@ -1186,7 +1187,7 @@ gather_children2(const apr_array_header_
                  apr_pool_t *result_pool,
                  apr_pool_t *scratch_pool)
 {
-  apr_hash_t *names_hash = apr_hash_make(scratch_pool);
+  apr_hash_t *names_hash = svn_hash__make(scratch_pool);
   apr_array_header_t *names_array;
 
   /* All of the names get allocated in RESULT_POOL.  It
@@ -1210,7 +1211,7 @@ gather_children(const apr_array_header_t
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
 {
-  apr_hash_t *names_hash = apr_hash_make(scratch_pool);
+  apr_hash_t *names_hash = svn_hash__make(scratch_pool);
   apr_array_header_t *names_array;
 
   /* All of the names get allocated in RESULT_POOL.  It
@@ -2210,7 +2211,7 @@ svn_wc__db_base_get_children_info(apr_ha
                               dir_abspath, scratch_pool, scratch_pool));
   VERIFY_USABLE_WCROOT(wcroot);
 
-  *nodes = apr_hash_make(result_pool);
+  *nodes = svn_hash__make(result_pool);
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_SELECT_BASE_CHILDREN_INFO));
@@ -7687,8 +7688,8 @@ svn_wc__db_read_children_info(apr_hash_t
   svn_wc__db_wcroot_t *wcroot;
   const char *dir_relpath;
 
-  *conflicts = apr_hash_make(result_pool);
-  *nodes = apr_hash_make(result_pool);
+  *conflicts = svn_hash__make(result_pool);
+  *nodes = svn_hash__make(result_pool);
   SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
 
   SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &dir_relpath, db,
@@ -7881,7 +7882,7 @@ svn_wc__db_read_children_walker_info(apr
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, dir_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
 
-  *nodes = apr_hash_make(result_pool);
+  *nodes = svn_hash__make(result_pool);
   while (have_row)
     {
       struct svn_wc__db_walker_info_t *child;

Modified: subversion/branches/ev2-export/subversion/svnsync/sync.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svnsync/sync.c?rev=1339210&r1=1339209&r2=1339210&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svnsync/sync.c (original)
+++ subversion/branches/ev2-export/subversion/svnsync/sync.c Wed May 16 14:57:41 2012
@@ -225,9 +225,7 @@ add_directory(const char *path,
   edit_baton_t *eb = pb->edit_baton;
   node_baton_t *b = apr_palloc(pool, sizeof(*b));
 
-  /* if copyfrom_path starts with '/' join rest of copyfrom_path leaving
-   * leading '/' with canonicalized url eb->to_url.
-   */
+  /* if copyfrom_path is an fspath create a proper uri */
   if (copyfrom_path && copyfrom_path[0] == '/')
     copyfrom_path = svn_path_url_add_component2(eb->to_url,
                                                 copyfrom_path + 1, pool);
@@ -276,9 +274,10 @@ add_file(const char *path,
   edit_baton_t *eb = pb->edit_baton;
   node_baton_t *fb = apr_palloc(pool, sizeof(*fb));
 
-  if (copyfrom_path)
-    copyfrom_path = apr_psprintf(pool, "%s%s", eb->to_url,
-                                 svn_path_uri_encode(copyfrom_path, pool));
+  /* if copyfrom_path is an fspath create a proper uri */
+  if (copyfrom_path && copyfrom_path[0] == '/')
+    copyfrom_path = svn_path_url_add_component2(eb->to_url,
+                                                copyfrom_path + 1, pool);
 
   SVN_ERR(eb->wrapped_editor->add_file(path, pb->wrapped_node_baton,
                                        copyfrom_path, copyfrom_rev,

Modified: subversion/branches/ev2-export/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/authz_tests.py?rev=1339210&r1=1339209&r2=1339210&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/authz_tests.py Wed May 16 14:57:41 2012
@@ -1398,6 +1398,59 @@ def upgrade_absent(sbox):
   svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output,
                                         None, None)
 
+@Issue(4183)
+@XFail()
+@Skip(svntest.main.is_ra_type_file)
+def remove_subdir_with_authz_and_tc(sbox):
+  "remove a subdir with authz file"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_rm('A/B')
+  sbox.simple_commit()
+
+  svntest.main.write_restrictive_svnserve_conf(sbox.repo_dir)
+  svntest.main.write_authz_file(sbox, { "/"      : "*=rw",
+                                        "/A/B/E" : "*="})
+
+  # Now update back to r1. This will reintroduce A/B except A/B/E.
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.remove('A/B/E', 'A/B/E/alpha', 'A/B/E/beta')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B'               : Item(status='A '),
+    'A/B/F'             : Item(status='A '),
+    'A/B/lambda'        : Item(status='A '),
+  })
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        None,
+                                        expected_status,
+                                        None,
+                                        None, None,
+                                        None, None, False,
+                                        wc_dir, '-r', '1')
+
+  # Perform some edit operation to introduce a tree conflict
+  svntest.main.file_write(sbox.ospath('A/B/lambda'), 'qq')
+
+  # And now update to r2. This tries to delete A/B and causes a tree conflict
+  # ### But is also causes an error in creating the copied state
+  # ###  svn: E220001: Cannot copy '<snip>\A\B\E' excluded by server
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B'               : Item(status='  ', treeconflict='C'),
+  })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        None,
+                                        None,
+                                        None,
+                                        None, None,
+                                        None, None, False,
+                                        wc_dir)
+
 ########################################################################
 # Run the tests
 
@@ -1427,6 +1480,7 @@ test_list = [ None,
               wc_delete,
               wc_commit_error_handling,
               upgrade_absent,
+              remove_subdir_with_authz_and_tc
              ]
 serial_only = True
 

Modified: subversion/branches/ev2-export/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/diff_tests.py?rev=1339210&r1=1339209&r2=1339210&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/diff_tests.py Wed May 16 14:57:41 2012
@@ -2584,6 +2584,52 @@ def basic_diff_summarize(sbox):
   wc_dir = sbox.wc_dir
   p = sbox.ospath
 
+  # Diff summarize of a newly added file
+  expected_diff = svntest.wc.State(wc_dir, {
+    'iota': Item(status='A '),
+    })
+  svntest.actions.run_and_verify_diff_summarize(expected_diff,
+                                                p('iota'), '-c1')
+
+  # Reverse summarize diff of a newly added file
+  expected_diff = svntest.wc.State(wc_dir, {
+    'iota': Item(status='D '),
+    })
+  svntest.actions.run_and_verify_diff_summarize(expected_diff,
+                                                p('iota'), '-c-1')
+
+  # Diff summarize of a newly added directory
+  expected_diff = svntest.wc.State(wc_dir, {
+    'A/D':          Item(status='A '),
+    'A/D/gamma':    Item(status='A '),
+    'A/D/H':        Item(status='A '),
+    'A/D/H/chi':    Item(status='A '),
+    'A/D/H/psi':    Item(status='A '),
+    'A/D/H/omega':  Item(status='A '),
+    'A/D/G':        Item(status='A '),
+    'A/D/G/pi':     Item(status='A '),
+    'A/D/G/rho':    Item(status='A '),
+    'A/D/G/tau':    Item(status='A '),
+    })
+  svntest.actions.run_and_verify_diff_summarize(expected_diff,
+                                                p('A/D'), '-c1')
+
+  # Reverse summarize diff of a newly added directory
+  expected_diff = svntest.wc.State(wc_dir, {
+    'A/D':          Item(status='D '),
+    'A/D/gamma':    Item(status='D '),
+    'A/D/H':        Item(status='D '),
+    'A/D/H/chi':    Item(status='D '),
+    'A/D/H/psi':    Item(status='D '),
+    'A/D/H/omega':  Item(status='D '),
+    'A/D/G':        Item(status='D '),
+    'A/D/G/pi':     Item(status='D '),
+    'A/D/G/rho':    Item(status='D '),
+    'A/D/G/tau':    Item(status='D '),
+    })
+  svntest.actions.run_and_verify_diff_summarize(expected_diff,
+                                                p('A/D'), '-c-1')
+
   # Add props to some items that will be deleted, and commit.
   sbox.simple_propset('prop', 'val',
                       'A/C',
@@ -3878,6 +3924,141 @@ def diff_two_working_copies(sbox):
                                      'diff', '--old', wc_dir_old,
                                      '--new', wc_dir)
 
+def diff_deleted_url(sbox):
+  "diff -cN of URL deleted in rN"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # remove A/D/H in r2
+  sbox.simple_rm("A/D/H")
+  sbox.simple_commit()
+
+  # A diff of r2 with target A/D/H should show the removed children
+  expected_output = make_diff_header("chi", "revision 1", "revision 2") + [
+                      "@@ -1 +0,0 @@\n",
+                      "-This is the file 'chi'.\n",
+                    ] + make_diff_header("omega", "revision 1",
+                                         "revision 2") + [
+                      "@@ -1 +0,0 @@\n",
+                      "-This is the file 'omega'.\n",
+                    ] + make_diff_header("psi", "revision 1",
+                                         "revision 2") + [
+                      "@@ -1 +0,0 @@\n",
+                      "-This is the file 'psi'.\n",
+                    ]
+
+  # Files in diff may be in any order.
+  expected_output = svntest.verify.UnorderedOutput(expected_output)
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'diff', '-c2',
+                                     sbox.repo_url + '/A/D/H')
+
+def diff_arbitrary_files_and_dirs(sbox):
+  "diff arbitrary files and dirs"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # diff iota with A/mu
+  expected_output = make_diff_header("mu", "working copy", "working copy",
+                                     "iota", "A/mu") + [
+                      "@@ -1 +1 @@\n",
+                      "-This is the file 'iota'.\n",
+                      "+This is the file 'mu'.\n"
+                    ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'diff', '--old', sbox.ospath('iota'),
+                                     '--new', sbox.ospath('A/mu'))
+
+  # diff A/B/E with A/D
+  expected_output = make_diff_header("G/pi", "working copy", "working copy",
+                                     "B/E", "D") + [
+                      "@@ -0,0 +1 @@\n",
+                      "+This is the file 'pi'.\n"
+                    ] + make_diff_header("G/rho", "working copy",
+                                         "working copy", "B/E", "D") + [
+                      "@@ -0,0 +1 @@\n",
+                      "+This is the file 'rho'.\n"
+                    ] + make_diff_header("G/tau", "working copy",
+                                         "working copy", "B/E", "D") + [
+                      "@@ -0,0 +1 @@\n",
+                      "+This is the file 'tau'.\n"
+                    ] + make_diff_header("H/chi", "working copy",
+                                         "working copy", "B/E", "D") + [
+                      "@@ -0,0 +1 @@\n",
+                      "+This is the file 'chi'.\n"
+                    ] + make_diff_header("H/omega", "working copy",
+                                         "working copy", "B/E", "D") + [
+                      "@@ -0,0 +1 @@\n",
+                      "+This is the file 'omega'.\n"
+                    ] + make_diff_header("H/psi", "working copy",
+                                         "working copy", "B/E", "D") + [
+                      "@@ -0,0 +1 @@\n",
+                      "+This is the file 'psi'.\n"
+                    ] + make_diff_header("alpha", "working copy",
+                                         "working copy", "B/E", "D") + [
+                      "@@ -1 +0,0 @@\n",
+                      "-This is the file 'alpha'.\n"
+                    ] + make_diff_header("beta", "working copy",
+                                         "working copy", "B/E", "D") + [
+                      "@@ -1 +0,0 @@\n",
+                      "-This is the file 'beta'.\n"
+                    ] + make_diff_header("gamma", "working copy",
+                                         "working copy", "B/E", "D") + [
+                      "@@ -0,0 +1 @@\n",
+                      "+This is the file 'gamma'.\n"
+                    ]
+
+  # Files in diff may be in any order.
+  expected_output = svntest.verify.UnorderedOutput(expected_output)
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'diff', '--old', sbox.ospath('A/B/E'),
+                                     '--new', sbox.ospath('A/D'))
+
+def diff_properties_only(sbox):
+  "diff --properties-only"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  expected_output = \
+    make_diff_header("iota", "revision 1", "revision 2") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_added("svn:eol-style", "native")
+
+  expected_reverse_output = \
+    make_diff_header("iota", "revision 2", "revision 1") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_deleted("svn:eol-style", "native")
+
+  expected_rev1_output = \
+    make_diff_header("iota", "revision 1", "working copy") + \
+    make_diff_prop_header("iota") + \
+    make_diff_prop_added("svn:eol-style", "native")
+
+  # Make a property change and a content change to 'iota'
+  # Only the property change should be displayed by diff --properties-only
+  sbox.simple_propset('svn:eol-style', 'native', 'iota')
+  svntest.main.file_append(sbox.ospath('iota'), 'new text\n')
+
+  sbox.simple_commit() # r2
+
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'diff', '--properties-only', '-r', '1:2',
+                                     sbox.repo_url + '/iota')
+
+  svntest.actions.run_and_verify_svn(None, expected_reverse_output, [],
+                                     'diff', '--properties-only', '-r', '2:1',
+                                     sbox.repo_url + '/iota')
+
+  os.chdir(wc_dir)
+  svntest.actions.run_and_verify_svn(None, expected_rev1_output, [],
+                                     'diff', '--properties-only', '-r', '1',
+                                     'iota')
+
+  svntest.actions.run_and_verify_svn(None, expected_rev1_output, [],
+                                     'diff', '--properties-only',
+                                     '-r', 'PREV', 'iota')
+
 ########################################################################
 #Run the tests
 
@@ -3946,6 +4127,9 @@ test_list = [ None,
               no_spurious_conflict,
               diff_correct_wc_base_revnum,
               diff_two_working_copies,
+              diff_deleted_url,
+              diff_arbitrary_files_and_dirs,
+              diff_properties_only,
               ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ev2-export/subversion/tests/cmdline/import_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/import_tests.py?rev=1339210&r1=1339209&r2=1339210&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/import_tests.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/import_tests.py Wed May 16 14:57:41 2012
@@ -298,6 +298,7 @@ def import_avoid_empty_revision(sbox):
 #----------------------------------------------------------------------
 
 # test for issue 2433: "import" does not handle eol-style correctly
+# and for normalising files with mixed line-endings upon import (r1205193)
 @Issue(2433)
 def import_eol_style(sbox):
   "import should honor the eol-style property"
@@ -315,6 +316,7 @@ enable-auto-props = yes
 
 [auto-props]
 *.dsp = svn:eol-style=CRLF
+*.txt = svn:eol-style=native
 '''
   tmp_dir = os.path.abspath(svntest.main.temp_dir)
   config_dir = os.path.join(tmp_dir, 'autoprops_config')
@@ -369,6 +371,26 @@ enable-auto-props = yes
                                      file_path,
                                      '--config-dir', config_dir)
 
+  # create a file with inconsistent EOLs and eol-style=native, and import it
+  file_name = "test.txt"
+  file_path = file_name
+  imp_dir_path = 'dir2'
+  imp_file_path = os.path.join(imp_dir_path, file_name)
+
+  os.mkdir(imp_dir_path, 0755)
+  svntest.main.file_append_binary(imp_file_path,
+                                  "This is file test.txt.\n" + \
+                                  "The second line.\r\n" + \
+                                  "The third line.\r")
+
+  # The import should succeed and not error out
+  svntest.actions.run_and_verify_svn(None, None, [], 'import',
+                                     '-m', 'Log message for new import',
+                                     imp_dir_path,
+                                     sbox.repo_url,
+                                     '--config-dir', config_dir)
+
+
 #----------------------------------------------------------------------
 @Issue(3983)
 def import_into_foreign_repo(sbox):

Modified: subversion/branches/ev2-export/subversion/tests/cmdline/log_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/log_tests.py?rev=1339210&r1=1339209&r2=1339210&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/log_tests.py Wed May 16 14:57:41 2012
@@ -2209,7 +2209,6 @@ def log_xml_old(sbox):
 
 
 @Issue(4153)
-@XFail(svntest.main.is_ra_type_dav)
 def log_diff_moved(sbox):
   "log --diff on moved file"
 
@@ -2225,7 +2224,7 @@ def log_diff_moved(sbox):
   mu_at_1 = sbox.repo_url + '/A/mu@1'
   mu3_at_3 = sbox.repo_url + '/A/mu3@3'
 
-  r1diff = [make_diff_header('A/mu', 'revision 0', 'revision 1')
+  r1diff = [make_diff_header('mu', 'revision 0', 'revision 1')
             + ["@@ -0,0 +1 @@\n",
                "+This is the file 'mu'.\n"]]
 



Mime
View raw message