Modified: subversion/branches/authzperf/subversion/mod_dav_svn/reports/log.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/reports/log.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/reports/log.c 
(original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/reports/log.c Thu Oct 
13 15:25:15 2016
@@ -50,7 +50,7 @@ struct log_receiver_baton
   apr_bucket_brigade *bb;
 
   /* where to deliver the output */
-  ap_filter_t *output;
+  dav_svn__output *output;
 
   /* Whether we've written the <S:log-report> header.  Allows for lazy
      writes to support mod_dav-based error handling. */
@@ -334,25 +334,17 @@ log_revision_receiver(void *baton,
   lrb->result_count++;
   if (lrb->result_count == lrb->next_forced_flush)
     {
-      apr_status_t apr_err;
+      apr_bucket *bkt;
 
-      /* This flush is similar to that in dav_svn__final_flush_or_error().
-
-         Compared to using ap_filter_flush(), which we use in other place
+      /* Compared to using ap_filter_flush(), which we use in other place
          this adds a flush frame before flushing the brigade, to make output
          filters perform a flush as well */
 
       /* No brigade empty check. We want output filters to flush anyway */
-      apr_err = ap_fflush(lrb->output, lrb->bb);
-      if (apr_err)
-        return svn_error_create(apr_err, NULL, NULL);
-
-      /* Check for an aborted connection, just like our brigade write
-         helper functions, since the brigade functions don't appear to
-         be return useful errors when the connection is dropped. */
-      if (lrb->output->c->aborted)
-        return svn_error_create(SVN_ERR_APMOD_CONNECTION_ABORTED,
-                                NULL, NULL);
+      bkt = apr_bucket_flush_create(
+                dav_svn__output_get_bucket_alloc(lrb->output));
+      APR_BRIGADE_INSERT_TAIL(lrb->bb, bkt);
+      SVN_ERR(dav_svn__output_pass_brigade(lrb->output, lrb->bb));
 
       if (lrb->result_count < 256)
         lrb->next_forced_flush = lrb->next_forced_flush * 4;
@@ -365,7 +357,7 @@ log_revision_receiver(void *baton,
 dav_error *
 dav_svn__log_report(const dav_resource *resource,
                     const apr_xml_doc *doc,
-                    ap_filter_t *output)
+                    dav_svn__output *output)
 {
   svn_error_t *serr;
   dav_error *derr = NULL;
@@ -497,7 +489,7 @@ dav_svn__log_report(const dav_resource *
 
   /* Build log receiver baton */
   lrb.bb = apr_brigade_create(resource->pool,  /* not the subpool! */
-                              output->c->bucket_alloc);
+                              dav_svn__output_get_bucket_alloc(output));
   lrb.output = output;
   lrb.needs_header = TRUE;
   lrb.needs_log_item = TRUE;

Modified: 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/mergeinfo.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/reports/mergeinfo.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/reports/mergeinfo.c 
(original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/reports/mergeinfo.c 
Thu Oct 13 15:25:15 2016
@@ -46,7 +46,7 @@
 dav_error *
 dav_svn__get_mergeinfo_report(const dav_resource *resource,
                               const apr_xml_doc *doc,
-                              ap_filter_t *output)
+                              dav_svn__output *output)
 {
   svn_error_t *serr;
   dav_error *derr = NULL;
@@ -124,7 +124,8 @@ dav_svn__get_mergeinfo_report(const dav_
   arb.repos = resource->info->repos;
 
   /* Build mergeinfo brigade */
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
   serr = svn_repos_fs_get_mergeinfo(&catalog, repos->repos, paths, rev,
                                     inherit, include_descendants,

Modified: subversion/branches/authzperf/subversion/mod_dav_svn/reports/replay.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/reports/replay.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/reports/replay.c 
(original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/reports/replay.c Thu 
Oct 13 15:25:15 2016
@@ -44,7 +44,7 @@
 
 typedef struct edit_baton_t {
   apr_bucket_brigade *bb;
-  ap_filter_t *output;
+  dav_svn__output *output;
   svn_boolean_t started;
   svn_boolean_t sending_textdelta;
   int compression_level;
@@ -367,7 +367,7 @@ static void
 make_editor(const svn_delta_editor_t **editor,
             void **edit_baton,
             apr_bucket_brigade *bb,
-            ap_filter_t *output,
+            dav_svn__output *output,
             int compression_level,
             apr_pool_t *pool)
 {
@@ -413,7 +413,7 @@ malformed_element_error(const char *tagn
 dav_error *
 dav_svn__replay_report(const dav_resource *resource,
                        const apr_xml_doc *doc,
-                       ap_filter_t *output)
+                       dav_svn__output *output)
 {
   dav_error *derr = NULL;
   svn_revnum_t low_water_mark = SVN_INVALID_REVNUM;
@@ -530,7 +530,8 @@ dav_svn__replay_report(const dav_resourc
   if (! base_dir)
     base_dir = "";
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
   if ((err = svn_fs_revision_root(&root, resource->info->repos->fs, rev,
                                   resource->pool)))

Modified: subversion/branches/authzperf/subversion/mod_dav_svn/reports/update.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/reports/update.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/reports/update.c 
(original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/reports/update.c Thu 
Oct 13 15:25:15 2016
@@ -68,7 +68,7 @@ typedef struct update_ctx_t {
   apr_bucket_brigade *bb;
 
   /* where to deliver the output */
-  ap_filter_t *output;
+  dav_svn__output *output;
 
   /* where do these editor paths *really* point to? */
   apr_hash_t *pathmap;
@@ -954,7 +954,7 @@ validate_input_revision(svn_revnum_t rev
 dav_error *
 dav_svn__update_report(const dav_resource *resource,
                        const apr_xml_doc *doc,
-                       ap_filter_t *output)
+                       dav_svn__output *output)
 {
   svn_delta_editor_t *editor;
   apr_xml_elem *child;
@@ -1202,7 +1202,8 @@ dav_svn__update_report(const dav_resourc
   uc.output = output;
   uc.anchor = src_path;
   uc.target = target;
-  uc.bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  uc.bb = apr_brigade_create(resource->pool,
+                             dav_svn__output_get_bucket_alloc(output));
   uc.pathmap = NULL;
   uc.enable_v2_response = ((resource->info->restype == DAV_SVN_RESTYPE_ME)
                            && (resource->info->repos->v2_protocol));

Modified: subversion/branches/authzperf/subversion/mod_dav_svn/repos.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/repos.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/repos.c Thu Oct 13 
15:25:15 2016
@@ -3236,8 +3236,8 @@ set_headers(request_rec *r, const dav_re
 
 
 typedef struct diff_ctx_t {
-  ap_filter_t *output;
-  apr_pool_t *pool;
+  dav_svn__output *output;
+  apr_bucket_brigade *bb;
 } diff_ctx_t;
 
 
@@ -3245,18 +3245,9 @@ static svn_error_t *  __attribute__((war
 write_to_filter(void *baton, const char *buffer, apr_size_t *len)
 {
   diff_ctx_t *dc = baton;
-  apr_bucket_brigade *bb;
-  apr_bucket *bkt;
-  apr_status_t status;
 
   /* take the current data and shove it into the filter */
-  bb = apr_brigade_create(dc->pool, dc->output->c->bucket_alloc);
-  bkt = apr_bucket_transient_create(buffer, *len, dc->output->c->bucket_alloc);
-  APR_BRIGADE_INSERT_TAIL(bb, bkt);
-  if ((status = ap_pass_brigade(dc->output, bb)) != APR_SUCCESS) {
-    return svn_error_create(status, NULL,
-                            "Could not write data to filter");
-  }
+  SVN_ERR(dav_svn__brigade_write(dc->bb, dc->output, buffer, *len));
 
   return SVN_NO_ERROR;
 }
@@ -3266,28 +3257,270 @@ static svn_error_t *  __attribute__((war
 close_filter(void *baton)
 {
   diff_ctx_t *dc = baton;
-  apr_bucket_brigade *bb;
   apr_bucket *bkt;
-  apr_status_t status;
 
   /* done with the file. write an EOS bucket now. */
-  bb = apr_brigade_create(dc->pool, dc->output->c->bucket_alloc);
-  bkt = apr_bucket_eos_create(dc->output->c->bucket_alloc);
-  APR_BRIGADE_INSERT_TAIL(bb, bkt);
-  if ((status = ap_pass_brigade(dc->output, bb)) != APR_SUCCESS)
-    return svn_error_create(status, NULL, "Could not write EOS to filter");
+  bkt = apr_bucket_eos_create(dav_svn__output_get_bucket_alloc(dc->output));
+  APR_BRIGADE_INSERT_TAIL(dc->bb, bkt);
+  SVN_ERR(dav_svn__output_pass_brigade(dc->output, dc->bb));
+
+  return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+emit_collection_head(const dav_resource *resource,
+                     apr_bucket_brigade *bb,
+                     dav_svn__output *output,
+                     svn_boolean_t gen_html,
+                     apr_pool_t *pool)
+{
+  /* XML schema for the directory index if xslt_uri is set:
+
+     <?xml version="1.0"?>
+     <?xml-stylesheet type="text/xsl" href="[info->repos->xslt_uri]"?> */
+  static const char xml_index_dtd[] =
+    "<!DOCTYPE svn [\n"
+    "  <!ELEMENT svn   (index)>\n"
+    "  <!ATTLIST svn   version CDATA #REQUIRED\n"
+    "                  href    CDATA #REQUIRED>\n"
+    "  <!ELEMENT index (updir?, (file | dir)*)>\n"
+    "  <!ATTLIST index name    CDATA #IMPLIED\n"
+    "                  path    CDATA #IMPLIED\n"
+    "                  rev     CDATA #IMPLIED\n"
+    "                  base    CDATA #IMPLIED>\n"
+    "  <!ELEMENT updir EMPTY>\n"
+    "  <!ATTLIST updir href    CDATA #REQUIRED>\n"
+    "  <!ELEMENT file  EMPTY>\n"
+    "  <!ATTLIST file  name    CDATA #REQUIRED\n"
+    "                  href    CDATA #REQUIRED>\n"
+    "  <!ELEMENT dir   EMPTY>\n"
+    "  <!ATTLIST dir   name    CDATA #REQUIRED\n"
+    "                  href    CDATA #REQUIRED>\n"
+    "]>\n";
+
+  if (gen_html)
+    {
+      const char *title;
+      if (resource->info->repos_path == NULL)
+        title = "unknown location";
+      else
+        title = resource->info->repos_path;
+
+      if (resource->info->restype != DAV_SVN_RESTYPE_PARENTPATH_COLLECTION)
+        {
+          if (SVN_IS_VALID_REVNUM(resource->info->root.rev))
+            title = apr_psprintf(pool,
+                                 "Revision %ld: %s",
+                                 resource->info->root.rev, title);
+          if (resource->info->repos->repo_basename)
+            title = apr_psprintf(pool, "%s - %s",
+                                 resource->info->repos->repo_basename,
+                                 title);
+          if (resource->info->repos->repo_name)
+            title = apr_psprintf(pool, "%s: %s",
+                                 resource->info->repos->repo_name,
+                                 title);
+        }
+
+      SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                      "<html><head><title>%s</title></head>\n"
+                                      "<body>\n <h2>%s</h2>\n <ul>\n",
+                                      title, title));
+    }
+  else
+    {
+      const char *name = resource->info->repos->repo_name;
+      const char *href = resource->info->repos_path;
+      const char *base = resource->info->repos->repo_basename;
+
+      SVN_ERR(dav_svn__brigade_puts(bb, output, "<?xml version=\"1.0\"?>\n"));
+      SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                      "<?xml-stylesheet type=\"text/xsl\" "
+                                      "href=\"%s\"?>\n",
+                                      resource->info->repos->xslt_uri));
+      SVN_ERR(dav_svn__brigade_puts(bb, output, xml_index_dtd));
+      SVN_ERR(dav_svn__brigade_puts(bb, output,
+                         "<svn version=\"" SVN_VERSION "\"\n"
+                         "     href=\"http://subversion.apache.org/\";>\n"));
+      SVN_ERR(dav_svn__brigade_puts(bb, output, "  <index"));
+
+      if (name)
+        SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                        " name=\"%s\"",
+                                        apr_xml_quote_string(resource->pool,
+                                                             name, 1)));
+      if (SVN_IS_VALID_REVNUM(resource->info->root.rev))
+        SVN_ERR(dav_svn__brigade_printf(bb, output, " rev=\"%ld\"",
+                                        resource->info->root.rev));
+      if (href)
+        SVN_ERR(dav_svn__brigade_printf(bb, output, " path=\"%s\"",
+                                        apr_xml_quote_string(resource->pool,
+                                                             href, 1)));
+      if (base)
+        SVN_ERR(dav_svn__brigade_printf(bb, output, " base=\"%s\"", base));
+
+      SVN_ERR(dav_svn__brigade_puts(bb, output, ">\n"));
+    }
+
+  if ((resource->info->restype != DAV_SVN_RESTYPE_PARENTPATH_COLLECTION)
+      && resource->info->repos_path
+      && ((resource->info->repos_path[1] != '\0')
+          || dav_svn__get_list_parentpath_flag(resource->info->r)))
+    {
+      const char *href;
+      if (resource->info->pegged)
+        {
+          href = apr_psprintf(pool, "../?p=%ld", resource->info->root.rev);
+        }
+      else
+        {
+          href = "../";
+        }
+
+      if (gen_html)
+        {
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                          "  <li><a href=\"%s\">..</a></li>\n",
+                                          href));
+        }
+      else
+        {
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                          "    <updir href=\"%s\"/>\n",
+                                          href));
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+emit_collection_entry(const dav_resource *resource,
+                      apr_bucket_brigade *bb,
+                      dav_svn__output *output,
+                      const svn_fs_dirent_t *entry,
+                      svn_boolean_t gen_html,
+                      apr_pool_t *pool)
+{
+  const char *name = entry->name;
+  const char *href = name;
+  svn_boolean_t is_dir = (entry->kind == svn_node_dir);
+
+  /* append a trailing slash onto the name for directories. we NEED
+     this for the href portion so that the relative reference will
+     descend properly. for the visible portion, it is just nice. */
+  /* ### The xml output doesn't like to see a trailing slash on
+     ### the visible portion, so avoid that. */
+  if (is_dir)
+    href = apr_pstrcat(pool, href, "/", SVN_VA_NULL);
+
+  if (gen_html)
+    name = href;
+
+  /* We quote special characters in both XML and HTML. */
+  name = apr_xml_quote_string(pool, name, !gen_html);
+
+  /* According to httpd-2.0.54/include/httpd.h, ap_os_escape_path()
+     behaves differently on different platforms.  It claims to
+     "convert an OS path to a URL in an OS dependant way".
+     Nevertheless, there appears to be only one implementation
+     of the function in httpd, and the code seems completely
+     platform independent, so we'll assume it's appropriate for
+     mod_dav_svn to use it to quote outbound paths. */
+  href = ap_os_escape_path(pool, href, 0);
+  href = apr_xml_quote_string(pool, href, 1);
+
+  if (gen_html)
+    {
+      /* If our directory was access using the public peg-rev
+         CGI query interface, we'll let its dirents carry that
+         peg-rev, too. */
+      if (resource->info->pegged)
+        {
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
+                     "  <li><a href=\"%s?p=%ld\">%s</a></li>\n",
+                     href, resource->info->root.rev, name));
+        }
+      else
+        {
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
+                     "  <li><a href=\"%s\">%s</a></li>\n",
+                     href, name));
+        }
+    }
+  else
+    {
+      const char *const tag = (is_dir ? "dir" : "file");
+
+      /* This is where we could search for props */
+
+      /* If our directory was access using the public peg-rev
+         CGI query interface, we'll let its dirents carry that
+         peg-rev, too. */
+      if (resource->info->pegged)
+        {
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
+                     "    <%s name=\"%s\" href=\"%s?p=%ld\" />\n",
+                     tag, name, href, resource->info->root.rev));
+        }
+      else
+        {
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
+                     "    <%s name=\"%s\" href=\"%s\" />\n",
+                     tag, name, href));
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+emit_collection_tail(const dav_resource *resource,
+                     apr_bucket_brigade *bb,
+                     dav_svn__output *output,
+                     svn_boolean_t gen_html,
+                     apr_pool_t *pool)
+{
+  if (gen_html)
+    {
+      if (strcmp(ap_psignature("FOO", resource->info->r), "") != 0)
+        {
+          /* Apache's signature generation code didn't eat our prefix.
+             ServerSignature must be enabled.  Print our version info.
+
+             WARNING: This is a kludge!! ap_psignature() doesn't promise
+             to return the empty string when ServerSignature is off.  We
+             know it does by code inspection, but this behavior is subject
+             to change. (Perhaps we should try to get the Apache folks to
+             make this promise, though.  Seems harmless/useful enough...)
+          */
+          SVN_ERR(dav_svn__brigade_puts(bb, output,
+                   " </ul>\n <hr noshade><em>Powered by "
+                   "<a href=\"http://subversion.apache.org/\";>"
+                   "Apache Subversion"
+                   "</a> version " SVN_VERSION "."
+                   "</em>\n</body></html>"));
+        }
+      else
+        SVN_ERR(dav_svn__brigade_puts(bb, output, " </ul>\n</body></html>"));
+    }
+  else
+    SVN_ERR(dav_svn__brigade_puts(bb, output, "  </index>\n</svn>\n"));
 
   return SVN_NO_ERROR;
 }
 
 
 static dav_error *
-deliver(const dav_resource *resource, ap_filter_t *output)
+deliver(const dav_resource *resource, ap_filter_t *unused)
 {
   svn_error_t *serr;
   apr_bucket_brigade *bb;
   apr_bucket *bkt;
-  apr_status_t status;
+  dav_svn__output *output;
 
   /* Check resource type */
   if (resource->baselined
@@ -3300,39 +3533,17 @@ deliver(const dav_resource *resource, ap
                                 "Cannot GET this type of resource.");
     }
 
+  output = dav_svn__output_create(resource->info->r, resource->pool);
+
   if (resource->collection)
     {
       const int gen_html = !resource->info->repos->xslt_uri;
       apr_hash_t *entries;
-      apr_pool_t *entry_pool;
+      apr_pool_t *iterpool;
       apr_array_header_t *sorted;
       svn_revnum_t dir_rev = SVN_INVALID_REVNUM;
       int i;
 
-      /* XML schema for the directory index if xslt_uri is set:
-
-         <?xml version="1.0"?>
-         <?xml-stylesheet type="text/xsl" href="[info->repos->xslt_uri]"?> */
-      static const char xml_index_dtd[] =
-        "<!DOCTYPE svn [\n"
-        "  <!ELEMENT svn   (index)>\n"
-        "  <!ATTLIST svn   version CDATA #REQUIRED\n"
-        "                  href    CDATA #REQUIRED>\n"
-        "  <!ELEMENT index (updir?, (file | dir)*)>\n"
-        "  <!ATTLIST index name    CDATA #IMPLIED\n"
-        "                  path    CDATA #IMPLIED\n"
-        "                  rev     CDATA #IMPLIED\n"
-        "                  base    CDATA #IMPLIED>\n"
-        "  <!ELEMENT updir EMPTY>\n"
-        "  <!ATTLIST updir href    CDATA #REQUIRED>\n"
-        "  <!ELEMENT file  EMPTY>\n"
-        "  <!ATTLIST file  name    CDATA #REQUIRED\n"
-        "                  href    CDATA #REQUIRED>\n"
-        "  <!ELEMENT dir   EMPTY>\n"
-        "  <!ATTLIST dir   name    CDATA #REQUIRED\n"
-        "                  href    CDATA #REQUIRED>\n"
-        "]>\n";
-
       /* <svn version="1.3.0 (dev-build)"
               href="http://subversion.apache.org";>
            <index name="[info->repos->repo_name]"
@@ -3413,99 +3624,21 @@ deliver(const dav_resource *resource, ap
                                         resource->pool);
         }
 
-      bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
-
-      if (gen_html)
-        {
-          const char *title;
-          if (resource->info->repos_path == NULL)
-            title = "unknown location";
-          else
-            title = resource->info->repos_path;
-
-          if (resource->info->restype != DAV_SVN_RESTYPE_PARENTPATH_COLLECTION)
-            {
-              if (SVN_IS_VALID_REVNUM(resource->info->root.rev))
-                title = apr_psprintf(resource->pool,
-                                     "Revision %ld: %s",
-                                     resource->info->root.rev, title);
-              if (resource->info->repos->repo_basename)
-                title = apr_psprintf(resource->pool, "%s - %s",
-                                     resource->info->repos->repo_basename,
-                                     title);
-              if (resource->info->repos->repo_name)
-                title = apr_psprintf(resource->pool, "%s: %s",
-                                     resource->info->repos->repo_name,
-                                     title);
-            }
+      bb = apr_brigade_create(resource->pool,
+                              dav_svn__output_get_bucket_alloc(output));
 
-          ap_fprintf(output, bb, "<html><head><title>%s</title></head>\n"
-                     "<body>\n <h2>%s</h2>\n <ul>\n", title, title);
-        }
-      else
-        {
-          const char *name = resource->info->repos->repo_name;
-          const char *href = resource->info->repos_path;
-          const char *base = resource->info->repos->repo_basename;
-
-          ap_fputs(output, bb, "<?xml version=\"1.0\"?>\n");
-          ap_fprintf(output, bb,
-                     "<?xml-stylesheet type=\"text/xsl\" href=\"%s\"?>\n",
-                     resource->info->repos->xslt_uri);
-          ap_fputs(output, bb, xml_index_dtd);
-          ap_fputs(output, bb,
-                   "<svn version=\"" SVN_VERSION "\"\n"
-                   "     href=\"http://subversion.apache.org/\";>\n");
-          ap_fputs(output, bb, "  <index");
-          if (name)
-            ap_fprintf(output, bb, " name=\"%s\"",
-                       apr_xml_quote_string(resource->pool, name, 1));
-          if (SVN_IS_VALID_REVNUM(resource->info->root.rev))
-            ap_fprintf(output, bb, " rev=\"%ld\"",
-                       resource->info->root.rev);
-          if (href)
-            ap_fprintf(output, bb, " path=\"%s\"",
-                       apr_xml_quote_string(resource->pool,
-                                            href,
-                                            1));
-          if (base)
-            ap_fprintf(output, bb, " base=\"%s\"", base);
-
-          ap_fputs(output, bb, ">\n");
-        }
-
-      if ((resource->info->restype != DAV_SVN_RESTYPE_PARENTPATH_COLLECTION)
-          && resource->info->repos_path
-          && ((resource->info->repos_path[1] != '\0')
-              || dav_svn__get_list_parentpath_flag(resource->info->r)))
-        {
-          const char *href;
-          if (resource->info->pegged)
-            {
-              href = apr_psprintf(resource->pool, "../?p=%ld",
-                                  resource->info->root.rev);
-            }
-          else
-            {
-              href = "../";
-            }
-
-          if (gen_html)
-            {
-              ap_fprintf(output, bb,
-                         "  <li><a href=\"%s\">..</a></li>\n", href);
-            }
-          else
-            {
-              ap_fprintf(output, bb, "    <updir href=\"%s\"/>\n", href);
-            }
-        }
+      serr = emit_collection_head(resource, bb, output, gen_html,
+                                  resource->pool);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "could not output collection",
+                                    resource->pool);
 
       /* get a sorted list of the entries */
       sorted = svn_sort__hash(entries, svn_sort_compare_items_as_paths,
                               resource->pool);
 
-      entry_pool = svn_pool_create(resource->pool);
+      iterpool = svn_pool_create(resource->pool);
 
       for (i = 0; i < sorted->nelts; ++i)
         {
@@ -3513,11 +3646,9 @@ deliver(const dav_resource *resource, ap
                                                         const 
svn_sort__item_t);
           const svn_fs_dirent_t *entry = item->value;
           const char *name = item->key;
-          const char *href = name;
-          svn_boolean_t is_dir = (entry->kind == svn_node_dir);
           const char *repos_relpath = NULL;
 
-          svn_pool_clear(entry_pool);
+          svn_pool_clear(iterpool);
 
           /* DIR_REV is set to a valid revision if we're looking at
              the entries of a versioned directory.  Otherwise, we're
@@ -3525,121 +3656,45 @@ deliver(const dav_resource *resource, ap
           if (SVN_IS_VALID_REVNUM(dir_rev))
             {
               repos_relpath = svn_fspath__join(resource->info->repos_path,
-                                               name, entry_pool);
+                                               name, iterpool);
               if (! dav_svn__allow_read(resource->info->r,
                                         resource->info->repos,
                                         repos_relpath,
                                         dir_rev,
-                                        entry_pool))
+                                        iterpool))
                 continue;
             }
           else
             {
                 if (! dav_svn__allow_list_repos(resource->info->r,
-                                                entry->name, entry_pool))
+                                                entry->name, iterpool))
                   continue;
             }
 
-          /* append a trailing slash onto the name for directories. we NEED
-             this for the href portion so that the relative reference will
-             descend properly. for the visible portion, it is just nice. */
-          /* ### The xml output doesn't like to see a trailing slash on
-             ### the visible portion, so avoid that. */
-          if (is_dir)
-            href = apr_pstrcat(entry_pool, href, "/", SVN_VA_NULL);
-
-          if (gen_html)
-            name = href;
-
-          /* We quote special characters in both XML and HTML. */
-          name = apr_xml_quote_string(entry_pool, name, !gen_html);
-
-          /* According to httpd-2.0.54/include/httpd.h, ap_os_escape_path()
-             behaves differently on different platforms.  It claims to
-             "convert an OS path to a URL in an OS dependant way".
-             Nevertheless, there appears to be only one implementation
-             of the function in httpd, and the code seems completely
-             platform independent, so we'll assume it's appropriate for
-             mod_dav_svn to use it to quote outbound paths. */
-          href = ap_os_escape_path(entry_pool, href, 0);
-          href = apr_xml_quote_string(entry_pool, href, 1);
-
-          if (gen_html)
-            {
-              /* If our directory was access using the public peg-rev
-                 CGI query interface, we'll let its dirents carry that
-                 peg-rev, too. */
-              if (resource->info->pegged)
-                {
-                  ap_fprintf(output, bb,
-                             "  <li><a href=\"%s?p=%ld\">%s</a></li>\n",
-                             href, resource->info->root.rev, name);
-                }
-              else
-                {
-                  ap_fprintf(output, bb,
-                             "  <li><a href=\"%s\">%s</a></li>\n",
-                             href, name);
-                }
-            }
-          else
-            {
-              const char *const tag = (is_dir ? "dir" : "file");
-
-              /* This is where we could search for props */
-
-              /* If our directory was access using the public peg-rev
-                 CGI query interface, we'll let its dirents carry that
-                 peg-rev, too. */
-              if (resource->info->pegged)
-                {
-                  ap_fprintf(output, bb,
-                             "    <%s name=\"%s\" href=\"%s?p=%ld\" />\n",
-                             tag, name, href, resource->info->root.rev);
-                }
-              else
-                {
-                  ap_fprintf(output, bb,
-                             "    <%s name=\"%s\" href=\"%s\" />\n",
-                             tag, name, href);
-                }
-            }
+          serr = emit_collection_entry(resource, bb, output, entry, gen_html,
+                                       iterpool);
+          if (serr != NULL)
+            return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                        "could not output collection entry",
+                                        resource->pool);
         }
 
-      svn_pool_destroy(entry_pool);
-
-      if (gen_html)
-        {
-          if (strcmp(ap_psignature("FOO", resource->info->r), "") != 0)
-            {
-              /* Apache's signature generation code didn't eat our prefix.
-                 ServerSignature must be enabled.  Print our version info.
+      svn_pool_destroy(iterpool);
 
-                 WARNING: This is a kludge!! ap_psignature() doesn't promise
-                 to return the empty string when ServerSignature is off.  We
-                 know it does by code inspection, but this behavior is subject
-                 to change. (Perhaps we should try to get the Apache folks to
-                 make this promise, though.  Seems harmless/useful enough...)
-              */
-              ap_fputs(output, bb,
-                       " </ul>\n <hr noshade><em>Powered by "
-                       "<a href=\"http://subversion.apache.org/\";>"
-                       "Apache Subversion"
-                       "</a> version " SVN_VERSION "."
-                       "</em>\n</body></html>");
-            }
-          else
-            ap_fputs(output, bb, " </ul>\n</body></html>");
-        }
-      else
-        ap_fputs(output, bb, "  </index>\n</svn>\n");
+      serr = emit_collection_tail(resource, bb, output, gen_html,
+                                  resource->pool);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "could not output collection",
+                                    resource->pool);
 
-      bkt = apr_bucket_eos_create(output->c->bucket_alloc);
+      bkt = apr_bucket_eos_create(dav_svn__output_get_bucket_alloc(output));
       APR_BRIGADE_INSERT_TAIL(bb, bkt);
-      if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS)
-        return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR,
-                                  0, status,
-                                  "Could not write EOS to filter.");
+      serr = dav_svn__output_pass_brigade(output, bb);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "Could not write EOS to filter.",
+                                    resource->pool);
 
       return NULL;
     }
@@ -3702,10 +3757,13 @@ deliver(const dav_resource *resource, ap
                                         "could not prepare to read a delta",
                                         resource->pool);
 
+          bb = apr_brigade_create(resource->pool,
+                                  dav_svn__output_get_bucket_alloc(output));
+
           /* create a stream that svndiff data will be written to,
              which will copy it to the network */
           dc.output = output;
-          dc.pool = resource->pool;
+          dc.bb = bb;
           o_stream = svn_stream_create(&dc, resource->pool);
           svn_stream_set_write(o_stream, write_to_filter);
           svn_stream_set_close(o_stream, close_filter);
@@ -3721,6 +3779,8 @@ deliver(const dav_resource *resource, ap
              to the network. */
           serr = svn_txdelta_send_txstream(txd_stream, handler, h_baton,
                                            resource->pool);
+          apr_brigade_destroy(bb);
+
           if (serr != NULL)
             return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                         "could not deliver the txdelta stream",
@@ -3826,6 +3886,9 @@ deliver(const dav_resource *resource, ap
          ### which will read from the FS stream on demand */
 
       block = apr_palloc(resource->pool, SVN__STREAM_CHUNK_SIZE);
+      bb = apr_brigade_create(resource->pool,
+                              dav_svn__output_get_bucket_alloc(output));
+
       while (1) {
         apr_size_t bufsize = SVN__STREAM_CHUNK_SIZE;
 
@@ -3833,6 +3896,7 @@ deliver(const dav_resource *resource, ap
         serr = svn_stream_read_full(stream, block, &bufsize);
         if (serr != NULL)
           {
+            apr_brigade_destroy(bb);
             return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                         "could not read the file contents",
                                         resource->pool);
@@ -3840,30 +3904,35 @@ deliver(const dav_resource *resource, ap
         if (bufsize == 0)
           break;
 
-        /* build a brigade and write to the filter ... */
-        bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
-        bkt = apr_bucket_transient_create(block, bufsize,
-                                          output->c->bucket_alloc);
+        /* write to the filter ... */
+        bkt = apr_bucket_transient_create(
+          block, bufsize, dav_svn__output_get_bucket_alloc(output));
         APR_BRIGADE_INSERT_TAIL(bb, bkt);
-        if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS) {
-          /* ### that HTTP code... */
-          return dav_svn__new_error(resource->pool,
-                                    HTTP_INTERNAL_SERVER_ERROR, 0, status,
-                                    "Could not write data to filter.");
-        }
+        serr = dav_svn__output_pass_brigade(output, bb);
+        if (serr != NULL)
+          {
+            apr_brigade_destroy(bb);
+            /* ### that HTTP code... */
+            return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                        "Could not write data to filter.",
+                                        resource->pool);
+          }
       }
 
       /* done with the file. write an EOS bucket now. */
-      bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
-      bkt = apr_bucket_eos_create(output->c->bucket_alloc);
+      bkt = apr_bucket_eos_create(dav_svn__output_get_bucket_alloc(output));
       APR_BRIGADE_INSERT_TAIL(bb, bkt);
-      if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS) {
-        /* ### that HTTP code... */
-        return dav_svn__new_error(resource->pool,
-                                  HTTP_INTERNAL_SERVER_ERROR, 0, status,
-                                  "Could not write EOS to filter.");
-      }
+      serr = dav_svn__output_pass_brigade(output, bb);
+      if (serr != NULL)
+        {
+          apr_brigade_destroy(bb);
+          /* ### that HTTP code... */
+          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                      "Could not write EOS to filter.",
+                                      resource->pool);
+        }
 
+      apr_brigade_destroy(bb);
       return NULL;
     }
 }
@@ -4642,7 +4711,7 @@ dav_svn__create_version_resource(dav_res
 static dav_error *
 handle_post_request(request_rec *r,
                     dav_resource *resource,
-                    ap_filter_t *output)
+                    dav_svn__output *output)
 {
   svn_skel_t *request_skel, *post_skel;
   int status;
@@ -4725,7 +4794,9 @@ int dav_svn__method_post(request_rec *r)
   content_type = apr_table_get(r->headers_in, "content-type");
   if (content_type && (strcmp(content_type, SVN_SKEL_MIME_TYPE) == 0))
     {
-      derr = handle_post_request(r, resource, r->output_filters);
+      dav_svn__output *output = dav_svn__output_create(resource->info->r,
+                                                       resource->pool);
+      derr = handle_post_request(r, resource, output);
     }
   else
     {

Modified: subversion/branches/authzperf/subversion/mod_dav_svn/util.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/util.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/util.c Thu Oct 13 
15:25:15 2016
@@ -465,6 +465,48 @@ dav_svn__find_ns(const apr_array_header_
   return -1;
 }
 
+
+/*** Output helpers ***/
+
+
+struct dav_svn__output
+{
+  request_rec *r;
+};
+
+dav_svn__output *
+dav_svn__output_create(request_rec *r,
+                       apr_pool_t *pool)
+{
+  dav_svn__output *output = apr_pcalloc(pool, sizeof(*output));
+  output->r = r;
+  return output;
+}
+
+apr_bucket_alloc_t *
+dav_svn__output_get_bucket_alloc(dav_svn__output *output)
+{
+  return output->r->connection->bucket_alloc;
+}
+
+svn_error_t *
+dav_svn__output_pass_brigade(dav_svn__output *output,
+                             apr_bucket_brigade *bb)
+{
+  apr_status_t status;
+
+  status = ap_pass_brigade(output->r->output_filters, bb);
+  /* Empty the brigade here, as required by ap_pass_brigade(). */
+  apr_brigade_cleanup(bb);
+  if (status)
+    return svn_error_create(status, NULL, "Could not write data to filter");
+
+  /* Check for an aborted connection, since the brigade functions don't
+     appear to return useful errors when the connection is dropped. */
+  if (output->r->connection->aborted)
+    return svn_error_create(SVN_ERR_APMOD_CONNECTION_ABORTED, NULL, NULL);
+  return SVN_NO_ERROR;
+}
 
 
 /*** Brigade I/O wrappers ***/
@@ -472,17 +514,18 @@ dav_svn__find_ns(const apr_array_header_
 
 svn_error_t *
 dav_svn__brigade_write(apr_bucket_brigade *bb,
-                       ap_filter_t *output,
+                       dav_svn__output *output,
                        const char *data,
                        apr_size_t len)
 {
   apr_status_t apr_err;
-  apr_err = apr_brigade_write(bb, ap_filter_flush, output, data, len);
+  apr_err = apr_brigade_write(bb, ap_filter_flush,
+                              output->r->output_filters, data, len);
   if (apr_err)
     return svn_error_create(apr_err, 0, NULL);
   /* Check for an aborted connection, since the brigade functions don't
      appear to be return useful errors when the connection is dropped. */
-  if (output->c->aborted)
+  if (output->r->connection->aborted)
     return svn_error_create(SVN_ERR_APMOD_CONNECTION_ABORTED, 0, NULL);
   return SVN_NO_ERROR;
 }
@@ -490,16 +533,17 @@ dav_svn__brigade_write(apr_bucket_brigad
 
 svn_error_t *
 dav_svn__brigade_puts(apr_bucket_brigade *bb,
-                      ap_filter_t *output,
+                      dav_svn__output *output,
                       const char *str)
 {
   apr_status_t apr_err;
-  apr_err = apr_brigade_puts(bb, ap_filter_flush, output, str);
+  apr_err = apr_brigade_puts(bb, ap_filter_flush,
+                             output->r->output_filters, str);
   if (apr_err)
     return svn_error_create(apr_err, 0, NULL);
   /* Check for an aborted connection, since the brigade functions don't
      appear to be return useful errors when the connection is dropped. */
-  if (output->c->aborted)
+  if (output->r->connection->aborted)
     return svn_error_create(SVN_ERR_APMOD_CONNECTION_ABORTED, 0, NULL);
   return SVN_NO_ERROR;
 }
@@ -507,7 +551,7 @@ dav_svn__brigade_puts(apr_bucket_brigade
 
 svn_error_t *
 dav_svn__brigade_printf(apr_bucket_brigade *bb,
-                        ap_filter_t *output,
+                        dav_svn__output *output,
                         const char *fmt,
                         ...)
 {
@@ -515,18 +559,41 @@ dav_svn__brigade_printf(apr_bucket_briga
   va_list ap;
 
   va_start(ap, fmt);
-  apr_err = apr_brigade_vprintf(bb, ap_filter_flush, output, fmt, ap);
+  apr_err = apr_brigade_vprintf(bb, ap_filter_flush,
+                                output->r->output_filters, fmt, ap);
   va_end(ap);
   if (apr_err)
     return svn_error_create(apr_err, 0, NULL);
   /* Check for an aborted connection, since the brigade functions don't
      appear to be return useful errors when the connection is dropped. */
-  if (output->c->aborted)
+  if (output->r->connection->aborted)
     return svn_error_create(SVN_ERR_APMOD_CONNECTION_ABORTED, 0, NULL);
   return SVN_NO_ERROR;
 }
 
 
+svn_error_t *
+dav_svn__brigade_putstrs(apr_bucket_brigade *bb,
+                         dav_svn__output *output,
+                         ...)
+{
+  apr_status_t apr_err;
+  va_list ap;
+
+  va_start(ap, output);
+  apr_err = apr_brigade_vputstrs(bb, ap_filter_flush,
+                                 output->r->output_filters, ap);
+  va_end(ap);
+  if (apr_err)
+    return svn_error_create(apr_err, NULL, NULL);
+  /* Check for an aborted connection, since the brigade functions don't
+     appear to return useful errors when the connection is dropped. */
+  if (output->r->connection->aborted)
+    return svn_error_create(SVN_ERR_APMOD_CONNECTION_ABORTED, NULL, NULL);
+  return SVN_NO_ERROR;
+}
+
+
 
 
 dav_error *
@@ -588,7 +655,7 @@ dav_svn__sanitize_error(svn_error_t *ser
 struct brigade_write_baton
 {
   apr_bucket_brigade *bb;
-  ap_filter_t *output;
+  dav_svn__output *output;
 };
 
 
@@ -599,7 +666,8 @@ brigade_write_fn(void *baton, const char
   struct brigade_write_baton *wb = baton;
   apr_status_t apr_err;
 
-  apr_err = apr_brigade_write(wb->bb, ap_filter_flush, wb->output, data, *len);
+  apr_err = apr_brigade_write(wb->bb, ap_filter_flush,
+                              wb->output->r->output_filters, data, *len);
 
   if (apr_err != APR_SUCCESS)
     return svn_error_wrap_apr(apr_err, "Error writing base64 data");
@@ -610,7 +678,7 @@ brigade_write_fn(void *baton, const char
 
 svn_stream_t *
 dav_svn__make_base64_output_stream(apr_bucket_brigade *bb,
-                                   ap_filter_t *output,
+                                   dav_svn__output *output,
                                    apr_pool_t *pool)
 {
   struct brigade_write_baton *wb = apr_palloc(pool, sizeof(*wb));
@@ -637,7 +705,7 @@ dav_svn__operational_log(struct dav_reso
 dav_error *
 dav_svn__final_flush_or_error(request_rec *r,
                               apr_bucket_brigade *bb,
-                              ap_filter_t *output,
+                              dav_svn__output *output,
                               dav_error *preferred_err,
                               apr_pool_t *pool)
 {
@@ -659,7 +727,7 @@ dav_svn__final_flush_or_error(request_re
      provided a more-important DERR, though. */
   if (do_flush)
     {
-      apr_status_t apr_err = ap_fflush(output, bb);
+      apr_status_t apr_err = ap_fflush(output->r->output_filters, bb);
       if (apr_err && (! derr))
         derr = dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0, apr_err,
                                   "Error flushing brigade.");

Modified: subversion/branches/authzperf/subversion/mod_dav_svn/version.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/version.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/version.c Thu Oct 13 
15:25:15 2016
@@ -1096,12 +1096,16 @@ static dav_error *
 deliver_report(request_rec *r,
                const dav_resource *resource,
                const apr_xml_doc *doc,
-               ap_filter_t *output)
+               ap_filter_t *unused)
 {
   int ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
 
   if (doc->root->ns == ns)
     {
+      dav_svn__output *output;
+
+      output = dav_svn__output_create(resource->info->r, resource->pool);
+
       /* ### note that these report names should have symbols... */
 
       if (strcmp(doc->root->name, "update-report") == 0)
@@ -1408,7 +1412,7 @@ merge(dav_resource *target,
       int no_auto_merge,
       int no_checkout,
       apr_xml_elem *prop_elem,
-      ap_filter_t *output)
+      ap_filter_t *unused)
 {
   apr_pool_t *pool;
   dav_error *err;
@@ -1419,6 +1423,7 @@ merge(dav_resource *target,
   svn_revnum_t new_rev;
   apr_hash_t *locks;
   svn_boolean_t disable_merge_response = FALSE;
+  dav_svn__output *output;
 
   /* We'll use the target's pool for our operation. We happen to know that
      it matches the request pool, which (should) have the proper lifetime. */
@@ -1588,6 +1593,7 @@ merge(dav_resource *target,
     }
 
   /* process the response for the new revision. */
+  output = dav_svn__output_create(target->info->r, pool);
   return dav_svn__merge_response(output, source->info->repos, new_rev,
                                  post_commit_err, prop_elem,
                                  disable_merge_response, pool);

Modified: subversion/branches/authzperf/subversion/svn/cl.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/svn/cl.h?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/svn/cl.h (original)
+++ subversion/branches/authzperf/subversion/svn/cl.h Thu Oct 13 15:25:15 2016
@@ -249,6 +249,7 @@ typedef struct svn_cl__opt_state_t
   svn_boolean_t show_passwords;    /* show cached passwords */
   svn_boolean_t pin_externals;     /* pin externals to last-changed revisions 
*/
   const char *show_item;           /* print only the given item */
+  svn_boolean_t adds_as_modification; /* update 'add vs add' no tree conflict 
*/
 } svn_cl__opt_state_t;
 
 /* Conflict stats for operations such as update and merge. */

Modified: subversion/branches/authzperf/subversion/svn/conflict-callbacks.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/svn/conflict-callbacks.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/authzperf/subversion/svn/conflict-callbacks.c Thu Oct 
13 15:25:15 2016
@@ -229,8 +229,8 @@ merge_prop_conflict(svn_stream_t *output
     base_propval = svn_string_create_empty(pool);
   if (my_propval == NULL)
     my_propval = svn_string_create_empty(pool);
-  if (my_propval == NULL)
-    my_propval = svn_string_create_empty(pool);
+  if (their_propval == NULL)
+    their_propval = svn_string_create_empty(pool);
     
   options->ignore_eol_style = TRUE;
   SVN_ERR(svn_diff_mem_string_diff3(&diff, base_propval,
@@ -338,23 +338,19 @@ edit_prop_conflict(const svn_string_t **
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
 {
-  apr_file_t *file;
   const char *file_path;
   svn_boolean_t performed_edit = FALSE;
   svn_stream_t *merged_prop;
 
-  SVN_ERR(svn_io_open_unique_file3(&file, &file_path, NULL,
-                                   svn_io_file_del_on_pool_cleanup,
-                                   result_pool, scratch_pool));
-  merged_prop = svn_stream_from_aprfile2(file, TRUE /* disown */,
-                                         scratch_pool);
+  SVN_ERR(svn_stream_open_unique(&merged_prop, &file_path, NULL,
+                                 svn_io_file_del_on_pool_cleanup,
+                                 scratch_pool, scratch_pool));
   SVN_ERR(merge_prop_conflict(merged_prop, base_propval, my_propval,
                               their_propval, NULL,
                               pb->cancel_func,
                               pb->cancel_baton,
                               scratch_pool));
   SVN_ERR(svn_stream_close(merged_prop));
-  SVN_ERR(svn_io_file_flush(file, scratch_pool));
   SVN_ERR(open_editor(&performed_edit, file_path, editor_cmd,
                       config, scratch_pool));
   if (performed_edit && merged_propval)
@@ -388,7 +384,7 @@ typedef struct resolver_option_t
 /* Resolver options for conflict options offered by libsvn_client.  */
 static const resolver_option_t builtin_resolver_options[] =
 {
-  { "r",  N_("mark resolved"),    NULL,
+  { "r",  NULL, NULL,
                                   svn_client_conflict_option_merged_text,
                                   SVN_CL__ACCEPT_WORKING },
   { "mc", NULL, NULL,
@@ -408,7 +404,7 @@ static const resolver_option_t builtin_r
                                   SVN_CL__ACCEPT_POSTPONE },
 
   /* This option resolves a tree conflict to the current working copy state. */
-  { "r", N_("accept current working copy state"), NULL,
+  { "r", NULL, NULL,
     svn_client_conflict_option_accept_current_wc_state,
     SVN_CL__ACCEPT_WORKING },
 
@@ -419,25 +415,23 @@ static const resolver_option_t builtin_r
   { "u", N_("update any moved-away children"), NULL,
     svn_client_conflict_option_update_any_moved_away_children },
 
-  /* Options for incoming add vs local add upon merge. */
+  /* Options for incoming add vs local add. */
   { "i", N_("ignore incoming addition"), NULL,
-    svn_client_conflict_option_merge_incoming_add_ignore },
+    svn_client_conflict_option_incoming_add_ignore },
 
   /* Options for incoming file add vs local file add upon merge. */
   { "m", N_("merge the files"), NULL,
-    svn_client_conflict_option_merge_incoming_added_file_text_merge },
-  { "R", N_("replace my file with incoming file"), NULL,
-    svn_client_conflict_option_merge_incoming_added_file_replace },
+    svn_client_conflict_option_incoming_added_file_text_merge },
   { "M", N_("replace my file with incoming file and merge the files"), NULL,
-    svn_client_conflict_option_merge_incoming_added_file_replace_and_merge },
+    svn_client_conflict_option_incoming_added_file_replace_and_merge },
 
   /* Options for incoming dir add vs local dir add upon merge. */
   { "m", N_("merge the directories"), NULL,
-    svn_client_conflict_option_merge_incoming_added_dir_merge },
-  { "R", N_("replace my directory with incoming directory"), NULL,
-    svn_client_conflict_option_merge_incoming_added_dir_replace },
+    svn_client_conflict_option_incoming_added_dir_merge },
+  { "R", N_("delete my directory and replace it with incoming directory"), 
NULL,
+    svn_client_conflict_option_incoming_added_dir_replace },
   { "M", N_("replace my directory with incoming directory and merge"), NULL,
-    svn_client_conflict_option_merge_incoming_added_dir_replace_and_merge },
+    svn_client_conflict_option_incoming_added_dir_replace_and_merge },
 
   /* Options for incoming delete vs any. */
   { "i", N_("ignore incoming deletion"), NULL,
@@ -445,6 +439,10 @@ static const resolver_option_t builtin_r
   { "a", N_("accept incoming deletion"), NULL,
     svn_client_conflict_option_incoming_delete_accept },
 
+  /* Options for incoming move vs local edit. */
+  { "m", NULL, NULL, svn_client_conflict_option_incoming_move_file_text_merge 
},
+  { "m", NULL, NULL, svn_client_conflict_option_incoming_move_dir_merge },
+
   { NULL }
 };
 
@@ -498,7 +496,7 @@ static const resolver_option_t extra_res
                                   svn_client_conflict_option_undefined,
                                   SVN_CL__ACCEPT_EDIT },
   { "h",  N_("help"),             N_("show this help (also '?')"),
-                                   svn_client_conflict_option_undefined },
+                                  svn_client_conflict_option_undefined },
   { NULL }
 };
 
@@ -507,8 +505,17 @@ static const resolver_option_t extra_res
 {
   /* Translators: keep long_desc below 70 characters (wrap with a left
      margin of 9 spaces if needed) */
+  { "d",  N_("set repository move destination path"),
+          N_("pick repository move target from list of possible targets"),
+                                  svn_client_conflict_option_undefined },
+
+  { "w",  N_("set working copy move destination path"),
+          N_("pick working copy move target from list of possible targets"),
+                                  svn_client_conflict_option_undefined },
+
   { "h",  N_("help"),             N_("show this help (also '?')"),
-                                   svn_client_conflict_option_undefined },
+                                  svn_client_conflict_option_undefined },
+
   { NULL }
 };
 
@@ -531,7 +538,7 @@ find_option(const resolver_option_t *opt
 }
 
 /* Return a pointer to the option description in OPTIONS matching the
- * the conflict option ID CHOICE.  Return NULL if not found. */
+ * conflict option ID CHOICE.  Return NULL if not found. */
 static const resolver_option_t *
 find_option_by_id(const resolver_option_t *options,
                   svn_client_conflict_option_id_t choice)
@@ -570,6 +577,8 @@ prompt_string(const resolver_option_t *o
           if (! *option_codes)
             break;
           opt = find_option(options, *option_codes++);
+          if (opt == NULL)
+            continue;
         }
       else
         {
@@ -686,6 +695,7 @@ prompt_user(const resolver_option_t **op
 static svn_error_t *
 build_text_conflict_options(resolver_option_t **options,
                             svn_client_conflict_t *conflict,
+                            svn_client_ctx_t *ctx,
                             svn_boolean_t is_binary,
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
@@ -698,7 +708,7 @@ build_text_conflict_options(resolver_opt
   apr_pool_t *iterpool;
 
   SVN_ERR(svn_client_conflict_text_get_resolution_options(&builtin_options,
-                                                          conflict,
+                                                          conflict, ctx,
                                                           scratch_pool,
                                                           scratch_pool));
   nopt = builtin_options->nelts + ARRAY_LEN(extra_resolver_options);
@@ -772,7 +782,7 @@ mark_conflict_resolved(svn_client_confli
   if (text_conflicted)
     {
       SVN_ERR(svn_client_conflict_text_resolve_by_id(conflict, option_id,
-                                                     scratch_pool));
+                                                     ctx, scratch_pool));
       svn_cl__conflict_stats_resolved(conflict_stats, local_relpath,
                                       svn_wc_conflict_kind_text);
     }
@@ -780,7 +790,7 @@ mark_conflict_resolved(svn_client_confli
   if (propname)
     {
       SVN_ERR(svn_client_conflict_prop_resolve_by_id(conflict, propname,
-                                                     option_id,
+                                                     option_id, ctx,
                                                      scratch_pool));
       svn_cl__conflict_stats_resolved(conflict_stats, local_relpath,
                                       svn_wc_conflict_kind_property);
@@ -789,7 +799,7 @@ mark_conflict_resolved(svn_client_confli
   if (tree_conflicted)
     {
       SVN_ERR(svn_client_conflict_tree_resolve_by_id(conflict, option_id,
-                                                     scratch_pool));
+                                                     ctx, scratch_pool));
       svn_cl__conflict_stats_resolved(conflict_stats, local_relpath,
                                       svn_wc_conflict_kind_tree);
     }
@@ -871,7 +881,7 @@ handle_text_conflict(svn_boolean_t *reso
       || (!base_abspath && my_abspath && their_abspath)))
     diff_allowed = TRUE;
 
-  SVN_ERR(build_text_conflict_options(&text_conflict_options, conflict,
+  SVN_ERR(build_text_conflict_options(&text_conflict_options, conflict, ctx,
                                       is_binary, scratch_pool, scratch_pool));
   while (TRUE)
     {
@@ -1157,6 +1167,7 @@ handle_text_conflict(svn_boolean_t *reso
 static svn_error_t *
 build_prop_conflict_options(resolver_option_t **options,
                             svn_client_conflict_t *conflict,
+                            svn_client_ctx_t *ctx,
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
 {
@@ -1168,7 +1179,7 @@ build_prop_conflict_options(resolver_opt
   apr_pool_t *iterpool;
 
   SVN_ERR(svn_client_conflict_prop_get_resolution_options(&builtin_options,
-                                                          conflict,
+                                                          conflict, ctx,
                                                           scratch_pool,
                                                           scratch_pool));
   nopt = builtin_options->nelts + ARRAY_LEN(extra_resolver_options) +
@@ -1214,11 +1225,10 @@ build_prop_conflict_options(resolver_opt
 }
 
 /* Ask the user what to do about the conflicted property PROPNAME described
- * by CONFLICT and return the answer in *OPTION_ID.
+ * by CONFLICT and return the corresponding resolution option in *OPTION.
  * SCRATCH_POOL is used for temporary allocations. */
 static svn_error_t *
-handle_one_prop_conflict(svn_client_conflict_option_id_t *option_id,
-                         const svn_string_t **merged_value,
+handle_one_prop_conflict(svn_client_conflict_option_t **option,
                          svn_boolean_t *quit,
                          const char *path_prefix,
                          svn_cmdline_prompt_baton_t *pb,
@@ -1226,6 +1236,7 @@ handle_one_prop_conflict(svn_client_conf
                          apr_hash_t *config,
                          svn_client_conflict_t *conflict,
                          const char *propname,
+                         svn_client_ctx_t *ctx,
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
 {
@@ -1236,10 +1247,9 @@ handle_one_prop_conflict(svn_client_conf
   const svn_string_t *base_propval;
   const svn_string_t *my_propval;
   const svn_string_t *their_propval;
+  apr_array_header_t *resolution_options;
   resolver_option_t *prop_conflict_options;
 
-  *option_id = svn_client_conflict_option_unspecified;
-
   SVN_ERR(svn_client_conflict_prop_get_propvals(NULL, &my_propval,
                                                 &base_propval, &their_propval,
                                                 conflict, propname,
@@ -1257,7 +1267,11 @@ handle_one_prop_conflict(svn_client_conf
                                                    scratch_pool, 
scratch_pool));
   SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n", description));
 
-  SVN_ERR(build_prop_conflict_options(&prop_conflict_options, conflict,
+  SVN_ERR(svn_client_conflict_prop_get_resolution_options(&resolution_options,
+                                                          conflict, ctx,
+                                                          result_pool,
+                                                          scratch_pool));
+  SVN_ERR(build_prop_conflict_options(&prop_conflict_options, conflict, ctx,
                                       scratch_pool, scratch_pool));
   iterpool = svn_pool_create(scratch_pool);
   while (TRUE)
@@ -1286,7 +1300,8 @@ handle_one_prop_conflict(svn_client_conf
 
       if (strcmp(opt->code, "q") == 0)
         {
-          *option_id = opt->choice;
+          *option = svn_client_conflict_option_find_by_id(resolution_options,
+                                                          opt->choice);
           *quit = TRUE;
           break;
         }
@@ -1315,13 +1330,17 @@ handle_one_prop_conflict(svn_client_conf
               continue;
             }
 
-          *merged_value = merged_propval;
-          *option_id = svn_client_conflict_option_merged_text;
+          *option = svn_client_conflict_option_find_by_id(
+                      resolution_options,
+                      svn_client_conflict_option_merged_text);
+          svn_client_conflict_option_set_merged_propval(*option,
+                                                        merged_propval);
           break;
         }
       else if (opt->choice != svn_client_conflict_option_undefined)
         {
-          *option_id = opt->choice;
+          *option = svn_client_conflict_option_find_by_id(resolution_options,
+                                                          opt->choice);
           break;
         }
     }
@@ -1361,23 +1380,29 @@ handle_prop_conflicts(svn_boolean_t *res
   for (i = 0; i < props_conflicted->nelts; i++)
     {
       const char *propname = APR_ARRAY_IDX(props_conflicted, i, const char *);
+      svn_client_conflict_option_t *option;
       svn_client_conflict_option_id_t option_id;
-      const svn_string_t *merged_propval = NULL;
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(handle_one_prop_conflict(&option_id, &merged_propval,
-                                       quit, path_prefix, pb,
+      SVN_ERR(handle_one_prop_conflict(&option, quit, path_prefix, pb,
                                        editor_cmd, config, conflict, propname,
+                                       ctx,
                                        iterpool, iterpool));
+      option_id = svn_client_conflict_option_get_id(option);
 
       if (option_id != svn_client_conflict_option_unspecified &&
           option_id != svn_client_conflict_option_postpone)
         {
-          SVN_ERR(mark_conflict_resolved(conflict, option_id,
-                                         FALSE, propname, FALSE,
-                                         path_prefix, conflict_stats,
-                                         ctx, iterpool));
+          const char *local_relpath =
+            svn_cl__local_style_skip_ancestor(
+              path_prefix, svn_client_conflict_get_local_abspath(conflict),
+              iterpool);
+
+          SVN_ERR(svn_client_conflict_prop_resolve(conflict, propname, option,
+                                                   ctx, iterpool));
+          svn_cl__conflict_stats_resolved(conflict_stats, local_relpath,
+                                          svn_wc_conflict_kind_property);
           nresolved++;
           *postponed = FALSE;
         }
@@ -1397,10 +1422,14 @@ handle_prop_conflicts(svn_boolean_t *res
 
 /* Set *OPTIONS to an array of resolution options for CONFLICT. */
 static svn_error_t *
-build_tree_conflict_options(resolver_option_t **options,
-                            svn_client_conflict_t *conflict,
-                            apr_pool_t *result_pool,
-                            apr_pool_t *scratch_pool)
+build_tree_conflict_options(
+  resolver_option_t **options,
+  apr_array_header_t **possible_moved_to_repos_relpaths,
+  apr_array_header_t **possible_moved_to_abspaths,
+  svn_client_conflict_t *conflict,
+  svn_client_ctx_t *ctx,
+  apr_pool_t *result_pool,
+  apr_pool_t *scratch_pool)
 {
   resolver_option_t *opt;
   const resolver_option_t *o;
@@ -1410,12 +1439,14 @@ build_tree_conflict_options(resolver_opt
   apr_pool_t *iterpool;
 
   SVN_ERR(svn_client_conflict_tree_get_resolution_options(&builtin_options,
-                                                          conflict,
+                                                          conflict, ctx,
                                                           scratch_pool,
                                                           scratch_pool));
-  nopt = builtin_options->nelts + ARRAY_LEN(extra_resolver_options) +
-           ARRAY_LEN(extra_resolver_options_tree);
+  nopt = builtin_options->nelts + ARRAY_LEN(extra_resolver_options_tree) +
+           ARRAY_LEN(extra_resolver_options);
   *options = apr_pcalloc(result_pool, sizeof(*opt) * (nopt + 1));
+  *possible_moved_to_abspaths = NULL;
+  *possible_moved_to_repos_relpaths = NULL;
 
   opt = *options;
   iterpool = svn_pool_create(scratch_pool);
@@ -1443,19 +1474,147 @@ build_tree_conflict_options(resolver_opt
       opt->accept_arg = known_option->accept_arg;
 
       opt++; 
-    }
 
+      if (id == svn_client_conflict_option_incoming_move_file_text_merge ||
+          id == svn_client_conflict_option_incoming_move_dir_merge)
+        {
+          SVN_ERR(
+            svn_client_conflict_option_get_moved_to_repos_relpath_candidates(
+              possible_moved_to_repos_relpaths, builtin_option,
+              result_pool, iterpool));
+          SVN_ERR(svn_client_conflict_option_get_moved_to_abspath_candidates(
+                    possible_moved_to_abspaths, builtin_option,
+                    result_pool, iterpool));
+        }
+    }
 
   svn_pool_destroy(iterpool);
 
-  for (o = extra_resolver_options; o->code; o++)
-    *opt++ = *o;
   for (o = extra_resolver_options_tree; o->code; o++)
+    {
+      /* Add move target choice options only if there are multiple
+       * move targets to choose from. */
+      if (strcmp(o->code, "d") == 0 &&
+          (*possible_moved_to_repos_relpaths == NULL || 
+           (*possible_moved_to_repos_relpaths)->nelts <= 1))
+        continue;
+      if (strcmp(o->code, "w") == 0 &&
+          (*possible_moved_to_abspaths == NULL || 
+           (*possible_moved_to_abspaths)->nelts <= 1))
+        continue;
+
+      *opt++ = *o;
+    }
+  for (o = extra_resolver_options; o->code; o++)
     *opt++ = *o;
 
   return SVN_NO_ERROR;
 }
 
+/* Make the user select a move target path for the moved-away VICTIM_ABSPATH. 
*/
+static svn_error_t *
+prompt_move_target_path(int *preferred_move_target_idx,
+                        apr_array_header_t *possible_moved_to_paths,
+                        svn_boolean_t paths_are_local,
+                        svn_cmdline_prompt_baton_t *pb,
+                        const char *victim_abspath,
+                        svn_client_ctx_t *ctx,
+                        apr_pool_t *scratch_pool)
+{
+  const char *move_targets_prompt = "";
+  const char *move_targets_list = "";
+  const char *wcroot_abspath;
+  const char *victim_relpath;
+  int i;
+  apr_int64_t idx;
+  apr_pool_t *iterpool;
+
+  SVN_ERR(svn_client_get_wc_root(&wcroot_abspath, victim_abspath,
+                                 ctx, scratch_pool, scratch_pool));
+  victim_relpath = svn_cl__local_style_skip_ancestor(wcroot_abspath,
+                                                     victim_abspath,
+                                                     scratch_pool),
+  iterpool = svn_pool_create(scratch_pool);
+
+  /* Build the prompt. */
+  for (i = 0; i < possible_moved_to_paths->nelts; i++)
+    {
+      svn_pool_clear(iterpool);
+
+      if (paths_are_local)
+        {
+          const char *moved_to_abspath;
+          const char *moved_to_relpath;
+
+          moved_to_abspath = APR_ARRAY_IDX(possible_moved_to_paths, i,
+                                           const char *);
+          moved_to_relpath = svn_cl__local_style_skip_ancestor(
+                               wcroot_abspath, moved_to_abspath, iterpool),
+          move_targets_list = apr_psprintf(scratch_pool, "%s (%d): '%s'\n",
+                                           move_targets_list, i + 1,
+                                           moved_to_relpath);
+        }
+      else
+        {
+          const char *moved_to_repos_relpath;
+
+          moved_to_repos_relpath = APR_ARRAY_IDX(possible_moved_to_paths, i,
+                                                 const char *);
+          move_targets_list = apr_psprintf(scratch_pool, "%s (%d): '^/%s'\n",
+                                           move_targets_list, i + 1,
+                                           moved_to_repos_relpath);
+        }
+    }
+  if (paths_are_local)
+    move_targets_prompt =
+      apr_psprintf(scratch_pool,
+                   _("Possible working copy destinations for moved-away '%s' "
+                     "are:\n%s"
+                     "Only one destination can be a move; the others are "
+                     "copies.\n"
+                     "Specify the correct move target path by number: "),
+                   victim_relpath, move_targets_list);
+  else
+    move_targets_prompt =
+      apr_psprintf(scratch_pool,
+                   _("Possible repository destinations for moved-away '%s' "
+                     "are:\n%s"
+                     "Only one destination can be a move; the others are "
+                     "copies.\n"
+                     "Specify the correct move target path by number: "),
+                   victim_relpath, move_targets_list);
+
+  /* Keep asking the user until we got a valid choice. */
+  while (1)
+    {
+      const char *answer;
+      svn_error_t *err;
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_cmdline_prompt_user2(&answer, move_targets_prompt,
+                                       pb, iterpool));
+      err = svn_cstring_strtoi64(&idx, answer, 1,
+                                 possible_moved_to_paths->nelts, 10);
+      if (err)
+        {
+          char buf[1024];
+
+          svn_cmdline_fprintf(stderr, iterpool, "%s\n",
+                              svn_err_best_message(err, buf, sizeof(buf)));
+          svn_error_clear(err);
+          continue;
+        }
+
+      break;
+    }
+
+  svn_pool_destroy(iterpool);
+
+  *preferred_move_target_idx = (idx - 1);
+  return SVN_NO_ERROR;
+}
+
 /* Ask the user what to do about the tree conflict described by CONFLICT
  * and either resolve the conflict accordingly or postpone resolution.
  * SCRATCH_POOL is used for temporary allocations. */
@@ -1474,18 +1633,22 @@ handle_tree_conflict(svn_boolean_t *reso
   apr_pool_t *iterpool;
   resolver_option_t *tree_conflict_options;
   svn_client_conflict_option_id_t option_id;
+  const char *local_abspath;
   const char *conflict_description;
   const char *local_change_description;
   const char *incoming_change_description;
+  apr_array_header_t *possible_moved_to_repos_relpaths;
+  apr_array_header_t *possible_moved_to_abspaths;
 
   option_id = svn_client_conflict_option_unspecified;
+  local_abspath = svn_client_conflict_get_local_abspath(conflict);
 
   /* Always show the best possible conflict description and options. */
-  SVN_ERR(svn_client_conflict_tree_get_details(conflict, scratch_pool));
+  SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, scratch_pool));
 
   SVN_ERR(svn_client_conflict_tree_get_description(
            &incoming_change_description, &local_change_description,
-           conflict, scratch_pool, scratch_pool));
+           conflict, ctx, scratch_pool, scratch_pool));
   conflict_description = apr_psprintf(scratch_pool, "%s\n%s",
                                       incoming_change_description,
                                       local_change_description);
@@ -1493,12 +1656,13 @@ handle_tree_conflict(svn_boolean_t *reso
     SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
                                 _("Tree conflict on '%s':\n%s\n"),
                                 svn_cl__local_style_skip_ancestor(
-                                  path_prefix,
-                                  
svn_client_conflict_get_local_abspath(conflict),
-                                  scratch_pool),
+                                  path_prefix, local_abspath, scratch_pool),
                                 conflict_description));
 
-  SVN_ERR(build_tree_conflict_options(&tree_conflict_options, conflict,
+  SVN_ERR(build_tree_conflict_options(&tree_conflict_options,
+                                      &possible_moved_to_repos_relpaths,
+                                      &possible_moved_to_abspaths,
+                                      conflict, ctx,
                                       scratch_pool, scratch_pool));
   iterpool = svn_pool_create(scratch_pool);
   while (1)
@@ -1508,8 +1672,7 @@ handle_tree_conflict(svn_boolean_t *reso
       svn_pool_clear(iterpool);
 
       SVN_ERR(prompt_user(&opt, tree_conflict_options, NULL,
-                          *printed_description ? NULL : conflict_description,
-                          pb, iterpool));
+                          conflict_description, pb, iterpool));
       *printed_description = TRUE;
       if (! opt)
         continue;
@@ -1520,6 +1683,91 @@ handle_tree_conflict(svn_boolean_t *reso
           *quit = TRUE;
           break;
         }
+      else if (strcmp(opt->code, "d") == 0)
+        {
+          int preferred_move_target_idx;
+          apr_array_header_t *options;
+          svn_client_conflict_option_t *conflict_option;
+
+          SVN_ERR(prompt_move_target_path(&preferred_move_target_idx,
+                                          possible_moved_to_repos_relpaths,
+                                          FALSE,
+                                          pb, local_abspath, ctx, iterpool));
+
+          /* Update preferred move target path. */
+          SVN_ERR(svn_client_conflict_tree_get_resolution_options(&options,
+                                                                  conflict,
+                                                                  ctx,
+                                                                  iterpool,
+                                                                  iterpool));
+          conflict_option =
+            svn_client_conflict_option_find_by_id( 
+              options,
+              svn_client_conflict_option_incoming_move_file_text_merge);
+          if (conflict_option == NULL)
+            {
+              conflict_option =
+                svn_client_conflict_option_find_by_id( 
+                  options, svn_client_conflict_option_incoming_move_dir_merge);
+            }
+
+          if (conflict_option)
+            {
+              SVN_ERR(svn_client_conflict_option_set_moved_to_repos_relpath(
+                        conflict_option, preferred_move_target_idx, iterpool));
+
+              /* Update option description. */
+              SVN_ERR(build_tree_conflict_options(
+                        &tree_conflict_options,
+                        &possible_moved_to_repos_relpaths,
+                        &possible_moved_to_abspaths,
+                        conflict, ctx,
+                        scratch_pool, scratch_pool));
+            }
+          continue;
+        }
+      else if (strcmp(opt->code, "w") == 0)
+        {
+          int preferred_move_target_idx;
+          apr_array_header_t *options;
+          svn_client_conflict_option_t *conflict_option;
+
+          SVN_ERR(prompt_move_target_path(&preferred_move_target_idx,
+                                           possible_moved_to_abspaths, TRUE,
+                                           pb, local_abspath, ctx, iterpool));
+
+          /* Update preferred move target path. */
+          SVN_ERR(svn_client_conflict_tree_get_resolution_options(&options,
+                                                                  conflict,
+                                                                  ctx,
+                                                                  iterpool,
+                                                                  iterpool));
+          conflict_option =
+            svn_client_conflict_option_find_by_id( 
+              options,
+              svn_client_conflict_option_incoming_move_file_text_merge);
+          if (conflict_option == NULL)
+            {
+              conflict_option =
+                svn_client_conflict_option_find_by_id( 
+                  options, svn_client_conflict_option_incoming_move_dir_merge);
+            }
+
+          if (conflict_option)
+            {
+              SVN_ERR(svn_client_conflict_option_set_moved_to_abspath(
+                        conflict_option, preferred_move_target_idx, ctx, 
iterpool));
+
+              /* Update option description. */
+              SVN_ERR(build_tree_conflict_options(
+                        &tree_conflict_options,
+                        &possible_moved_to_repos_relpaths,
+                        &possible_moved_to_abspaths,
+                        conflict, ctx,
+                        scratch_pool, scratch_pool));
+            }
+          continue;
+        }
       else if (opt->choice != svn_client_conflict_option_undefined)
         {
           option_id = opt->choice;

Modified: subversion/branches/authzperf/subversion/svn/merge-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/svn/merge-cmd.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/svn/merge-cmd.c (original)
+++ subversion/branches/authzperf/subversion/svn/merge-cmd.c Thu Oct 13 
15:25:15 2016
@@ -123,6 +123,11 @@ run_merge(svn_boolean_t two_sources_spec
                                 _("Merge sources must both be "
                                   "either paths or URLs"));
 
+      if (svn_path_is_url(targetpath))
+        return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                 _("Merge target '%s' must be a local path "
+                                   "but looks like a URL"), targetpath);
+
       if (opt_state->verbose)
         SVN_ERR(svn_cmdline_printf(scratch_pool, _("--- Merging\n")));
       merge_err = svn_client_merge5(sourcepath1,

Modified: subversion/branches/authzperf/subversion/svn/notify.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/svn/notify.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/svn/notify.c (original)
+++ subversion/branches/authzperf/subversion/svn/notify.c Thu Oct 13 15:25:15 
2016
@@ -472,6 +472,21 @@ notify_body(struct notify_baton *nb,
                                  path_local));
       break;
 
+    case svn_wc_notify_begin_search_tree_conflict_details:
+      SVN_ERR(svn_cmdline_printf(pool,
+                                 _("Searching tree conflict details for '%s' "
+                                   "in repository:\n"),
+                                 path_local));
+      break;
+
+    case svn_wc_notify_tree_conflict_details_progress:
+      SVN_ERR(svn_cmdline_printf(pool, _("\rChecking r%ld..."), n->revision));
+      break;
+
+    case svn_wc_notify_end_search_tree_conflict_details:
+      SVN_ERR(svn_cmdline_printf(pool, _(" done\n")));
+      break;
+
     case svn_wc_notify_add:
       /* We *should* only get the MIME_TYPE if PATH is a file.  If we
          do get it, and the mime-type is not textual, note that this

Modified: subversion/branches/authzperf/subversion/svn/svn.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/svn/svn.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/svn/svn.c (original)
+++ subversion/branches/authzperf/subversion/svn/svn.c Thu Oct 13 15:25:15 2016
@@ -143,6 +143,7 @@ typedef enum svn_cl__longopt_t {
   opt_show_passwords,
   opt_pin_externals,
   opt_show_item,
+  opt_adds_as_modification,
 } svn_cl__longopt_t;
 
 
@@ -449,6 +450,15 @@ const apr_getopt_option_t svn_cl__option
                           "                             "
                           "   'wc-root'    root of TARGET's working copy")},
 
+  {"adds-as-modification", opt_adds_as_modification, 0,
+                       N_("Local additions are merged with incoming additions "
+                       "                             "
+                       "instead of causing a tree conflict. Use of this\n"
+                       "                             "
+                       "option is not recommended! Use 'svn resolve' to\n"
+                       "                             "
+                       "resolve tree conflicts instead.")},
+
   /* Long-opt Aliases
    *
    * These have NULL desriptions, but an option code that matches some
@@ -1761,7 +1771,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "  targets of this operation.\n"),
     {'r', 'N', opt_depth, opt_set_depth, 'q', opt_merge_cmd, opt_force,
      opt_ignore_externals, opt_changelist, opt_editor_cmd, opt_accept,
-     opt_parents},
+     opt_parents, opt_adds_as_modification},
     { {opt_force,
        N_("handle unversioned obstructions as changes")} } },
 
@@ -2431,6 +2441,9 @@ sub_main(int *exit_code, int argc, const
         SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         opt_state.show_item = utf8_opt_arg;
         break;
+      case opt_adds_as_modification:
+        opt_state.adds_as_modification = TRUE;
+        break;
       default:
         /* Hmmm. Perhaps this would be a good place to squirrel away
            opts that commands like svn diff might need. Hmmm indeed. */

Modified: subversion/branches/authzperf/subversion/svn/update-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/svn/update-cmd.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/svn/update-cmd.c (original)
+++ subversion/branches/authzperf/subversion/svn/update-cmd.c Thu Oct 13 
15:25:15 2016
@@ -170,7 +170,8 @@ svn_cl__update(apr_getopt_t *os,
                              &(opt_state->start_revision),
                              depth, depth_is_sticky,
                              opt_state->ignore_externals,
-                             opt_state->force, TRUE /* adds_as_modification */,
+                             opt_state->force,
+                             opt_state->adds_as_modification,
                              opt_state->parents,
                              ctx, scratch_pool));
 

Modified: subversion/branches/authzperf/subversion/svnmucc/svnmucc.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/svnmucc/svnmucc.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/svnmucc/svnmucc.c (original)
+++ subversion/branches/authzperf/subversion/svnmucc/svnmucc.c Thu Oct 13 
15:25:15 2016
@@ -74,6 +74,7 @@ check_lib_versions(void)
   return svn_ver_check_list2(&my_version, checklist, svn_ver_equal);
 }
 
+/* Implements svn_commit_callback2_t */
 static svn_error_t *
 commit_callback(const svn_commit_info_t *commit_info,
                 void *baton,
@@ -84,6 +85,15 @@ commit_callback(const svn_commit_info_t
                              (commit_info->author
                               ? commit_info->author : "(no author)"),
                              commit_info->date));
+
+  /* Writing to stdout, as there maybe systems that consider the
+   * presence of stderr as an indication of commit failure.
+   * OTOH, this is only of informational nature to the user as
+   * the commit has succeeded. */
+  if (commit_info->post_commit_err)
+    SVN_ERR(svn_cmdline_printf(pool, _("\nWarning: %s\n"),
+                               commit_info->post_commit_err));
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/authzperf/subversion/tests/cmdline/depth_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/tests/cmdline/depth_tests.py?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/tests/cmdline/depth_tests.py 
(original)
+++ subversion/branches/authzperf/subversion/tests/cmdline/depth_tests.py Thu 
Oct 13 15:25:15 2016
@@ -2897,6 +2897,66 @@ def commit_excluded(sbox):
                                         [], False,
                                         "--set-depth=infinity", wc_dir)
 
+@Issue(4636)
+@XFail()
+def fold_tree_with_deleted_moved_items(sbox):
+  "deleted & moved items left untouched"
+  ign_a, ign_b, ign_c, wc_dir = set_up_depthy_working_copies(sbox,
+                                                             infinity=True)
+
+  A_path = sbox.ospath('A')
+
+  # Delete file lambda, move file pi and directory C
+  sbox.simple_rm('A/B/lambda')
+  sbox.simple_move('A/D/G/pi', 'A/D/G/pi_moved')
+  sbox.simple_move('A/C', 'A/C_moved')
+
+  # Fold the A dir to empty, expect the deleted & moved items ones left
+  # and visible in status, rather than gone without a trace.
+
+  # Directories B and D won't be deleted, because that would remove their
+  # local modifications. Their unmodified descendants are deleted though.
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B/E'          : Item(status='D '),
+    'A/B/F'          : Item(status='D '),
+    'A/D/G/rho'      : Item(status='D '),
+    'A/D/G/tau'      : Item(status='D '),
+    'A/D/H'          : Item(status='D '),
+    'A/D/gamma'      : Item(status='D '),
+    'A/mu'           : Item(status='D '),
+    })
+  expected_status = svntest.wc.State(wc_dir, {
+    ''               : Item(status='  ', wc_rev=1),
+    'iota'           : Item(status='  ', wc_rev=1),
+    'A'              : Item(status='  ', wc_rev=1),
+    'A/B'            : Item(status='  ', wc_rev=1),
+    'A/B/lambda'     : Item(status='D ', wc_rev=1),
+    'A/C'            : Item(status='D ', wc_rev=1, moved_to='A/C_moved'),
+    'A/C_moved'      : Item(status='A ', wc_rev='-', copied='+',
+                               moved_from='A/C'),
+    'A/D'            : Item(status='  ', wc_rev=1),
+    'A/D/G'          : Item(status='  ', wc_rev=1),
+    'A/D/G/pi'       : Item(status='D ', wc_rev=1, moved_to='A/D/G/pi_moved'),
+    'A/D/G/pi_moved' : Item(status='A ', wc_rev='-', copied='+',
+                               moved_from='A/D/G/pi'),
+    })
+  expected_disk = svntest.wc.State('', {
+    'iota'           : Item(contents="This is the file 'iota'.\n"),
+    'A'              : Item(contents=None),
+    'A/B'            : Item(contents=None),
+    'A/C_moved'      : Item(contents=None),
+    'A/D'            : Item(contents=None),
+    'A/D/G'          : Item(contents=None),
+    'A/D/G/pi_moved' : Item(contents="This is the file 'pi'.\n"),
+    })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        expected_disk,
+                                        expected_status,
+                                        [], False,
+                                        '--set-depth', 'empty', A_path)
+  verify_depth(None, "empty", A_path)
+
 #----------------------------------------------------------------------
 # list all tests here, starting with None:
 test_list = [ None,
@@ -2948,6 +3008,7 @@ test_list = [ None,
               revert_depth_files,
               spurious_nodes_row,
               commit_excluded,
+                         fold_tree_with_deleted_moved_items,
               ]
 
 if __name__ == "__main__":



Reply via email to