You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/12/19 19:49:43 UTC

svn commit: r1220893 [10/19] - in /subversion/branches/fs-py: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/server-side/mod_dontdothat/ notes/ subversion/bindings/javahl/native/ s...

Modified: subversion/branches/fs-py/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_repos/repos.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_repos/repos.c Mon Dec 19 18:49:34 2011
@@ -1694,31 +1694,38 @@ svn_error_t *svn_repos_db_logfiles(apr_a
   return SVN_NO_ERROR;
 }
 
-/** Hot copy structure copy context.
- */
+/* Baton for hotcopy_structure(). */
 struct hotcopy_ctx_t {
   const char *dest;     /* target location to construct */
   size_t src_len; /* len of the source path*/
+
+  /* As in svn_repos_hotcopy2() */
+  svn_boolean_t incremental;
+  svn_cancel_func_t cancel_func;
+  void *cancel_baton;
 };
 
-/** Called by (svn_io_dir_walk2).
- * Copies the repository structure with exception of @c SVN_REPOS__DB_DIR,
- * @c SVN_REPOS__LOCK_DIR and @c SVN_REPOS__FORMAT.
- * Those directories and files are handled separetly.
- * @a baton is a pointer to (struct hotcopy_ctx_t) specifying
- * destination path to copy to and the length of the source path.
+/* Copy the repository structure of PATH to BATON->DEST, with exception of
+ * @c SVN_REPOS__DB_DIR, @c SVN_REPOS__LOCK_DIR and @c SVN_REPOS__FORMAT;
+ * those directories and files are handled separately.
+ *
+ * BATON is a (struct hotcopy_ctx_t *).  BATON->SRC_LEN is the length
+ * of PATH.
  *
- * @copydoc svn_io_dir_walk2()
+ * Implements svn_io_walk_func_t.
  */
 static svn_error_t *hotcopy_structure(void *baton,
                                       const char *path,
                                       const apr_finfo_t *finfo,
                                       apr_pool_t *pool)
 {
-  const struct hotcopy_ctx_t *ctx = ((struct hotcopy_ctx_t *) baton);
+  const struct hotcopy_ctx_t *ctx = baton;
   const char *sub_path;
   const char *target;
 
+  if (ctx->cancel_func)
+    SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+
   if (strlen(path) == ctx->src_len)
     {
       sub_path = "";
@@ -1748,7 +1755,17 @@ static svn_error_t *hotcopy_structure(vo
   target = svn_dirent_join(ctx->dest, sub_path, pool);
 
   if (finfo->filetype == APR_DIR)
-    return create_repos_dir(target, pool);
+    {
+      svn_error_t *err;
+
+      err = create_repos_dir(target, pool);
+      if (ctx->incremental && err && err->apr_err == SVN_ERR_DIR_NOT_EMPTY)
+        {
+          svn_error_clear(err);
+          err = SVN_NO_ERROR;
+        }
+      return svn_error_trace(err);
+    }
   else if (finfo->filetype == APR_REG)
     return svn_io_copy_file(path, target, TRUE, pool);
   else if (finfo->filetype == APR_LNK)
@@ -1777,17 +1794,29 @@ lock_db_logs_file(svn_repos_t *repos,
 
 /* Make a copy of a repository with hot backup of fs. */
 svn_error_t *
-svn_repos_hotcopy(const char *src_path,
-                  const char *dst_path,
-                  svn_boolean_t clean_logs,
-                  apr_pool_t *pool)
+svn_repos_hotcopy2(const char *src_path,
+                   const char *dst_path,
+                   svn_boolean_t clean_logs,
+                   svn_boolean_t incremental,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
+                   apr_pool_t *pool)
 {
   svn_repos_t *src_repos;
   svn_repos_t *dst_repos;
   struct hotcopy_ctx_t hotcopy_context;
+  svn_error_t *err;
+  const char *src_abspath;
+  const char *dst_abspath;
+
+  SVN_ERR(svn_dirent_get_absolute(&src_abspath, src_path, pool));
+  SVN_ERR(svn_dirent_get_absolute(&dst_abspath, dst_path, pool));
+  if (strcmp(src_abspath, dst_abspath) == 0)
+    return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+                             _("Hotcopy source and destination are equal"));
 
   /* Try to open original repository */
-  SVN_ERR(get_repos(&src_repos, src_path,
+  SVN_ERR(get_repos(&src_repos, src_abspath,
                     FALSE, FALSE,
                     FALSE,    /* don't try to open the db yet. */
                     NULL,
@@ -1804,9 +1833,12 @@ svn_repos_hotcopy(const char *src_path,
   /* Copy the repository to a new path, with exception of
      specially handled directories */
 
-  hotcopy_context.dest = dst_path;
-  hotcopy_context.src_len = strlen(src_path);
-  SVN_ERR(svn_io_dir_walk2(src_path,
+  hotcopy_context.dest = dst_abspath;
+  hotcopy_context.src_len = strlen(src_abspath);
+  hotcopy_context.incremental = incremental;
+  hotcopy_context.cancel_func = cancel_func;
+  hotcopy_context.cancel_baton = cancel_baton;
+  SVN_ERR(svn_io_dir_walk2(src_abspath,
                            0,
                            hotcopy_structure,
                            &hotcopy_context,
@@ -1815,20 +1847,35 @@ svn_repos_hotcopy(const char *src_path,
   /* Prepare dst_repos object so that we may create locks,
      so that we may open repository */
 
-  dst_repos = create_svn_repos_t(dst_path, pool);
+  dst_repos = create_svn_repos_t(dst_abspath, pool);
   dst_repos->fs_type = src_repos->fs_type;
   dst_repos->format = src_repos->format;
 
-  SVN_ERR(create_locks(dst_repos, pool));
+  err = create_locks(dst_repos, pool);
+  if (err)
+    {
+      if (incremental && err->apr_err == SVN_ERR_DIR_NOT_EMPTY)
+        svn_error_clear(err);
+      else
+        return svn_error_trace(err);
+    }
 
-  SVN_ERR(svn_io_dir_make_sgid(dst_repos->db_path, APR_OS_DEFAULT, pool));
+  err = svn_io_dir_make_sgid(dst_repos->db_path, APR_OS_DEFAULT, pool);
+  if (err)
+    {
+      if (incremental && APR_STATUS_IS_EEXIST(err->apr_err))
+        svn_error_clear(err);
+      else
+        return svn_error_trace(err);
+    }
 
   /* Exclusively lock the new repository.
      No one should be accessing it at the moment */
   SVN_ERR(lock_repos(dst_repos, TRUE, FALSE, pool));
 
-  SVN_ERR(svn_fs_hotcopy(src_repos->db_path, dst_repos->db_path,
-                         clean_logs, pool));
+  SVN_ERR(svn_fs_hotcopy2(src_repos->db_path, dst_repos->db_path,
+                          clean_logs, incremental,
+                          cancel_func, cancel_baton, pool));
 
   /* Destination repository is ready.  Stamp it with a format number. */
   return svn_io_write_version_file
@@ -1836,6 +1883,16 @@ svn_repos_hotcopy(const char *src_path,
            dst_repos->format, pool);
 }
 
+svn_error_t *
+svn_repos_hotcopy(const char *src_path,
+                  const char *dst_path,
+                  svn_boolean_t clean_logs,
+                  apr_pool_t *pool)
+{
+  return svn_error_trace(svn_repos_hotcopy2(src_path, dst_path, clean_logs,
+                                            FALSE, NULL, NULL, pool));
+}
+
 /* Return the library version number. */
 const svn_version_t *
 svn_repos_version(void)

Modified: subversion/branches/fs-py/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_repos/rev_hunt.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_repos/rev_hunt.c Mon Dec 19 18:49:34 2011
@@ -590,7 +590,7 @@ svn_repos__prev_location(svn_revnum_t *a
                          apr_pool_t *pool)
 {
   svn_fs_root_t *root, *copy_root;
-  const char *copy_path, *copy_src_path, *remainder = "";
+  const char *copy_path, *copy_src_path, *remainder;
   svn_revnum_t copy_src_rev;
 
   /* Initialize return variables. */
@@ -623,8 +623,7 @@ svn_repos__prev_location(svn_revnum_t *a
   */
   SVN_ERR(svn_fs_copied_from(&copy_src_rev, &copy_src_path,
                              copy_root, copy_path, pool));
-  if (! strcmp(copy_path, path) == 0)
-    remainder = svn_fspath__is_child(copy_path, path, pool);
+  remainder = svn_fspath__skip_ancestor(copy_path, path);
   if (prev_path)
     *prev_path = svn_fspath__join(copy_src_path, remainder, pool);
   if (appeared_rev)
@@ -983,30 +982,27 @@ get_path_mergeinfo(apr_hash_t **mergeinf
                    svn_fs_t *fs,
                    const char *path,
                    svn_revnum_t revnum,
-                   apr_pool_t *pool)
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
 {
   svn_mergeinfo_catalog_t tmp_catalog;
   svn_fs_root_t *root;
-  apr_pool_t *subpool = svn_pool_create(pool);
-  apr_array_header_t *paths = apr_array_make(subpool, 1,
+  apr_array_header_t *paths = apr_array_make(scratch_pool, 1,
                                              sizeof(const char *));
 
   APR_ARRAY_PUSH(paths, const char *) = path;
 
-  SVN_ERR(svn_fs_revision_root(&root, fs, revnum, subpool));
+  SVN_ERR(svn_fs_revision_root(&root, fs, revnum, scratch_pool));
   /* We do not need to call svn_repos_fs_get_mergeinfo() (which performs authz)
      because we will filter out unreadable revisions in
      find_interesting_revision(), above */
-  SVN_ERR(svn_fs_get_mergeinfo(&tmp_catalog, root, paths,
-                               svn_mergeinfo_inherited, FALSE, subpool));
+  SVN_ERR(svn_fs_get_mergeinfo2(&tmp_catalog, root, paths,
+                                svn_mergeinfo_inherited, FALSE, TRUE,
+                                result_pool, scratch_pool));
 
   *mergeinfo = apr_hash_get(tmp_catalog, path, APR_HASH_KEY_STRING);
-  if (*mergeinfo)
-    *mergeinfo = svn_mergeinfo_dup(*mergeinfo, pool);
-  else
-    *mergeinfo = apr_hash_make(pool);
-
-  svn_pool_destroy(subpool);
+  if (!*mergeinfo)
+    *mergeinfo = apr_hash_make(result_pool);
 
   return SVN_NO_ERROR;
 }
@@ -1043,9 +1039,9 @@ static svn_error_t *
 get_merged_mergeinfo(apr_hash_t **merged_mergeinfo,
                      svn_repos_t *repos,
                      struct path_revision *old_path_rev,
-                     apr_pool_t *pool)
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
 {
-  apr_pool_t *subpool = svn_pool_create(pool);
   apr_hash_t *curr_mergeinfo, *prev_mergeinfo, *deleted, *changed;
   svn_error_t *err;
   svn_fs_root_t *root;
@@ -1055,8 +1051,8 @@ get_merged_mergeinfo(apr_hash_t **merged
   /* Getting/parsing/diffing svn:mergeinfo is expensive, so only do it
      if there is a property change. */
   SVN_ERR(svn_fs_revision_root(&root, repos->fs, old_path_rev->revnum,
-                               subpool));
-  SVN_ERR(svn_fs_paths_changed2(&changed_paths, root, subpool));
+                               scratch_pool));
+  SVN_ERR(svn_fs_paths_changed2(&changed_paths, root, scratch_pool));
   while (1)
     {
       svn_fs_path_change2_t *changed_path = apr_hash_get(changed_paths,
@@ -1066,17 +1062,17 @@ get_merged_mergeinfo(apr_hash_t **merged
         break;
       if (svn_fspath__is_root(path, strlen(path)))
         {
-          svn_pool_destroy(subpool);
           *merged_mergeinfo = NULL;
           return SVN_NO_ERROR;
         }
-      path = svn_fspath__dirname(path, subpool);
+      path = svn_fspath__dirname(path, scratch_pool);
     }
 
   /* First, find the mergeinfo difference for old_path_rev->revnum, and
      old_path_rev->revnum - 1. */
   err = get_path_mergeinfo(&curr_mergeinfo, repos->fs, old_path_rev->path,
-                           old_path_rev->revnum, subpool);
+                           old_path_rev->revnum, scratch_pool,
+                           scratch_pool);
   if (err)
     {
       if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
@@ -1085,7 +1081,6 @@ get_merged_mergeinfo(apr_hash_t **merged
              best we can do is ignore it and act is if there are
              no mergeinfo differences. */
           svn_error_clear(err);
-          svn_pool_destroy(subpool);
           *merged_mergeinfo = NULL;
           return SVN_NO_ERROR;
         }
@@ -1096,14 +1091,14 @@ get_merged_mergeinfo(apr_hash_t **merged
     }
 
   err = get_path_mergeinfo(&prev_mergeinfo, repos->fs, old_path_rev->path,
-                           old_path_rev->revnum - 1, subpool);
+                           old_path_rev->revnum - 1, scratch_pool,
+                           scratch_pool);
   if (err && (err->apr_err == SVN_ERR_FS_NOT_FOUND
               || err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR))
     {
       /* If the path doesn't exist in the previous revision or it does exist
          but has invalid mergeinfo (Issue #3896), assume no merges. */
       svn_error_clear(err);
-      svn_pool_destroy(subpool);
       *merged_mergeinfo = NULL;
       return SVN_NO_ERROR;
     }
@@ -1111,18 +1106,17 @@ get_merged_mergeinfo(apr_hash_t **merged
     SVN_ERR(err);
 
   /* Then calculate and merge the differences. */
-  SVN_ERR(svn_mergeinfo_diff(&deleted, &changed, prev_mergeinfo, curr_mergeinfo,
-                             FALSE, subpool));
-  SVN_ERR(svn_mergeinfo_merge(changed, deleted, subpool));
+  SVN_ERR(svn_mergeinfo_diff2(&deleted, &changed, prev_mergeinfo,
+                              curr_mergeinfo, FALSE, result_pool,
+                              scratch_pool));
+  SVN_ERR(svn_mergeinfo_merge2(changed, deleted, result_pool, scratch_pool));
 
   /* Store the result. */
   if (apr_hash_count(changed))
-    *merged_mergeinfo = svn_mergeinfo_dup(changed, pool);
+    *merged_mergeinfo = changed;
   else
     *merged_mergeinfo = NULL;
 
-  svn_pool_destroy(subpool);
-
   return SVN_NO_ERROR;
 }
 
@@ -1205,7 +1199,7 @@ find_interesting_revisions(apr_array_hea
 
       if (include_merged_revisions)
         SVN_ERR(get_merged_mergeinfo(&path_rev->merged_mergeinfo, repos,
-                                     path_rev, result_pool));
+                                     path_rev, result_pool, iterpool));
       else
         path_rev->merged_mergeinfo = NULL;
 

Propchange: subversion/branches/fs-py/subversion/libsvn_subr/adler32.c
            ('svn:mergeinfo' removed)

Modified: subversion/branches/fs-py/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/cache-membuffer.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/cache-membuffer.c Mon Dec 19 18:49:34 2011
@@ -1567,6 +1567,9 @@ typedef struct svn_membuffer_cache_t
    */
   int alloc_counter;
 
+  /* if enabled, this will serialize the access to this instance.
+   */
+  svn_mutex__t *mutex;
 #ifdef SVN_DEBUG_CACHE_MEMBUFFER
 
   /* Invariant tag info for all items stored by this cache instance.
@@ -1604,7 +1607,7 @@ combine_key(const void *prefix,
   memcpy((char *)*full_key + prefix_len, key, key_len);
 }
 
-/* Implement svn_cache__vtable_t.get
+/* Implement svn_cache__vtable_t.get (not thread-safe)
  */
 static svn_error_t *
 svn_membuffer_cache_get(void **value_p,
@@ -1655,7 +1658,7 @@ svn_membuffer_cache_get(void **value_p,
   return SVN_NO_ERROR;
 }
 
-/* Implement svn_cache__vtable_t.set
+/* Implement svn_cache__vtable_t.set (not thread-safe)
  */
 static svn_error_t *
 svn_membuffer_cache_set(void *cache_void,
@@ -1716,7 +1719,7 @@ svn_membuffer_cache_iter(svn_boolean_t *
                           _("Can't iterate a membuffer-based cache"));
 }
 
-/* Implement svn_cache__vtable_t.get_partial
+/* Implement svn_cache__vtable_t.get_partial (not thread-safe)
  */
 static svn_error_t *
 svn_membuffer_cache_get_partial(void **value_p,
@@ -1761,7 +1764,7 @@ svn_membuffer_cache_get_partial(void **v
   return SVN_NO_ERROR;
 }
 
-/* Implement svn_cache__vtable_t.set_partial
+/* Implement svn_cache__vtable_t.set_partial (not thread-safe)
  */
 static svn_error_t *
 svn_membuffer_cache_set_partial(void *cache_void,
@@ -1797,6 +1800,7 @@ svn_membuffer_cache_set_partial(void *ca
 }
 
 /* Implement svn_cache__vtable_t.is_cachable
+ * (thread-safe even without mutex)
  */
 static svn_boolean_t
 svn_membuffer_cache_is_cachable(void *cache_void, apr_size_t size)
@@ -1828,6 +1832,7 @@ svn_membuffer_get_segment_info(svn_membu
 }
 
 /* Implement svn_cache__vtable_t.get_info
+ * (thread-safe even without mutex)
  */
 static svn_error_t *
 svn_membuffer_cache_get_info(void *cache_void,
@@ -1862,7 +1867,7 @@ svn_membuffer_cache_get_info(void *cache
 }
 
 
-/* the v-table for membuffer-based caches
+/* the v-table for membuffer-based caches (single-threaded access)
  */
 static svn_cache__vtable_t membuffer_cache_vtable = {
   svn_membuffer_cache_get,
@@ -1874,6 +1879,100 @@ static svn_cache__vtable_t membuffer_cac
   svn_membuffer_cache_get_info
 };
 
+/* Implement svn_cache__vtable_t.get and serialize all cache access.
+ */
+static svn_error_t *
+svn_membuffer_cache_get_synced(void **value_p,
+                               svn_boolean_t *found,
+                               void *cache_void,
+                               const void *key,
+                               apr_pool_t *result_pool)
+{
+  svn_membuffer_cache_t *cache = cache_void;
+  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+                       svn_membuffer_cache_get(value_p,
+                                               found,
+                                               cache_void,
+                                               key,
+                                               result_pool));
+  
+  return SVN_NO_ERROR;
+}
+
+/* Implement svn_cache__vtable_t.set and serialize all cache access.
+ */
+static svn_error_t *
+svn_membuffer_cache_set_synced(void *cache_void,
+                               const void *key,
+                               void *value,
+                               apr_pool_t *scratch_pool)
+{
+  svn_membuffer_cache_t *cache = cache_void;
+  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+                       svn_membuffer_cache_set(cache_void,
+                                               key,
+                                               value,
+                                               scratch_pool));
+  
+  return SVN_NO_ERROR;
+}
+
+/* Implement svn_cache__vtable_t.get_partial and serialize all cache access.
+ */
+static svn_error_t *
+svn_membuffer_cache_get_partial_synced(void **value_p,
+                                       svn_boolean_t *found,
+                                       void *cache_void,
+                                       const void *key,
+                                       svn_cache__partial_getter_func_t func,
+                                       void *baton,
+                                       apr_pool_t *result_pool)
+{
+  svn_membuffer_cache_t *cache = cache_void;
+  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+                       svn_membuffer_cache_get_partial(value_p,
+                                                       found,
+                                                       cache_void,
+                                                       key,
+                                                       func,
+                                                       baton,
+                                                       result_pool));
+  
+  return SVN_NO_ERROR;
+}
+
+/* Implement svn_cache__vtable_t.set_partial and serialize all cache access.
+ */
+static svn_error_t *
+svn_membuffer_cache_set_partial_synced(void *cache_void,
+                                       const void *key,
+                                       svn_cache__partial_setter_func_t func,
+                                       void *baton,
+                                       apr_pool_t *scratch_pool)
+{
+  svn_membuffer_cache_t *cache = cache_void;
+  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+                       svn_membuffer_cache_set_partial(cache_void,
+                                                       key,
+                                                       func,
+                                                       baton,
+                                                       scratch_pool));
+  
+  return SVN_NO_ERROR;
+}
+
+/* the v-table for membuffer-based caches with multi-threading support)
+ */
+static svn_cache__vtable_t membuffer_cache_synced_vtable = {
+  svn_membuffer_cache_get_synced,
+  svn_membuffer_cache_set_synced,
+  svn_membuffer_cache_iter,               /* no sync required */
+  svn_membuffer_cache_is_cachable,        /* no sync required */
+  svn_membuffer_cache_get_partial_synced,
+  svn_membuffer_cache_set_partial_synced,
+  svn_membuffer_cache_get_info            /* no sync required */
+};
+
 /* standard serialization function for svn_stringbuf_t items.
  * Implements svn_cache__serialize_func_t.
  */
@@ -1918,6 +2017,7 @@ svn_cache__create_membuffer_cache(svn_ca
                                   svn_cache__deserialize_func_t deserializer,
                                   apr_ssize_t klen,
                                   const char *prefix,
+                                  svn_boolean_t thread_safe,
                                   apr_pool_t *pool)
 {
   svn_checksum_t *checksum;
@@ -1941,6 +2041,8 @@ svn_cache__create_membuffer_cache(svn_ca
   cache->pool = svn_pool_create(pool);
   cache->alloc_counter = 0;
 
+  SVN_ERR(svn_mutex__init(&cache->mutex, thread_safe, pool));
+  
   /* for performance reasons, we don't actually store the full prefix but a
    * hash value of it
    */
@@ -1961,7 +2063,8 @@ svn_cache__create_membuffer_cache(svn_ca
 
   /* initialize the generic cache wrapper
    */
-  wrapper->vtable = &membuffer_cache_vtable;
+  wrapper->vtable = thread_safe ? &membuffer_cache_synced_vtable 
+                                : &membuffer_cache_vtable;
   wrapper->cache_internal = cache;
   wrapper->error_handler = 0;
   wrapper->error_baton = 0;

Modified: subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c Mon Dec 19 18:49:34 2011
@@ -637,7 +637,7 @@ svn_cmdline__print_xml_prop(svn_stringbu
   const char *encoding = NULL;
 
   if (*outstr == NULL)
-    *outstr = svn_stringbuf_create("", pool);
+    *outstr = svn_stringbuf_create_empty(pool);
 
   if (svn_xml_is_xml_safe(propval->data, propval->len))
     {

Modified: subversion/branches/fs-py/subversion/libsvn_subr/config.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/config.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/config.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/config.c Mon Dec 19 18:49:34 2011
@@ -88,8 +88,8 @@ svn_config_create(svn_config_t **cfgp,
   cfg->pool = result_pool;
   cfg->x_pool = svn_pool_create(result_pool);
   cfg->x_values = FALSE;
-  cfg->tmp_key = svn_stringbuf_create("", result_pool);
-  cfg->tmp_value = svn_stringbuf_create("", result_pool);
+  cfg->tmp_key = svn_stringbuf_create_empty(result_pool);
+  cfg->tmp_value = svn_stringbuf_create_empty(result_pool);
   cfg->section_names_case_sensitive = section_names_case_sensitive;
 
   *cfgp = cfg;
@@ -974,5 +974,13 @@ svn_config_get_server_setting_bool(svn_c
 svn_boolean_t
 svn_config_has_section(svn_config_t *cfg, const char *section)
 {
-  return apr_hash_get(cfg->sections, section, APR_HASH_KEY_STRING) != NULL;
+  cfg_section_t *sec;
+
+  /* Canonicalize the hash key */
+  svn_stringbuf_set(cfg->tmp_key, section);
+  if (! cfg->section_names_case_sensitive)
+    make_hash_key(cfg->tmp_key->data);
+
+  sec = apr_hash_get(cfg->sections, cfg->tmp_key->data, APR_HASH_KEY_STRING);
+  return sec != NULL;
 }

Modified: subversion/branches/fs-py/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/config_file.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/config_file.c Mon Dec 19 18:49:34 2011
@@ -386,9 +386,9 @@ svn_config__parse_file(svn_config_t *cfg
                                            pool);
   ctx.line = 1;
   ctx.have_ungotten_char = FALSE;
-  ctx.section = svn_stringbuf_create("", pool);
-  ctx.option = svn_stringbuf_create("", pool);
-  ctx.value = svn_stringbuf_create("", pool);
+  ctx.section = svn_stringbuf_create_empty(pool);
+  ctx.option = svn_stringbuf_create_empty(pool);
+  ctx.value = svn_stringbuf_create_empty(pool);
 
   do
     {

Modified: subversion/branches/fs-py/subversion/libsvn_subr/config_win.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/config_win.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/config_win.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/config_win.c Mon Dec 19 18:49:34 2011
@@ -200,9 +200,9 @@ svn_config__parse_registry(svn_config_t 
 
 
   subpool = svn_pool_create(pool);
-  section = svn_stringbuf_create("", subpool);
-  option = svn_stringbuf_create("", subpool);
-  value = svn_stringbuf_create("", subpool);
+  section = svn_stringbuf_create_empty(subpool);
+  option = svn_stringbuf_create_empty(subpool);
+  value = svn_stringbuf_create_empty(subpool);
 
   /* The top-level values belong to the [DEFAULT] section */
   svn_err = parse_section(cfg, hkey, SVN_CONFIG__DEFAULT_SECTION,

Modified: subversion/branches/fs-py/subversion/libsvn_subr/debug.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/debug.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/debug.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/debug.c Mon Dec 19 18:49:34 2011
@@ -27,10 +27,16 @@
 #include <stdarg.h>
 
 #include "svn_types.h"
+#include "svn_string.h"
+
+/* We only build this code if SVN_DEBUG is defined. */
+#ifdef SVN_DEBUG
 
 #include "private/svn_debug.h"
 
 
+#define DBG_FLAG "DBG: "
+
 /* This will be tweaked by the preamble code.  */
 static FILE * volatile debug_output = NULL;
 
@@ -59,21 +65,54 @@ svn_dbg__preamble(const char *file, long
       else
         ++slash;
 
-      fprintf(output, "DBG: %s:%4ld: ", slash, line);
+      fprintf(output, DBG_FLAG "%s:%4ld: ", slash, line);
     }
 }
 
 
-void
-svn_dbg__printf(const char *fmt, ...)
+static void
+print_line(const char *fmt, va_list ap)
 {
   FILE *output = debug_output;
-  va_list ap;
 
   if (output == NULL || quiet_mode())
     return;
 
-  va_start(ap, fmt);
   (void) vfprintf(output, fmt, ap);
+}
+
+
+void
+svn_dbg__printf(const char *fmt, ...)
+{
+  va_list ap;
+
+  va_start(ap, fmt);
+  print_line(fmt, ap);
+  va_end(ap);
+}
+
+
+void
+svn_dbg__print_props(apr_hash_t *props,
+                     const char *header_fmt,
+                     ...)
+{
+  apr_hash_index_t *hi;
+  va_list ap;
+
+  va_start(ap, header_fmt);
+  print_line(header_fmt, ap);
   va_end(ap);
+
+  for (hi = apr_hash_first(apr_hash_pool_get(props), props); hi;
+        hi = apr_hash_next(hi))
+    {
+      const char *name = svn__apr_hash_index_key(hi);
+      svn_string_t *val = svn__apr_hash_index_val(hi);
+
+      SVN_DBG(("    '%s' -> '%s'\n", name, val->data));
+    }
 }
+
+#endif

Modified: subversion/branches/fs-py/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/deprecated.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/deprecated.c Mon Dec 19 18:49:34 2011
@@ -1083,6 +1083,17 @@ svn_rangelist_merge(apr_array_header_t *
 }
 
 svn_error_t *
+svn_mergeinfo_diff(svn_mergeinfo_t *deleted, svn_mergeinfo_t *added,
+                   svn_mergeinfo_t from, svn_mergeinfo_t to,
+                   svn_boolean_t consider_inheritance,
+                   apr_pool_t *pool)
+{
+  return svn_error_trace(svn_mergeinfo_diff2(deleted, added, from, to,
+                                             consider_inheritance, pool,
+                                             pool));
+}
+
+svn_error_t *
 svn_mergeinfo_merge(svn_mergeinfo_t mergeinfo,
                     svn_mergeinfo_t changes,
                     apr_pool_t *pool)

Modified: subversion/branches/fs-py/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/dirent_uri.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/dirent_uri.c Mon Dec 19 18:49:34 2011
@@ -884,10 +884,10 @@ svn_dirent_local_style(const char *diren
 }
 
 const char *
-svn_relpath__internal_style(const char *dirent,
-                           apr_pool_t *pool)
+svn_relpath__internal_style(const char *relpath,
+                            apr_pool_t *pool)
 {
-  return svn_relpath_canonicalize(internal_style(dirent, pool), pool);
+  return svn_relpath_canonicalize(internal_style(relpath, pool), pool);
 }
 
 
@@ -1295,25 +1295,17 @@ svn_uri_basename(const char *uri, apr_po
 {
   apr_size_t len = strlen(uri);
   apr_size_t start;
-  const char *base_name;
 
   assert(svn_uri_is_canonical(uri, NULL));
 
   if (svn_uri_is_root(uri, len))
     return "";
-  else
-    {
-      start = len;
-      while (start > 0 && uri[start - 1] != '/')
-        --start;
-    }
 
-  if (pool)
-    base_name = apr_pstrmemdup(pool, uri + start, len - start);
-  else
-    base_name = uri + start;
+  start = len;
+  while (start > 0 && uri[start - 1] != '/')
+    --start;
 
-  return svn_path_uri_decode(base_name, pool);
+  return svn_path_uri_decode(uri + start, pool);
 }
 
 void
@@ -1403,34 +1395,6 @@ svn_dirent_is_child(const char *parent_d
 }
 
 const char *
-svn_relpath__is_child(const char *parent_relpath,
-                      const char *child_relpath,
-                      apr_pool_t *pool)
-{
-  /* assert(relpath_is_canonical(parent_relpath)); */
-  /* assert(relpath_is_canonical(child_relpath)); */
-
-  return is_child(type_relpath, parent_relpath, child_relpath, pool);
-}
-
-const char *
-svn_uri__is_child(const char *parent_uri,
-                  const char *child_uri,
-                  apr_pool_t *pool)
-{
-  const char *relpath;
-
-  assert(pool); /* hysterical raisins. */
-  assert(svn_uri_is_canonical(parent_uri, NULL));
-  assert(svn_uri_is_canonical(child_uri, NULL));
-
-  relpath = is_child(type_uri, parent_uri, child_uri, pool);
-  if (relpath)
-    relpath = svn_path_uri_decode(relpath, pool);
-  return relpath;
-}
-
-const char *
 svn_dirent_skip_ancestor(const char *parent_dirent,
                          const char *child_dirent)
 {
@@ -1547,12 +1511,6 @@ svn_dirent_is_ancestor(const char *paren
 }
 
 svn_boolean_t
-svn_relpath__is_ancestor(const char *parent_relpath, const char *child_relpath)
-{
-  return svn_relpath_skip_ancestor(parent_relpath, child_relpath) != NULL;
-}
-
-svn_boolean_t
 svn_uri__is_ancestor(const char *parent_uri, const char *child_uri)
 {
   return uri_skip_ancestor(parent_uri, child_uri) != NULL;
@@ -1653,7 +1611,7 @@ svn_dirent_canonicalize(const char *dire
 }
 
 svn_boolean_t
-svn_dirent_is_canonical(const char *dirent, apr_pool_t *pool)
+svn_dirent_is_canonical(const char *dirent, apr_pool_t *scratch_pool)
 {
   const char *ptr = dirent;
   if (*ptr == '/')
@@ -1666,7 +1624,8 @@ svn_dirent_is_canonical(const char *dire
           /* TODO: Scan hostname and sharename and fall back to part code */
 
           /* ### Fall back to old implementation */
-          return (strcmp(dirent, svn_dirent_canonicalize(dirent, pool)) == 0);
+          return (strcmp(dirent, svn_dirent_canonicalize(dirent, scratch_pool))
+                  == 0);
         }
 #endif /* SVN_USE_DOS_PATHS */
     }
@@ -1740,7 +1699,7 @@ svn_relpath_is_canonical(const char *rel
 }
 
 svn_boolean_t
-svn_uri_is_canonical(const char *uri, apr_pool_t *pool)
+svn_uri_is_canonical(const char *uri, apr_pool_t *scratch_pool)
 {
   const char *ptr = uri, *seg = uri;
   const char *schema_data = NULL;
@@ -2459,21 +2418,6 @@ svn_fspath__is_root(const char *fspath, 
 
 
 const char *
-svn_fspath__is_child(const char *parent_fspath,
-                     const char *child_fspath,
-                     apr_pool_t *pool)
-{
-  const char *result;
-  assert(svn_fspath__is_canonical(parent_fspath));
-  assert(svn_fspath__is_canonical(child_fspath));
-
-  result = svn_relpath__is_child(parent_fspath + 1, child_fspath + 1, pool);
-
-  assert(result == NULL || svn_relpath_is_canonical(result));
-  return result;
-}
-
-const char *
 svn_fspath__skip_ancestor(const char *parent_fspath,
                           const char *child_fspath)
 {
@@ -2483,16 +2427,6 @@ svn_fspath__skip_ancestor(const char *pa
   return svn_relpath_skip_ancestor(parent_fspath + 1, child_fspath + 1);
 }
 
-svn_boolean_t
-svn_fspath__is_ancestor(const char *parent_fspath,
-                        const char *child_fspath)
-{
-  assert(svn_fspath__is_canonical(parent_fspath));
-  assert(svn_fspath__is_canonical(child_fspath));
-
-  return svn_relpath__is_ancestor(parent_fspath + 1, child_fspath + 1);
-}
-
 
 const char *
 svn_fspath__dirname(const char *fspath,

Modified: subversion/branches/fs-py/subversion/libsvn_subr/dso.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/dso.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/dso.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/dso.c Mon Dec 19 18:49:34 2011
@@ -54,7 +54,7 @@ svn_dso_initialize2(void)
 
   dso_pool = svn_pool_create(NULL);
 
-  SVN_ERR(svn_mutex__init(&dso_mutex, APR_HAS_THREADS, dso_pool));
+  SVN_ERR(svn_mutex__init(&dso_mutex, TRUE, dso_pool));
 
   dso_cache = apr_hash_make(dso_pool);
   return SVN_NO_ERROR;

Propchange: subversion/branches/fs-py/subversion/libsvn_subr/hash.c
            ('svn:mergeinfo' removed)

Modified: subversion/branches/fs-py/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/io.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/io.c Mon Dec 19 18:49:34 2011
@@ -2980,6 +2980,13 @@ svn_io_is_binary_data(const void *data, 
 {
   const unsigned char *buf = data;
 
+  if (len == 3 && buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF)
+    {
+      /* This is an empty UTF-8 file which only contains the UTF-8 BOM.
+       * Treat it as plain text. */
+      return FALSE;
+    }
+
   /* Right now, this function is going to be really stupid.  It's
      going to examine the block of data, and make sure that 15%
      of the bytes are such that their value is in the ranges 0x07-0x0D

Modified: subversion/branches/fs-py/subversion/libsvn_subr/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/log.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/log.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/log.c Mon Dec 19 18:49:34 2011
@@ -121,7 +121,7 @@ svn_log__get_mergeinfo(const apr_array_h
 {
   int i;
   apr_pool_t *iterpool = svn_pool_create(pool);
-  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool);
 
   for (i = 0; i < paths->nelts; i++)
     {
@@ -210,8 +210,8 @@ svn_log__log(const apr_array_header_t *p
 {
   int i;
   apr_pool_t *iterpool = svn_pool_create(pool);
-  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create("", pool);
-  svn_stringbuf_t *options = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool);
+  svn_stringbuf_t *options = svn_stringbuf_create_empty(pool);
 
   for (i = 0; i < paths->nelts; i++)
     {
@@ -264,7 +264,7 @@ svn_log__get_locations(const char *path,
 {
   const svn_revnum_t *revision_ptr, *revision_ptr_start, *revision_ptr_end;
   apr_pool_t *iterpool = svn_pool_create(pool);
-  svn_stringbuf_t *space_separated_revnums = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *space_separated_revnums = svn_stringbuf_create_empty(pool);
 
   revision_ptr_start = (const svn_revnum_t *)location_revisions->elts;
   revision_ptr = revision_ptr_start;
@@ -311,7 +311,7 @@ svn_log__lock(const apr_array_header_t *
 {
   int i;
   apr_pool_t *iterpool = svn_pool_create(pool);
-  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool);
 
   for (i = 0; i < paths->nelts; i++)
     {
@@ -334,7 +334,7 @@ svn_log__unlock(const apr_array_header_t
 {
   int i;
   apr_pool_t *iterpool = svn_pool_create(pool);
-  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool);
 
   for (i = 0; i < paths->nelts; i++)
     {

Modified: subversion/branches/fs-py/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/mergeinfo.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/mergeinfo.c Mon Dec 19 18:49:34 2011
@@ -488,13 +488,10 @@ range_to_string(const svn_merge_range_t 
    revisionlist -> (revisionelement)(COMMA revisionelement)*
    revisionrange -> REVISION "-" REVISION("*")
    revisionelement -> revisionrange | REVISION("*")
-
-   PATHNAME is the path this revisionlist is mapped to.  It is
-   used only for producing a more descriptive error message.
 */
 static svn_error_t *
 parse_rangelist(const char **input, const char *end,
-                apr_array_header_t *rangelist, const char *pathname,
+                apr_array_header_t *rangelist,
                 apr_pool_t *pool)
 {
   const char *curr = *input;
@@ -507,9 +504,7 @@ parse_rangelist(const char **input, cons
     {
       /* Empty range list. */
       *input = curr;
-      return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
-                               _("Mergeinfo for '%s' maps to an "
-                                 "empty revision range"), pathname);
+      return SVN_NO_ERROR;
     }
 
   while (curr < end && *curr != '\n')
@@ -603,6 +598,18 @@ parse_rangelist(const char **input, cons
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_rangelist__parse(apr_array_header_t **rangelist,
+                     const char *str,
+                     apr_pool_t *result_pool)
+{
+  const char *s = str;
+
+  *rangelist = apr_array_make(result_pool, 1, sizeof(svn_merge_range_t *));
+  SVN_ERR(parse_rangelist(&s, s + strlen(s), *rangelist, result_pool));
+  return SVN_NO_ERROR;
+}
+
 /* revisionline -> PATHNAME COLON revisionlist */
 static svn_error_t *
 parse_revision_line(const char **input, const char *end, svn_mergeinfo_t hash,
@@ -621,8 +628,12 @@ parse_revision_line(const char **input, 
 
   *input = *input + 1;
 
-  SVN_ERR(parse_rangelist(input, end, rangelist, pathname, scratch_pool));
+  SVN_ERR(parse_rangelist(input, end, rangelist, scratch_pool));
 
+  if (rangelist->nelts == 0)
+      return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
+                               _("Mergeinfo for '%s' maps to an "
+                                 "empty revision range"), pathname);
   if (*input != end && *(*input) != '\n')
     return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                              _("Could not find end of line in range list line "
@@ -1598,31 +1609,32 @@ walk_mergeinfo_hash_for_diff(svn_mergein
 }
 
 svn_error_t *
-svn_mergeinfo_diff(svn_mergeinfo_t *deleted, svn_mergeinfo_t *added,
-                   svn_mergeinfo_t from, svn_mergeinfo_t to,
-                   svn_boolean_t consider_inheritance,
-                   apr_pool_t *pool)
+svn_mergeinfo_diff2(svn_mergeinfo_t *deleted, svn_mergeinfo_t *added,
+                    svn_mergeinfo_t from, svn_mergeinfo_t to,
+                    svn_boolean_t consider_inheritance,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool)
 {
   if (from && to == NULL)
     {
-      *deleted = svn_mergeinfo_dup(from, pool);
-      *added = apr_hash_make(pool);
+      *deleted = svn_mergeinfo_dup(from, result_pool);
+      *added = apr_hash_make(result_pool);
     }
   else if (from == NULL && to)
     {
-      *deleted = apr_hash_make(pool);
-      *added = svn_mergeinfo_dup(to, pool);
+      *deleted = apr_hash_make(result_pool);
+      *added = svn_mergeinfo_dup(to, result_pool);
     }
   else
     {
-      *deleted = apr_hash_make(pool);
-      *added = apr_hash_make(pool);
+      *deleted = apr_hash_make(result_pool);
+      *added = apr_hash_make(result_pool);
 
       if (from && to)
         {
           SVN_ERR(walk_mergeinfo_hash_for_diff(from, to, *deleted, *added,
-                                               consider_inheritance, pool,
-                                               pool));
+                                               consider_inheritance,
+                                               result_pool, scratch_pool));
         }
     }
 
@@ -1639,8 +1651,8 @@ svn_mergeinfo__equals(svn_boolean_t *is_
   if (apr_hash_count(info1) == apr_hash_count(info2))
     {
       svn_mergeinfo_t deleted, added;
-      SVN_ERR(svn_mergeinfo_diff(&deleted, &added, info1, info2,
-                                 consider_inheritance, pool));
+      SVN_ERR(svn_mergeinfo_diff2(&deleted, &added, info1, info2,
+                                  consider_inheritance, pool, pool));
       *is_equal = apr_hash_count(deleted) == 0 && apr_hash_count(added) == 0;
     }
   else
@@ -1841,7 +1853,7 @@ svn_rangelist_to_string(svn_string_t **o
                         const apr_array_header_t *rangelist,
                         apr_pool_t *pool)
 {
-  svn_stringbuf_t *buf = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *buf = svn_stringbuf_create_empty(pool);
 
   if (rangelist->nelts > 0)
     {
@@ -1878,7 +1890,7 @@ mergeinfo_to_stringbuf(svn_stringbuf_t *
                        const char *prefix,
                        apr_pool_t *pool)
 {
-  *output = svn_stringbuf_create("", pool);
+  *output = svn_stringbuf_create_empty(pool);
 
   if (apr_hash_count(input) > 0)
     {
@@ -1911,16 +1923,10 @@ svn_error_t *
 svn_mergeinfo_to_string(svn_string_t **output, svn_mergeinfo_t input,
                         apr_pool_t *pool)
 {
-  if (apr_hash_count(input) > 0)
-    {
-      svn_stringbuf_t *mergeinfo_buf;
-      SVN_ERR(mergeinfo_to_stringbuf(&mergeinfo_buf, input, NULL, pool));
-      *output = svn_stringbuf__morph_into_string(mergeinfo_buf);
-    }
-  else
-    {
-      *output = svn_string_create("", pool);
-    }
+  svn_stringbuf_t *mergeinfo_buf;
+
+  SVN_ERR(mergeinfo_to_stringbuf(&mergeinfo_buf, input, NULL, pool));
+  *output = svn_stringbuf__morph_into_string(mergeinfo_buf);
   return SVN_NO_ERROR;
 }
 
@@ -2119,7 +2125,7 @@ svn_mergeinfo__remove_prefix_from_catalo
       apr_ssize_t padding = 0;
 
       SVN_ERR_ASSERT(klen >= prefix_len);
-      SVN_ERR_ASSERT(svn_fspath__is_ancestor(prefix_path, original_path));
+      SVN_ERR_ASSERT(svn_fspath__skip_ancestor(prefix_path, original_path));
 
       /* If the ORIGINAL_PATH doesn't match the PREFIX_PATH exactly
          and we're not simply removing a single leading slash (such as
@@ -2166,6 +2172,36 @@ svn_mergeinfo__add_prefix_to_catalog(svn
 }
 
 svn_error_t *
+svn_mergeinfo__relpaths_to_urls(apr_hash_t **out_mergeinfo,
+                                svn_mergeinfo_t mergeinfo,
+                                const char *repos_root_url,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool)
+{
+  *out_mergeinfo = NULL;
+  if (mergeinfo)
+    {
+      apr_hash_index_t *hi;
+      apr_hash_t *full_path_mergeinfo = apr_hash_make(result_pool);
+
+      for (hi = apr_hash_first(scratch_pool, mergeinfo);
+           hi; hi = apr_hash_next(hi))
+        {
+          const char *key = svn__apr_hash_index_key(hi);
+          void *val = svn__apr_hash_index_val(hi);
+
+          apr_hash_set(full_path_mergeinfo,
+                       svn_path_url_add_component2(repos_root_url, key + 1,
+                                                   result_pool),
+                       APR_HASH_KEY_STRING, val);
+        }
+      *out_mergeinfo = full_path_mergeinfo;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_mergeinfo__add_suffix_to_mergeinfo(svn_mergeinfo_t *out_mergeinfo,
                                        svn_mergeinfo_t mergeinfo,
                                        const char *suffix_relpath,
@@ -2182,13 +2218,13 @@ svn_mergeinfo__add_suffix_to_mergeinfo(s
        hi;
        hi = apr_hash_next(hi))
     {
-      const char *path = svn__apr_hash_index_key(hi);
+      const char *fspath = svn__apr_hash_index_key(hi);
       apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
 
       apr_hash_set(*out_mergeinfo,
-                   svn_dirent_join(path, suffix_relpath, result_pool),
+                   svn_fspath__join(fspath, suffix_relpath, result_pool),
                    APR_HASH_KEY_STRING,
-                   svn_rangelist_dup(rangelist, result_pool));
+                   rangelist);
     }
 
   return SVN_NO_ERROR;
@@ -2247,7 +2283,7 @@ svn_mergeinfo__catalog_to_formatted_stri
       apr_array_header_t *sorted_catalog =
         svn_sort__hash(catalog, svn_sort_compare_items_as_paths, pool);
 
-      output_buf = svn_stringbuf_create("", pool);
+      output_buf = svn_stringbuf_create_empty(pool);
       for (i = 0; i < sorted_catalog->nelts; i++)
         {
           svn_sort__item_t elt =
@@ -2320,7 +2356,7 @@ svn_mergeinfo__to_formatted_string(svn_s
 #endif
 
   *output = output_buf ? svn_stringbuf__morph_into_string(output_buf)
-                       : svn_string_create("", pool);
+                       : svn_string_create_empty(pool);
   return SVN_NO_ERROR;
 }
 
@@ -2522,25 +2558,6 @@ svn_mergeinfo__is_noninheritable(svn_mer
   return FALSE;
 }
 
-svn_error_t *
-svn_mergeinfo__string_has_noninheritable(svn_boolean_t *is_noninheritable,
-                                         const char *mergeinfo_str,
-                                         apr_pool_t *scratch_pool)
-{
-  *is_noninheritable = FALSE;
-
-  if (mergeinfo_str)
-    {
-      svn_mergeinfo_t mergeinfo;
-
-      SVN_ERR(svn_mergeinfo_parse(&mergeinfo, mergeinfo_str, scratch_pool));
-      *is_noninheritable = svn_mergeinfo__is_noninheritable(mergeinfo,
-                                                            scratch_pool);
-    }
-
-  return SVN_NO_ERROR;
-}
-
 apr_array_header_t *
 svn_rangelist__initialize(svn_revnum_t start,
                           svn_revnum_t end,

Modified: subversion/branches/fs-py/subversion/libsvn_subr/opt.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/opt.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/opt.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/opt.c Mon Dec 19 18:49:34 2011
@@ -644,6 +644,32 @@ svn_opt__revision_to_string(const svn_op
     }
 }
 
+svn_opt_revision_range_t *
+svn_opt__revision_range_create(const svn_opt_revision_t *start_revision,
+                               const svn_opt_revision_t *end_revision,
+                               apr_pool_t *result_pool)
+{
+  svn_opt_revision_range_t *range = apr_palloc(result_pool, sizeof(*range));
+
+  range->start = *start_revision;
+  range->end = *end_revision;
+  return range;
+}
+
+svn_opt_revision_range_t *
+svn_opt__revision_range_from_revnums(svn_revnum_t start_revnum,
+                                     svn_revnum_t end_revnum,
+                                     apr_pool_t *result_pool)
+{
+  svn_opt_revision_range_t *range = apr_palloc(result_pool, sizeof(*range));
+
+  range->start.kind = svn_opt_revision_number;
+  range->start.value.number = start_revnum;
+  range->end.kind = svn_opt_revision_number;
+  range->end.value.number = end_revnum;
+  return range;
+}
+
 
 
 /*** Parsing arguments. ***/
@@ -944,7 +970,7 @@ svn_opt_parse_revprop(apr_hash_t **revpr
   else
     {
       SVN_ERR(svn_utf_cstring_to_utf8(&propname, revprop_spec, pool));
-      propval = svn_string_create("", pool);
+      propval = svn_string_create_empty(pool);
     }
 
   if (!svn_prop_name_is_valid(propname))

Modified: subversion/branches/fs-py/subversion/libsvn_subr/prompt.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/prompt.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/prompt.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/prompt.c Mon Dec 19 18:49:34 2011
@@ -95,7 +95,7 @@ prompt(const char **result,
   apr_file_t *fp;
   char c;
 
-  svn_stringbuf_t *strbuf = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *strbuf = svn_stringbuf_create_empty(pool);
 
   status = apr_file_open_stdin(&fp, pool);
   if (status)

Modified: subversion/branches/fs-py/subversion/libsvn_subr/quoprint.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/quoprint.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/quoprint.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/quoprint.c Mon Dec 19 18:49:34 2011
@@ -120,7 +120,7 @@ encode_data(void *baton, const char *dat
 {
   struct encode_baton *eb = baton;
   apr_pool_t *subpool = svn_pool_create(eb->pool);
-  svn_stringbuf_t *encoded = svn_stringbuf_create("", subpool);
+  svn_stringbuf_t *encoded = svn_stringbuf_create_empty(subpool);
   apr_size_t enclen;
   svn_error_t *err = SVN_NO_ERROR;
 
@@ -177,7 +177,7 @@ svn_quoprint_encode(svn_stream_t *output
 svn_stringbuf_t *
 svn_quoprint_encode_string(const svn_stringbuf_t *str, apr_pool_t *pool)
 {
-  svn_stringbuf_t *encoded = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *encoded = svn_stringbuf_create_empty(pool);
   int linelen = 0;
 
   encode_bytes(encoded, str->data, str->len, &linelen);
@@ -254,7 +254,7 @@ decode_data(void *baton, const char *dat
 
   /* Decode this block of data.  */
   subpool = svn_pool_create(db->pool);
-  decoded = svn_stringbuf_create("", subpool);
+  decoded = svn_stringbuf_create_empty(subpool);
   decode_bytes(decoded, data, *len, db->buf, &db->buflen);
 
   /* Write the output, clean up, go home.  */
@@ -300,7 +300,7 @@ svn_quoprint_decode(svn_stream_t *output
 svn_stringbuf_t *
 svn_quoprint_decode_string(const svn_stringbuf_t *str, apr_pool_t *pool)
 {
-  svn_stringbuf_t *decoded = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *decoded = svn_stringbuf_create_empty(pool);
   char ingroup[4];
   int ingrouplen = 0;
 

Modified: subversion/branches/fs-py/subversion/libsvn_subr/sorts.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/sorts.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/sorts.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/sorts.c Mon Dec 19 18:49:34 2011
@@ -257,23 +257,16 @@ svn_sort__array_delete(apr_array_header_
       && elements_to_delete > 0
       && (elements_to_delete + delete_index) <= arr->nelts)
     {
-      if (delete_index == (arr->nelts - 1))
-        {
-          /* Deleting the last or only element in an array is easy. */
-          apr_array_pop(arr);
-        }
-      else if ((delete_index + elements_to_delete) == arr->nelts)
-        {
-          /* Delete the last ELEMENTS_TO_DELETE elements. */
-          arr->nelts -= elements_to_delete;
-        }
-      else
-        {
-          memmove(
-            arr->elts + arr->elt_size * delete_index,
-            arr->elts + (arr->elt_size * (delete_index + elements_to_delete)),
-            arr->elt_size * (arr->nelts - elements_to_delete - delete_index));
-          arr->nelts -= elements_to_delete;
-        }
+      /* If we are not deleting a block of elements that extends to the end
+         of the array, then we need to move the remaining elements to keep
+         the array contiguous. */
+      if ((elements_to_delete + delete_index) < arr->nelts)
+        memmove(
+          arr->elts + arr->elt_size * delete_index,
+          arr->elts + (arr->elt_size * (delete_index + elements_to_delete)),
+          arr->elt_size * (arr->nelts - elements_to_delete - delete_index));
+
+      /* Delete the last ELEMENTS_TO_DELETE elements. */
+      arr->nelts -= elements_to_delete;
     }
 }

Modified: subversion/branches/fs-py/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/sqlite.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/sqlite.c Mon Dec 19 18:49:34 2011
@@ -606,12 +606,12 @@ static volatile svn_atomic_t sqlite_init
 static svn_error_t *
 init_sqlite(void *baton, apr_pool_t *pool)
 {
-  if (sqlite3_libversion_number() < SQLITE_VERSION_NUMBER)
+  if (sqlite3_libversion_number() < SVN_SQLITE_MIN_VERSION_NUMBER)
     {
       return svn_error_createf(
                     SVN_ERR_SQLITE_ERROR, NULL,
                     _("SQLite compiled for %s, but running with %s"),
-                    SQLITE_VERSION, sqlite3_libversion());
+                    SVN_SQLITE_MIN_VERSION, sqlite3_libversion());
     }
 
 #if APR_HAS_THREADS
@@ -667,13 +667,6 @@ internal_open(sqlite3 **db3, const char 
     flags |= SQLITE_OPEN_NOMUTEX;
 #endif
 
-    /* SQLite 3.5 allows sharing cache instances, even in a multithreaded
-       environment. This allows sharing cached data when we open a database
-       more than once.
-
-       OS X 10.7 doesn't support sqlite3_enable_shared_cache. */
-    flags |= SQLITE_OPEN_SHAREDCACHE;
-
     /* Open the database. Note that a handle is returned, even when an error
        occurs (except for out-of-memory); thus, we can safely use it to
        extract an error message and construct an svn_error_t. */

Modified: subversion/branches/fs-py/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/subst.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/subst.c Mon Dec 19 18:49:34 2011
@@ -1467,7 +1467,7 @@ stream_translated(svn_stream_t *stream,
     = create_translation_baton(eol_str, translated_eol, repair, keywords,
                                expand, result_pool);
   baton->written = FALSE;
-  baton->readbuf = svn_stringbuf_create("", result_pool);
+  baton->readbuf = svn_stringbuf_create_empty(result_pool);
   baton->readbuf_off = 0;
   baton->iterpool = svn_pool_create(result_pool);
   baton->buf = apr_palloc(result_pool, SVN__TRANSLATION_BUF_SIZE);
@@ -1522,7 +1522,7 @@ translate_cstring(const char **dst,
     }
 
   /* Create a stringbuf and wrapper stream to hold the output. */
-  dst_stringbuf = svn_stringbuf_create("", pool);
+  dst_stringbuf = svn_stringbuf_create_empty(pool);
   dst_stream = svn_stream_from_stringbuf(dst_stringbuf, pool);
 
   if (translated_eol)
@@ -1813,7 +1813,7 @@ svn_subst_create_specialfile(svn_stream_
   /* SCRATCH_POOL may not exist after the function returns. */
   baton->pool = result_pool;
 
-  baton->write_content = svn_stringbuf_create("", result_pool);
+  baton->write_content = svn_stringbuf_create_empty(result_pool);
   baton->write_stream = svn_stream_from_stringbuf(baton->write_content,
                                                   result_pool);
 
@@ -1852,7 +1852,7 @@ svn_subst_stream_from_specialfile(svn_st
       baton->read_stream = NULL;
     }
 
-  baton->write_content = svn_stringbuf_create("", pool);
+  baton->write_content = svn_stringbuf_create_empty(pool);
   baton->write_stream = svn_stream_from_stringbuf(baton->write_content, pool);
 
   *stream = svn_stream_create(baton, pool);

Modified: subversion/branches/fs-py/subversion/libsvn_subr/svn_base64.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/svn_base64.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/svn_base64.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/svn_base64.c Mon Dec 19 18:49:34 2011
@@ -208,7 +208,7 @@ static svn_error_t *
 encode_data(void *baton, const char *data, apr_size_t *len)
 {
   struct encode_baton *eb = baton;
-  svn_stringbuf_t *encoded = svn_stringbuf_create("", eb->scratch_pool);
+  svn_stringbuf_t *encoded = svn_stringbuf_create_empty(eb->scratch_pool);
   apr_size_t enclen;
   svn_error_t *err = SVN_NO_ERROR;
 
@@ -227,7 +227,7 @@ static svn_error_t *
 finish_encoding_data(void *baton)
 {
   struct encode_baton *eb = baton;
-  svn_stringbuf_t *encoded = svn_stringbuf_create("", eb->scratch_pool);
+  svn_stringbuf_t *encoded = svn_stringbuf_create_empty(eb->scratch_pool);
   apr_size_t enclen;
   svn_error_t *err = SVN_NO_ERROR;
 
@@ -267,7 +267,7 @@ svn_base64_encode_string2(const svn_stri
                           svn_boolean_t break_lines,
                           apr_pool_t *pool)
 {
-  svn_stringbuf_t *encoded = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *encoded = svn_stringbuf_create_empty(pool);
   unsigned char ingroup[3];
   size_t ingrouplen = 0;
   size_t linelen = 0;
@@ -461,7 +461,7 @@ decode_data(void *baton, const char *dat
   svn_error_t *err = SVN_NO_ERROR;
 
   /* Decode this block of data.  */
-  decoded = svn_stringbuf_create("", db->scratch_pool);
+  decoded = svn_stringbuf_create_empty(db->scratch_pool);
   decode_bytes(decoded, data, *len, db->buf, &db->buflen, &db->done);
 
   /* Write the output, clean up, go home.  */
@@ -507,7 +507,7 @@ svn_base64_decode(svn_stream_t *output, 
 const svn_string_t *
 svn_base64_decode_string(const svn_string_t *str, apr_pool_t *pool)
 {
-  svn_stringbuf_t *decoded = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *decoded = svn_stringbuf_create_empty(pool);
   unsigned char ingroup[4];
   int ingrouplen = 0;
   svn_boolean_t done = FALSE;
@@ -531,7 +531,7 @@ base64_from_checksum(const svn_checksum_
   unsigned char ingroup[3];
   size_t ingrouplen = 0;
   size_t linelen = 0;
-  checksum_str = svn_stringbuf_create("", pool);
+  checksum_str = svn_stringbuf_create_empty(pool);
 
   encode_bytes(checksum_str, checksum->digest,
                svn_checksum_size(checksum), ingroup, &ingrouplen,

Modified: subversion/branches/fs-py/subversion/libsvn_subr/svn_mutex.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/svn_mutex.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/svn_mutex.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/svn_mutex.c Mon Dec 19 18:49:34 2011
@@ -26,12 +26,15 @@
 
 svn_error_t *
 svn_mutex__init(svn_mutex__t **mutex_p, 
-                svn_boolean_t enable_mutex, 
+                svn_boolean_t mutex_required, 
                 apr_pool_t *result_pool)
 {
-#if APR_HAS_THREADS
+  /* always initialize the mutex pointer, even though it is not
+     strictly necessary if APR_HAS_THREADS has not been set */
   *mutex_p = NULL;
-  if (enable_mutex)
+
+#if APR_HAS_THREADS
+  if (mutex_required)
     {
       apr_thread_mutex_t *apr_mutex;
       apr_status_t status =
@@ -43,10 +46,6 @@ svn_mutex__init(svn_mutex__t **mutex_p, 
 
       *mutex_p = apr_mutex;
     }
-#else
-  if (enable_mutex)
-    return svn_error_wrap_apr(SVN_ERR_UNSUPPORTED_FEATURE,
-                              _("APR doesn't support threads"));
 #endif
     
   return SVN_NO_ERROR;

Modified: subversion/branches/fs-py/subversion/libsvn_subr/svn_string.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/svn_string.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/svn_string.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/svn_string.c Mon Dec 19 18:49:34 2011
@@ -28,7 +28,6 @@
 #include <apr.h>
 
 #include <string.h>      /* for memcpy(), memcmp(), strlen() */
-#include <apr_lib.h>     /* for apr_isspace() */
 #include <apr_fnmatch.h>
 #include "svn_string.h"  /* loads "svn_types.h" and <apr_pools.h> */
 #include "svn_ctype.h"
@@ -133,6 +132,19 @@ create_string(const char *data, apr_size
   return new_string;
 }
 
+static char empty_buffer[1] = {0};
+  
+svn_string_t *
+svn_string_create_empty(apr_pool_t *pool)
+{
+  svn_string_t *new_string = apr_palloc(pool, sizeof(*new_string));
+  new_string->data = empty_buffer;
+  new_string->len = 0;
+
+  return new_string;
+}
+
+
 svn_string_t *
 svn_string_ncreate(const char *bytes, apr_size_t size, apr_pool_t *pool)
 {
@@ -286,6 +298,17 @@ create_stringbuf(char *data, apr_size_t 
 }
 
 svn_stringbuf_t *
+svn_stringbuf_create_empty(apr_pool_t *pool)
+{
+  /* All instances share the same zero-length buffer.
+   * Some algorithms, however, assume that they may write
+   * the terminating zero. So, empty_buffer must be writable 
+   * (a simple (char *)"" will cause SEGFAULTs). */
+
+  return create_stringbuf(empty_buffer, 0, 0, pool);
+}
+
+svn_stringbuf_t *
 svn_stringbuf_create_ensure(apr_size_t blocksize, apr_pool_t *pool)
 {
   void *mem;
@@ -724,7 +747,7 @@ svn_cstring_join(const apr_array_header_
                  const char *separator,
                  apr_pool_t *pool)
 {
-  svn_stringbuf_t *new_str = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *new_str = svn_stringbuf_create_empty(pool);
   size_t sep_len = strlen(separator);
   int i;
 

Propchange: subversion/branches/fs-py/subversion/libsvn_subr/svn_temp_serializer.c
            ('svn:mergeinfo' removed)

Modified: subversion/branches/fs-py/subversion/libsvn_subr/target.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/target.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/target.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/target.c Mon Dec 19 18:49:34 2011
@@ -303,18 +303,12 @@ svn_path_remove_redundancies(apr_array_h
           if (is_url != keeper_is_url)
             continue;
 
-          /* Quit here if we find this path already in the keepers. */
-          if (strcmp(keeper, abs_path) == 0)
-            {
-              keep_me = FALSE;
-              break;
-            }
-
-          /* Quit here if this path is a child of one of the keepers. */
+          /* Quit here if this path is the same as or a child of one of the
+             keepers. */
           if (is_url)
-            child_relpath = svn_uri__is_child(keeper, abs_path, temp_pool);
+            child_relpath = svn_uri_skip_ancestor(keeper, abs_path, temp_pool);
           else
-            child_relpath = svn_dirent_is_child(keeper, abs_path, temp_pool);
+            child_relpath = svn_dirent_skip_ancestor(keeper, abs_path);
           if (child_relpath)
             {
               keep_me = FALSE;

Modified: subversion/branches/fs-py/subversion/libsvn_subr/win32_xlate.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/win32_xlate.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/win32_xlate.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/win32_xlate.c Mon Dec 19 18:49:34 2011
@@ -185,7 +185,7 @@ svn_subr__win32_xlate_to_stringbuf(win32
 
   if (src_length == 0)
   {
-    *dest = svn_stringbuf_create("", pool);
+    *dest = svn_stringbuf_create_empty(pool);
     return APR_SUCCESS;
   }
 

Modified: subversion/branches/fs-py/subversion/libsvn_subr/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/xml.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/xml.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/xml.c Mon Dec 19 18:49:34 2011
@@ -115,7 +115,7 @@ xml_escape_cdata(svn_stringbuf_t **outst
   const char *p = data, *q;
 
   if (*outstr == NULL)
-    *outstr = svn_stringbuf_create("", pool);
+    *outstr = svn_stringbuf_create_empty(pool);
 
   while (1)
     {
@@ -277,7 +277,7 @@ svn_xml_fuzzy_escape(const char *string,
   if (q == end)
     return string;
 
-  outstr = svn_stringbuf_create("", pool);
+  outstr = svn_stringbuf_create_empty(pool);
   while (1)
     {
       q = p;
@@ -479,7 +479,7 @@ svn_xml_make_header2(svn_stringbuf_t **s
 {
 
   if (*str == NULL)
-    *str = svn_stringbuf_create("", pool);
+    *str = svn_stringbuf_create_empty(pool);
   svn_stringbuf_appendcstr(*str, "<?xml version=\"1.0\"");
   if (encoding)
     {
@@ -646,7 +646,7 @@ void svn_xml_make_close_tag(svn_stringbu
                             const char *tagname)
 {
   if (*str == NULL)
-    *str = svn_stringbuf_create("", pool);
+    *str = svn_stringbuf_create_empty(pool);
 
   svn_stringbuf_appendcstr(*str, "</");
   svn_stringbuf_appendcstr(*str, tagname);

Modified: subversion/branches/fs-py/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/adm_crawler.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_wc/adm_crawler.c Mon Dec 19 18:49:34 2011
@@ -420,9 +420,8 @@ report_revisions_and_depths(svn_wc__db_t
         }
       else
         {
-          const char *childname = svn_relpath__is_child(dir_repos_relpath,
-                                                        ths->repos_relpath,
-                                                        NULL);
+          const char *childname
+            = svn_relpath_skip_ancestor(dir_repos_relpath, ths->repos_relpath);
 
           if (childname == NULL || strcmp(childname, child) != 0)
             {
@@ -562,7 +561,7 @@ report_revisions_and_depths(svn_wc__db_t
                    || (dir_depth == svn_depth_immediates
                        && ths->depth != svn_depth_empty)
                    || (ths->depth < svn_depth_infinity
-                       && depth == svn_depth_infinity))
+                       && SVN_DEPTH_IS_RECURSIVE(depth)))
             {
               /* ... or perhaps just a differing revision, lock token,
                  incomplete subdir, the mere presence of the directory

Modified: subversion/branches/fs-py/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/adm_files.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_wc/adm_files.c Mon Dec 19 18:49:34 2011
@@ -428,7 +428,8 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
                             apr_pool_t *scratch_pool)
 {
   int format;
-  const char *repos_relpath;
+  const char *repos_relpath = svn_uri_skip_ancestor(repos_root_url, url,
+                                                    scratch_pool);
   svn_wc__db_status_t status;
   const char *db_repos_relpath, *db_repos_root_url, *db_repos_uuid;
   svn_revnum_t db_revision;
@@ -437,15 +438,11 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
   SVN_ERR_ASSERT(url != NULL);
   SVN_ERR_ASSERT(repos_root_url != NULL);
   SVN_ERR_ASSERT(repos_uuid != NULL);
-  SVN_ERR_ASSERT(svn_uri__is_ancestor(repos_root_url, url));
+  SVN_ERR_ASSERT(repos_relpath != NULL);
 
   SVN_ERR(svn_wc__internal_check_wc(&format, db, local_abspath, TRUE,
                                     scratch_pool));
 
-  repos_relpath = svn_uri__is_child(repos_root_url, url, scratch_pool);
-  if (repos_relpath == NULL)
-    repos_relpath = "";
-
   /* Early out: we know we're not dealing with an existing wc, so
      just create one. */
   if (format == 0)
@@ -503,7 +500,7 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
       /* ### comparing URLs, should they be canonicalized first? */
       if (strcmp(db_repos_uuid, repos_uuid)
           || strcmp(db_repos_root_url, repos_root_url)
-          || !svn_relpath__is_ancestor(db_repos_relpath, repos_relpath))
+          || !svn_relpath_skip_ancestor(db_repos_relpath, repos_relpath))
         {
           const char *copyfrom_root_url, *copyfrom_repos_relpath;
 

Modified: subversion/branches/fs-py/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/adm_ops.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_wc/adm_ops.c Mon Dec 19 18:49:34 2011
@@ -174,6 +174,7 @@ process_committed_leaf(svn_wc__db_t *db,
     }
 
   SVN_ERR_ASSERT(status == svn_wc__db_status_normal
+                 || status == svn_wc__db_status_incomplete
                  || status == svn_wc__db_status_added);
 
   if (kind != svn_kind_dir)
@@ -594,6 +595,168 @@ erase_unversioned_from_wc(const char *pa
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_wc__delete_many(svn_wc_context_t *wc_ctx,
+                    const apr_array_header_t *targets,
+                    svn_boolean_t keep_local,
+                    svn_boolean_t delete_unversioned_target,
+                    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_t *db = wc_ctx->db;
+  svn_error_t *err;
+  svn_wc__db_status_t status;
+  svn_kind_t kind;
+  svn_boolean_t conflicted;
+  const apr_array_header_t *conflicts;
+  apr_array_header_t *versioned_targets;
+  const char *local_abspath;
+  int i;
+  apr_pool_t *iterpool;
+
+  iterpool = svn_pool_create(scratch_pool);
+  versioned_targets = apr_array_make(scratch_pool, targets->nelts,
+                                     sizeof(const char *));
+  for (i = 0; i < targets->nelts; i++)
+    {
+      svn_pool_clear(iterpool);
+
+      local_abspath = APR_ARRAY_IDX(targets, i, const char *);
+      err = svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, &conflicted,
+                                 NULL, NULL, NULL, NULL, NULL, NULL,
+                                 db, local_abspath, iterpool, iterpool);
+
+      if (err)
+        {
+          if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+            {
+              svn_error_clear(err);
+              if (delete_unversioned_target && !keep_local)
+                SVN_ERR(erase_unversioned_from_wc(local_abspath, FALSE,
+                                                  cancel_func, cancel_baton,
+                                                  iterpool));
+              continue;
+            }
+         else
+          return svn_error_trace(err);
+        }
+
+      APR_ARRAY_PUSH(versioned_targets, const char *) = local_abspath;
+
+      switch (status)
+        {
+          /* svn_wc__db_status_server_excluded handled by
+           * svn_wc__db_op_delete_many */
+          case svn_wc__db_status_excluded:
+          case svn_wc__db_status_not_present:
+            return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                                     _("'%s' cannot be deleted"),
+                                     svn_dirent_local_style(local_abspath,
+                                                            iterpool));
+
+          /* Explicitly ignore other statii */
+          default:
+            break;
+        }
+
+      if (status == svn_wc__db_status_normal
+          && kind == svn_kind_dir)
+        {
+          svn_boolean_t is_wcroot;
+          SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, local_abspath,
+                                       iterpool));
+
+          if (is_wcroot)
+            return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
+                                     _("'%s' is the root of a working copy and "
+                                       "cannot be deleted"),
+                                     svn_dirent_local_style(local_abspath,
+                                                            iterpool));
+        }
+
+      /* Verify if we have a write lock on the parent of this node as we might
+         be changing the childlist of that directory. */
+      SVN_ERR(svn_wc__write_check(db, svn_dirent_dirname(local_abspath,
+                                                         iterpool),
+                                  iterpool));
+
+      /* Read conflicts, to allow deleting the markers after updating the DB */
+      if (!keep_local && conflicted)
+        SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
+                                          scratch_pool, iterpool));
+
+    }
+
+  if (versioned_targets->nelts == 0)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(svn_wc__db_op_delete_many(db, versioned_targets,
+                                    cancel_func, cancel_baton,
+                                    notify_func, notify_baton, scratch_pool));
+
+  if (!keep_local && conflicted && conflicts != NULL)
+    {
+      svn_pool_clear(iterpool);
+
+      /* Do we have conflict markers that should be removed? */
+      for (i = 0; i < conflicts->nelts; i++)
+        {
+          const svn_wc_conflict_description2_t *desc;
+
+          desc = APR_ARRAY_IDX(conflicts, i,
+                               const svn_wc_conflict_description2_t*);
+
+          if (desc->kind == svn_wc_conflict_kind_text)
+            {
+              if (desc->base_abspath != NULL)
+                {
+                  SVN_ERR(svn_io_remove_file2(desc->base_abspath, TRUE,
+                                              iterpool));
+                }
+              if (desc->their_abspath != NULL)
+                {
+                  SVN_ERR(svn_io_remove_file2(desc->their_abspath, TRUE,
+                                              iterpool));
+                }
+              if (desc->my_abspath != NULL)
+                {
+                  SVN_ERR(svn_io_remove_file2(desc->my_abspath, TRUE,
+                                              iterpool));
+                }
+            }
+          else if (desc->kind == svn_wc_conflict_kind_property
+                   && desc->their_abspath != NULL)
+            {
+              SVN_ERR(svn_io_remove_file2(desc->their_abspath, TRUE,
+                                          iterpool));
+            }
+        }
+    }
+
+  /* By the time we get here, the db knows that all targets are now
+   * unversioned. */
+  if (!keep_local)
+    {
+      for (i = 0; i < versioned_targets->nelts; i++)
+        {
+          svn_pool_clear(iterpool);
+
+          local_abspath = APR_ARRAY_IDX(versioned_targets, i, const char *);
+          SVN_ERR(erase_unversioned_from_wc(local_abspath, TRUE,
+                                            cancel_func, cancel_baton,
+                                            iterpool));
+        }
+    }
+
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_wc__delete_internal(svn_wc_context_t *wc_ctx,
@@ -1165,7 +1328,7 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
                                          repos_relpath,
                                          repos_root_url, repos_uuid,
                                          copyfrom_rev,
-                                         NULL /* children */, depth,
+                                         NULL /* children */, FALSE, depth,
                                          NULL /* conflicts */,
                                          NULL /* work items */,
                                          scratch_pool));

Modified: subversion/branches/fs-py/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/copy.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_wc/copy.c Mon Dec 19 18:49:34 2011
@@ -435,6 +435,7 @@ copy_versioned_dir(svn_wc__db_t *db,
         SVN_ERR(svn_wc__db_op_copy_shadowed_layer(db,
                                                   child_src_abspath,
                                                   child_dst_abspath,
+                                                  is_move,
                                                   scratch_pool));
 
       if (child_status == svn_wc__db_status_normal
@@ -496,6 +497,15 @@ copy_versioned_dir(svn_wc__db_t *db,
           /* Don't recurse on children while all we do is creating not-present
              children */
         }
+      else if (child_status == svn_wc__db_status_incomplete)
+        {
+          /* Should go ahead and copy incomplete to incomplete? Try to
+             copy as much as possible, or give up early? */
+          return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
+                                   _("Cannot handle status of '%s'"),
+                                   svn_dirent_local_style(src_abspath,
+                                                          iterpool));
+        }
       else
         {
           SVN_ERR_ASSERT(child_status == svn_wc__db_status_server_excluded);
@@ -975,6 +985,7 @@ svn_wc_move(svn_wc_context_t *wc_ctx,
             apr_pool_t *scratch_pool)
 {
   svn_wc__db_t *db = wc_ctx->db;
+
   SVN_ERR(copy_or_move(wc_ctx, src_abspath, dst_abspath,
                        TRUE /* metadata_only */,
                        TRUE /* is_move */,
@@ -982,6 +993,10 @@ svn_wc_move(svn_wc_context_t *wc_ctx,
                        notify_func, notify_baton,
                        scratch_pool));
 
+  /* An iterrupt at this point will leave the new copy marked as
+     moved-here but the source has not yet been deleted or marked as
+     moved-to. */
+
   /* Should we be using a workqueue for this move?  It's not clear.
      What should happen if the copy above is interrupted?  The user
      may want to abort the move and a workqueue might interfere with

Modified: subversion/branches/fs-py/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/deprecated.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_wc/deprecated.c Mon Dec 19 18:49:34 2011
@@ -3426,6 +3426,14 @@ svn_wc_get_switch_editor(svn_revnum_t *t
 }
 
 
+svn_error_t *
+svn_wc_external_item_create(const svn_wc_external_item2_t **item,
+                            apr_pool_t *pool)
+{
+  *item = apr_pcalloc(pool, sizeof(svn_wc_external_item2_t));
+  return SVN_NO_ERROR;
+}
+
 svn_wc_external_item_t *
 svn_wc_external_item_dup(const svn_wc_external_item_t *item,
                          apr_pool_t *pool)

Modified: subversion/branches/fs-py/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/diff_editor.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_wc/diff_editor.c Mon Dec 19 18:49:34 2011
@@ -1880,6 +1880,8 @@ svn_wc_get_diff_editor6(const svn_delta_
   void *inner_baton;
   svn_delta_editor_t *tree_editor;
   const svn_delta_editor_t *inner_editor;
+  svn_delta_shim_callbacks_t *shim_callbacks =
+                                svn_delta_shim_callbacks_default(result_pool);
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(anchor_abspath));
 
@@ -1932,8 +1934,7 @@ svn_wc_get_diff_editor6(const svn_delta_
                                             result_pool));
 
   SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
-                                   NULL, NULL, NULL, NULL,
-                                   result_pool, scratch_pool));
+                                   shim_callbacks, result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }