subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhuij...@apache.org
Subject svn commit: r1764214 [13/21] - in /subversion/branches/ra-git: ./ build/ build/ac-macros/ build/generator/ build/win32/ contrib/client-side/ contrib/client-side/svnmerge/ contrib/hook-scripts/ contrib/server-side/ contrib/server-side/fsfsfixer/fixer/ c...
Date Tue, 11 Oct 2016 09:11:54 GMT
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/reports/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/log.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/log.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/log.c Tue Oct 11 09:11:50 2016
@@ -50,12 +50,17 @@ 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. */
   svn_boolean_t needs_header;
 
+  /* Whether we've written the <S:log-item> header for the current revision.
+     Allows for lazy XML node creation while receiving the data through
+     callbacks. */
+  svn_boolean_t needs_log_item;
+
   /* How deep we are in the log message tree.  We only need to surpress the
      SVN_INVALID_REVNUM message if the stack_depth is 0. */
   int stack_depth;
@@ -88,6 +93,22 @@ maybe_send_header(struct log_receiver_ba
                                     "xmlns:D=\"DAV:\">" DEBUG_CR));
       lrb->needs_header = FALSE;
     }
+
+  return SVN_NO_ERROR;
+}
+
+/* If LRB->needs_log_item is true, send the "<S:log-item>" start
+   element and set LRB->needs_log_item to zero.  Else do nothing. */
+static svn_error_t *
+maybe_start_log_item(struct log_receiver_baton *lrb)
+{
+  if (lrb->needs_log_item)
+    {
+      SVN_ERR(dav_svn__brigade_printf(lrb->bb, lrb->output,
+                                      "<S:log-item>" DEBUG_CR));
+      lrb->needs_log_item = FALSE;
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -99,17 +120,22 @@ maybe_send_header(struct log_receiver_ba
 static svn_error_t *
 start_path_with_copy_from(const char **element,
                           struct log_receiver_baton *lrb,
-                          svn_log_changed_path2_t *log_item,
+                          svn_repos_path_change_t *log_item,
                           apr_pool_t *pool)
 {
-  switch (log_item->action)
+  switch (log_item->change_kind)
     {
-      case 'A': *element = "S:added-path";
-                break;
-      case 'R': *element = "S:replaced-path";
-                break;
-      default:  /* Caller, you did wrong! */
-                SVN_ERR_MALFUNCTION();
+      case svn_fs_path_change_add: 
+        *element = "S:added-path";
+        break;
+
+      case svn_fs_path_change_replace:
+        *element = "S:replaced-path";
+        break;
+
+      default:
+        /* Caller, you did wrong! */
+        SVN_ERR_MALFUNCTION();
     }
 
   if (log_item->copyfrom_path
@@ -129,15 +155,76 @@ start_path_with_copy_from(const char **e
 }
 
 
-/* This implements `svn_log_entry_receiver_t'.
+/* This implements `svn_repos_path_change_receiver_t'.
    BATON is a `struct log_receiver_baton *'.  */
 static svn_error_t *
-log_receiver(void *baton,
-             svn_log_entry_t *log_entry,
-             apr_pool_t *pool)
+log_change_receiver(void *baton,
+                    svn_repos_path_change_t *change,
+                    apr_pool_t *scratch_pool)
+{
+  struct log_receiver_baton *lrb = baton;
+  const char *close_element = NULL;
+
+  /* We must open the XML nodes for the report and log-item before
+     sending the first changed path.
+
+     Note that we can't get here for empty revisions that log() injects
+     to indicate the end of a recursive merged rev sequence.
+   */
+  SVN_ERR(maybe_send_header(lrb));
+  SVN_ERR(maybe_start_log_item(lrb));
+
+  /* ### todo: is there a D: namespace equivalent for
+      `changed-path'?  Should use it if so. */
+  switch (change->change_kind)
+    {
+    case svn_fs_path_change_add:
+    case svn_fs_path_change_replace:
+      SVN_ERR(start_path_with_copy_from(&close_element, lrb,
+                                        change, scratch_pool));
+      break;
+
+    case svn_fs_path_change_delete:
+      SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
+                                    "<S:deleted-path"));
+      close_element = "S:deleted-path";
+      break;
+
+    case svn_fs_path_change_modify:
+      SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
+                                    "<S:modified-path"));
+      close_element = "S:modified-path";
+      break;
+
+    default:
+      break;
+    }
+
+  /* If we need to close the element, then send the attributes
+      that apply to all changed items and then close the element. */
+  if (close_element)
+    SVN_ERR(dav_svn__brigade_printf
+             (lrb->bb, lrb->output,
+              " node-kind=\"%s\""
+              " text-mods=\"%s\""
+              " prop-mods=\"%s\">%s</%s>" DEBUG_CR,
+              svn_node_kind_to_word(change->node_kind),
+              change->text_mod ? "true" : "false",
+              change->prop_mod ? "true" : "false",
+              apr_xml_quote_string(scratch_pool, change->path.data, 0),
+              close_element));
+
+  return SVN_NO_ERROR;
+}
+
+/* This implements `svn_repos_log_entry_receiver_t'.
+   BATON is a `struct log_receiver_baton *'.  */
+static svn_error_t *
+log_revision_receiver(void *baton,
+                      svn_repos_log_entry_t *log_entry,
+                      apr_pool_t *scratch_pool)
 {
   struct log_receiver_baton *lrb = baton;
-  apr_pool_t *iterpool = svn_pool_create(pool);
 
   SVN_ERR(maybe_send_header(lrb));
 
@@ -151,15 +238,24 @@ log_receiver(void *baton,
         lrb->stack_depth--;
     }
 
+  /* If we have not received any path changes, the log-item XML node
+     still needs to be opened.  Also, reset the controlling flag to
+     prepare it for the next revision - if there should be one. */
+  SVN_ERR(maybe_start_log_item(lrb));
+  lrb->needs_log_item = TRUE;
+
+  /* Path changes have been processed already. 
+     Now send the remaining per-revision info. */
   SVN_ERR(dav_svn__brigade_printf(lrb->bb, lrb->output,
-                                  "<S:log-item>" DEBUG_CR "<D:version-name>%ld"
+                                  "<D:version-name>%ld"
                                   "</D:version-name>" DEBUG_CR,
                                   log_entry->revision));
 
   if (log_entry->revprops)
     {
+      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
       apr_hash_index_t *hi;
-      for (hi = apr_hash_first(pool, log_entry->revprops);
+      for (hi = apr_hash_first(scratch_pool, log_entry->revprops);
            hi != NULL;
            hi = apr_hash_next(hi))
         {
@@ -200,7 +296,7 @@ log_receiver(void *baton,
             SVN_ERR(dav_svn__brigade_printf
                     (lrb->bb, lrb->output,
                      "<D:comment%s>%s</D:comment>" DEBUG_CR, encoding_str,
-                     apr_xml_quote_string(pool,
+                     apr_xml_quote_string(scratch_pool,
                                           svn_xml_fuzzy_escape(value->data,
                                                                iterpool), 0)));
           else
@@ -210,6 +306,8 @@ log_receiver(void *baton,
                      apr_xml_quote_string(iterpool, name, 0), encoding_str,
                      apr_xml_quote_string(iterpool, value->data, 0)));
         }
+
+      svn_pool_destroy(iterpool);
     }
 
   if (log_entry->has_children)
@@ -222,67 +320,6 @@ log_receiver(void *baton,
     SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                   "<S:subtractive-merge/>"));
 
-  if (log_entry->changed_paths2)
-    {
-      apr_hash_index_t *hi;
-      char *path;
-
-      for (hi = apr_hash_first(pool, log_entry->changed_paths2);
-           hi != NULL;
-           hi = apr_hash_next(hi))
-        {
-          void *val;
-          svn_log_changed_path2_t *log_item;
-          const char *close_element = NULL;
-
-          svn_pool_clear(iterpool);
-          apr_hash_this(hi, (void *) &path, NULL, &val);
-          log_item = val;
-
-          /* ### todo: is there a D: namespace equivalent for
-             `changed-path'?  Should use it if so. */
-          switch (log_item->action)
-            {
-            case 'A':
-            case 'R':
-              SVN_ERR(start_path_with_copy_from(&close_element, lrb,
-                                                log_item, iterpool));
-              break;
-
-            case 'D':
-              SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
-                                            "<S:deleted-path"));
-              close_element = "S:deleted-path";
-              break;
-
-            case 'M':
-              SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
-                                            "<S:modified-path"));
-              close_element = "S:modified-path";
-              break;
-
-            default:
-              break;
-            }
-
-          /* If we need to close the element, then send the attributes
-             that apply to all changed items and then close the element. */
-          if (close_element)
-            SVN_ERR(dav_svn__brigade_printf
-                    (lrb->bb, lrb->output,
-                     " node-kind=\"%s\""
-                     " text-mods=\"%s\""
-                     " prop-mods=\"%s\">%s</%s>" DEBUG_CR,
-                     svn_node_kind_to_word(log_item->node_kind),
-                     svn_tristate__to_word(log_item->text_modified),
-                     svn_tristate__to_word(log_item->props_modified),
-                     apr_xml_quote_string(iterpool, path, 0),
-                     close_element));
-        }
-    }
-
-  svn_pool_destroy(iterpool);
-
   SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                 "</S:log-item>" DEBUG_CR));
 
