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 2018/11/07 12:30:11 UTC

svn commit: r1846002 [15/44] - in /subversion/branches/ra-git: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ build/generator/util/ build/win32/ contrib/client-side/ contrib/client-side/svn_load_dirs/ contr...

Modified: subversion/branches/ra-git/subversion/libsvn_repos/config_pool.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_repos/config_pool.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_repos/config_pool.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_repos/config_pool.c Wed Nov  7 12:30:06 2018
@@ -25,110 +25,17 @@
 
 
 #include "svn_checksum.h"
-#include "svn_config.h"
-#include "svn_error.h"
-#include "svn_hash.h"
 #include "svn_path.h"
 #include "svn_pools.h"
-#include "svn_repos.h"
 
-#include "private/svn_dep_compat.h"
-#include "private/svn_mutex.h"
 #include "private/svn_subr_private.h"
 #include "private/svn_repos_private.h"
-#include "private/svn_object_pool.h"
 
 #include "svn_private_config.h"
 
-
-/* Our wrapper structure for parsed svn_config_t* instances.  All data in
- * CS_CFG and CI_CFG is expanded (to make it thread-safe) and considered
- * read-only.
- */
-typedef struct config_object_t
-{
-  /* UUID of the configuration contents.
-   * This is a SHA1 checksum of the parsed textual representation of CFG. */
-  svn_checksum_t *key;
-
-  /* Parsed and expanded configuration.  At least one of the following
-   * must not be NULL. */
-
-  /* Case-sensitive config. May be NULL */
-  svn_config_t *cs_cfg;
-
-  /* Case-insensitive config. May be NULL */
-  svn_config_t *ci_cfg;
-} config_object_t;
-
-
-/* Data structure used to short-circuit the repository access for configs
- * read via URL.  After reading such a config successfully, we store key
- * repository information here and will validate it without actually opening
- * the repository.
- *
- * As this is only an optimization and may create many entries in
- * svn_repos__config_pool_t's IN_REPO_HASH_POOL index, we clean them up
- * once in a while.
- */
-typedef struct in_repo_config_t
-{
-  /* URL used to open the configuration */
-  const char *url;
-
-  /* Path of the repository that contained URL */
-  const char *repo_root;
-
-  /* Head revision of that repository when last read */
-  svn_revnum_t revision;
-
-  /* Contents checksum of the file stored under URL@REVISION */
-  svn_checksum_t *key;
-} in_repo_config_t;
-
-
-/* Core data structure extending the encapsulated OBJECT_POOL.  All access
- * to it must be serialized using the OBJECT_POOL->MUTEX.
- *
- * To speed up URL@HEAD lookups, we maintain IN_REPO_CONFIGS as a secondary
- * hash index.  It maps URLs as provided by the caller onto in_repo_config_t
- * instances.  If that is still up-to-date, a further lookup into CONFIG
- * may yield the desired configuration without the need to actually open
- * the respective repository.
- *
- * Unused configurations that are kept in the IN_REPO_CONFIGS hash and may
- * be cleaned up when the hash is about to grow.
- */
-struct svn_repos__config_pool_t
-{
-  svn_object_pool__t *object_pool;
-
-  /* URL -> in_repo_config_t* mapping.
-   * This is only a partial index and will get cleared regularly. */
-  apr_hash_t *in_repo_configs;
-
-  /* allocate the IN_REPO_CONFIGS index and in_repo_config_t here */
-  apr_pool_t *in_repo_hash_pool;
-};
+#include "config_file.h"
 
 
-/* Return an automatic reference to the CFG member in CONFIG that will be
- * released when POOL gets cleaned up.  The case sensitivity flag in *BATON
- * selects the desired option and section name matching mode.
- */
-static void *
-getter(void *object,
-       void *baton,
-       apr_pool_t *pool)
-{
-  config_object_t *wrapper = object;
-  svn_boolean_t *case_sensitive = baton;
-  svn_config_t *config = *case_sensitive ? wrapper->cs_cfg : wrapper->ci_cfg;
-
-  /* we need to duplicate the root structure as it contains temp. buffers */
-  return config ? svn_config__shallow_copy(config, pool) : NULL;
-}
-
 /* Return a memory buffer structure allocated in POOL and containing the
  * data from CHECKSUM.
  */
@@ -146,286 +53,43 @@ checksum_as_key(svn_checksum_t *checksum
   return result;
 }
 
