You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2016/10/11 09:11:54 UTC

svn commit: r1764214 [12/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...

Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc_db_update_move.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc_db_update_move.c Tue Oct 11 09:11:50 2016
@@ -1197,6 +1197,135 @@ tc_editor_alter_file(node_move_baton_t *
 }
 
 static svn_error_t *
+tc_editor_merge_local_file_change(node_move_baton_t *nmb,
+                                  const char *dst_relpath,
+                                  const char *src_relpath,
+                                  const svn_checksum_t *src_checksum,
+                                  const svn_checksum_t *dst_checksum,
+                                  apr_hash_t *dst_props,
+                                  apr_hash_t *src_props,
+                                  svn_boolean_t do_text_merge,
+                                  apr_pool_t *scratch_pool)
+{
+  update_move_baton_t *b = nmb->umb;
+  working_node_version_t old_version, new_version;
+  const char *dst_abspath = svn_dirent_join(b->wcroot->abspath,
+                                            dst_relpath,
+                                            scratch_pool);
+  svn_skel_t *conflict_skel = NULL;
+  apr_hash_t *actual_props;
+  apr_array_header_t *propchanges;
+  enum svn_wc_merge_outcome_t merge_outcome;
+  svn_wc_notify_state_t prop_state, content_state;
+  svn_skel_t *work_item, *work_items = NULL;
+  svn_node_kind_t dst_kind_on_disk;
+  svn_boolean_t obstructed = FALSE;
+
+  SVN_ERR(mark_node_edited(nmb, scratch_pool));
+  if (nmb->skip)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(svn_io_check_path(dst_abspath, &dst_kind_on_disk, scratch_pool));
+  if (dst_kind_on_disk != svn_node_none && dst_kind_on_disk != svn_node_file)
+    {
+      SVN_ERR(create_node_tree_conflict(&conflict_skel, nmb, dst_relpath,
+                                        svn_node_file, svn_node_file,
+                                        svn_wc_conflict_reason_obstructed,
+                                        svn_wc_conflict_action_edit,
+                                        NULL,
+                                        scratch_pool, scratch_pool));
+      obstructed = TRUE;
+    }
+
+  old_version.location_and_kind = b->old_version;
+  new_version.location_and_kind = b->new_version;
+
+  old_version.checksum = src_checksum;
+  old_version.props = src_props;
+  new_version.checksum = dst_checksum;
+  new_version.props = dst_props;
+
+  SVN_ERR(update_working_props(&prop_state, &conflict_skel, &propchanges,
+                               &actual_props, b, dst_relpath,
+                               &old_version, &new_version,
+                               scratch_pool, scratch_pool));
+
+  if (!obstructed && do_text_merge)
+    {
+      const char *old_pristine_abspath;
+      const char *src_abspath;
+
+      /*
+       * Run a 3-way merge to update the file at its post-move location, using
+       * the pre-move file's pristine text as the merge base, the post-move
+       * content as the merge-left version, and the current content of the
+       * working file at the pre-move location as the merge-right version.
+       */
+      SVN_ERR(svn_wc__db_pristine_get_path(&old_pristine_abspath,
+                                           b->db, b->wcroot->abspath,
+                                           src_checksum,
+                                           scratch_pool, scratch_pool));
+      src_abspath = svn_dirent_join(b->wcroot->abspath, src_relpath,
+                                    scratch_pool);
+      SVN_ERR(svn_wc__internal_merge(&work_item, &conflict_skel,
+                                     &merge_outcome, b->db,
+                                     old_pristine_abspath,
+                                     src_abspath,
+                                     dst_abspath,
+                                     dst_abspath,
+                                     NULL, NULL, NULL, /* diff labels */
+                                     actual_props,
+                                     FALSE, /* dry-run */
+                                     NULL, /* diff3-cmd */
+                                     NULL, /* merge options */
+                                     propchanges,
+                                     b->cancel_func, b->cancel_baton,
+                                     scratch_pool, scratch_pool));
+
+      work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+
+      if (merge_outcome == svn_wc_merge_conflict)
+        content_state = svn_wc_notify_state_conflicted;
+      else
+        content_state = svn_wc_notify_state_merged;
+    }
+  else
+    content_state = svn_wc_notify_state_unchanged;
+
+  /* If there are any conflicts to be stored, convert them into work items
+   * too. */
+  if (conflict_skel)
+    {
+      const char *dst_repos_relpath;
+
+      SVN_ERR(svn_wc__db_depth_get_info(NULL, NULL, NULL,
+                                        &dst_repos_relpath, NULL, NULL,
+                                        NULL, NULL, NULL, NULL, NULL, NULL,
+                                        NULL,
+                                        b->wcroot, dst_relpath,
+                                        b->dst_op_depth,
+                                        scratch_pool, scratch_pool));
+
+      SVN_ERR(create_conflict_markers(&work_item, dst_abspath, b->db,
+                                      dst_repos_relpath, conflict_skel,
+                                      b->operation, &old_version, &new_version,
+                                      svn_node_file, !obstructed,
+                                      scratch_pool, scratch_pool));
+
+      work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+    }
+
+  SVN_ERR(update_move_list_add(b->wcroot, dst_relpath, b->db,
+                               svn_wc_notify_update_update,
+                               svn_node_file,
+                               content_state,
+                               prop_state,
+                               conflict_skel, work_items, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 tc_editor_delete(node_move_baton_t *nmb,
                  const char *relpath,
                  svn_node_kind_t old_kind,
@@ -1805,6 +1934,402 @@ svn_wc__db_update_moved_away_conflict_vi
 
   /* Send all queued up notifications. */
   SVN_ERR(svn_wc__db_update_move_list_notify(wcroot, old_rev, new_rev,
+                                             notify_func, notify_baton,
+                                             scratch_pool));
+  if (notify_func)
+    {
+      svn_wc_notify_t *notify;
+
+      notify = svn_wc_create_notify(svn_dirent_join(wcroot->abspath,
+                                                    local_relpath,
+                                                    scratch_pool),
+                                    svn_wc_notify_update_completed,
+                                    scratch_pool);
+      notify->kind = svn_node_none;
+      notify->content_state = svn_wc_notify_state_inapplicable;
+      notify->prop_state = svn_wc_notify_state_inapplicable;
+      notify->revision = new_rev;
+      notify_func(notify_baton, notify, scratch_pool);
+    }
+
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+get_working_info(apr_hash_t **props,
+                 const svn_checksum_t **checksum,
+                 apr_array_header_t **children,
+                 svn_node_kind_t *kind,
+                 const char *local_relpath,
+                 svn_wc__db_wcroot_t *wcroot,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  svn_wc__db_status_t status;
+  const char *repos_relpath;
+  svn_node_kind_t db_kind;
+  svn_error_t *err;
+
+  err = svn_wc__db_read_info_internal(&status, &db_kind, NULL, &repos_relpath,
+                                      NULL, NULL, NULL, NULL, NULL,
+                                      checksum,
+                                      NULL, NULL, NULL, NULL, NULL,
+                                      NULL, NULL, NULL, NULL, NULL,
+                                      NULL, NULL, NULL, NULL, NULL,
+                                      wcroot, local_relpath,
+                                      result_pool, scratch_pool);
+
+  /* If there is no node, or only a node that describes a delete
+     of a lower layer we report this node as not existing. */
+  if ((err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+      || (!err && status != svn_wc__db_status_added
+               && status != svn_wc__db_status_normal))
+    {
+      svn_error_clear(err);
+
+      if (kind)
+        *kind = svn_node_none;
+      if (checksum)
+        *checksum = NULL;
+      if (props)
+        *props = NULL;
+      if (children)
+        *children = apr_array_make(result_pool, 0, sizeof(const char *));
+
+      return SVN_NO_ERROR;
+    }
+  else
+    SVN_ERR(err);
+
+  SVN_ERR(svn_wc__db_read_props_internal(props, wcroot, local_relpath,
+                                         result_pool, scratch_pool));
+
+  if (kind)
+    *kind = db_kind;
+
+  if (children && db_kind == svn_node_dir)
+    {
+      svn_sqlite__stmt_t *stmt;
+      svn_boolean_t have_row;
+
+      *children = apr_array_make(result_pool, 16, sizeof(const char *));
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_SELECT_WORKING_CHILDREN));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      while (have_row)
+        {
+          const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+
+          APR_ARRAY_PUSH(*children, const char *)
+              = svn_relpath_basename(child_relpath, result_pool);
+
+          SVN_ERR(svn_sqlite__step(&have_row, stmt));
+        }
+      SVN_ERR(svn_sqlite__reset(stmt));
+    }
+  else if (children)
+    *children = apr_array_make(result_pool, 0, sizeof(const char *));
+
+  return SVN_NO_ERROR;
+}
+
+/* ### Drive TC_EDITOR so as to ...
+ */
+static svn_error_t *
+walk_local_changes(node_move_baton_t *nmb,
+                   svn_wc__db_wcroot_t *wcroot,
+                   const char *src_relpath,
+                   const char *dst_relpath,
+                   apr_pool_t *scratch_pool)
+{
+  update_move_baton_t *b = nmb->umb;
+  svn_node_kind_t src_kind, dst_kind;
+  const svn_checksum_t *src_checksum, *dst_checksum;
+  apr_hash_t *src_props, *dst_props;
+  apr_array_header_t *src_children, *dst_children;
+
+  if (b->cancel_func)
+    SVN_ERR(b->cancel_func(b->cancel_baton));
+
+  SVN_ERR(get_working_info(&src_props, &src_checksum, &src_children,
+                           &src_kind, src_relpath, wcroot, scratch_pool,
+                           scratch_pool));
+
+  SVN_ERR(get_info(&dst_props, &dst_checksum, &dst_children, &dst_kind,
+                   dst_relpath, b->dst_op_depth,
+                   wcroot, scratch_pool, scratch_pool));
+
+  if (src_kind == svn_node_none
+      || (dst_kind != svn_node_none && src_kind != dst_kind))
+    {
+      SVN_ERR(tc_editor_delete(nmb, dst_relpath, dst_kind, src_kind,
+                               scratch_pool));
+    }
+
+  if (nmb->skip)
+    return SVN_NO_ERROR;
+
+  if (src_kind != svn_node_none && src_kind != dst_kind)
+    {
+      if (src_kind == svn_node_file || src_kind == svn_node_symlink)
+        {
+          SVN_ERR(tc_editor_add_file(nmb, dst_relpath, dst_kind,
+                                     src_checksum, src_props,
+                                     scratch_pool));
+        }
+      else if (src_kind == svn_node_dir)
+        {
+          SVN_ERR(tc_editor_add_directory(nmb, dst_relpath, dst_kind,
+                                          src_props, scratch_pool));
+        }
+    }
+  else if (src_kind != svn_node_none)
+    {
+      svn_boolean_t props_equal;
+
+      SVN_ERR(props_match(&props_equal, src_props, dst_props, scratch_pool));
+
+      if (src_kind == svn_node_file || src_kind == svn_node_symlink)
+        {
+          svn_boolean_t is_modified;
+
+          SVN_ERR(svn_wc__internal_file_modified_p(&is_modified, b->db,
+                                                   svn_dirent_join(
+                                                     b->wcroot->abspath,
+                                                     src_relpath,
+                                                     scratch_pool),
+                                                   FALSE /* exact_comparison */,
+                                                   scratch_pool));
+          if (!props_equal || is_modified)
+            SVN_ERR(tc_editor_merge_local_file_change(nmb, dst_relpath,
+                                                      src_relpath,
+                                                      src_checksum,
+                                                      dst_checksum,
+                                                      dst_props, src_props,
+                                                      is_modified,
+                                                      scratch_pool));
+        }
+      else if (src_kind == svn_node_dir)
+        {
+          if (!props_equal)
+            SVN_ERR(tc_editor_alter_directory(nmb, dst_relpath,
+                                              dst_props, src_props,
+                                              scratch_pool));
+        }
+    }
+
+  if (nmb->skip)
+    return SVN_NO_ERROR;
+
+  if (src_kind == svn_node_dir)
+    {
+      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+      int i = 0, j = 0;
+
+      while (i < src_children->nelts || j < dst_children->nelts)
+        {
+          const char *child_name;
+          svn_boolean_t src_only = FALSE, dst_only = FALSE;
+          node_move_baton_t cnmb = { 0 };
+
+          cnmb.pb = nmb;
+          cnmb.umb = nmb->umb;
+          cnmb.shadowed = nmb->shadowed;
+
+          svn_pool_clear(iterpool);
+          if (i >= src_children->nelts)
+            {
+              dst_only = TRUE;
+              child_name = APR_ARRAY_IDX(dst_children, j, const char *);
+            }
+          else if (j >= dst_children->nelts)
+            {
+              src_only = TRUE;
+              child_name = APR_ARRAY_IDX(src_children, i, const char *);
+            }
+          else
+            {
+              const char *src_name = APR_ARRAY_IDX(src_children, i,
+                                                   const char *);
+              const char *dst_name = APR_ARRAY_IDX(dst_children, j,
+                                                   const char *);
+              int cmp = strcmp(src_name, dst_name);
+
+              if (cmp > 0)
+                dst_only = TRUE;
+              else if (cmp < 0)
+                src_only = TRUE;
+
+              child_name = dst_only ? dst_name : src_name;
+            }
+
+          cnmb.src_relpath = svn_relpath_join(src_relpath, child_name,
+                                              iterpool);
+          cnmb.dst_relpath = svn_relpath_join(dst_relpath, child_name,
+                                              iterpool);
+
+          if (!cnmb.shadowed)
+            SVN_ERR(check_node_shadowed(&cnmb.shadowed, wcroot,
+                                        cnmb.dst_relpath, b->dst_op_depth,
+                                        iterpool));
+
+          SVN_ERR(walk_local_changes(&cnmb, wcroot, cnmb.src_relpath,
+                                     cnmb.dst_relpath, iterpool));
+
+          if (!dst_only)
+            ++i;
+          if (!src_only)
+            ++j;
+
+          if (nmb->skip) /* Does parent now want a skip? */
+            break;
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* The body of svn_wc__db_merge_local_changes(). */
+static svn_error_t *
+merge_local_changes(svn_revnum_t *old_rev,
+                    svn_revnum_t *new_rev,
+                    svn_wc__db_t *db,
+                    svn_wc__db_wcroot_t *wcroot,
+                    const char *local_relpath,
+                    const char *dst_relpath,
+                    svn_wc_operation_t operation,
+                    svn_wc_conflict_action_t action,
+                    svn_wc_conflict_reason_t reason,
+                    svn_cancel_func_t cancel_func,
+                    void *cancel_baton,
+                    apr_pool_t *scratch_pool)
+{
+  update_move_baton_t umb = { NULL };
+  svn_wc_conflict_version_t old_version;
+  svn_wc_conflict_version_t new_version;
+  apr_int64_t repos_id;
+  node_move_baton_t nmb = { 0 };
+
+  SVN_ERR_ASSERT(svn_relpath_skip_ancestor(dst_relpath, local_relpath) == NULL);
+
+  /* In case of 'merge' the source is in the BASE tree (+ local mods) and the
+   * destination is a copied tree. For update/switch the source is a copied
+   * tree (copied from the pre-update BASE revision when the tree conflict
+   * was raised), and the destination is in the BASE tree. */
+  if (operation == svn_wc_operation_merge)
+    {
+      umb.src_op_depth = 0;
+      umb.dst_op_depth = relpath_depth(dst_relpath);
+    }
+  else
+    {
+      umb.src_op_depth = relpath_depth(local_relpath);
+      umb.dst_op_depth = 0;
+    }
+
+  SVN_ERR(verify_write_lock(wcroot, local_relpath, scratch_pool));
+  SVN_ERR(verify_write_lock(wcroot, dst_relpath, scratch_pool));
+
+  SVN_ERR(svn_wc__db_depth_get_info(NULL, &new_version.node_kind,
+                                    &new_version.peg_rev,
+                                    &new_version.path_in_repos, &repos_id,
+                                    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                    NULL,
+                                    wcroot, local_relpath, umb.src_op_depth,
+                                    scratch_pool, scratch_pool));
+
+  SVN_ERR(svn_wc__db_fetch_repos_info(&new_version.repos_url,
+                                      &new_version.repos_uuid,
+                                      wcroot, repos_id,
+                                      scratch_pool));
+
+  SVN_ERR(svn_wc__db_depth_get_info(NULL, &old_version.node_kind,
+                                    &old_version.peg_rev,
+                                    &old_version.path_in_repos, &repos_id,
+                                    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                    NULL,
+                                    wcroot, dst_relpath, umb.dst_op_depth,
+                                    scratch_pool, scratch_pool));
+
+  SVN_ERR(svn_wc__db_fetch_repos_info(&old_version.repos_url,
+                                      &old_version.repos_uuid,
+                                      wcroot, repos_id,
+                                      scratch_pool));
+  *old_rev = old_version.peg_rev;
+  *new_rev = new_version.peg_rev;
+
+  umb.operation = operation;
+  umb.old_version= &old_version;
+  umb.new_version= &new_version;
+  umb.db = db;
+  umb.wcroot = wcroot;
+  umb.cancel_func = cancel_func;
+  umb.cancel_baton = cancel_baton;
+
+  if (umb.src_op_depth == 0)
+    SVN_ERR(suitable_for_move(wcroot, local_relpath, scratch_pool));
+
+  /* Create a new, and empty, list for notification information. */
+  SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
+                                      STMT_CREATE_UPDATE_MOVE_LIST));
+
+  /* Drive the editor... */
+
+  nmb.umb = &umb;
+  nmb.src_relpath = local_relpath;
+  nmb.dst_relpath = dst_relpath;
+  /* nmb.shadowed = FALSE; */
+  /* nmb.edited = FALSE; */
+  /* nmb.skip_children = FALSE; */
+
+  /* We walk the move source, comparing each node with the equivalent node at
+   * the move destination and applying any local changes to nodes at the move
+   destination. */
+  SVN_ERR(walk_local_changes(&nmb, wcroot, local_relpath, dst_relpath,
+                             scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_merge_local_changes(svn_wc__db_t *db,
+                               const char *local_abspath,
+                               const char *dest_abspath,
+                               svn_wc_operation_t operation,
+                               svn_wc_conflict_action_t action,
+                               svn_wc_conflict_reason_t reason,
+                               svn_cancel_func_t cancel_func,
+                               void *cancel_baton,
+                               svn_wc_notify_func2_t notify_func,
+                               void *notify_baton,
+                               apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  svn_revnum_t old_rev, new_rev;
+  const char *local_relpath;
+  const char *dest_relpath;
+
+  /* ### Check for mixed-rev src or dst? */
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
+                                                db, local_abspath,
+                                                scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  dest_relpath
+    = svn_dirent_skip_ancestor(wcroot->abspath, dest_abspath);
+
+  SVN_WC__DB_WITH_TXN(merge_local_changes(&old_rev, &new_rev, db, wcroot,
+                                          local_relpath, dest_relpath,
+                                          operation, action, reason,
+                                          cancel_func, cancel_baton,
+                                          scratch_pool),
+                      wcroot);
+
+  /* Send all queued up notifications. */
+  SVN_ERR(svn_wc__db_update_move_list_notify(wcroot, old_rev, new_rev,
                                              notify_func, notify_baton,
                                              scratch_pool));
   if (notify_func)

Modified: subversion/branches/ra-git/subversion/mod_authz_svn/INSTALL
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_authz_svn/INSTALL?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_authz_svn/INSTALL (original)
+++ subversion/branches/ra-git/subversion/mod_authz_svn/INSTALL Tue Oct 11 09:11:50 2016
@@ -186,10 +186,16 @@ II.   Configuration
          The "Require" statement in the previous example is not strictly
          needed, but has been included for clarity.
 
-      H. Example 8: Separate authz and groups files.
+      H. Example 8: Separating groups and authorization rules
 
-         This configuration allows storing the groups separately from the
-         main authz file with the authorization rules.
+         It may be convenient to maintain group definitions separately from
+         the authorization rules.  This configuration allows splitting them
+         into two separate files.
+
+         The file specified by the AuthzSVNGroupsFile directive uses the
+         same format as the ordinary authz file and should contain a single
+         section with the group definitions.  See section II.2.B for more
+         details.
 
          <Location /svn>
            DAV svn
@@ -205,78 +211,106 @@ II.   Configuration
            Require valid-user
          </Location>
 
+         Configurations with per-repository access files may also use a
+         single file containing the group definitions.  This configuration
+         avoids the need to duplicate the group definitions across multiple
+         per-repository access files.
+
+           AuthzSVNReposRelativeAccessFile filename
+           AuthzSVNGroupsFile /path/to/groups/file
+
+         NOTE: When the AuthzSVNGroupsFile directive is enabled, the
+         file specified with the AuthzSVNReposRelativeAccessFile or
+         AuthzSVNAccessFile directive cannot contain any group definitions.
+
    2. Specifying permissions
 
-      The file format of the access file looks like this:
+      A. File format of the access file
 
-        [groups]
-        <groupname> = <user>[,<user>...]
-        ...
-
-        [<path in repository>]
-        @<group> = [rw|r]
-        <user> = [rw|r]
-        * = [rw|r]
-
-        [<repository name>:<path in repository>]
-        @<group> = [rw|r]
-        <user> = [rw|r]
-        * = [rw|r]
-
-      An example (line continued lines are supposed to be on one line):
-
-        [groups]
-        subversion = jimb,sussman,kfogel,gstein,brane,joe,ghudson,fitz, \
-                     daniel,cmpilato,kevin,philip,jerenkrantz,rooneg, \
-                     bcollins,blair,striker,naked,dwhedon,dlr,kraai,mbk, \
-                     epg,bdenny,jaa
-        subversion-doc = nsd,zbrown,fmatias,dimentiy,patrick
-        subversion-bindings = xela,yoshiki,morten,jespersm,knacke
-        subversion-rm = mprice
-        ...and so on and so on...
-
-        [/]
-        # Allow everyone read on the entire repository
-        * = r
-        # Allow devs with blanket commit to write to the entire repository
-        @subversion = rw
-
-        [/trunk/doc]
-        @subversion-doc = rw
-
-        [/trunk/subversion/bindings]
-        @subversion-bindings = rw
-
-        [/branches]
-        @subversion-rm = rw
-
-        [/tags]
-        @subversion-rm = rw
-
-        [/branches/issue-650-ssl-certs]
-        mass = rw
-
-        [/branches/pluggable-db]
-        gthompson = rw
-
-        ...
-
-        [/secrets]
-        # Just for demonstration
-        * =
-        @subversion = rw
-
-        # In case of SVNParentPath we can specify which repository we are
-        # referring to.  If no matching repository qualified section is found,
-        # the general unqualified section is tried.
-        #
-        # NOTE: This will work in the case of using SVNPath as well, only the
-        # repository name (the last element of the url) will always be the
-        # same.
-        [dark:/]
-        * =
-        @dark = rw
+         The file format of the access file looks like this:
 
-        [light:/]
-        @light = rw
+           [groups]
+           <groupname> = <user>[,<user>...]
+           ...
+
+           [<path in repository>]
+           @<group> = [rw|r]
+           <user> = [rw|r]
+           * = [rw|r]
+
+           [<repository name>:<path in repository>]
+           @<group> = [rw|r]
+           <user> = [rw|r]
+           * = [rw|r]
+
+         An example (line continued lines are supposed to be on one line):
+
+           [groups]
+           subversion = jimb,sussman,kfogel,gstein,brane,joe,ghudson,fitz, \
+                        daniel,cmpilato,kevin,philip,jerenkrantz,rooneg, \
+                        bcollins,blair,striker,naked,dwhedon,dlr,kraai,mbk, \
+                        epg,bdenny,jaa
+           subversion-doc = nsd,zbrown,fmatias,dimentiy,patrick
+           subversion-bindings = xela,yoshiki,morten,jespersm,knacke
+           subversion-rm = mprice
+           ...and so on and so on...
+
+           [/]
+           # Allow everyone read on the entire repository
+           * = r
+           # Allow devs with blanket commit to write to the entire repository
+           @subversion = rw
+
+           [/trunk/doc]
+           @subversion-doc = rw
+
+           [/trunk/subversion/bindings]
+           @subversion-bindings = rw
+
+           [/branches]
+           @subversion-rm = rw
+
+           [/tags]
+           @subversion-rm = rw
+
+           [/branches/issue-650-ssl-certs]
+           mass = rw
+
+           [/branches/pluggable-db]
+           gthompson = rw
+
+           ...
+
+           [/secrets]
+           # Just for demonstration
+           * =
+           @subversion = rw
+
+           # In case of SVNParentPath we can specify which repository we are
+           # referring to.  If no matching repository qualified section is
+           # found, the general unqualified section is tried.
+           #
+           # NOTE: This will work in the case of using SVNPath as well, only
+           # the repository name (the last element of the url) will always be
+           # the same.
+           [dark:/]
+           * =
+           @dark = rw
+
+           [light:/]
+           @light = rw
+
+      B. File format of the groups file
+
+         The file format of the groups file looks like this:
+
+           [groups]
+           <groupname> = <user>[,<user>...]
+           ...
+
+         An example:
+
+           [groups]
+           developers = harry,sally,john
+           managers = jim,joe
 

Modified: subversion/branches/ra-git/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_authz_svn/mod_authz_svn.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/ra-git/subversion/mod_authz_svn/mod_authz_svn.c Tue Oct 11 09:11:50 2016
@@ -639,6 +639,8 @@ req_check_access(request_rec *r,
 
   if (r->method_number == M_MOVE || r->method_number == M_COPY)
     {
+      apr_status_t status;
+
       dest_uri = apr_table_get(r->headers_in, "Destination");
 
       /* Decline MOVE or COPY when there is no Destination uri, this will
@@ -647,7 +649,19 @@ req_check_access(request_rec *r,
       if (!dest_uri)
         return DECLINED;
 
-      apr_uri_parse(r->pool, dest_uri, &parsed_dest_uri);
+      status = apr_uri_parse(r->pool, dest_uri, &parsed_dest_uri);
+      if (status)
+        {
+          ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
+                        "Invalid URI in Destination header");
+          return HTTP_BAD_REQUEST;
+        }
+      if (!parsed_dest_uri.path)
+        {
+          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                        "Invalid URI in Destination header");
+          return HTTP_BAD_REQUEST;
+        }
 
       ap_unescape_url(parsed_dest_uri.path);
       dest_uri = parsed_dest_uri.path;

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/activity.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/activity.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/activity.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/activity.c Tue Oct 11 09:11:50 2016
@@ -227,7 +227,7 @@ dav_svn__store_activity(const dav_svn_re
 
 
 dav_error *
-dav_svn__create_txn(const dav_svn_repos *repos,
+dav_svn__create_txn(dav_svn_repos *repos,
                     const char **ptxn_name,
                     apr_hash_t *revprops,
                     apr_pool_t *pool)
@@ -248,7 +248,7 @@ dav_svn__create_txn(const dav_svn_repos
                     svn_string_create(repos->username, pool));
     }
 
-  serr = svn_fs_youngest_rev(&rev, repos->fs, pool);
+  serr = dav_svn__get_youngest_rev(&rev, repos, pool);
   if (serr != NULL)
     {
       return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/dav_svn.h?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/dav_svn.h Tue Oct 11 09:11:50 2016
@@ -149,6 +149,9 @@ typedef struct dav_svn_repos {
   /* The path to the activities db */
   const char *activities_db;
 
+  /* Cached yongest revision of the repository. SVN_INVALID_REVNUM if
+     youngest revision is not fetched yet. */
+  svn_revnum_t youngest_rev;
 } dav_svn_repos;
 
 
@@ -333,6 +336,10 @@ svn_boolean_t dav_svn__get_fulltext_cach
 /* for the repository referred to by this request, is revprop caching active? */
 svn_boolean_t dav_svn__get_revprop_cache_flag(request_rec *r);
 
+/* for the repository referred to by this request, is node prop caching active? */
+svn_boolean_t
+dav_svn__get_nodeprop_cache_flag(request_rec *r);
+
 /* has block read mode been enabled for the repository referred to by this
  * request? */
 svn_boolean_t dav_svn__get_block_read_flag(request_rec *r);
@@ -450,6 +457,40 @@ const char *dav_svn__get_vtxn_stub(reque
 /* For accessing transaction properties (typically "!svn/vtxr") */
 const char *dav_svn__get_vtxn_root_stub(request_rec *r);
 
+
+/*** Output helpers ***/
+
+/* An opaque type which represents an output for a particular request.
+
+   All writes should target a dav_svn__output object by either using
+   the dav_svn__brigade functions or by preparing a bucket brigade and
+   passing it to the output with dav_svn__output_pass_brigade().
+
+   IMPORTANT:  Don't write to an ap_filter_t coming from mod_dav, and
+   use this wrapper and the corresponding private API instead.  Using
+   the ap_filter_t can cause unbounded memory usage with self-removing
+   output filters (e.g., with the filters installed by mod_headers or
+   mod_deflate).
+
+   See https://mail-archives.apache.org/mod_mbox/httpd-dev/201608.mbox/%3C20160822151917.GA22369%40redhat.com%3E
+*/
+typedef struct dav_svn__output dav_svn__output;
+
+/* Create the output wrapper for request R, allocated in POOL. */
+dav_svn__output *
+dav_svn__output_create(request_rec *r,
+                       apr_pool_t *pool);
+
+/* Get a bucket allocator to use for all bucket/brigade creations
+   when writing to OUTPUT. */
+apr_bucket_alloc_t *
+dav_svn__output_get_bucket_alloc(dav_svn__output *output);
+
+/* Pass the bucket brigade BB down to the OUTPUT's filter stack. */
+svn_error_t *
+dav_svn__output_pass_brigade(dav_svn__output *output,
+                             apr_bucket_brigade *bb);
+
 
 /*** activity.c ***/
 
@@ -462,7 +503,7 @@ const char *dav_svn__get_vtxn_root_stub(
    NOTE:  This function will overwrite the svn:author property, if
    any, found in REVPROPS.  */
 dav_error *
-dav_svn__create_txn(const dav_svn_repos *repos,
+dav_svn__create_txn(dav_svn_repos *repos,
                     const char **ptxn_name,
                     apr_hash_t *revprops,
                     apr_pool_t *pool);
@@ -638,7 +679,7 @@ dav_svn__insert_all_liveprops(request_re
 /* Generate the HTTP response body for a successful MERGE. */
 /* ### more docco */
 dav_error *
-dav_svn__merge_response(ap_filter_t *output,
+dav_svn__merge_response(dav_svn__output *output,
                         const dav_svn_repos *repos,
                         svn_revnum_t new_rev,
                         const char *post_commit_err,
@@ -672,49 +713,49 @@ static const dav_report_elem dav_svn__re
 dav_error *
 dav_svn__update_report(const dav_resource *resource,
                        const apr_xml_doc *doc,
-                       ap_filter_t *output);
+                       dav_svn__output *output);
 dav_error *
 dav_svn__log_report(const dav_resource *resource,
                     const apr_xml_doc *doc,
-                    ap_filter_t *output);
+                    dav_svn__output *output);
 dav_error *
 dav_svn__dated_rev_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output);
+                          dav_svn__output *output);
 dav_error *
 dav_svn__get_locations_report(const dav_resource *resource,
                               const apr_xml_doc *doc,
-                              ap_filter_t *output);
+                              dav_svn__output *output);
 dav_error *
 dav_svn__get_location_segments_report(const dav_resource *resource,
                                       const apr_xml_doc *doc,
-                                      ap_filter_t *output);
+                                      dav_svn__output *output);
 dav_error *
 dav_svn__file_revs_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output);
+                          dav_svn__output *output);
 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 *
 dav_svn__get_mergeinfo_report(const dav_resource *resource,
                               const apr_xml_doc *doc,
-                              ap_filter_t *output);
+                              dav_svn__output *output);
 dav_error *
 dav_svn__get_locks_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output);
+                          dav_svn__output *output);
 
 dav_error *
 dav_svn__get_deleted_rev_report(const dav_resource *resource,
                                 const apr_xml_doc *doc,
-                                ap_filter_t *output);
+                                dav_svn__output *output);
 
 dav_error *
 dav_svn__get_inherited_props_report(const dav_resource *resource,
                                     const apr_xml_doc *doc,
-                                    ap_filter_t *output);
+                                    dav_svn__output *output);
 
 /*** posts/ ***/
 
@@ -722,11 +763,11 @@ dav_svn__get_inherited_props_report(cons
 dav_error *
 dav_svn__post_create_txn(const dav_resource *resource,
                          svn_skel_t *request_skel,
-                         ap_filter_t *output);
+                         dav_svn__output *output);
 dav_error *
 dav_svn__post_create_txn_with_props(const dav_resource *resource,
                                     svn_skel_t *request_skel,
-                                    ap_filter_t *output);
+                                    dav_svn__output *output);
 
 /*** authz.c ***/
 
@@ -933,23 +974,28 @@ int dav_svn__find_ns(const apr_array_hea
 
 /* Write LEN bytes from DATA to OUTPUT using BB.  */
 svn_error_t *dav_svn__brigade_write(apr_bucket_brigade *bb,
-                                    ap_filter_t *output,
+                                    dav_svn__output *output,
                                     const char *buf,
                                     apr_size_t len);
 
 /* Write NULL-terminated string STR to OUTPUT using BB.  */
 svn_error_t *dav_svn__brigade_puts(apr_bucket_brigade *bb,
-                                   ap_filter_t *output,
+                                   dav_svn__output *output,
                                    const char *str);
 
 
 /* Write data to OUTPUT using BB, using FMT as the output format string.  */
 svn_error_t *dav_svn__brigade_printf(apr_bucket_brigade *bb,
-                                     ap_filter_t *output,
+                                     dav_svn__output *output,
                                      const char *fmt,
                                      ...)
   __attribute__((format(printf, 3, 4)));
 
+/* Write an unspecified number of strings to OUTPUT using BB.  */
+svn_error_t *dav_svn__brigade_putstrs(apr_bucket_brigade *bb,
+                                      dav_svn__output *output,
+                                      ...) SVN_NEEDS_SENTINEL_NULL;
+
 
 
 
@@ -983,11 +1029,10 @@ dav_svn__sanitize_error(svn_error_t *ser
 
 
 /* Return a writable generic stream that will encode its output to base64
-   and send it to the Apache filter OUTPUT using BB.  Allocate the stream in
-   POOL. */
+   and send it to OUTPUT using BB.  Allocate the stream in POOL. */
 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);
 
 /* In INFO->r->subprocess_env set "SVN-ACTION" to LINE, "SVN-REPOS" to
@@ -1029,7 +1074,8 @@ 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_error *preferred_err,
+                              dav_svn__output *output,
+                              dav_error *preferred_err,
                               apr_pool_t *pool);
 
 /* Log a DAV error response.
@@ -1055,6 +1101,19 @@ int dav_svn__error_response_tag(request_
 int dav_svn__parse_request_skel(svn_skel_t **skel, request_rec *r,
                                 apr_pool_t *pool);
 
+/* Set *YOUNGEST_P to the number of the youngest revision in REPOS.
+ *
+ * Youngest revision will be cached in REPOS->YOUNGEST_REV to avoid
+ * fetching the youngest revision multiple times during proccessing
+ * the request.
+ *
+ * Uses SCRATCH_POOL for temporary allocations.
+ */
+svn_error_t *
+dav_svn__get_youngest_rev(svn_revnum_t *youngest_p,
+                          dav_svn_repos *repos,
+                          apr_pool_t *scratch_pool);
+
 /*** mirror.c ***/
 
 /* Perform the fixup hook for the R request.  */

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/deadprops.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/deadprops.c Tue Oct 11 09:11:50 2016
@@ -110,7 +110,12 @@ get_value(dav_db *db, const dav_prop_nam
       return NULL;
     }
 
-  /* ### if db->props exists, then try in there first */
+  /* If db->props exists, then use it to obtain property value. */
+  if (db->props)
+    {
+      *pvalue = svn_hash_gets(db->props, propname);
+      return NULL;
+    }
 
   /* We've got three different types of properties (node, txn, and
      revision), and we've got two different protocol versions to deal
@@ -705,19 +710,14 @@ db_first_name(dav_db *db, dav_prop_name
         }
       else
         {
-          svn_node_kind_t kind;
           serr = svn_fs_node_proplist(&db->props,
                                       db->resource->info->root.root,
                                       get_repos_path(db->resource->info),
                                       db->p);
-          if (! serr)
-            serr = svn_fs_check_path(&kind, db->resource->info->root.root,
-                                     get_repos_path(db->resource->info),
-                                     db->p);
 
           if (! serr)
             {
-              if (kind == svn_node_dir)
+              if (db->resource->collection)
                 action = svn_log__get_dir(db->resource->info->repos_path,
                                           db->resource->info->root.rev,
                                           FALSE, TRUE, 0, db->resource->pool);

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/liveprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/liveprops.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/liveprops.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/liveprops.c Tue Oct 11 09:11:50 2016
@@ -598,8 +598,8 @@ insert_prop_internal(const dav_resource
         {
           svn_revnum_t revnum;
 
-          serr = svn_fs_youngest_rev(&revnum, resource->info->repos->fs,
-                                     scratch_pool);
+          serr = dav_svn__get_youngest_rev(&revnum, resource->info->repos,
+                                           scratch_pool);
           if (serr != NULL)
             {
               ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
@@ -720,7 +720,6 @@ insert_prop_internal(const dav_resource
               || resource->type == DAV_RESOURCE_TYPE_WORKING
               || resource->type == DAV_RESOURCE_TYPE_VERSION))
         {
-          svn_node_kind_t kind;
           svn_checksum_t *checksum;
           svn_checksum_kind_t checksum_kind;
 
@@ -733,14 +732,20 @@ insert_prop_internal(const dav_resource
               checksum_kind = svn_checksum_sha1;
             }
 
-          serr = svn_fs_check_path(&kind, resource->info->root.root,
-                                   resource->info->repos_path, scratch_pool);
-          if (!serr && kind == svn_node_file)
-            serr = svn_fs_file_checksum(&checksum, checksum_kind,
-                                        resource->info->root.root,
-                                        resource->info->repos_path, TRUE,
-                                        scratch_pool);
-          if (serr != NULL)
+          serr = svn_fs_file_checksum(&checksum, checksum_kind,
+                                      resource->info->root.root,
+                                      resource->info->repos_path, TRUE,
+                                      scratch_pool);
+          if (serr && serr->apr_err == SVN_ERR_FS_NOT_FILE)
+            {
+              /* It should not happen since we're already checked
+                 RESOURCE->COLLECTION, but svn_fs_check_path() call
+                 was added in r1239596 for some reason. Keep it for
+                 now. */
+              svn_error_clear(serr);
+              return DAV_PROP_INSERT_NOTSUPP;
+            }
+          else if (serr)
             {
               ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
                             resource->info->r,
@@ -756,9 +761,6 @@ insert_prop_internal(const dav_resource
               break;
             }
 
-          if (kind != svn_node_file)
-            return DAV_PROP_INSERT_NOTSUPP;
-
           value = svn_checksum_to_cstring(checksum, scratch_pool);
 
           if (! value)

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/lock.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/lock.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/lock.c Tue Oct 11 09:11:50 2016
@@ -717,7 +717,7 @@ append_locks(dav_lockdb *lockdb,
 
       /* Commit a 0-byte file: */
 
-      if ((serr = svn_fs_youngest_rev(&rev, repos->fs, resource->pool)))
+      if ((serr = dav_svn__get_youngest_rev(&rev, repos, resource->pool)))
         return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                     "Could not determine youngest revision",
                                     resource->pool);

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/merge.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/merge.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/merge.c Tue Oct 11 09:11:50 2016
@@ -72,13 +72,12 @@ send_response(const dav_svn_repos *repos
               svn_fs_root_t *root,
               const char *path,
               svn_boolean_t is_dir,
-              ap_filter_t *output,
+              dav_svn__output *output,
               apr_bucket_brigade *bb,
               apr_pool_t *pool)
 {
   const char *href;
   const char *vsn_url;
-  apr_status_t status;
   svn_revnum_t rev_to_use;
 
   href = dav_svn__build_uri(repos, DAV_SVN__BUILD_URI_PUBLIC,
@@ -86,7 +85,7 @@ send_response(const dav_svn_repos *repos
   rev_to_use = dav_svn__get_safe_cr(root, path, pool);
   vsn_url = dav_svn__build_uri(repos, DAV_SVN__BUILD_URI_VERSION,
                                rev_to_use, path, FALSE /* add_href */, pool);
-  status = ap_fputstrs(output, bb,
+  SVN_ERR(dav_svn__brigade_putstrs(bb, output,
                        "<D:response>" DEBUG_CR
                        "<D:href>",
                        apr_xml_quote_string(pool, href, 1),
@@ -103,9 +102,7 @@ send_response(const dav_svn_repos *repos
                        "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                        "</D:propstat>" DEBUG_CR
                        "</D:response>" DEBUG_CR,
-                       NULL);
-  if (status != APR_SUCCESS)
-    return svn_error_wrap_apr(status, "Can't write response to output");
+                       SVN_VA_NULL));
 
   return SVN_NO_ERROR;
 }
@@ -115,36 +112,36 @@ static svn_error_t *
 do_resources(const dav_svn_repos *repos,
              svn_fs_root_t *root,
              svn_revnum_t revision,
-             ap_filter_t *output,
+             dav_svn__output *output,
              apr_bucket_brigade *bb,
              apr_pool_t *pool)
 {
-  apr_hash_t *changes;
-  apr_hash_t *sent = apr_hash_make(pool);
-  apr_hash_index_t *hi;
+  svn_fs_path_change_iterator_t *iterator;
+  svn_fs_path_change3_t *change;
+
+  /* Change lists can have >100000 entries, so we must make sure to release
+     any collection as soon as possible.  Allocate them in SUBPOOL. */
   apr_pool_t *subpool = svn_pool_create(pool);
+  apr_hash_t *sent = apr_hash_make(subpool);
+
+  /* Standard iteration pool. */
+  apr_pool_t *iterpool = svn_pool_create(subpool);
 
   /* Fetch the paths changed in this revision.  This will contain
      everything except otherwise-unchanged parent directories of added
      and deleted things.  Also, note that deleted things don't merit
      responses of their own -- they are considered modifications to
      their parent.  */
-  SVN_ERR(svn_fs_paths_changed2(&changes, root, pool));
+  SVN_ERR(svn_fs_paths_changed3(&iterator, root, subpool, subpool));
+  SVN_ERR(svn_fs_path_change_get(&change, iterator));
 
-  for (hi = apr_hash_first(pool, changes); hi; hi = apr_hash_next(hi))
+  while (change)
     {
-      const void *key;
-      void *val;
-      const char *path;
-      apr_ssize_t path_len;
-      svn_fs_path_change2_t *change;
       svn_boolean_t send_self;
       svn_boolean_t send_parent;
+      const char *path = change->path.data;
 
-      svn_pool_clear(subpool);
-      apr_hash_this(hi, &key, &path_len, &val);
-      path = key;
-      change = val;
+      svn_pool_clear(iterpool);
 
       /* Figure out who needs to get sent. */
       switch (change->change_kind)
@@ -171,30 +168,38 @@ do_resources(const dav_svn_repos *repos,
         {
           /* If we haven't already sent this path, send it (and then
              remember that we sent it). */
-          if (! apr_hash_get(sent, path, path_len))
+          if (! apr_hash_get(sent, path, change->path.len))
             {
               svn_node_kind_t kind;
-              SVN_ERR(svn_fs_check_path(&kind, root, path, subpool));
-              SVN_ERR(send_response(repos, root, path,
+              SVN_ERR(svn_fs_check_path(&kind, root, path, iterpool));
+              SVN_ERR(send_response(repos, root, change->path.data,
                                     kind == svn_node_dir,
-                                    output, bb, subpool));
-              apr_hash_set(sent, path, path_len, (void *)1);
+                                    output, bb, iterpool));
+
+              /* The paths in CHANGES are unique, i.e. they can only
+               * clash with those that we end in the SEND_PARENT case.
+               *
+               * Because file paths cannot be the parent of other paths,
+               * we only need to track non-file paths. */
+              if (change->node_kind != svn_node_file)
+                {
+                  path = apr_pstrmemdup(subpool, path, change->path.len);
+                  apr_hash_set(sent, path, change->path.len, (void *)1);
+                }
             }
         }
       if (send_parent)
         {
-          /* If it hasn't already been sent, send the parent directory
-             (and then remember that you sent it).  Allocate parent in
-             pool, not subpool, because it stays in the sent hash
-             afterwards. */
-          const char *parent = svn_fspath__dirname(path, pool);
+          const char *parent = svn_fspath__dirname(path, iterpool);
           if (! svn_hash_gets(sent, parent))
             {
               SVN_ERR(send_response(repos, root, parent,
-                                    TRUE, output, bb, subpool));
-              svn_hash_sets(sent, parent, (void *)1);
+                                    TRUE, output, bb, iterpool));
+              svn_hash_sets(sent, apr_pstrdup(subpool, parent), (void *)1);
             }
         }
+
+      SVN_ERR(svn_fs_path_change_get(&change, iterator));
     }
 
   svn_pool_destroy(subpool);
@@ -209,7 +214,7 @@ do_resources(const dav_svn_repos *repos,
 */
 
 dav_error *
-dav_svn__merge_response(ap_filter_t *output,
+dav_svn__merge_response(dav_svn__output *output,
                         const dav_svn_repos *repos,
                         svn_revnum_t new_rev,
                         const char *post_commit_err,
@@ -225,7 +230,7 @@ dav_svn__merge_response(ap_filter_t *out
   svn_string_t *creationdate, *creator_displayname;
   const char *post_commit_err_elem = NULL,
              *post_commit_header_info = NULL;
-  apr_status_t status;
+  apr_hash_t *revprops;
 
   serr = svn_fs_revision_root(&root, repos->fs, new_rev, pool);
   if (serr != NULL)
@@ -236,7 +241,8 @@ dav_svn__merge_response(ap_filter_t *out
                                   repos->pool);
     }
 
-  bb = apr_brigade_create(pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
   /* prep some strings */
 
@@ -268,25 +274,19 @@ dav_svn__merge_response(ap_filter_t *out
 
 
   /* get the creationdate and creator-displayname of the new revision, too. */
-  serr = svn_fs_revision_prop2(&creationdate, repos->fs, new_rev,
-                               SVN_PROP_REVISION_DATE, TRUE, pool, pool);
+  serr = svn_fs_revision_proplist2(&revprops, repos->fs, new_rev,
+                                   TRUE, pool, pool);
   if (serr != NULL)
     {
       return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
-                                  "Could not get date of newest revision",
-                                  repos->pool);
-    }
-  serr = svn_fs_revision_prop2(&creator_displayname, repos->fs, new_rev,
-                               SVN_PROP_REVISION_AUTHOR, TRUE, pool, pool);
-  if (serr != NULL)
-    {
-      return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
-                                  "Could not get author of newest revision",
-                                  repos->pool);
+                                  "Could not get date and author of newest "
+                                  "revision", repos->pool);
     }
 
+  creationdate = svn_hash_gets(revprops, SVN_PROP_REVISION_DATE);
+  creator_displayname = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR);
 
-  status = ap_fputstrs(output, bb,
+  serr = dav_svn__brigade_putstrs(bb, output,
                      DAV_XML_HEADER DEBUG_CR
                      "<D:merge-response xmlns:D=\"DAV:\"",
                      post_commit_header_info,
@@ -305,48 +305,47 @@ dav_svn__merge_response(ap_filter_t *out
                      "<D:resourcetype><D:baseline/></D:resourcetype>" DEBUG_CR,
                      post_commit_err_elem, DEBUG_CR
                      "<D:version-name>", rev, "</D:version-name>" DEBUG_CR,
-                     NULL);
-  if (status != APR_SUCCESS)
-    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
-                              0, status,
-                              "Could not write output");
+                     SVN_VA_NULL);
+  if (serr != NULL)
+    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                "Could not write output",
+                                repos->pool);
 
   if (creationdate)
     {
-      status = ap_fputstrs(output, bb,
+      serr = dav_svn__brigade_putstrs(bb, output,
                          "<D:creationdate>",
                          apr_xml_quote_string(pool, creationdate->data, 1),
                          "</D:creationdate>" DEBUG_CR,
-                         NULL);
-      if (status != APR_SUCCESS)
-        return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
-                                  0, status,
-                                  "Could not write output");
+                         SVN_VA_NULL);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "Could not write output",
+                                    repos->pool);
     }
   if (creator_displayname)
     {
-      status = ap_fputstrs(output, bb,
+      serr = dav_svn__brigade_putstrs(bb, output,
                          "<D:creator-displayname>",
                          apr_xml_quote_string(pool,
                                               creator_displayname->data, 1),
                          "</D:creator-displayname>" DEBUG_CR,
-                         NULL);
-      if (status != APR_SUCCESS)
-        return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
-                                  0, status,
-                                  "Could not write output");
+                         SVN_VA_NULL);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "Could not write output",
+                                    repos->pool);
     }
-  status = ap_fputstrs(output, bb,
+  serr = dav_svn__brigade_putstrs(bb, output,
                      "</D:prop>" DEBUG_CR
                      "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                      "</D:propstat>" DEBUG_CR
                      "</D:response>" DEBUG_CR,
-
-                     NULL);
-  if (status != APR_SUCCESS)
-    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
-                              0, status,
-                              "Could not write output");
+                     SVN_VA_NULL);
+  if (serr != NULL)
+    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                "Could not write output",
+                                repos->pool);
 
   /* ONLY have dir_delta drive the editor if the caller asked us to
      generate a full MERGE response.  svn clients can ask us to
@@ -375,20 +374,20 @@ dav_svn__merge_response(ap_filter_t *out
     }
 
   /* wrap up the merge response */