@@ -297,25 +334,17 @@ log_receiver(void *baton,
   lrb->result_count++;
   if (lrb->result_count == lrb->next_forced_flush)
     {
-      apr_status_t apr_err;
-
-      /* This flush is similar to that in dav_svn__final_flush_or_error().
+      apr_bucket *bkt;
 
-         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;
@@ -328,7 +357,7 @@ log_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;
@@ -460,9 +489,10 @@ 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;
   lrb.stack_depth = 0;
   /* lrb.requested_custom_revprops set above */
 
@@ -475,18 +505,20 @@ dav_svn__log_report(const dav_resource *
      flag in our log_receiver_baton structure). */
 
   /* Send zero or more log items. */
-  serr = svn_repos_get_logs4(repos->repos,
+  serr = svn_repos_get_logs5(repos->repos,
                              paths,
                              start,
                              end,
                              limit,
-                             discover_changed_paths,
                              strict_node_history,
                              include_merged_revisions,
                              revprops,
                              dav_svn__authz_read_func(&arb),
                              &arb,
-                             log_receiver,
+                             discover_changed_paths ? log_change_receiver
+                                                    : NULL,
+                             &lrb,
+                             log_revision_receiver,
                              &lrb,
                              resource->pool);
   if (serr)

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/reports/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/mergeinfo.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/mergeinfo.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/mergeinfo.c Tue Oct 11 09:11:50 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/ra-git/subversion/mod_dav_svn/reports/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/replay.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/replay.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/replay.c Tue Oct 11 09:11:50 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/ra-git/subversion/mod_dav_svn/reports/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/update.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/update.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/update.c Tue Oct 11 09:11:50 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;
@@ -970,7 +970,7 @@ dav_svn__update_report(const dav_resourc
   dav_error *derr = NULL;
   const char *src_path = NULL;
   const char *dst_path = NULL;
-  const dav_svn_repos *repos = resource->info->repos;
+  dav_svn_repos *repos = resource->info->repos;
   const char *target = "";
   svn_boolean_t text_deltas = TRUE;
   svn_depth_t requested_depth = svn_depth_unknown;
@@ -1028,7 +1028,7 @@ dav_svn__update_report(const dav_resourc
 
   /* Ask the repository about its youngest revision (which we'll need
      for some input validation later). */
-  if ((serr = svn_fs_youngest_rev(&youngest, repos->fs, resource->pool)))
+  if ((serr = dav_svn__get_youngest_rev(&youngest, repos, resource->pool)))
     return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                 "Could not determine the youngest "
                                 "revision for the update process.",
@@ -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/ra-git/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/repos.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/repos.c Tue Oct 11 09:11:50 2016
@@ -810,7 +810,7 @@ prep_regular(dav_resource_combined *comb
      ### other cases besides a BC? */
   if (comb->priv.root.rev == SVN_INVALID_REVNUM)
     {
-      serr = svn_fs_youngest_rev(&comb->priv.root.rev, repos->fs, pool);
+      serr = dav_svn__get_youngest_rev(&comb->priv.root.rev, repos, pool);
       if (serr != NULL)
         {
           return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
@@ -879,9 +879,9 @@ prep_version(dav_resource_combined *comb
   /* if we don't have a revision, then assume the youngest */
   if (!SVN_IS_VALID_REVNUM(comb->priv.root.rev))
     {
-      serr = svn_fs_youngest_rev(&comb->priv.root.rev,
-                                 comb->priv.repos->fs,
-                                 pool);
+      serr = dav_svn__get_youngest_rev(&comb->priv.root.rev,
+                                       comb->priv.repos,
+                                       pool);
       if (serr != NULL)
         {
           /* ### might not be a baseline */
@@ -1583,6 +1583,7 @@ get_parentpath_resource(request_rec *r,
   repos->special_uri = dav_svn__get_special_uri(r);
   repos->username = r->user;
   repos->client_capabilities = apr_hash_make(repos->pool);
+  repos->youngest_rev = SVN_INVALID_REVNUM;
 
   /* Make sure this type of resource always has a trailing slash; if
      not, redirect to a URI that does. */
@@ -2020,7 +2021,7 @@ parse_querystring(request_rec *r, const
   else
     {
       /* No peg-rev?  Default to HEAD, just like the cmdline client. */
-      serr = svn_fs_youngest_rev(&peg_rev, comb->priv.repos->fs, pool);
+      serr = dav_svn__get_youngest_rev(&peg_rev, comb->priv.repos, pool);
       if (serr != NULL)
         return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                     "Couldn't fetch youngest rev.", pool);
@@ -2259,6 +2260,7 @@ get_resource(request_rec *r,
   /* create the repository structure and stash it away */
   repos = apr_pcalloc(r->pool, sizeof(*repos));
   repos->pool = r->pool;
+  repos->youngest_rev = SVN_INVALID_REVNUM;
 
   comb->priv.repos = repos;
 
@@ -2367,6 +2369,8 @@ get_resource(request_rec *r,
                     dav_svn__get_fulltext_cache_flag(r) ? "1" :"0");
       svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
                     dav_svn__get_revprop_cache_flag(r) ? "2" :"0");
+      svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_NODEPROPS,
+                    dav_svn__get_nodeprop_cache_flag(r) ? "1" :"0");
       svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_BLOCK_READ,
                     dav_svn__get_block_read_flag(r) ? "1" :"0");
 
@@ -3034,50 +3038,6 @@ seek_stream(dav_stream *stream, apr_off_
        && resource->baselined))
 
 
-/* Return the last modification time of RESOURCE, or -1 if the DAV
-   resource type is not handled, or if an error occurs.  Temporary
-   allocations are made from RESOURCE->POOL. */
-static apr_time_t
-get_last_modified(const dav_resource *resource)
-{
-  apr_time_t last_modified;
-  svn_error_t *serr;
-  svn_revnum_t created_rev;
-  svn_string_t *date_time;
-
-  if (RESOURCE_LACKS_ETAG_POTENTIAL(resource))
-    return -1;
-
-  if ((serr = svn_fs_node_created_rev(&created_rev, resource->info->root.root,
-                                      resource->info->repos_path,
-                                      resource->pool)))
-    {
-      svn_error_clear(serr);
-      return -1;
-    }
-
-  if ((serr = svn_fs_revision_prop2(&date_time, resource->info->repos->fs,
-                                    created_rev, "svn:date", TRUE,
-                                    resource->pool, resource->pool)))
-    {
-      svn_error_clear(serr);
-      return -1;
-    }
-
-  if (date_time == NULL || date_time->data == NULL)
-    return -1;
-
-  if ((serr = svn_time_from_cstring(&last_modified, date_time->data,
-                                    resource->pool)))
-    {
-      svn_error_clear(serr);
-      return -1;
-    }
-
-  return last_modified;
-}
-
-
 const char *
 dav_svn__getetag(const dav_resource *resource, apr_pool_t *pool)
 {
@@ -3147,7 +3107,6 @@ set_headers(request_rec *r, const dav_re
   svn_error_t *serr;
   svn_filesize_t length;
   const char *mimetype = NULL;
-  apr_time_t last_modified;
 
   /* As version resources don't change, encourage caching. */
   if (is_cacheable(r, resource))
@@ -3159,15 +3118,6 @@ set_headers(request_rec *r, const dav_re
   if (!resource->exists)
     return NULL;
 
-  last_modified = get_last_modified(resource);
-  if (last_modified != -1)
-    {
-      /* Note the modification time for the requested resource, and
-         include the Last-Modified header in the response. */
-      ap_update_mtime(r, last_modified);
-      ap_set_last_modified(r);
-    }
-
   /* generate our etag and place it into the output */
   apr_table_setn(r->headers_out, "ETag",
                  dav_svn__getetag(resource, resource->pool));
@@ -3286,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;
 
 
@@ -3295,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;
 }
@@ -3316,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
@@ -3350,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]"
@@ -3463,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);
-            }
-
-          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 = "../";
-            }
+      bb = apr_brigade_create(resource->pool,
+                              dav_svn__output_get_bucket_alloc(output));
 
-          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)
         {
@@ -3563,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
@@ -3575,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);
+      svn_pool_destroy(iterpool);
 
-      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...)
-              */
-              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;
     }
@@ -3752,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);
@@ -3771,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",
@@ -3876,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;
 
@@ -3883,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);
@@ -3890,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;
     }
 }
@@ -4633,7 +4652,7 @@ dav_svn__working_to_regular_resource(dav
   /* Change the URL into either a baseline-collection or a public one. */
   if (priv->root.rev == SVN_INVALID_REVNUM)
     {
-      serr = svn_fs_youngest_rev(&priv->root.rev, repos->fs, resource->pool);
+      serr = dav_svn__get_youngest_rev(&priv->root.rev, repos, resource->pool);
       if (serr != NULL)
         return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                     "Could not determine youngest rev.",
@@ -4692,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;
@@ -4775,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/ra-git/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/util.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/util.c Tue Oct 11 09:11:50 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.");
@@ -870,3 +938,19 @@ dav_svn__parse_request_skel(svn_skel_t *
   *skel = svn_skel__parse(skel_str->data, skel_str->len, pool);
   return OK;
 }
+
+svn_error_t *
+dav_svn__get_youngest_rev(svn_revnum_t *youngest_p,
+                          dav_svn_repos *repos,
+                          apr_pool_t *scratch_pool)
+{
+  if (repos->youngest_rev == SVN_INVALID_REVNUM)
+    {
+      svn_revnum_t revnum;
+      SVN_ERR(svn_fs_youngest_rev(&revnum, repos->fs, scratch_pool));
+      repos->youngest_rev = revnum;
+    }
+
+   *youngest_p = repos->youngest_rev;
+   return SVN_NO_ERROR;
+}

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/version.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/version.c Tue Oct 11 09:11:50 2016
@@ -221,8 +221,8 @@ get_option(const dav_resource *resource,
       const char *uuid;
 
       /* Got youngest revision? */
-      if ((serr = svn_fs_youngest_rev(&youngest, resource->info->repos->fs,
-                                      resource->pool)))
+      if ((serr = dav_svn__get_youngest_rev(&youngest, resource->info->repos,
+                                            resource->pool)))
         {
           return dav_svn__convert_err
             (serr, HTTP_INTERNAL_SERVER_ERROR,
@@ -616,8 +616,8 @@ dav_svn__checkout(dav_resource *resource
       svn_revnum_t youngest;
 
       /* make sure the baseline being checked out is the latest */
-      serr = svn_fs_youngest_rev(&youngest, resource->info->repos->fs,
-                                 resource->pool);
+      serr = dav_svn__get_youngest_rev(&youngest, resource->info->repos,
+                                       resource->pool);
       if (serr != NULL)
         {
           /* ### correct HTTP error? */
@@ -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/ra-git/subversion/svn/cl-conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svn/cl-conflicts.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svn/cl-conflicts.c (original)
+++ subversion/branches/ra-git/subversion/svn/cl-conflicts.c Tue Oct 11 09:11:50 2016
@@ -58,14 +58,6 @@ static const svn_token_map_t map_conflic
   { NULL,               0 }
 };
 
-static const svn_token_map_t map_conflict_kind_xml[] =
-{
-  { "text",             svn_wc_conflict_kind_text },
-  { "property",         svn_wc_conflict_kind_property },
-  { "tree",             svn_wc_conflict_kind_tree },
-  { NULL,               0 }
-};
-
 /* Return a localised string representation of the local part of a conflict;
    NULL for non-localised odd cases. */
 static const char *
@@ -229,7 +221,7 @@ operation_str(svn_wc_operation_t operati
 svn_error_t *
 svn_cl__get_human_readable_prop_conflict_description(
   const char **desc,
-  const svn_client_conflict_t *conflict,
+  svn_client_conflict_t *conflict,
   apr_pool_t *pool)
 {
   const char *reason_str, *action_str;
@@ -288,7 +280,7 @@ svn_cl__get_human_readable_prop_conflict
 svn_error_t *
 svn_cl__get_human_readable_tree_conflict_description(
   const char **desc,
-  const svn_client_conflict_t *conflict,
+  svn_client_conflict_t *conflict,
   apr_pool_t *pool)
 {
   const char *action, *reason, *operation;
@@ -411,7 +403,7 @@ add_conflict_version_xml(svn_stringbuf_t
 
 static svn_error_t *
 append_tree_conflict_info_xml(svn_stringbuf_t *str,
-                              const svn_client_conflict_t *conflict,
+                              svn_client_conflict_t *conflict,
                               apr_pool_t *pool)
 {
   apr_hash_t *att_hash = apr_hash_make(pool);
@@ -479,115 +471,128 @@ append_tree_conflict_info_xml(svn_string
 
 svn_error_t *
 svn_cl__append_conflict_info_xml(svn_stringbuf_t *str,
-                                 const svn_client_conflict_t *conflict,
+                                 svn_client_conflict_t *conflict,
                                  apr_pool_t *scratch_pool)
 {
   apr_hash_t *att_hash;
-  const char *kind;
-  svn_wc_conflict_kind_t conflict_kind;
+  svn_boolean_t text_conflicted;
+  apr_array_header_t *props_conflicted;
+  svn_boolean_t tree_conflicted;
   svn_wc_operation_t conflict_operation;
   const char *repos_root_url;
   const char *repos_relpath;
   svn_revnum_t peg_rev;
   svn_node_kind_t node_kind;
 
-  conflict_kind = svn_client_conflict_get_kind(conflict);
   conflict_operation = svn_client_conflict_get_operation(conflict);
 
-  if (conflict_kind == svn_wc_conflict_kind_tree)
+  SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted,
+                                             &props_conflicted,
+                                             &tree_conflicted,
+                                             conflict,
+                                             scratch_pool, scratch_pool));
+  if (tree_conflicted)
     {
       /* Uses other element type */
       return svn_error_trace(
                 append_tree_conflict_info_xml(str, conflict, scratch_pool));
     }
 
+  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, NULL,
+                                             conflict,
+                                             scratch_pool, scratch_pool));
   att_hash = apr_hash_make(scratch_pool);
 
   svn_hash_sets(att_hash, "operation",
                 svn_cl__operation_str_xml(conflict_operation, scratch_pool));
 
-
-  kind = svn_token__to_word(map_conflict_kind_xml, conflict_kind);
-  svn_hash_sets(att_hash, "type", kind);
-
   svn_hash_sets(att_hash, "operation",
                 svn_cl__operation_str_xml(conflict_operation, scratch_pool));
 
-
-  /* "<conflict>" */
-  svn_xml_make_open_tag_hash(&str, scratch_pool,
-                             svn_xml_normal, "conflict", att_hash);
-
-  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, NULL, conflict,
-                                             scratch_pool, scratch_pool));
-  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(&repos_relpath,
-                                                              &peg_rev,
-                                                              &node_kind,
-                                                              conflict,
-                                                              scratch_pool,
-                                                              scratch_pool));
-  if (repos_root_url && repos_relpath)
-    SVN_ERR(add_conflict_version_xml(&str, "source-left",
-                                     repos_root_url, repos_relpath, peg_rev,
-                                     node_kind, scratch_pool));
-
-  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(&repos_relpath,
-                                                              &peg_rev,
-                                                              &node_kind,
-                                                              conflict,
-                                                              scratch_pool,
-                                                              scratch_pool));
-  if (repos_root_url && repos_relpath)
-    SVN_ERR(add_conflict_version_xml(&str, "source-right",
-                                     repos_root_url, repos_relpath, peg_rev,
-                                     node_kind, scratch_pool));
-
-  switch (conflict_kind)
+  if (text_conflicted)
     {
       const char *base_abspath;
       const char *my_abspath;
       const char *their_abspath;
 
-      case svn_wc_conflict_kind_text:
-        SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
-                                                      &base_abspath,
-                                                      &their_abspath,
-                                                      conflict, scratch_pool,
-                                                      scratch_pool));
-        /* "<prev-base-file> xx </prev-base-file>" */
-        svn_cl__xml_tagged_cdata(
-          &str, scratch_pool, "prev-base-file", base_abspath);
-
-        /* "<prev-wc-file> xx </prev-wc-file>" */
-        svn_cl__xml_tagged_cdata(
-          &str, scratch_pool, "prev-wc-file", my_abspath);
-
-        /* "<cur-base-file> xx </cur-base-file>" */
-        svn_cl__xml_tagged_cdata(
-          &str, scratch_pool, "cur-base-file", their_abspath);
+      svn_hash_sets(att_hash, "type", "text");
 
-        break;
+      /* "<conflict>" */
+      svn_xml_make_open_tag_hash(&str, scratch_pool,
+                                 svn_xml_normal, "conflict", att_hash);
 
-      case svn_wc_conflict_kind_property:
-        {
-          const char *reject_abspath;
-
-          /* "<prop-file> xx </prop-file>" */
-          reject_abspath =
-            svn_client_conflict_prop_get_reject_abspath(conflict);
-          svn_cl__xml_tagged_cdata(
-            &str, scratch_pool, "prop-file", reject_abspath);
-        }
-        break;
+      SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
+                &repos_relpath, &peg_rev, &node_kind, conflict,
+                scratch_pool, scratch_pool));
+      if (repos_root_url && repos_relpath)
+        SVN_ERR(add_conflict_version_xml(&str, "source-left",
+                                         repos_root_url, repos_relpath, peg_rev,
+                                         node_kind, scratch_pool));
 
-      default:
-      case svn_wc_conflict_kind_tree:
-        SVN_ERR_MALFUNCTION(); /* Handled separately */
-        break;
-    }
+      SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
+                &repos_relpath, &peg_rev, &node_kind, conflict,
+                scratch_pool, scratch_pool));
+      if (repos_root_url && repos_relpath)
+        SVN_ERR(add_conflict_version_xml(&str, "source-right",
+                                         repos_root_url, repos_relpath, peg_rev,
+                                         node_kind, scratch_pool));
+
+      SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
+                                                    &base_abspath,
+                                                    &their_abspath,
+                                                    conflict, scratch_pool,
+                                                    scratch_pool));
+      /* "<prev-base-file> xx </prev-base-file>" */
+      svn_cl__xml_tagged_cdata(
+        &str, scratch_pool, "prev-base-file", base_abspath);
+
+      /* "<prev-wc-file> xx </prev-wc-file>" */
+      svn_cl__xml_tagged_cdata(
+        &str, scratch_pool, "prev-wc-file", my_abspath);
+
+      /* "<cur-base-file> xx </cur-base-file>" */
+      svn_cl__xml_tagged_cdata(
+        &str, scratch_pool, "cur-base-file", their_abspath);
+
+      /* "</conflict>" */
+      svn_xml_make_close_tag(&str, scratch_pool, "conflict");
+    }
+
+  if (props_conflicted->nelts > 0)
+    {
+      const char *reject_abspath;
+
+      svn_hash_sets(att_hash, "type", "property");
+
+      /* "<conflict>" */
+      svn_xml_make_open_tag_hash(&str, scratch_pool,
+                                 svn_xml_normal, "conflict", att_hash);
 
-  /* "</conflict>" */
-  svn_xml_make_close_tag(&str, scratch_pool, "conflict");
+      SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
+                &repos_relpath, &peg_rev, &node_kind, conflict,
+                scratch_pool, scratch_pool));
+      if (repos_root_url && repos_relpath)
+        SVN_ERR(add_conflict_version_xml(&str, "source-left",
+                                         repos_root_url, repos_relpath, peg_rev,
+                                         node_kind, scratch_pool));
+
+      SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
+                &repos_relpath, &peg_rev, &node_kind, conflict,
+                scratch_pool, scratch_pool));
+      if (repos_root_url && repos_relpath)
+        SVN_ERR(add_conflict_version_xml(&str, "source-right",
+                                         repos_root_url, repos_relpath, peg_rev,
+                                         node_kind, scratch_pool));
+
+      /* "<prop-file> xx </prop-file>" */
+      reject_abspath =
+        svn_client_conflict_prop_get_reject_abspath(conflict);
+      svn_cl__xml_tagged_cdata(
+        &str, scratch_pool, "prop-file", reject_abspath);
+
+      /* "</conflict>" */
+      svn_xml_make_close_tag(&str, scratch_pool, "conflict");
+    }
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ra-git/subversion/svn/cl-conflicts.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svn/cl-conflicts.h?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svn/cl-conflicts.h (original)
+++ subversion/branches/ra-git/subversion/svn/cl-conflicts.h Tue Oct 11 09:11:50 2016
@@ -49,7 +49,7 @@ extern "C" {
 svn_error_t *
 svn_cl__get_human_readable_prop_conflict_description(
   const char **desc,
-  const svn_client_conflict_t *conflict,
+  svn_client_conflict_t *conflict,
   apr_pool_t *pool);
 
 /**
@@ -61,7 +61,7 @@ svn_cl__get_human_readable_prop_conflict
 svn_error_t *
 svn_cl__get_human_readable_tree_conflict_description(
   const char **desc,
-  const svn_client_conflict_t *conflict,
+  svn_client_conflict_t *conflict,
   apr_pool_t *pool);
 
 /* Like svn_cl__get_human_readable_tree_conflict_description but
@@ -81,7 +81,7 @@ svn_cl__get_human_readable_action_descri
 svn_error_t *
 svn_cl__append_conflict_info_xml(
   svn_stringbuf_t *str,
-  const svn_client_conflict_t *conflict,
+  svn_client_conflict_t *conflict,
   apr_pool_t *pool);
 
 #ifdef __cplusplus

Modified: subversion/branches/ra-git/subversion/svn/cl-log.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svn/cl-log.h?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svn/cl-log.h (original)
+++ subversion/branches/ra-git/subversion/svn/cl-log.h Tue Oct 11 09:11:50 2016
@@ -31,6 +31,8 @@
 
 #include "svn_types.h"
 
+#include "private/svn_string_private.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -70,6 +72,9 @@ typedef struct svn_cl__log_receiver_bato
    * the log message, or a changed path matches one of these patterns. */
   apr_array_header_t *search_patterns;
 
+  /* Buffer for Unicode normalization and case folding. */
+  svn_membuf_t buffer;
+
   /* Pool for persistent allocations. */
   apr_pool_t *pool;
 } svn_cl__log_receiver_baton;