-/* Copy the configuration from the wrapper in SOURCE to the wrapper in
- * *TARGET with the case sensitivity flag in *BATON selecting the config
- * to copy.  This is usually done to add the missing case-(in)-sensitive
- * variant.  Since we must hold all data in *TARGET from the same POOL,
- * a deep copy is required.
- */
-static svn_error_t *
-setter(void **target,
-       void *source,
-       void *baton,
-       apr_pool_t *pool)
-{
-  svn_boolean_t *case_sensitive = baton;
-  config_object_t *target_cfg = *(config_object_t **)target;
-  config_object_t *source_cfg = source;
-
-  /* Maybe, we created a variant with different case sensitivity? */
-  if (*case_sensitive && target_cfg->cs_cfg == NULL)
-    {
-      SVN_ERR(svn_config_dup(&target_cfg->cs_cfg, source_cfg->cs_cfg, pool));
-      svn_config__set_read_only(target_cfg->cs_cfg, pool);
-    }
-  else if (!*case_sensitive && target_cfg->ci_cfg == NULL)
-    {
-      SVN_ERR(svn_config_dup(&target_cfg->ci_cfg, source_cfg->ci_cfg, pool));
-      svn_config__set_read_only(target_cfg->ci_cfg, pool);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* Set *CFG to the configuration passed in as text in CONTENTS and *KEY to
- * the corresponding object pool key.  If no such configuration exists in
- * CONFIG_POOL, yet, parse CONTENTS and cache the result.  CASE_SENSITIVE
- * controls option and section name matching.
+/* Set *CFG to the configuration serialized in STREAM and cache it in
+ * CONFIG_POOL under CHECKSUM.  The configuration will only be parsed if
+ * we can't find it the CONFIG_POOL already.
  *
  * RESULT_POOL determines the lifetime of the returned reference and
  * SCRATCH_POOL is being used for temporary allocations.
  */
 static svn_error_t *
-auto_parse(svn_config_t **cfg,
-           svn_membuf_t **key,
-           svn_repos__config_pool_t *config_pool,
-           svn_stringbuf_t *contents,
-           svn_boolean_t case_sensitive,
-           apr_pool_t *result_pool,
-           apr_pool_t *scratch_pool)
-{
-  svn_checksum_t *checksum;
-  config_object_t *config_object;
-  apr_pool_t *cfg_pool;
-
-  /* calculate SHA1 over the whole file contents */
-  SVN_ERR(svn_checksum(&checksum, svn_checksum_sha1,
-                       contents->data, contents->len, scratch_pool));
-
-  /* return reference to suitable config object if that already exists */
-  *key = checksum_as_key(checksum, result_pool);
-  SVN_ERR(svn_object_pool__lookup((void **)cfg, config_pool->object_pool,
-                                  *key, &case_sensitive, result_pool));
-  if (*cfg)
-    return SVN_NO_ERROR;
-
-  /* create a pool for the new config object and parse the data into it  */
-  cfg_pool = svn_object_pool__new_wrapper_pool(config_pool->object_pool);
-
-  config_object = apr_pcalloc(cfg_pool, sizeof(*config_object));
-
-  SVN_ERR(svn_config_parse(case_sensitive ? &config_object->cs_cfg
-                                          : &config_object->ci_cfg,
-                           svn_stream_from_stringbuf(contents, scratch_pool),
-                           case_sensitive, case_sensitive, cfg_pool));
-
-  /* switch config data to r/o mode to guarantee thread-safe access */
-  svn_config__set_read_only(case_sensitive ? config_object->cs_cfg
-                                           : config_object->ci_cfg,
-                            cfg_pool);
-
-  /* add config in pool, handle loads races and return the right config */
-  SVN_ERR(svn_object_pool__insert((void **)cfg, config_pool->object_pool,
-                                  *key, config_object, &case_sensitive,
-                                  cfg_pool, result_pool));
-
-  return SVN_NO_ERROR;
-}
-
-/* Store a URL@REVISION to CHECKSUM, REPOS_ROOT in CONFIG_POOL.
- */
-static svn_error_t *
-add_checksum(svn_repos__config_pool_t *config_pool,
-             const char *url,
-             const char *repos_root,
-             svn_revnum_t revision,
-             svn_checksum_t *checksum)
-{
-  apr_size_t path_len = strlen(url);
-  apr_pool_t *pool = config_pool->in_repo_hash_pool;
-  in_repo_config_t *config = apr_hash_get(config_pool->in_repo_configs,
-                                          url, path_len);
-  if (config)
-    {
-      /* update the existing entry */
-      memcpy((void *)config->key->digest, checksum->digest,
-             svn_checksum_size(checksum));
-      config->revision = revision;
-
-      /* duplicate the string only if necessary */
-      if (strcmp(config->repo_root, repos_root))
-        config->repo_root = apr_pstrdup(pool, repos_root);
-    }
-  else
-    {
-      /* insert a new entry.
-       * Limit memory consumption by cyclically clearing pool and hash. */
-      if (2 * svn_object_pool__count(config_pool->object_pool)
-          < apr_hash_count(config_pool->in_repo_configs))
-        {
-          svn_pool_clear(pool);
-          config_pool->in_repo_configs = svn_hash__make(pool);
-        }
-
-      /* construct the new entry */
-      config = apr_pcalloc(pool, sizeof(*config));
-      config->key = svn_checksum_dup(checksum, pool);
-      config->url = apr_pstrmemdup(pool, url, path_len);
-      config->repo_root = apr_pstrdup(pool, repos_root);
-      config->revision = revision;
+find_config(svn_config_t **cfg,
+            svn_repos__config_pool_t *config_pool,
+            svn_stream_t *stream,
+            svn_checksum_t *checksum,
+            apr_pool_t *result_pool,
+            apr_pool_t *scratch_pool)
+{
+  /* First, attempt the cache lookup. */
+  svn_membuf_t *key = checksum_as_key(checksum, scratch_pool);
+  SVN_ERR(svn_object_pool__lookup((void **)cfg, config_pool, key,
+                                  result_pool));
 
-      /* add to index */
-      apr_hash_set(config_pool->in_repo_configs, url, path_len, config);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* Set *CFG to the configuration stored in URL@HEAD and cache it in
- * CONFIG_POOL.  CASE_SENSITIVE controls
- * option and section name matching.  If PREFERRED_REPOS is given,
- * use that if it also matches URL.
- *
- * RESULT_POOL determines the lifetime of the returned reference and
- * SCRATCH_POOL is being used for temporary allocations.
- */
-static svn_error_t *
-find_repos_config(svn_config_t **cfg,
-                  svn_membuf_t **key,
-                  svn_repos__config_pool_t *config_pool,
-                  const char *url,
-                  svn_boolean_t case_sensitive,
-                  svn_repos_t *preferred_repos,
-                  apr_pool_t *result_pool,
-                  apr_pool_t *scratch_pool)
-{
-  svn_repos_t *repos = NULL;
-  svn_fs_t *fs;
-  svn_fs_root_t *root;
-  svn_revnum_t youngest_rev;
-  svn_node_kind_t node_kind;
-  const char *dirent;
-  svn_stream_t *stream;
-  const char *fs_path;
-  const char *repos_root_dirent;
-  svn_checksum_t *checksum;
-  svn_stringbuf_t *contents;
-
-  *cfg = NULL;
-  SVN_ERR(svn_uri_get_dirent_from_file_url(&dirent, url, scratch_pool));
-
-  /* maybe we can use the preferred repos instance instead of creating a
-   * new one */
-  if (preferred_repos)
-    {
-      repos_root_dirent = svn_repos_path(preferred_repos, scratch_pool);
-      if (!svn_dirent_is_absolute(repos_root_dirent))
-        SVN_ERR(svn_dirent_get_absolute(&repos_root_dirent,
-                                        repos_root_dirent,
-                                        scratch_pool));
-
-      if (svn_dirent_is_ancestor(repos_root_dirent, dirent))
-        repos = preferred_repos;
-    }
-
-  /* open repos if no suitable preferred repos was provided. */
-  if (!repos)
-    {
-      /* Search for a repository in the full path. */
-      repos_root_dirent = svn_repos_find_root_path(dirent, scratch_pool);
-
-      /* Attempt to open a repository at repos_root_dirent. */
-      SVN_ERR(svn_repos_open3(&repos, repos_root_dirent, NULL,
-                              scratch_pool, scratch_pool));
-    }
-
-  fs_path = &dirent[strlen(repos_root_dirent)];
-
-  /* Get the filesystem. */
-  fs = svn_repos_fs(repos);
-
-  /* Find HEAD and the revision root */
-  SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, scratch_pool));
-  SVN_ERR(svn_fs_revision_root(&root, fs, youngest_rev, scratch_pool));
-
-  /* Fetch checksum and see whether we already have a matching config */
-  SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1, root, fs_path,
-                               FALSE, scratch_pool));
-  if (checksum)
-    {
-      *key = checksum_as_key(checksum, scratch_pool);
-      SVN_ERR(svn_object_pool__lookup((void **)cfg, config_pool->object_pool,
-                                      *key, &case_sensitive, result_pool));
-    }
-
-  /* not parsed, yet? */
+  /* Not found? => parse and cache */
   if (!*cfg)
     {
-      svn_filesize_t length;
+      svn_config_t *config;
 
-      /* fetch the file contents */
-      SVN_ERR(svn_fs_check_path(&node_kind, root, fs_path, scratch_pool));
-      if (node_kind != svn_node_file)
-        return SVN_NO_ERROR;
-
-      SVN_ERR(svn_fs_file_length(&length, root, fs_path, scratch_pool));
-      SVN_ERR(svn_fs_file_contents(&stream, root, fs_path, scratch_pool));
-      SVN_ERR(svn_stringbuf_from_stream(&contents, stream,
-                                        (apr_size_t)length, scratch_pool));
-
-      /* handle it like ordinary file contents and cache it */
-      SVN_ERR(auto_parse(cfg, key, config_pool, contents, case_sensitive,
-                         result_pool, scratch_pool));
+      /* create a pool for the new config object and parse the data into it */
+      apr_pool_t *cfg_pool = svn_object_pool__new_item_pool(config_pool);
+      SVN_ERR(svn_config_parse(&config, stream, FALSE, FALSE, cfg_pool));
+
+      /* switch config data to r/o mode to guarantee thread-safe access */
+      svn_config__set_read_only(config, cfg_pool);
+
+      /* add config in pool, handle loads races and return the right config */
+      SVN_ERR(svn_object_pool__insert((void **)cfg, config_pool, key,
+                                      config, cfg_pool, result_pool));
     }
 
-  /* store the (path,rev) -> checksum mapping as well */
-  if (*cfg && checksum)
-    SVN_MUTEX__WITH_LOCK(svn_object_pool__mutex(config_pool->object_pool),
-                         add_checksum(config_pool, url, repos_root_dirent,
-                                      youngest_rev, checksum));
-
-  return SVN_NO_ERROR;
-}
-
-/* Given the URL, search the CONFIG_POOL for an entry that maps it URL to
- * a content checksum and is still up-to-date.  If this could be found,
- * return the object's *KEY.  Use POOL for allocations.
- *
- * Requires external serialization on CONFIG_POOL.
- *
- * Note that this is only the URL(+rev) -> Checksum lookup and does not
- * guarantee that there is actually a config object available for *KEY.
- */
-static svn_error_t *
-key_by_url(svn_membuf_t **key,
-           svn_repos__config_pool_t *config_pool,
-           const char *url,
-           apr_pool_t *pool)
-{
-  svn_error_t *err;
-  svn_stringbuf_t *contents;
-  apr_int64_t current;
-
-  /* hash lookup url -> sha1 -> config */
-  in_repo_config_t *config = svn_hash_gets(config_pool->in_repo_configs, url);
-  *key = NULL;
-  if (!config)
-    return SVN_NO_ERROR;
-
-  /* found *some* reference to a configuration.
-   * Verify that it is still current.  Will fail for BDB repos. */
-  err = svn_stringbuf_from_file2(&contents,
-                                 svn_dirent_join(config->repo_root,
-                                                 "db/current", pool),
-                                 pool);
-  if (!err)
-    err = svn_cstring_atoi64(&current, contents->data);
-
-  if (err)
-    svn_error_clear(err);
-  else if (current == config->revision)
-    *key = checksum_as_key(config->key, pool);
-
   return SVN_NO_ERROR;
 }
 
@@ -436,94 +100,49 @@ svn_repos__config_pool_create(svn_repos_
                               svn_boolean_t thread_safe,
                               apr_pool_t *pool)
 {
-  svn_repos__config_pool_t *result;
-  svn_object_pool__t *object_pool;
-
-  SVN_ERR(svn_object_pool__create(&object_pool, getter, setter,
-                                  thread_safe, pool));
-
-  /* construct the config pool in our private ROOT_POOL to survive POOL
-   * cleanup and to prevent threading issues with the allocator */
-  result = apr_pcalloc(pool, sizeof(*result));
-
-  result->object_pool = object_pool;
-  result->in_repo_hash_pool = svn_pool_create(pool);
-  result->in_repo_configs = svn_hash__make(result->in_repo_hash_pool);
-
-  *config_pool = result;
-  return SVN_NO_ERROR;
+  return svn_error_trace(svn_object_pool__create(config_pool,
+                                                 thread_safe, pool));
 }
 
 svn_error_t *
 svn_repos__config_pool_get(svn_config_t **cfg,
-                           svn_membuf_t **key,
                            svn_repos__config_pool_t *config_pool,
                            const char *path,
                            svn_boolean_t must_exist,
-                           svn_boolean_t case_sensitive,
                            svn_repos_t *preferred_repos,
                            apr_pool_t *pool)
 {
   svn_error_t *err = SVN_NO_ERROR;
   apr_pool_t *scratch_pool = svn_pool_create(pool);
+  config_access_t *access = svn_repos__create_config_access(preferred_repos,
+                                                            scratch_pool);
+  svn_stream_t *stream;
+  svn_checksum_t *checksum;
 
-  /* make sure we always have a *KEY object */
-  svn_membuf_t *local_key = NULL;
-  if (key == NULL)
-    key = &local_key;
-  else
-    *key = NULL;
+  *cfg = NULL;
+  err = svn_repos__get_config(&stream, &checksum, access, path, must_exist,
+                              scratch_pool);
+  if (!err)
+    err = svn_error_quick_wrapf(find_config(cfg, config_pool, stream,
+                                            checksum, pool, scratch_pool),
+                                "Error while parsing config file: '%s':",
+                                path);
 
-  if (svn_path_is_url(path))
-    {
-      /* Read config file from repository.
-       * Attempt a quick lookup first. */
-      SVN_MUTEX__WITH_LOCK(svn_object_pool__mutex(config_pool->object_pool),
-                           key_by_url(key, config_pool, path, pool));
-      if (*key)
-        {
-          SVN_ERR(svn_object_pool__lookup((void **)cfg,
-                                          config_pool->object_pool,
-                                          *key, &case_sensitive, pool));
-          if (*cfg)
-            {
-              svn_pool_destroy(scratch_pool);
-              return SVN_NO_ERROR;
-            }
-        }
-
-      /* Read and cache the configuration.  This may fail. */
-      err = find_repos_config(cfg, key, config_pool, path, case_sensitive,
-                              preferred_repos, pool, scratch_pool);
-      if (err || !*cfg)
-        {
-          /* let the standard implementation handle all the difficult cases */
-          svn_error_clear(err);
-          err = svn_repos__retrieve_config(cfg, path, must_exist,
-                                           case_sensitive, pool);
-        }
-    }
-  else
+  /* Let the standard implementation handle all the difficult cases.
+   * Note that for in-repo configs, there are no further special cases to
+   * check for and deal with. */
+  if (!*cfg && !svn_path_is_url(path))
     {
-      /* Outside of repo file.  Read it. */
-      svn_stringbuf_t *contents;
-      err = svn_stringbuf_from_file2(&contents, path, scratch_pool);
-      if (err)
-        {
-          /* let the standard implementation handle all the difficult cases */
-          svn_error_clear(err);
-          err = svn_config_read3(cfg, path, must_exist, case_sensitive,
-                                 case_sensitive, pool);
-        }
-      else
-        {
-          /* parsing and caching will always succeed */
-          err = auto_parse(cfg, key, config_pool, contents, case_sensitive,
-                           pool, scratch_pool);
-        }
+      svn_error_clear(err);
+      err = svn_config_read3(cfg, path, must_exist, FALSE, FALSE, pool);
     }
 
+  svn_repos__destroy_config_access(access);
   svn_pool_destroy(scratch_pool);
 
-  return err;
+  /* we need to duplicate the root structure as it contains temp. buffers */
+  if (*cfg)
+    *cfg = svn_config__shallow_copy(*cfg, pool);
+
+  return svn_error_trace(err);
 }

Modified: subversion/branches/ra-git/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_repos/deprecated.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_repos/deprecated.c Wed Nov  7 12:30:06 2018
@@ -29,13 +29,16 @@
 #include "svn_repos.h"
 #include "svn_compat.h"
 #include "svn_hash.h"
+#include "svn_path.h"
 #include "svn_props.h"
+#include "svn_pools.h"
 
 #include "svn_private_config.h"
 
 #include "repos.h"
 
 #include "private/svn_repos_private.h"
+#include "private/svn_subr_private.h"
 
 
 
@@ -505,6 +508,45 @@ svn_repos_fs_get_locks(apr_hash_t **lock
                                                  authz_read_baton, pool));
 }
 