-  status = ap_fputs(output, bb,
-                  "</D:updated-set>" DEBUG_CR
-                  "</D:merge-response>" DEBUG_CR);
-  if (status != APR_SUCCESS)
-    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
-                              0, status,
-                              "Could not write output");
+  serr = dav_svn__brigade_puts(bb, output,
+                               "</D:updated-set>" DEBUG_CR
+                               "</D:merge-response>" DEBUG_CR);
+  if (serr != NULL)
+    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                "Could not write output",
+                                repos->pool);
 
   /* send whatever is left in the brigade */
-  status = ap_pass_brigade(output, bb);
-  if (status != APR_SUCCESS)
-    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
-                              0, status,
-                              "Could not write output");
+  serr = dav_svn__output_pass_brigade(output, bb);
+  if (serr != NULL)
+    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                "Could not write output",
+                                repos->pool);
 
   return NULL;
 }

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/mod_dav_svn.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/mod_dav_svn.c Tue Oct 11 09:11:50 2016
@@ -105,6 +105,7 @@ typedef struct dir_conf_t {
   enum conf_flag txdelta_cache;      /* whether to enable txdelta caching */
   enum conf_flag fulltext_cache;     /* whether to enable fulltext caching */
   enum conf_flag revprop_cache;      /* whether to enable revprop caching */
+  enum conf_flag nodeprop_cache;     /* whether to enable nodeprop caching */
   enum conf_flag block_read;         /* whether to enable block read mode */
   const char *hooks_env;             /* path to hook script env config file */
 } dir_conf_t;