Modified: subversion/branches/ra-git/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/svn/cl.h?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/svn/cl.h (original)
+++ subversion/branches/ra-git/subversion/svn/cl.h Tue Oct 11 09:11:50 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. */
@@ -338,8 +339,7 @@ svn_cl__try(svn_error_t *err,
 
 
 /* Our cancellation callback. */
-svn_error_t *
-svn_cl__check_cancel(void *baton);
+extern svn_cancel_func_t svn_cl__check_cancel;
 
 
 
@@ -362,6 +362,14 @@ svn_cl__conflict_stats_resolved(svn_cl__
                                 const char *path_local,
                                 svn_wc_conflict_kind_t conflict_kind);
 
+/* Set *CONFLICTED_PATHS to the conflicted paths contained in CONFLICT_STATS.
+ * If no conflicted path exists, set *CONFLICTED_PATHS to NULL. */
+svn_error_t *
+svn_cl__conflict_stats_get_paths(apr_array_header_t **conflicted_paths,
+                                 svn_cl__conflict_stats_t *conflict_stats,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool);
+
 /* Print the conflict stats accumulated in CONFLICT_STATS.
  *
  * Return any error encountered during printing.
@@ -371,39 +379,11 @@ svn_error_t *
 svn_cl__print_conflict_stats(svn_cl__conflict_stats_t *conflict_stats,
                              apr_pool_t *scratch_pool);
 
-/* Create and return an baton for use with svn_cl__conflict_func_interactive
- * in *B, allocated from RESULT_POOL, and initialised with the values
- * ACCEPT_WHICH, CONFIG, EDITOR_CMD, CANCEL_FUNC and CANCEL_BATON. */
-svn_error_t *
-svn_cl__get_conflict_func_interactive_baton(
-  svn_cl__interactive_conflict_baton_t **b,
-  svn_cl__accept_t accept_which,
-  apr_hash_t *config,
-  const char *editor_cmd,
-  svn_cl__conflict_stats_t *conflict_stats,
-  svn_cancel_func_t cancel_func,
-  void *cancel_baton,
-  apr_pool_t *result_pool);
-
-/* A callback capable of doing interactive conflict resolution.
-
-   The BATON must come from svn_cl__get_conflict_func_interactive_baton().
-   Resolves based on the --accept option if one was given to that function,
-   otherwise prompts the user to choose one of the three fulltexts, edit
-   the merged file on the spot, or just skip the conflict (to be resolved
-   later), among other options.
-
-   Implements svn_wc_conflict_resolver_func2_t.
+/* 
+ * Interactively resolve the conflict a @a CONFLICT.
+ * TODO: more docs
  */
 svn_error_t *
-svn_cl__conflict_func_interactive(svn_wc_conflict_result_t **result,
-                                  const svn_wc_conflict_description2_t *desc,
-                                  void *baton,
-                                  apr_pool_t *result_pool,
-                                  apr_pool_t *scratch_pool);
-
-
-svn_error_t *
 svn_cl__resolve_conflict(svn_boolean_t *resolved,
                          svn_cl__accept_t *accept_which,
                          svn_boolean_t *quit,
@@ -419,6 +399,18 @@ svn_cl__resolve_conflict(svn_boolean_t *
                          svn_client_ctx_t *ctx,
                          apr_pool_t *scratch_pool);
 
+/* 
+ * Interactively resolve conflicts for all TARGETS.
+ * TODO: more docs
+ */
+svn_error_t *
+svn_cl__walk_conflicts(apr_array_header_t *targets,
+                       svn_cl__conflict_stats_t *conflict_stats,
+                       svn_boolean_t is_resolve_cmd,
+                       svn_cl__opt_state_t *opt_state,
+                       svn_client_ctx_t *ctx,
+                       apr_pool_t *scratch_pool);
+
 
 /*** Command-line output functions -- printing to the user. ***/
 



Mime
View raw message