+static svn_error_t *
+mergeinfo_receiver(const char *path,
+                   svn_mergeinfo_t mergeinfo,
+                   void *baton,
+                   apr_pool_t *scratch_pool)
+{
+  svn_mergeinfo_catalog_t catalog = baton;
+  apr_pool_t *result_pool = apr_hash_pool_get(catalog);
+  apr_size_t len = strlen(path);
+
+  apr_hash_set(catalog,
+               apr_pstrmemdup(result_pool, path, len),
+               len,
+               svn_mergeinfo_dup(mergeinfo, result_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_repos_fs_get_mergeinfo(svn_mergeinfo_catalog_t *mergeinfo,
+                           svn_repos_t *repos,
+                           const apr_array_header_t *paths,
+                           svn_revnum_t rev,
+                           svn_mergeinfo_inheritance_t inherit,
+                           svn_boolean_t include_descendants,
+                           svn_repos_authz_func_t authz_read_func,
+                           void *authz_read_baton,
+                           apr_pool_t *pool)
+{
+  svn_mergeinfo_catalog_t result_catalog = svn_hash__make(pool);
+  SVN_ERR(svn_repos_fs_get_mergeinfo2(repos, paths, rev, inherit,
+                                      include_descendants,
+                                      authz_read_func, authz_read_baton,
+                                      mergeinfo_receiver, result_catalog,
+                                      pool));
+  *mergeinfo = result_catalog;
+
+  return SVN_NO_ERROR;
+}
 
 /*** From logs.c ***/
 svn_error_t *
@@ -780,6 +822,7 @@ svn_repos_dump_fs3(svn_repos_t *repos,
                                             TRUE,
                                             notify_func,
                                             notify_baton,
+                                            NULL, NULL,
                                             cancel_func,
                                             cancel_baton,
                                             pool));
@@ -859,6 +902,31 @@ svn_repos_verify_fs(svn_repos_t *repos,
 /*** From load.c ***/
 
 svn_error_t *
+svn_repos_load_fs5(svn_repos_t *repos,
+                   svn_stream_t *dumpstream,
+                   svn_revnum_t start_rev,
+                   svn_revnum_t end_rev,
+                   enum svn_repos_load_uuid uuid_action,
+                   const char *parent_dir,
+                   svn_boolean_t use_pre_commit_hook,
+                   svn_boolean_t use_post_commit_hook,
+                   svn_boolean_t validate_props,
+                   svn_boolean_t ignore_dates,
+                   svn_repos_notify_func_t notify_func,
+                   void *notify_baton,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
+                   apr_pool_t *pool)
+{
+  return svn_repos_load_fs6(repos, dumpstream, start_rev, end_rev,
+                            uuid_action, parent_dir,
+                            use_post_commit_hook, use_post_commit_hook,
+                            validate_props, ignore_dates, FALSE,
+                            notify_func, notify_baton,
+                            cancel_func, cancel_baton, pool);
+}
+
+svn_error_t *
 svn_repos_load_fs4(svn_repos_t *repos,
                    svn_stream_t *dumpstream,
                    svn_revnum_t start_rev,
@@ -1050,6 +1118,40 @@ svn_repos_load_fs(svn_repos_t *repos,
 }
 
 svn_error_t *
+svn_repos_get_fs_build_parser5(const svn_repos_parse_fns3_t **parser,
+                               void **parse_baton,
+                               svn_repos_t *repos,
+                               svn_revnum_t start_rev,
+                               svn_revnum_t end_rev,
+                               svn_boolean_t use_history,
+                               svn_boolean_t validate_props,
+                               enum svn_repos_load_uuid uuid_action,
+                               const char *parent_dir,
+                               svn_boolean_t use_pre_commit_hook,
+                               svn_boolean_t use_post_commit_hook,
+                               svn_boolean_t ignore_dates,
+                               svn_repos_notify_func_t notify_func,
+                               void *notify_baton,
+                               apr_pool_t *pool)
+{
+  SVN_ERR(svn_repos_get_fs_build_parser6(parser, parse_baton,
+                                         repos,
+                                         start_rev, end_rev,
+                                         use_history,
+                                         validate_props,
+                                         uuid_action,
+                                         parent_dir,
+                                         use_pre_commit_hook,
+                                         use_post_commit_hook,
+                                         ignore_dates,
+                                         FALSE /* normalize_props */,
+                                         notify_func,
+                                         notify_baton,
+                                         pool));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_repos_get_fs_build_parser4(const svn_repos_parse_fns3_t **callbacks,
                                void **parse_baton,
                                svn_repos_t *repos,
@@ -1171,9 +1273,30 @@ svn_repos_fs_begin_txn_for_update(svn_fs
 /*** From authz.c ***/
 
 svn_error_t *
+svn_repos_authz_read2(svn_authz_t **authz_p,
+                      const char *path,
+                      const char *groups_path,
+                      svn_boolean_t must_exist,
+                      apr_pool_t *pool)
+{
+  apr_pool_t *scratch_pool = svn_pool_create(pool);
+  svn_error_t *err = svn_repos_authz_read3(authz_p, path, groups_path,
+                                           must_exist, NULL,
+                                           pool, scratch_pool);
+  svn_pool_destroy(scratch_pool);
+
+  return svn_error_trace(err);
+}
+
+svn_error_t *
 svn_repos_authz_read(svn_authz_t **authz_p, const char *file,
                      svn_boolean_t must_exist, apr_pool_t *pool)
 {
-  return svn_repos__authz_read(authz_p, file, NULL, must_exist,
-                               FALSE, pool);
+  /* Prevent accidental new features in existing API. */
+  if (svn_path_is_url(file))
+    return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                             "'%s' is not a file name", file);
+
+  return svn_error_trace(svn_repos_authz_read2(authz_p, file, NULL,
+                                               must_exist, pool));
 }

Modified: subversion/branches/ra-git/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_repos/dump.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_repos/dump.c Wed Nov  7 12:30:06 2018
@@ -512,6 +512,30 @@ svn_repos__dump_headers(svn_stream_t *st
 }
 
 svn_error_t *
+svn_repos__dump_magic_header_record(svn_stream_t *dump_stream,
+                                    int version,
+                                    apr_pool_t *pool)
+{
+  SVN_ERR(svn_stream_printf(dump_stream, pool,
+                            SVN_REPOS_DUMPFILE_MAGIC_HEADER ": %d\n\n",
+                            version));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_repos__dump_uuid_header_record(svn_stream_t *dump_stream,
+                                   const char *uuid,
+                                   apr_pool_t *pool)
+{
+  if (uuid)
+    {
+      SVN_ERR(svn_stream_printf(dump_stream, pool, SVN_REPOS_DUMPFILE_UUID
+                                ": %s\n\n", uuid));
+    }
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_repos__dump_revision_record(svn_stream_t *dump_stream,
                                 svn_revnum_t revision,
                                 apr_hash_t *extra_headers,
@@ -546,11 +570,15 @@ svn_repos__dump_revision_record(svn_stre
                                  "%" APR_SIZE_T_FMT, propstring->len));
     }
 
-  /* Write out a regular Content-length header for the benefit of
-     non-Subversion RFC-822 parsers. */
-  svn_hash_sets(headers, SVN_REPOS_DUMPFILE_CONTENT_LENGTH,
-                apr_psprintf(scratch_pool,
-                             "%" APR_SIZE_T_FMT, propstring->len));
+  if (propstring)
+    {
+      /* Write out a regular Content-length header for the benefit of
+         non-Subversion RFC-822 parsers. */
+      svn_hash_sets(headers, SVN_REPOS_DUMPFILE_CONTENT_LENGTH,
+                    apr_psprintf(scratch_pool,
+                                 "%" APR_SIZE_T_FMT, propstring->len));
+    }
+
   SVN_ERR(write_revision_headers(dump_stream, headers, scratch_pool));
 
   /* End of headers */
@@ -1918,35 +1946,25 @@ get_dump_editor(const svn_delta_editor_t
 
 /* Helper for svn_repos_dump_fs.
 
-   Write a revision record of REV in FS to writable STREAM, using POOL.
+   Write a revision record of REV in REPOS to writable STREAM, using POOL.
    Dump revision properties as well if INCLUDE_REVPROPS has been set.
+   AUTHZ_FUNC and AUTHZ_BATON are passed directly to the repos layer.
  */
 static svn_error_t *
 write_revision_record(svn_stream_t *stream,
-                      svn_fs_t *fs,
+                      svn_repos_t *repos,
                       svn_revnum_t rev,
                       svn_boolean_t include_revprops,
+                      svn_repos_authz_func_t authz_func,
+                      void *authz_baton,
                       apr_pool_t *pool)
 {
   apr_hash_t *props;
-  apr_time_t timetemp;
-  svn_string_t *datevalue;
 
   if (include_revprops)
     {
-      SVN_ERR(svn_fs_revision_proplist2(&props, fs, rev, FALSE, pool, pool));
-
-      /* Run revision date properties through the time conversion to
-        canonicalize them. */
-      /* ### Remove this when it is no longer needed for sure. */
-      datevalue = svn_hash_gets(props, SVN_PROP_REVISION_DATE);
-      if (datevalue)
-        {
-          SVN_ERR(svn_time_from_cstring(&timetemp, datevalue->data, pool));
-          datevalue = svn_string_create(svn_time_to_cstring(timetemp, pool),
-                                        pool);
-          svn_hash_sets(props, SVN_PROP_REVISION_DATE, datevalue);
-        }
+      SVN_ERR(svn_repos_fs_revision_proplist(&props, repos, rev,
+                                             authz_func, authz_baton, pool));
     }
    else
     {
@@ -1961,6 +1979,27 @@ write_revision_record(svn_stream_t *stre
   return SVN_NO_ERROR;
 }
 
+/* Baton for dump_filter_authz_func(). */
+typedef struct dump_filter_baton_t
+{
+  svn_repos_dump_filter_func_t filter_func;
+  void *filter_baton;
+} dump_filter_baton_t;
+
+/* Implements svn_repos_authz_func_t. */
+static svn_error_t *
+dump_filter_authz_func(svn_boolean_t *allowed,
+                       svn_fs_root_t *root,
+                       const char *path,
+                       void *baton,
+                       apr_pool_t *pool)
+{
+  dump_filter_baton_t *b = baton;
+
+  return svn_error_trace(b->filter_func(allowed, root, path, b->filter_baton,
+                                        pool));
+}
+
 
 
 /* The main dumper. */
@@ -1975,6 +2014,8 @@ svn_repos_dump_fs4(svn_repos_t *repos,
                    svn_boolean_t include_changes,
                    svn_repos_notify_func_t notify_func,
                    void *notify_baton,
+                   svn_repos_dump_filter_func_t filter_func,
+                   void *filter_baton,
                    svn_cancel_func_t cancel_func,
                    void *cancel_baton,
                    apr_pool_t *pool)
@@ -1990,6 +2031,8 @@ svn_repos_dump_fs4(svn_repos_t *repos,
   svn_boolean_t found_old_reference = FALSE;
   svn_boolean_t found_old_mergeinfo = FALSE;
   svn_repos_notify_t *notify;
+  svn_repos_authz_func_t authz_func;
+  dump_filter_baton_t authz_baton = {0};
 
   /* Make sure we catch up on the latest revprop changes.  This is the only
    * time we will refresh the revprop data in this query. */
@@ -2018,6 +2061,20 @@ svn_repos_dump_fs4(svn_repos_t *repos,
                                "(youngest revision is %ld)"),
                              end_rev, youngest);
 
+  /* We use read authz callback to implement dump filtering. If there is no
+   * read access for some node, it will be excluded from dump as well as
+   * references to it (e.g. copy source). */
+  if (filter_func)
+    {
+      authz_func = dump_filter_authz_func;
+      authz_baton.filter_func = filter_func;
+      authz_baton.filter_baton = filter_baton;
+    }
+  else
+    {
+      authz_func = NULL;
+    }
+
   /* Write out the UUID. */
   SVN_ERR(svn_fs_get_uuid(fs, &uuid, pool));
 
@@ -2029,11 +2086,8 @@ svn_repos_dump_fs4(svn_repos_t *repos,
 
   /* Write out "general" metadata for the dumpfile.  In this case, a
      magic header followed by a dumpfile format version. */
-  SVN_ERR(svn_stream_printf(stream, pool,
-                            SVN_REPOS_DUMPFILE_MAGIC_HEADER ": %d\n\n",
-                            version));
-  SVN_ERR(svn_stream_printf(stream, pool, SVN_REPOS_DUMPFILE_UUID
-                            ": %s\n\n", uuid));
+  SVN_ERR(svn_repos__dump_magic_header_record(stream, version, pool));
+  SVN_ERR(svn_repos__dump_uuid_header_record(stream, uuid, pool));
 
   /* Create a notify object that we can reuse in the loop. */
   if (notify_func)
@@ -2053,8 +2107,8 @@ svn_repos_dump_fs4(svn_repos_t *repos,
         SVN_ERR(cancel_func(cancel_baton));
 
       /* Write the revision record. */
-      SVN_ERR(write_revision_record(stream, fs, rev, include_revprops,
-                                    iterpool));
+      SVN_ERR(write_revision_record(stream, repos, rev, include_revprops,
+                                    authz_func, &authz_baton, iterpool));
 
       /* When dumping revision 0, we just write out the revision record.
          The parser might want to use its properties.
@@ -2087,8 +2141,7 @@ svn_repos_dump_fs4(svn_repos_t *repos,
           SVN_ERR(svn_repos_dir_delta2(from_root, "", "",
                                        to_root, "",
                                        dump_editor, dump_edit_baton,
-                                       NULL,
-                                       NULL,
+                                       authz_func, &authz_baton,
                                        FALSE, /* don't send text-deltas */
                                        svn_depth_infinity,
                                        FALSE, /* don't send entry props */
@@ -2100,7 +2153,7 @@ svn_repos_dump_fs4(svn_repos_t *repos,
           /* The normal case: compare consecutive revs. */
           SVN_ERR(svn_repos_replay2(to_root, "", SVN_INVALID_REVNUM, FALSE,
                                     dump_editor, dump_edit_baton,
-                                    NULL, NULL, iterpool));
+                                    authz_func, &authz_baton, iterpool));
 
           /* While our editor close_edit implementation is a no-op, we still
              do this for completeness. */

Modified: subversion/branches/ra-git/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_repos/fs-wrap.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_repos/fs-wrap.c Wed Nov  7 12:30:06 2018
@@ -33,6 +33,7 @@
 #include "svn_repos.h"
 #include "svn_time.h"
 #include "svn_sorts.h"
+#include "svn_subst.h"
 #include "repos.h"
 #include "svn_private_config.h"
 #include "private/svn_repos_private.h"
@@ -235,10 +236,13 @@ svn_repos__validate_prop(const char *nam
            * carriage return characters ('\r'). */
           if (strchr(value->data, '\r') != NULL)
             {
-              return svn_error_createf
-                (SVN_ERR_BAD_PROPERTY_VALUE, NULL,
+              svn_error_t *err = svn_error_createf
+                (SVN_ERR_BAD_PROPERTY_VALUE_EOL, NULL,
                  _("Cannot accept non-LF line endings in '%s' property"),
                    name);
+
+              return svn_error_create(SVN_ERR_BAD_PROPERTY_VALUE, err,
+                                      _("Invalid property value"));
             }
         }
 
@@ -259,6 +263,34 @@ svn_repos__validate_prop(const char *nam
 }
 
 
+svn_error_t *
+svn_repos__normalize_prop(const svn_string_t **result_p,
+                          svn_boolean_t *normalized_p,
+                          const char *name,
+                          const svn_string_t *value,
+                          apr_pool_t *result_pool,
+                          apr_pool_t *scratch_pool)
+{
+  if (svn_prop_needs_translation(name) && value)
+    {
+      svn_string_t *new_value;
+
+      SVN_ERR(svn_subst_translate_string2(&new_value, NULL, normalized_p,
+                                          value, "UTF-8", TRUE,
+                                          result_pool, scratch_pool));
+      *result_p = new_value;
+    }
+  else
+    {
+      *result_p = svn_string_dup(value, result_pool);
+      if (normalized_p)
+        *normalized_p = FALSE;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
 /* Verify the mergeinfo property value VALUE and return an error if it
  * is invalid. The PATH on which that property is set is used for error
  * messages only.  Use SCRATCH_POOL for temporary allocations. */
@@ -901,25 +933,26 @@ svn_repos_fs_get_locks2(apr_hash_t **loc
 
 
 svn_error_t *
-svn_repos_fs_get_mergeinfo(svn_mergeinfo_catalog_t *mergeinfo,
-                           svn_repos_t *repos,
-                           const apr_array_header_t *paths,
-                           svn_revnum_t rev,
-                           svn_mergeinfo_inheritance_t inherit,
-                           svn_boolean_t include_descendants,
-                           svn_repos_authz_func_t authz_read_func,
-                           void *authz_read_baton,
-                           apr_pool_t *pool)
+svn_repos_fs_get_mergeinfo2(svn_repos_t *repos,
+                            const apr_array_header_t *paths,
+                            svn_revnum_t rev,
+                            svn_mergeinfo_inheritance_t inherit,
+                            svn_boolean_t include_descendants,
+                            svn_repos_authz_func_t authz_read_func,
+                            void *authz_read_baton,
+                            svn_repos_mergeinfo_receiver_t receiver,
+                            void *receiver_baton,
+                            apr_pool_t *scratch_pool)
 {
   /* Here we cast away 'const', but won't try to write through this pointer
    * without first allocating a new array. */
   apr_array_header_t *readable_paths = (apr_array_header_t *) paths;
   svn_fs_root_t *root;
-  apr_pool_t *iterpool = svn_pool_create(pool);
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
   if (!SVN_IS_VALID_REVNUM(rev))
-    SVN_ERR(svn_fs_youngest_rev(&rev, repos->fs, pool));
-  SVN_ERR(svn_fs_revision_root(&root, repos->fs, rev, pool));
+    SVN_ERR(svn_fs_youngest_rev(&rev, repos->fs, scratch_pool));
+  SVN_ERR(svn_fs_revision_root(&root, repos->fs, rev, scratch_pool));
 
   /* Filter out unreadable paths before divining merge tracking info. */
   if (authz_read_func)
@@ -940,7 +973,7 @@ svn_repos_fs_get_mergeinfo(svn_mergeinfo
               /* Requested paths differ from readable paths.  Fork
                  list of readable paths from requested paths. */
               int j;
-              readable_paths = apr_array_make(pool, paths->nelts - 1,
+              readable_paths = apr_array_make(scratch_pool, paths->nelts - 1,
                                               sizeof(char *));
               for (j = 0; j < i; j++)
                 {
@@ -957,10 +990,10 @@ svn_repos_fs_get_mergeinfo(svn_mergeinfo
      the change itself. */
   /* ### TODO(reint): ... but how about descendant merged-to paths? */
   if (readable_paths->nelts > 0)
-    SVN_ERR(svn_fs_get_mergeinfo2(mergeinfo, root, readable_paths, inherit,
-                                  include_descendants, TRUE, pool, pool));
-  else
-    *mergeinfo = apr_hash_make(pool);
+    SVN_ERR(svn_fs_get_mergeinfo3(root, readable_paths, inherit,
+                                  include_descendants, TRUE,
+                                  receiver, receiver_baton,
+                                  scratch_pool));
 
   svn_pool_destroy(iterpool);
   return SVN_NO_ERROR;

Modified: subversion/branches/ra-git/subversion/libsvn_repos/hooks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_repos/hooks.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_repos/hooks.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_repos/hooks.c Wed Nov  7 12:30:06 2018
@@ -476,11 +476,8 @@ svn_repos__hooks_start_commit(svn_repos_
 
       if (capabilities)
         {
-          capabilities_string = svn_cstring_join(capabilities, ":", pool);
-
-          /* Get rid of that annoying final colon. */
-          if (capabilities_string[0])
-            capabilities_string[strlen(capabilities_string) - 1] = '\0';
+          capabilities_string = svn_cstring_join2(capabilities, ":",
+                                                  FALSE, pool);
         }
       else
         {
@@ -799,8 +796,8 @@ svn_repos__hooks_post_lock(svn_repos_t *
     {
       const char *args[5];
       apr_file_t *stdin_handle = NULL;
-      svn_string_t *paths_str = svn_string_create(svn_cstring_join
-                                                  (paths, "\n", pool),
+      svn_string_t *paths_str = svn_string_create(svn_cstring_join2
+                                                  (paths, "\n", TRUE, pool),
                                                   pool);
 
       SVN_ERR(create_temp_file(&stdin_handle, paths_str, pool));
@@ -875,8 +872,8 @@ svn_repos__hooks_post_unlock(svn_repos_t
     {
       const char *args[5];
       apr_file_t *stdin_handle = NULL;
-      svn_string_t *paths_str = svn_string_create(svn_cstring_join
-                                                  (paths, "\n", pool),
+      svn_string_t *paths_str = svn_string_create(svn_cstring_join2
+                                                  (paths, "\n", TRUE, pool),
                                                   pool);
 
       SVN_ERR(create_temp_file(&stdin_handle, paths_str, pool));

Modified: subversion/branches/ra-git/subversion/libsvn_repos/list.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_repos/list.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_repos/list.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_repos/list.c Wed Nov  7 12:30:06 2018
@@ -30,6 +30,7 @@
 
 #include "private/svn_repos_private.h"
 #include "private/svn_sorts_private.h"
+#include "private/svn_utf_private.h"
 #include "svn_private_config.h" /* for SVN_TEMPLATE_ROOT_DIR */
 
 #include "repos.h"
@@ -49,6 +50,8 @@ fill_dirent(svn_dirent_t *dirent,
 
   if (dirent->kind == svn_node_file)
     SVN_ERR(svn_fs_file_length(&(dirent->size), root, path, scratch_pool));
+  else
+    dirent->size = SVN_INVALID_FILESIZE;
 
   SVN_ERR(svn_fs_node_has_props(&dirent->has_props, root, path,
                                 scratch_pool));
@@ -91,23 +94,16 @@ svn_repos_stat(svn_dirent_t **dirent,
 }
 
 /* Return TRUE of DIRNAME matches any of the const char * in PATTERNS.
- * Note that any DIRNAME will match if PATTERNS is empty. */
+ * Note that any DIRNAME will match if PATTERNS is empty.
+ * Use SCRATCH_BUFFER for temporary string contents. */
 static svn_boolean_t
 matches_any(const char *dirname,
-            apr_array_header_t *patterns)
+            const apr_array_header_t *patterns,
+            svn_membuf_t *scratch_buffer)
 {
-  int i;
-  if (!patterns)
-    return TRUE;
-
-  for (i = 0; i < patterns->nelts; ++i)
-    {
-      const char *pattern = APR_ARRAY_IDX(patterns, i, const char *);
-      if (apr_fnmatch(pattern, dirname, APR_FNM_PERIOD) == APR_SUCCESS)
-        return TRUE;
-    }
-
-  return FALSE;
+  return patterns
+       ? svn_utf__fuzzy_glob_match(dirname, patterns, scratch_buffer)
+       : TRUE;
 }
 
 /* Utility to prevent code duplication.
@@ -166,11 +162,13 @@ compare_filtered_dirent(const void *lhs,
  *
  * However, DEPTH is not svn_depth_empty and PATH has already been reported.
  * Therefore, we can call this recursively.
+ *
+ * Uses SCRATCH_BUFFER for temporary string contents.
  */
 static svn_error_t *
 do_list(svn_fs_root_t *root,
         const char *path,
-        apr_array_header_t *patterns,
+        const apr_array_header_t *patterns,
         svn_depth_t depth,
         svn_boolean_t path_info_only,
         svn_repos_authz_func_t authz_read_func,
@@ -179,6 +177,7 @@ do_list(svn_fs_root_t *root,
         void *receiver_baton,
         svn_cancel_func_t cancel_func,
         void *cancel_baton,
+        svn_membuf_t *scratch_buffer,
         apr_pool_t *scratch_pool)
 {
   apr_hash_t *entries;
@@ -210,7 +209,8 @@ do_list(svn_fs_root_t *root,
         continue;
 
       /* We can skip files that don't match any of the search patterns. */
-      filtered.is_match = matches_any(filtered.dirent->name, patterns);
+      filtered.is_match = matches_any(filtered.dirent->name, patterns,
+                                      scratch_buffer);
       if (!filtered.is_match && filtered.dirent->kind == svn_node_file)
         continue;
 
@@ -258,7 +258,7 @@ do_list(svn_fs_root_t *root,
         SVN_ERR(do_list(root, sub_path, patterns, svn_depth_infinity,
                         path_info_only, authz_read_func, authz_read_baton,
                         receiver, receiver_baton, cancel_func,
-                        cancel_baton, iterpool));
+                        cancel_baton, scratch_buffer, iterpool));
     }
 
   svn_pool_destroy(iterpool);
@@ -269,7 +269,7 @@ do_list(svn_fs_root_t *root,
 svn_error_t *
 svn_repos_list(svn_fs_root_t *root,
                const char *path,
-               apr_array_header_t *patterns,
+               const apr_array_header_t *patterns,
                svn_depth_t depth,
                svn_boolean_t path_info_only,
                svn_repos_authz_func_t authz_read_func,
@@ -280,6 +280,8 @@ svn_repos_list(svn_fs_root_t *root,
                void *cancel_baton,
                apr_pool_t *scratch_pool)
 {
+  svn_membuf_t scratch_buffer;
+
   /* Parameter check. */
   svn_node_kind_t kind;
   if (depth < svn_depth_empty)
@@ -317,8 +319,13 @@ svn_repos_list(svn_fs_root_t *root,
   if (patterns && patterns->nelts == 0)
     return SVN_NO_ERROR;
 
+  /* We need a scratch buffer for temporary string data.
+   * Create one with a reasonable initial size. */
+  svn_membuf__create(&scratch_buffer, 256, scratch_pool);
+
   /* Actually report PATH, if it passes the filters. */
-  if (matches_any(svn_dirent_dirname(path, scratch_pool), patterns))
+  if (matches_any(svn_dirent_basename(path, scratch_pool), patterns,
+                  &scratch_buffer))
     SVN_ERR(report_dirent(root, path, kind, path_info_only,
                           receiver, receiver_baton, scratch_pool));
 
@@ -327,7 +334,7 @@ svn_repos_list(svn_fs_root_t *root,
     SVN_ERR(do_list(root, path, patterns, depth,
                     path_info_only, authz_read_func, authz_read_baton,
                     receiver, receiver_baton, cancel_func, cancel_baton,
-                    scratch_pool));
+                    &scratch_buffer, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ra-git/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_repos/load-fs-vtable.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_repos/load-fs-vtable.c Wed Nov  7 12:30:06 2018
@@ -55,6 +55,7 @@ struct parse_baton
   svn_boolean_t use_history;
   svn_boolean_t validate_props;
   svn_boolean_t ignore_dates;
+  svn_boolean_t normalize_props;
   svn_boolean_t use_pre_commit_hook;
   svn_boolean_t use_post_commit_hook;
   enum svn_repos_load_uuid uuid_action;
@@ -74,7 +75,7 @@ struct parse_baton
      (svn_revnum_t *) in the dump stream to their corresponding revisions
      (svn_revnum_t *) in the loaded repository.  The hash and its
      contents are allocated in POOL. */
-  /* ### See http://subversion.tigris.org/issues/show_bug.cgi?id=3903
+  /* ### See https://issues.apache.org/jira/browse/SVN-3903
      ### for discussion about improving the memory costs of this mapping. */
   apr_hash_t *rev_map;
 
@@ -163,8 +164,12 @@ change_rev_prop(svn_repos_t *repos,
                 const char *name,
                 const svn_string_t *value,
                 svn_boolean_t validate_props,
+                svn_boolean_t normalize_props,
                 apr_pool_t *pool)
 {
+  if (normalize_props)
+    SVN_ERR(svn_repos__normalize_prop(&value, NULL, name, value, pool, pool));
+
   if (validate_props)
     return svn_repos_fs_change_rev_prop4(repos, revision, NULL, name,
                                          NULL, value, FALSE, FALSE,
@@ -248,7 +253,7 @@ renumber_mergeinfo_revs(svn_string_t **f
   SVN_ERR(svn_mergeinfo_parse(&mergeinfo, initial_val->data, subpool));
 
   /* Issue #3020
-     http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16
+     https://issues.apache.org/jira/browse/SVN-3020#desc16
      Remove mergeinfo older than the oldest revision in the dump stream
      and adjust its revisions by the difference between the head rev of
      the target repository and the current dump stream rev. */
@@ -318,7 +323,7 @@ renumber_mergeinfo_revs(svn_string_t **f
                  mergeinfo with a start rev > end rev.  If that gets into the
                  repository then a world of bustage breaks loose anytime that
                  bogus mergeinfo is parsed.  See
-                 http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16.
+                 https://issues.apache.org/jira/browse/SVN-3020#desc16.
                  */
               continue;
             }
@@ -1024,7 +1029,8 @@ close_revision(void *baton)
               const svn_prop_t *prop = &APR_ARRAY_IDX(diff, i, svn_prop_t);
 
               SVN_ERR(change_rev_prop(pb->repos, 0, prop->name, prop->value,
-                                      pb->validate_props, rb->pool));
+                                      pb->validate_props, pb->normalize_props,
+                                      rb->pool));
           }
         }
 
@@ -1042,6 +1048,23 @@ close_revision(void *baton)
       prop->value = NULL;
     }
 
+  if (rb->pb->normalize_props)
+    {
+      apr_pool_t *iterpool;
+      int i;
+
+      iterpool = svn_pool_create(rb->pool);
+      for (i = 0; i < rb->revprops->nelts; i++)
+        {
+          svn_prop_t *prop = &APR_ARRAY_IDX(rb->revprops, i, svn_prop_t);
+
+          svn_pool_clear(iterpool);
+          SVN_ERR(svn_repos__normalize_prop(&prop->value, NULL, prop->name,
+                                            prop->value, rb->pool, iterpool));
+        }
+      svn_pool_destroy(iterpool);
+    }
+
   /* Apply revision property changes. */
   if (rb->pb->validate_props)
     SVN_ERR(svn_repos_fs_change_txn_props(rb->txn, rb->revprops, rb->pool));
@@ -1158,7 +1181,7 @@ close_revision(void *baton)
 
 
 svn_error_t *
-svn_repos_get_fs_build_parser5(const svn_repos_parse_fns3_t **callbacks,
+svn_repos_get_fs_build_parser6(const svn_repos_parse_fns3_t **callbacks,
                                void **parse_baton,
                                svn_repos_t *repos,
                                svn_revnum_t start_rev,
@@ -1170,6 +1193,7 @@ svn_repos_get_fs_build_parser5(const svn
                                svn_boolean_t use_pre_commit_hook,
                                svn_boolean_t use_post_commit_hook,
                                svn_boolean_t ignore_dates,
+                               svn_boolean_t normalize_props,
                                svn_repos_notify_func_t notify_func,
                                void *notify_baton,
                                apr_pool_t *pool)
@@ -1218,6 +1242,7 @@ svn_repos_get_fs_build_parser5(const svn
   pb->use_pre_commit_hook = use_pre_commit_hook;
   pb->use_post_commit_hook = use_post_commit_hook;
   pb->ignore_dates = ignore_dates;
+  pb->normalize_props = normalize_props;
 
   *callbacks = parser;
   *parse_baton = pb;
@@ -1226,7 +1251,7 @@ svn_repos_get_fs_build_parser5(const svn
 
 
 svn_error_t *
-svn_repos_load_fs5(svn_repos_t *repos,
+svn_repos_load_fs6(svn_repos_t *repos,
                    svn_stream_t *dumpstream,
                    svn_revnum_t start_rev,
                    svn_revnum_t end_rev,
@@ -1236,6 +1261,7 @@ svn_repos_load_fs5(svn_repos_t *repos,
                    svn_boolean_t use_post_commit_hook,
                    svn_boolean_t validate_props,
                    svn_boolean_t ignore_dates,
+                   svn_boolean_t normalize_props,
                    svn_repos_notify_func_t notify_func,
                    void *notify_baton,
                    svn_cancel_func_t cancel_func,
@@ -1247,7 +1273,7 @@ svn_repos_load_fs5(svn_repos_t *repos,
 
   /* This is really simple. */
 
-  SVN_ERR(svn_repos_get_fs_build_parser5(&parser, &parse_baton,
+  SVN_ERR(svn_repos_get_fs_build_parser6(&parser, &parse_baton,
                                          repos,
                                          start_rev, end_rev,
                                          TRUE, /* look for copyfrom revs */
@@ -1257,6 +1283,7 @@ svn_repos_load_fs5(svn_repos_t *repos,
                                          use_pre_commit_hook,
                                          use_post_commit_hook,
                                          ignore_dates,
+                                         normalize_props,
                                          notify_func,
                                          notify_baton,
                                          pool));
@@ -1345,7 +1372,8 @@ revprops_close_revision(void *baton)
       const svn_prop_t *prop = &APR_ARRAY_IDX(diff, i, svn_prop_t);
 
       SVN_ERR(change_rev_prop(pb->repos, rb->rev, prop->name, prop->value,
-                              pb->validate_props, rb->pool));
+                              pb->validate_props, pb->normalize_props,
+                              rb->pool));
     }
 
   if (pb->notify_func)
@@ -1386,6 +1414,11 @@ revprops_close_revision(void *baton)
  *
  * If IGNORE_DATES is set, ignore any revision datestamps found in
  * DUMPSTREAM, keeping whatever timestamps the revisions currently have.
+ *
+ * If NORMALIZE_PROPS is set, attempt to normalize invalid Subversion
+ * revision and node properties (those in the svn: namespace) so that
+ * their values would follow the established rules for them.  Currently,
+ * this means translating non-LF line endings in the property values to LF.
  */
 static svn_error_t *
 build_revprop_parser(const svn_repos_parse_fns3_t **callbacks,
@@ -1395,6 +1428,7 @@ build_revprop_parser(const svn_repos_par
                      svn_revnum_t end_rev,
                      svn_boolean_t validate_props,
                      svn_boolean_t ignore_dates,
+                     svn_boolean_t normalize_props,
                      svn_repos_notify_func_t notify_func,
                      void *notify_baton,
                      apr_pool_t *result_pool)
@@ -1440,6 +1474,7 @@ build_revprop_parser(const svn_repos_par
   pb->use_pre_commit_hook = FALSE;
   pb->use_post_commit_hook = FALSE;
   pb->ignore_dates = ignore_dates;
+  pb->normalize_props = normalize_props;
 
   *callbacks = parser;
   *parse_baton = pb;
@@ -1454,6 +1489,7 @@ svn_repos_load_fs_revprops(svn_repos_t *
                            svn_revnum_t end_rev,
                            svn_boolean_t validate_props,
                            svn_boolean_t ignore_dates,
+                           svn_boolean_t normalize_props,
                            svn_repos_notify_func_t notify_func,
                            void *notify_baton,
                            svn_cancel_func_t cancel_func,
@@ -1470,6 +1506,7 @@ svn_repos_load_fs_revprops(svn_repos_t *
                                start_rev, end_rev,
                                validate_props,
                                ignore_dates,
+                               normalize_props,
                                notify_func,
                                notify_baton,
                                scratch_pool));

Modified: subversion/branches/ra-git/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_repos/log.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_repos/log.c Wed Nov  7 12:30:06 2018
@@ -58,6 +58,57 @@ typedef struct log_callbacks_t
   void *authz_read_baton;
 } log_callbacks_t;
 
+
+svn_repos_path_change_t *
+svn_repos_path_change_create(apr_pool_t *result_pool)
+{
+  svn_repos_path_change_t *change = apr_pcalloc(result_pool, sizeof(*change));
+
+  change->path.data = "";
+  change->change_kind = svn_fs_path_change_reset;
+  change->mergeinfo_mod = svn_tristate_unknown;
+  change->copyfrom_rev = SVN_INVALID_REVNUM;
+
+  return change;
+}
+
+svn_repos_path_change_t *
+svn_repos_path_change_dup(svn_repos_path_change_t *change,
+                          apr_pool_t *result_pool)
+{
+  svn_repos_path_change_t *new_change = apr_pmemdup(result_pool, change,
+                                                    sizeof(*new_change));
+
+  new_change->path.data = apr_pstrmemdup(result_pool, change->path.data,
+                                         change->path.len);
+  if (change->copyfrom_path)
+    new_change->copyfrom_path = apr_pstrdup(result_pool,
+                                            change->copyfrom_path);
+
+  return new_change;
+}
+
+svn_repos_log_entry_t *
+svn_repos_log_entry_create(apr_pool_t *result_pool)
+{
+  svn_repos_log_entry_t *log_entry = apr_pcalloc(result_pool,
+                                                 sizeof(*log_entry));
+
+  return log_entry;
+}
+
+svn_repos_log_entry_t *
+svn_repos_log_entry_dup(const svn_repos_log_entry_t *log_entry,
+                        apr_pool_t *result_pool)
+{
+  svn_repos_log_entry_t *new_entry = apr_pmemdup(result_pool, log_entry,
+                                                sizeof(*new_entry));
+
+  if (log_entry->revprops)
+    new_entry->revprops = svn_prop_hash_dup(log_entry->revprops, result_pool);
+
+  return new_entry;
+}
 
 svn_error_t *
 svn_repos_check_revision_access(svn_repos_revision_access_level_t *access_level,
@@ -1184,7 +1235,7 @@ typedef struct interesting_merge_baton_t
  */
 static svn_error_t *
 interesting_merge(void *baton,
-                  svn_fs_path_change3_t *change,
+                  svn_repos_path_change_t *change,
                   apr_pool_t *scratch_pool)
 {
   interesting_merge_baton_t *b = baton;
@@ -2396,7 +2447,7 @@ svn_repos_get_logs5(svn_repos_t *repos,
      represents all of PATHS' history between START and END.  We will use
      this later to squelch duplicate log revisions that might exist in
      both natural history and merged-in history.  See
-     http://subversion.tigris.org/issues/show_bug.cgi?id=3650#desc5 */
+     https://issues.apache.org/jira/browse/SVN-3650#desc5 */
   if (include_merged_revisions)
     {
       apr_pool_t *subpool = svn_pool_create(scratch_pool);

Modified: subversion/branches/ra-git/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_repos/reporter.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_repos/reporter.c Wed Nov  7 12:30:06 2018
@@ -973,11 +973,11 @@ update_entry(report_baton_t *b, svn_revn
           if (s_root == NULL)
             SVN_ERR(get_source_root(b, &s_root, s_rev));
 
-          SVN_ERR(svn_fs_props_different(&changed, s_root, s_path,
-                                         b->t_root, t_path, pool));
+          SVN_ERR(svn_fs_props_changed(&changed, s_root, s_path,
+                                       b->t_root, t_path, pool));
           if (!changed)
-            SVN_ERR(svn_fs_contents_different(&changed, s_root, s_path,
-                                              b->t_root, t_path, pool));
+            SVN_ERR(svn_fs_contents_changed(&changed, s_root, s_path,
+                                            b->t_root, t_path, pool));
         }
 
       if ((distance == 0 || !changed) && !any_path_info(b, e_path)

Modified: subversion/branches/ra-git/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_repos/repos.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_repos/repos.c Wed Nov  7 12:30:06 2018
@@ -882,7 +882,7 @@ create_conf(svn_repos_t *repos, apr_pool
 "[sasl]"                                                                     NL
 "### This option specifies whether you want to use the Cyrus SASL"           NL
 "### library for authentication. Default is false."                          NL
-"### This section will be ignored if svnserve is not built with Cyrus"       NL
+"### Enabling this option requires svnserve to have been built with Cyrus"   NL
 "### SASL support; to check, run 'svnserve --version' and look for a line"   NL
 "### reading 'Cyrus SASL authentication is available.'"                      NL
 "# use-sasl = true"                                                          NL
@@ -1504,6 +1504,16 @@ static const char *capability_yes = "yes
 /* Repository does not support the capability. */
 static const char *capability_no = "no";
 
+static svn_error_t *
+dummy_mergeinfo_receiver(const char *path,
+                         svn_mergeinfo_t mergeinfo,
+                         void *baton,
+                         apr_pool_t *scratch_pool)
+{
+  return SVN_NO_ERROR;
+}
+
+
 svn_error_t *
 svn_repos_has_capability(svn_repos_t *repos,
                          svn_boolean_t *has,
@@ -1525,14 +1535,13 @@ svn_repos_has_capability(svn_repos_t *re
     {
       svn_error_t *err;
       svn_fs_root_t *root;
-      svn_mergeinfo_catalog_t ignored;
       apr_array_header_t *paths = apr_array_make(pool, 1,
                                                  sizeof(char *));
 
       SVN_ERR(svn_fs_revision_root(&root, repos->fs, 0, pool));
       APR_ARRAY_PUSH(paths, const char *) = "";
-      err = svn_fs_get_mergeinfo2(&ignored, root, paths, FALSE, FALSE,
-                                  TRUE, pool, pool);
+      err = svn_fs_get_mergeinfo3(root, paths, FALSE, FALSE, TRUE,
+                                  dummy_mergeinfo_receiver, NULL, pool);
 
       if (err)
         {
@@ -1712,7 +1721,7 @@ svn_repos_recover4(const char *path,
 }
 
 struct freeze_baton_t {
-  apr_array_header_t *paths;
+  const apr_array_header_t *paths;
   int counter;
   svn_repos_freeze_func_t freeze_func;
   void *freeze_baton;
@@ -1779,7 +1788,7 @@ multi_freeze(void *baton,
    and an SQLite reserved lock which means the repository is readable
    while frozen. */
 svn_error_t *
-svn_repos_freeze(apr_array_header_t *paths,
+svn_repos_freeze(const apr_array_header_t *paths,
                  svn_repos_freeze_func_t freeze_func,
                  void *freeze_baton,
                  apr_pool_t *pool)

Modified: subversion/branches/ra-git/subversion/libsvn_repos/repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_repos/repos.h?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_repos/repos.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_repos/repos.h Wed Nov  7 12:30:06 2018
@@ -27,6 +27,7 @@
 #include <apr_hash.h>
 
 #include "svn_fs.h"
+#include "svn_config.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -362,32 +363,6 @@ svn_repos__hooks_post_unlock(svn_repos_t
                              apr_pool_t *pool);
 
 
-/*** Authz Functions ***/
-
-/* Read authz configuration data from PATH into *AUTHZ_P, allocated
-   in POOL.  If GROUPS_PATH is set, use the global groups parsed from it.
-
-   PATH and GROUPS_PATH may be a dirent or a registry path and iff ACCEPT_URLS
-   is set it may also be an absolute file url.
-
-   If PATH or GROUPS_PATH is not a valid authz rule file, then return
-   SVN_AUTHZ_INVALID_CONFIG.  The contents of *AUTHZ_P is then
-   undefined.  If MUST_EXIST is TRUE, a missing authz or global groups file
-   is also an error. */
-svn_error_t *
-svn_repos__authz_read(svn_authz_t **authz_p,
-                      const char *path,
-                      const char *groups_path,
-                      svn_boolean_t must_exist,
-                      svn_boolean_t accept_urls,
-                      apr_pool_t *pool);
-
-/* Walk the configuration in AUTHZ looking for any errors. */
-svn_error_t *
-svn_repos__authz_validate(svn_authz_t *authz,
-                          apr_pool_t *pool);
-
-
 /*** Utility Functions ***/
 
 /* Set *PREV_PATH and *PREV_REV to the path and revision which

Modified: subversion/branches/ra-git/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_subr/auth.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_subr/auth.c Wed Nov  7 12:30:06 2018
@@ -502,7 +502,7 @@ svn_auth_get_platform_specific_provider(
   if (apr_strnatcmp(provider_name, "gnome_keyring") == 0 ||
       apr_strnatcmp(provider_name, "kwallet") == 0)
     {
-#if defined(SVN_HAVE_GNOME_KEYRING) || defined(SVN_HAVE_KWALLET)
+#if defined(SVN_HAVE_GNOME_KEYRING) || defined(SVN_HAVE_KWALLET) || defined (SVN_HAVE_LIBSECRET)
       apr_dso_handle_t *dso;
       apr_dso_handle_sym_t provider_function_symbol, version_function_symbol;
       const char *library_label, *library_name;

Modified: subversion/branches/ra-git/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_subr/cache-membuffer.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_subr/cache-membuffer.c Wed Nov  7 12:30:06 2018
@@ -812,6 +812,11 @@ struct svn_membuffer_t
    */
   svn_boolean_t allow_blocking_writes;
 #endif
+
+  /* A write lock counter, must be either 0 or 1.
+   * This one is only used in debug assertions to verify that you used
+   * the correct multi-threading settings. */
+  svn_atomic_t write_lock_count;
 };
 
 /* Align integer VALUE to the next ITEM_ALIGNMENT boundary.
@@ -2039,6 +2044,8 @@ svn_cache__membuffer_cache_create(svn_me
        */
       c[seg].allow_blocking_writes = allow_blocking_writes;
 #endif
+      /* No writers at the moment. */
+      c[seg].write_lock_count = 0;
     }
 
   /* done here
@@ -2198,6 +2205,10 @@ membuffer_cache_set_internal(svn_membuff
   /* first, look for a previous entry for the given key */
   entry_t *entry = find_entry(cache, group_index, to_find, FALSE);
 
+  /* If this one fails, you are using multiple threads but created the
+   * membuffer in single-threaded mode. */
+  assert(0 == svn_atomic_inc(&cache->write_lock_count));
+
   /* Quick check make sure arithmetics will work further down the road. */
   size = item_size + to_find->entry_key.key_len;
   if (size < item_size)
@@ -2237,6 +2248,10 @@ membuffer_cache_set_internal(svn_membuff
                item_size);
 
       cache->total_writes++;
+
+      /* Putting the decrement into an assert() to make it disappear
+       * in production code. */
+      assert(0 == svn_atomic_dec(&cache->write_lock_count));
       return SVN_NO_ERROR;
     }
 
@@ -2289,6 +2304,9 @@ membuffer_cache_set_internal(svn_membuff
         drop_entry(cache, entry);
     }
 
+  /* Putting the decrement into an assert() to make it disappear
+   * in production code. */
+  assert(0 == svn_atomic_dec(&cache->write_lock_count));
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/ra-git/subversion/libsvn_subr/checksum.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_subr/checksum.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_subr/checksum.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_subr/checksum.c Wed Nov  7 12:30:06 2018
@@ -570,6 +570,36 @@ svn_checksum_ctx_create(svn_checksum_kin
 }
 
 svn_error_t *
+svn_checksum_ctx_reset(svn_checksum_ctx_t *ctx)
+{
+  switch (ctx->kind)
+    {
+      case svn_checksum_md5:
+        memset(ctx->apr_ctx, 0, sizeof(apr_md5_ctx_t));
+        apr_md5_init(ctx->apr_ctx);
+        break;
+
+      case svn_checksum_sha1:
+        memset(ctx->apr_ctx, 0, sizeof(apr_sha1_ctx_t));
+        apr_sha1_init(ctx->apr_ctx);
+        break;
+
+      case svn_checksum_fnv1a_32:
+        svn_fnv1a_32__context_reset(ctx->apr_ctx);
+        break;
+
+      case svn_checksum_fnv1a_32x4:
+        svn_fnv1a_32x4__context_reset(ctx->apr_ctx);
+        break;
+
+      default:
+        SVN_ERR_MALFUNCTION();
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_checksum_update(svn_checksum_ctx_t *ctx,
                     const void *data,
                     apr_size_t len)

Modified: subversion/branches/ra-git/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_subr/cmdline.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_subr/cmdline.c Wed Nov  7 12:30:06 2018
@@ -343,6 +343,23 @@ svn_cmdline_path_local_style_from_utf8(c
 }
 
 svn_error_t *
+svn_cmdline__stdin_readline(const char **result,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  svn_stringbuf_t *buf = NULL;
+  svn_stream_t *stdin_stream = NULL;
+  svn_boolean_t oob = FALSE;
+
+  SVN_ERR(svn_stream_for_stdin2(&stdin_stream, TRUE, scratch_pool));
+  SVN_ERR(svn_stream_readline(stdin_stream, &buf, APR_EOL_STR, &oob, result_pool));
+
+  *result = buf->data;
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_cmdline_printf(apr_pool_t *pool, const char *fmt, ...)
 {
   const char *message;

Modified: subversion/branches/ra-git/subversion/libsvn_subr/config.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_subr/config.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_subr/config.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_subr/config.c Wed Nov  7 12:30:06 2018
@@ -33,12 +33,15 @@
 #include <apr_lib.h>
 #include "svn_hash.h"
 #include "svn_error.h"
+#include "svn_string.h"
 #include "svn_pools.h"
 #include "config_impl.h"
 
-#include "svn_private_config.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_subr_private.h"
+#include "private/svn_config_private.h"
+
+#include "svn_private_config.h"
 
 
 
@@ -108,7 +111,7 @@ svn_config_create2(svn_config_t **cfgp,
 {
   svn_config_t *cfg = apr_palloc(result_pool, sizeof(*cfg));
 
-  cfg->sections = apr_hash_make(result_pool);
+  cfg->sections = svn_hash__make(result_pool);
   cfg->pool = result_pool;
   cfg->x_pool = svn_pool_create(result_pool);
   cfg->x_values = FALSE;
@@ -159,6 +162,18 @@ svn_config_read3(svn_config_t **cfgp, co
 }
 
 svn_error_t *
+svn_config__default_add_value_fn(void *baton,
+                                 svn_stringbuf_t *section,
+                                 svn_stringbuf_t *option,
+                                 svn_stringbuf_t *value)
+{
+  /* FIXME: We may as well propagate the known string sizes here. */
+  svn_config_set((svn_config_t *)baton, section->data,
+                 option->data, value->data);
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_config_parse(svn_config_t **cfgp, svn_stream_t *stream,
                  svn_boolean_t section_names_case_sensitive,
                  svn_boolean_t option_names_case_sensitive,
@@ -174,7 +189,12 @@ svn_config_parse(svn_config_t **cfgp, sv
                            result_pool);
 
   if (err == SVN_NO_ERROR)
-    err = svn_config__parse_stream(cfg, stream, result_pool, scratch_pool);
+    err = svn_config__parse_stream(stream,
+                                   svn_config__constructor_create(
+                                       NULL, NULL,
+                                       svn_config__default_add_value_fn,
+                                       scratch_pool),
+                                   cfg, scratch_pool);
 
   if (err == SVN_NO_ERROR)
     *cfgp = cfg;
@@ -315,7 +335,7 @@ svn_config_get_config(apr_hash_t **cfg_h
                       apr_pool_t *pool)
 {
   svn_config_t *cfg;
-  *cfg_hash = apr_hash_make(pool);
+  *cfg_hash = svn_hash__make(pool);
 
   SVN_ERR(get_category_config(&cfg, config_dir, SVN_CONFIG_CATEGORY_SERVERS,
                               pool));
@@ -333,7 +353,7 @@ svn_config__get_default_config(apr_hash_
                                apr_pool_t *pool)
 {
   svn_config_t *empty_cfg;
-  *cfg_hash = apr_hash_make(pool);
+  *cfg_hash = svn_hash__make(pool);
 
   SVN_ERR(svn_config_create2(&empty_cfg, FALSE, FALSE, pool));
   svn_hash_sets(*cfg_hash, SVN_CONFIG_CATEGORY_CONFIG, empty_cfg);
@@ -690,7 +710,8 @@ svn_config_addsection(svn_config_t *cfg,
     hash_key = s->name;
   else
     hash_key = make_hash_key(apr_pstrdup(cfg->pool, section));
-  s->options = apr_hash_make(cfg->pool);
+  s->options = svn_hash__make(cfg->pool);
+
   svn_hash_sets(cfg->sections, hash_key, s);
 
   return s;
@@ -1234,7 +1255,7 @@ svn_config_copy_config(apr_hash_t **cfg_
 {
   apr_hash_index_t *cidx;
 
-  *cfg_hash = apr_hash_make(pool);
+  *cfg_hash = svn_hash__make(pool);
   for (cidx = apr_hash_first(pool, src_hash);
        cidx != NULL;
        cidx = apr_hash_next(cidx))
@@ -1311,3 +1332,40 @@ svn_config_has_section(svn_config_t *cfg
   return NULL != get_hash_value(cfg->sections, cfg->tmp_key, section,
                                 cfg->section_names_case_sensitive);
 }
+
+svn_error_t *
+svn_config__write(svn_stream_t *stream,
+                  const struct svn_config_t *cfg,
+                  apr_pool_t *scratch_pool)
+{
+  apr_hash_index_t *section_i;
+  apr_hash_index_t *options_i;
+  apr_pool_t *section_pool = svn_pool_create(scratch_pool);
+  apr_pool_t *options_pool = svn_pool_create(scratch_pool);
+
+  for (section_i = apr_hash_first(scratch_pool, cfg->sections);
+       section_i != NULL;
+       section_i = apr_hash_next(section_i))
+    {
+      cfg_section_t *section = apr_hash_this_val(section_i);
+      svn_pool_clear(section_pool);
+      SVN_ERR(svn_stream_printf(stream, section_pool, "\n[%s]\n",
+                                section->name));
+
+      for (options_i = apr_hash_first(section_pool, section->options);
+           options_i != NULL;
+           options_i = apr_hash_next(options_i))
+        {
+          cfg_option_t *option = apr_hash_this_val(options_i);
+          svn_pool_clear(options_pool);
+          SVN_ERR(svn_stream_printf(stream, options_pool, "%s=%s\n",
+                                    option->name, option->value));
+        }
+    }
+
+  svn_pool_destroy(section_pool);
+  svn_pool_destroy(options_pool);
+
+  return SVN_NO_ERROR;
+}
+