@@ -240,6 +241,7 @@ create_dir_config(apr_pool_t *p, char *d
   conf->v2_protocol = CONF_FLAG_DEFAULT;
   conf->hooks_env = NULL;
   conf->txdelta_cache = CONF_FLAG_DEFAULT;
+  conf->nodeprop_cache = CONF_FLAG_DEFAULT;
 
   return conf;
 }
@@ -270,6 +272,7 @@ merge_dir_config(apr_pool_t *p, void *ba
   newconf->txdelta_cache = INHERIT_VALUE(parent, child, txdelta_cache);
   newconf->fulltext_cache = INHERIT_VALUE(parent, child, fulltext_cache);
   newconf->revprop_cache = INHERIT_VALUE(parent, child, revprop_cache);
+  newconf->nodeprop_cache = INHERIT_VALUE(parent, child, nodeprop_cache);
   newconf->block_read = INHERIT_VALUE(parent, child, block_read);
   newconf->root_dir = INHERIT_VALUE(parent, child, root_dir);
   newconf->hooks_env = INHERIT_VALUE(parent, child, hooks_env);
@@ -567,6 +570,19 @@ SVNCacheRevProps_cmd(cmd_parms *cmd, voi
 }
 
 static const char *
+SVNCacheNodeProps_cmd(cmd_parms *cmd, void *config, int arg)
+{
+  dir_conf_t *conf = config;
+
+  if (arg)
+    conf->nodeprop_cache = CONF_FLAG_ON;
+  else
+    conf->nodeprop_cache = CONF_FLAG_OFF;
+
+  return NULL;
+}
+
+static const char *
 SVNBlockRead_cmd(cmd_parms *cmd, void *config, int arg)
 {
   dir_conf_t *conf = config;
@@ -991,6 +1007,15 @@ dav_svn__get_revprop_cache_flag(request_
   return conf->revprop_cache == CONF_FLAG_ON;
 }
 
+svn_boolean_t
+dav_svn__get_nodeprop_cache_flag(request_rec *r)
+{
+  dir_conf_t *conf;
+
+  conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
+  /* node properties caching is enabled by default. */
+  return get_conf_flag(conf->nodeprop_cache, FALSE);
+}
 
 svn_boolean_t
 dav_svn__get_block_read_flag(request_rec *r)
@@ -1343,6 +1368,13 @@ static const command_rec cmds[] =
                "(default is Off)."),
 
   /* per directory/location */
+  AP_INIT_FLAG("SVNCacheNodeProps", SVNCacheNodeProps_cmd, NULL,
+               ACCESS_CONF|RSRC_CONF,
+               "speeds up data access by caching node properties "
+               "if sufficient in-memory cache is available"
+               "(default is On)."),
+
+  /* per directory/location */
   AP_INIT_FLAG("SVNBlockRead", SVNBlockRead_cmd, NULL,
                ACCESS_CONF|RSRC_CONF,
                "speeds up operations of FSFS 1.9+ repositories if large"

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/posts/create_txn.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/posts/create_txn.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/posts/create_txn.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/posts/create_txn.c Tue Oct 11 09:11:50 2016
@@ -34,7 +34,7 @@
 dav_error *
 dav_svn__post_create_txn(const dav_resource *resource,
                          svn_skel_t *request_skel,
-                         ap_filter_t *output)
+                         dav_svn__output *output)
 {
   const char *txn_name;
   const char *vtxn_name;
@@ -75,7 +75,7 @@ dav_svn__post_create_txn(const dav_resou
 dav_error *
 dav_svn__post_create_txn_with_props(const dav_resource *resource,
                                     svn_skel_t *request_skel,
-                                    ap_filter_t *output)
+                                    dav_svn__output *output)
 {
   const char *txn_name;
   const char *vtxn_name;

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/reports/dated-rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/dated-rev.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/dated-rev.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/dated-rev.c Tue Oct 11 09:11:50 2016
@@ -50,7 +50,7 @@
 dav_error *
 dav_svn__dated_rev_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output)
+                          dav_svn__output *output)
 {
   apr_xml_elem *child;
   int ns;
@@ -58,7 +58,6 @@ dav_svn__dated_rev_report(const dav_reso
   svn_revnum_t rev;
   apr_bucket_brigade *bb;
   svn_error_t *err;
-  apr_status_t apr_err;
   dav_error *derr = NULL;
 
   /* Find the DAV:creationdate element and get the requested time from it. */
@@ -95,15 +94,16 @@ dav_svn__dated_rev_report(const dav_reso
                                 "Could not access revision times.");
     }
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
-  apr_err = ap_fprintf(output, bb,
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
+  err = dav_svn__brigade_printf(bb, output,
                        DAV_XML_HEADER DEBUG_CR
                        "<S:dated-rev-report xmlns:S=\"" SVN_XML_NAMESPACE "\" "
                        "xmlns:D=\"DAV:\">" DEBUG_CR
                        "<D:" SVN_DAV__VERSION_NAME ">%ld</D:"
                        SVN_DAV__VERSION_NAME ">""</S:dated-rev-report>", rev);
-  if (apr_err)
-    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+  if (err)
+    derr = dav_svn__convert_err(err,
                                 HTTP_INTERNAL_SERVER_ERROR,
                                 "Error writing REPORT response.",
                                 resource->pool);

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/reports/deleted-rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/deleted-rev.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/deleted-rev.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/deleted-rev.c Tue Oct 11 09:11:50 2016
@@ -41,7 +41,7 @@
 dav_error *
 dav_svn__get_deleted_rev_report(const dav_resource *resource,
                                 const apr_xml_doc *doc,
-                                ap_filter_t *output)
+                                dav_svn__output *output)
 {
   apr_xml_elem *child;
   int ns;
@@ -52,7 +52,6 @@ dav_svn__get_deleted_rev_report(const da
   svn_revnum_t deleted_rev;
   apr_bucket_brigade *bb;
   svn_error_t *err;
-  apr_status_t apr_err;
   dav_error *derr = NULL;
 
   /* Sanity check. */
@@ -118,16 +117,17 @@ dav_svn__get_deleted_rev_report(const da
                                 "Could not find revision path was deleted.");
     }
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
-  apr_err = ap_fprintf(output, bb,
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
+  err = dav_svn__brigade_printf(bb, output,
                        DAV_XML_HEADER DEBUG_CR
                        "<S:get-deleted-rev-report xmlns:S=\""
                        SVN_XML_NAMESPACE "\" xmlns:D=\"DAV:\">" DEBUG_CR
                        "<D:" SVN_DAV__VERSION_NAME ">%ld</D:"
                        SVN_DAV__VERSION_NAME ">""</S:get-deleted-rev-report>",
                        deleted_rev);
-  if (apr_err)
-    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+  if (err)
+    derr = dav_svn__convert_err(err,
                                 HTTP_INTERNAL_SERVER_ERROR,
                                 "Error writing REPORT response.",
                                 resource->pool);

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/reports/file-revs.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/file-revs.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/file-revs.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/file-revs.c Tue Oct 11 09:11:50 2016
@@ -43,7 +43,7 @@ struct file_rev_baton {
   apr_bucket_brigade *bb;
 
   /* where to deliver the output */
-  ap_filter_t *output;
+  dav_svn__output *output;
 
   /* Whether we've written the <S:file-revs-report> header.  Allows for lazy
      writes to support mod_dav-based error handling. */
@@ -234,7 +234,7 @@ file_rev_handler(void *baton,
 dav_error *
 dav_svn__file_revs_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;
@@ -304,7 +304,7 @@ dav_svn__file_revs_report(const dav_reso
                                   "Not all parameters passed");
 
   frb.bb = apr_brigade_create(resource->pool,
-                              output->c->bucket_alloc);
+                              dav_svn__output_get_bucket_alloc(output));
   frb.output = output;
   frb.needs_header = TRUE;
   frb.svndiff_version = resource->info->svndiff_version;

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/reports/get-location-segments.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/get-location-segments.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/get-location-segments.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/get-location-segments.c Tue Oct 11 09:11:50 2016
@@ -48,7 +48,7 @@
 struct location_segment_baton
 {
   svn_boolean_t sent_opener;
-  ap_filter_t *output;
+  dav_svn__output *output;
   apr_bucket_brigade *bb;
   dav_svn__authz_read_baton arb;
 };
@@ -79,28 +79,26 @@ location_segment_receiver(svn_location_s
                           apr_pool_t *pool)
 {
   struct location_segment_baton *b = baton;
-  apr_status_t apr_err;
 
   SVN_ERR(maybe_send_opener(b));
 
   if (segment->path)
     {
       const char *path_quoted = apr_xml_quote_string(pool, segment->path, 1);
-      apr_err = ap_fprintf(b->output, b->bb,
+
+      SVN_ERR(dav_svn__brigade_printf(b->bb, b->output,
                            "<S:location-segment path=\"%s\" "
                            "range-start=\"%ld\" range-end=\"%ld\"/>" DEBUG_CR,
                            path_quoted,
-                           segment->range_start, segment->range_end);
+                           segment->range_start, segment->range_end));
     }
   else
     {
-      apr_err = ap_fprintf(b->output, b->bb,
+      SVN_ERR(dav_svn__brigade_printf(b->bb, b->output,
                            "<S:location-segment "
                            "range-start=\"%ld\" range-end=\"%ld\"/>" DEBUG_CR,
-                           segment->range_start, segment->range_end);
+                           segment->range_start, segment->range_end));
     }
-  if (apr_err)
-    return svn_error_create(apr_err, 0, NULL);
   return SVN_NO_ERROR;
 }
 
@@ -108,7 +106,7 @@ location_segment_receiver(svn_location_s
 dav_error *
 dav_svn__get_location_segments_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;
@@ -183,8 +181,8 @@ dav_svn__get_location_segments_report(co
     {
       svn_revnum_t youngest;
 
-      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)
         return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                     "Could not determine youngest revision",
@@ -216,7 +214,8 @@ dav_svn__get_location_segments_report(co
   arb.repos = resource->info->repos;
 
   /* Build the bucket brigade we'll use for output. */
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
   /* Do what we came here for. */
   location_segment_baton.sent_opener = FALSE;

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/reports/get-locations.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/get-locations.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/get-locations.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/get-locations.c Tue Oct 11 09:11:50 2016
@@ -44,23 +44,20 @@
 #include "../dav_svn.h"
 
 
-static apr_status_t
-send_get_locations_report(ap_filter_t *output,
+static svn_error_t *
+send_get_locations_report(dav_svn__output *output,
                           apr_bucket_brigade *bb,
                           const dav_resource *resource,
                           apr_hash_t *fs_locations)
 {
   apr_hash_index_t *hi;
-  apr_pool_t *pool;
-  apr_status_t apr_err;
+  apr_pool_t *pool = resource->pool;
 
-  pool = resource->pool;
-
-  apr_err = ap_fprintf(output, bb, DAV_XML_HEADER DEBUG_CR
+  SVN_ERR(dav_svn__brigade_printf(
+                       bb, output,
+                       DAV_XML_HEADER DEBUG_CR
                        "<S:get-locations-report xmlns:S=\"" SVN_XML_NAMESPACE
-                       "\" xmlns:D=\"DAV:\">" DEBUG_CR);
-  if (apr_err)
-    return apr_err;
+                       "\" xmlns:D=\"DAV:\">" DEBUG_CR));
 
   for (hi = apr_hash_first(pool, fs_locations); hi; hi = apr_hash_next(hi))
     {
@@ -70,24 +67,25 @@ send_get_locations_report(ap_filter_t *o
 
       apr_hash_this(hi, &key, NULL, &value);
       path_quoted = apr_xml_quote_string(pool, value, 1);
-      apr_err = ap_fprintf(output, bb, "<S:location "
+      SVN_ERR(dav_svn__brigade_printf(
+                           bb, output, "<S:location "
                            "rev=\"%ld\" path=\"%s\"/>" DEBUG_CR,
-                           *(const svn_revnum_t *)key, path_quoted);
-      if (apr_err)
-        return apr_err;
+                           *(const svn_revnum_t *)key, path_quoted));
     }
-  return ap_fprintf(output, bb, "</S:get-locations-report>" DEBUG_CR);
+
+  SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                  "</S:get-locations-report>" DEBUG_CR));
+  return SVN_NO_ERROR;
 }
 
 
 dav_error *
 dav_svn__get_locations_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;
-  apr_status_t apr_err;
   apr_bucket_brigade *bb;
   dav_svn__authz_read_baton arb;
 
@@ -171,12 +169,13 @@ dav_svn__get_locations_report(const dav_
                                   resource->pool);
     }
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
-  apr_err = send_get_locations_report(output, bb, resource, fs_locations);
+  serr = send_get_locations_report(output, bb, resource, fs_locations);
 
-  if (apr_err)
-    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+  if (serr)
+    derr = dav_svn__convert_err(serr,
                                 HTTP_INTERNAL_SERVER_ERROR,
                                 "Error writing REPORT response.",
                                 resource->pool);

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/reports/get-locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/get-locks.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/get-locks.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/get-locks.c Tue Oct 11 09:11:50 2016
@@ -44,25 +44,11 @@
    report in libsvn_ra_neon/get_locks.c.  */
 
 
-#define SVN_APR_ERR(expr)                       \
-  do {                                          \
-    apr_status_t apr_status__temp = (expr);     \
-    if (apr_status__temp)                       \
-      return apr_status__temp;                  \
-  } while (0)
-
-
 /* Transmit LOCKS (a hash of Subversion filesystem locks keyed by
-   path) across OUTPUT using BB.  Use POOL for necessary allocations.
-
-   NOTE:  As written, this function currently returns one of only two
-   status values -- "success", and "we had trouble writing out to the
-   output stream".  If you need to return something more interesting,
-   you'll probably want to generate dav_error's here instead of
-   passing back only apr_status_t's.  */
-static apr_status_t
+   path) across OUTPUT using BB.  Use POOL for necessary allocations. */
+static svn_error_t *
 send_get_lock_response(apr_hash_t *locks,
-                       ap_filter_t *output,
+                       dav_svn__output *output,
                        apr_bucket_brigade *bb,
                        apr_pool_t *pool)
 {
@@ -70,7 +56,7 @@ send_get_lock_response(apr_hash_t *locks
   apr_hash_index_t *hi;
 
   /* start sending report */
-  SVN_APR_ERR(ap_fprintf(output, bb,
+  SVN_ERR(dav_svn__brigade_printf(bb, output,
                          DAV_XML_HEADER DEBUG_CR
                          "<S:get-locks-report xmlns:S=\"" SVN_XML_NAMESPACE
                          "\" xmlns:D=\"DAV:\">" DEBUG_CR));
@@ -86,7 +72,7 @@ send_get_lock_response(apr_hash_t *locks
 
       /* Begin the <S:lock> tag, transmitting the path, token, and
          creation date. */
-      SVN_APR_ERR(ap_fprintf(output, bb,
+      SVN_ERR(dav_svn__brigade_printf(bb, output,
                              "<S:lock>" DEBUG_CR
                              "<S:path>%s</S:path>" DEBUG_CR
                              "<S:token>%s</S:token>" DEBUG_CR
@@ -98,7 +84,7 @@ send_get_lock_response(apr_hash_t *locks
 
       /* Got expiration date?  Tell the client. */
       if (lock->expiration_date)
-        SVN_APR_ERR(ap_fprintf(output, bb,
+        SVN_ERR(dav_svn__brigade_printf(bb, output,
                                "<S:expirationdate>%s</S:expirationdate>"
                                DEBUG_CR,
                                svn_time_to_cstring(lock->expiration_date,
@@ -126,7 +112,7 @@ send_get_lock_response(apr_hash_t *locks
               owner = encoded_owner->data;
               owner_base64 = TRUE;
             }
-          SVN_APR_ERR(ap_fprintf(output, bb,
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
                                  "<S:owner %s>%s</S:owner>" DEBUG_CR,
                                  owner_base64 ? "encoding=\"base64\"" : "",
                                  owner));
@@ -154,34 +140,32 @@ send_get_lock_response(apr_hash_t *locks
               comment = encoded_comment->data;
               comment_base64 = TRUE;
             }
-          SVN_APR_ERR(ap_fprintf(output, bb,
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
                                  "<S:comment %s>%s</S:comment>" DEBUG_CR,
                                  comment_base64 ? "encoding=\"base64\"" : "",
                                  comment));
         }
 
       /* Okay, finish up this lock by closing the <S:lock> tag. */
-      SVN_APR_ERR(ap_fprintf(output, bb, "</S:lock>" DEBUG_CR));
+      SVN_ERR(dav_svn__brigade_printf(bb, output, "</S:lock>" DEBUG_CR));
     }
   svn_pool_destroy(iterpool);
 
   /* Finish the report */
-  SVN_APR_ERR(ap_fprintf(output, bb, "</S:get-locks-report>" DEBUG_CR));
+  SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                  "</S:get-locks-report>" DEBUG_CR));
 
   return APR_SUCCESS;
 }
 
-#undef SVN_APR_ERR
-
 dav_error *
 dav_svn__get_locks_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output)
+                          dav_svn__output *output)
 {
   apr_bucket_brigade *bb;
   svn_error_t *err;
   dav_error *derr = NULL;
-  apr_status_t apr_err;
   apr_hash_t *locks;
   dav_svn__authz_read_baton arb;
   svn_depth_t depth = svn_depth_unknown;
@@ -227,10 +211,12 @@ dav_svn__get_locks_report(const dav_reso
     return dav_svn__convert_err(err, HTTP_INTERNAL_SERVER_ERROR,
                                 err->message, resource->pool);
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
-  if ((apr_err = send_get_lock_response(locks, output, bb, resource->pool)))
-    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+  err = send_get_lock_response(locks, output, bb, resource->pool);
+  if (err)
+    derr = dav_svn__convert_err(err,
                                 HTTP_INTERNAL_SERVER_ERROR,
                                 "Error writing REPORT response.",
                                 resource->pool);

Modified: subversion/branches/ra-git/subversion/mod_dav_svn/reports/inherited-props.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/inherited-props.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/inherited-props.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/inherited-props.c Tue Oct 11 09:11:50 2016
@@ -47,7 +47,7 @@
 dav_error *
 dav_svn__get_inherited_props_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;
@@ -106,7 +106,8 @@ dav_svn__get_inherited_props_report(cons
   arb.repos = resource->info->repos;
 
   /* Build inherited property 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_fs_revision_root(&root, resource->info->repos->fs,
                               rev, resource->pool);