subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hwri...@apache.org
Subject svn commit: r984234 [6/20] - in /subversion/branches/ignore-mergeinfo: ./ build/ build/ac-macros/ build/generator/ notes/ notes/api-errata/ notes/obliterate/ notes/obliterate/fspec-cc1/ notes/rename-tracking/ notes/svnpatch/ notes/tree-conflicts/ notes...
Date Tue, 10 Aug 2010 22:07:31 GMT
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.c Tue Aug 10 22:07:24 2010
@@ -1042,12 +1042,6 @@ write_format(const char *path, int forma
                                   contents->data, contents->len,
                                   svn_io_file_del_none, pool));
 
-#ifdef WIN32
-      /* make the destination writable, but only on Windows, because
-         Windows does not let us replace read-only files. */
-      SVN_ERR(svn_io_set_file_read_write(path, TRUE, pool));
-#endif /* WIN32 */
-
       /* rename the temp file as the real destination */
       SVN_ERR(svn_io_file_rename(path_tmp, path, pool));
     }
@@ -1568,8 +1562,8 @@ svn_fs_fs__hotcopy(const char *src_path,
             {
               SVN_ERR(svn_io_dir_make(dst_subdir_shard, APR_OS_DEFAULT,
                                       iterpool));
-              SVN_ERR(svn_fs_fs__dup_perms(dst_subdir_shard, dst_subdir,
-                                           iterpool));
+              SVN_ERR(svn_io_copy_perms(dst_subdir, dst_subdir_shard,
+                                        iterpool));
             }
         }
 
@@ -1630,8 +1624,8 @@ svn_fs_fs__hotcopy(const char *src_path,
             {
               SVN_ERR(svn_io_dir_make(dst_subdir_shard, APR_OS_DEFAULT,
                                       iterpool));
-              SVN_ERR(svn_fs_fs__dup_perms(dst_subdir_shard, dst_subdir,
-                                           iterpool));
+              SVN_ERR(svn_io_copy_perms(dst_subdir, dst_subdir_shard,
+                                        iterpool));
             }
         }
 
@@ -2591,7 +2585,10 @@ get_root_changes_offset(apr_off_t *root_
 /* Move a file into place from OLD_FILENAME in the transactions
    directory to its final location NEW_FILENAME in the repository.  On
    Unix, match the permissions of the new file to the permissions of
-   PERMS_REFERENCE.  Temporary allocations are from POOL. */
+   PERMS_REFERENCE.  Temporary allocations are from POOL.
+   
+   This function almost duplicates svn_io_file_move(), but it tries to
+   guarantee a flush. */
 static svn_error_t *
 move_into_place(const char *old_filename,
                 const char *new_filename,
@@ -2600,7 +2597,7 @@ move_into_place(const char *old_filename
 {
   svn_error_t *err;
 
-  SVN_ERR(svn_fs_fs__dup_perms(old_filename, perms_reference, pool));
+  SVN_ERR(svn_io_copy_perms(perms_reference, old_filename, pool));
 
   /* Move the file into place. */
   err = svn_io_file_rename(old_filename, new_filename, pool);
@@ -2616,6 +2613,11 @@ move_into_place(const char *old_filename
       /* Flush the target of the copy to disk. */
       SVN_ERR(svn_io_file_open(&file, new_filename, APR_READ,
                                APR_OS_DEFAULT, pool));
+      /* ### BH: Does this really guarantee a flush of the data written
+         ### via a completely different handle on all operating systems?
+         ###
+         ### Maybe we should perform the copy ourselves instead of making
+         ### apr do that and flush the real handle? */
       SVN_ERR(svn_io_file_flush_to_disk(file, pool));
       SVN_ERR(svn_io_file_close(file, pool));
     }
@@ -5709,34 +5711,6 @@ write_final_changed_path_info(apr_off_t 
   return SVN_NO_ERROR;
 }
 
-
-svn_error_t *
-svn_fs_fs__dup_perms(const char *filename,
-                     const char *perms_reference,
-                     apr_pool_t *pool)
-{
-#ifndef WIN32
-  apr_status_t status;
-  apr_finfo_t finfo;
-  const char *filename_apr, *perms_reference_apr;
-
-  SVN_ERR(svn_path_cstring_from_utf8(&filename_apr, filename, pool));
-  SVN_ERR(svn_path_cstring_from_utf8(&perms_reference_apr, perms_reference,
-                                     pool));
-
-  status = apr_stat(&finfo, perms_reference_apr, APR_FINFO_PROT, pool);
-  if (status)
-    return svn_error_wrap_apr(status, _("Can't stat '%s'"),
-                              svn_dirent_local_style(perms_reference, pool));
-  status = apr_file_perms_set(filename_apr, finfo.protection);
-  if (status)
-    return svn_error_wrap_apr(status, _("Can't chmod '%s'"),
-                              svn_dirent_local_style(filename, pool));
-#endif
-  return SVN_NO_ERROR;
-}
-
-
 /* Atomically update the 'current' file to hold the specifed REV,
    NEXT_NODE_ID, and NEXT_COPY_ID.  (The two next-ID parameters are
    ignored and may be NULL if the FS format does not use them.)
@@ -5980,13 +5954,12 @@ commit_body(void *baton, apr_pool_t *poo
       const char *new_dir = path_rev_shard(cb->fs, new_rev, pool);
       err = svn_io_dir_make(new_dir, APR_OS_DEFAULT, pool);
       if (err && !APR_STATUS_IS_EEXIST(err->apr_err))
-        SVN_ERR(err);
+        return svn_error_return(err);
       svn_error_clear(err);
-      SVN_ERR(svn_fs_fs__dup_perms(new_dir,
-                                   svn_dirent_join(cb->fs->path,
-                                                   PATH_REVS_DIR,
-                                                   pool),
-                                   pool));
+      SVN_ERR(svn_io_copy_perms(svn_dirent_join(cb->fs->path,
+                                                PATH_REVS_DIR,
+                                                pool),
+                                new_dir, pool));
 
       if (ffd->format < SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT ||
           new_rev >= ffd->min_unpacked_revprop)
@@ -5996,11 +5969,10 @@ commit_body(void *baton, apr_pool_t *poo
           if (err && !APR_STATUS_IS_EEXIST(err->apr_err))
             SVN_ERR(err);
           svn_error_clear(err);
-          SVN_ERR(svn_fs_fs__dup_perms(new_dir,
-                                       svn_dirent_join(cb->fs->path,
-                                                       PATH_REVPROPS_DIR,
-                                                       pool),
-                                       pool));
+          SVN_ERR(svn_io_copy_perms(svn_dirent_join(cb->fs->path,
+                                                    PATH_REVPROPS_DIR,
+                                                    pool),
+                                    new_dir, pool));
         }
     }
 
@@ -6896,7 +6868,7 @@ svn_fs_fs__ensure_dir_exists(const char 
 
   /* We successfully created a new directory.  Dup the permissions
      from FS->path. */
-  return svn_fs_fs__dup_perms(path, fs->path, pool);
+  return svn_io_copy_perms(path, fs->path, pool);
 }
 
 /* Set *NODE_ORIGINS to a hash mapping 'const char *' node IDs to
@@ -7167,6 +7139,7 @@ struct change_rev_prop_baton {
   svn_fs_t *fs;
   svn_revnum_t rev;
   const char *name;
+  const svn_string_t *const *old_value_p;
   const svn_string_t *value;
 };
 
@@ -7182,6 +7155,23 @@ change_rev_prop_body(void *baton, apr_po
 
   SVN_ERR(svn_fs_fs__revision_proplist(&table, cb->fs, cb->rev, pool));
 
+  if (cb->old_value_p)
+    {
+      const svn_string_t *wanted_value = *cb->old_value_p;
+      const svn_string_t *present_value = apr_hash_get(table, cb->name,
+                                                       APR_HASH_KEY_STRING);
+      if ((!wanted_value != !present_value)
+          || (wanted_value && present_value
+              && !svn_string_compare(wanted_value, present_value)))
+        {
+          /* What we expected isn't what we found. */
+          return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
+                                   _("revprop '%s' has unexpected value in "
+                                     "filesystem"),
+                                   cb->name);
+        }
+      /* Fall through. */
+    }
   apr_hash_set(table, cb->name, APR_HASH_KEY_STRING, cb->value);
 
   return set_revision_proplist(cb->fs, cb->rev, table, pool);
@@ -7191,6 +7181,7 @@ svn_error_t *
 svn_fs_fs__change_rev_prop(svn_fs_t *fs,
                            svn_revnum_t rev,
                            const char *name,
+                           const svn_string_t *const *old_value_p,
                            const svn_string_t *value,
                            apr_pool_t *pool)
 {
@@ -7201,6 +7192,7 @@ svn_fs_fs__change_rev_prop(svn_fs_t *fs,
   cb.fs = fs;
   cb.rev = rev;
   cb.name = name;
+  cb.old_value_p = old_value_p;
   cb.value = value;
 
   return svn_fs_fs__with_write_lock(fs, change_rev_prop_body, &cb, pool);
@@ -7399,7 +7391,7 @@ pack_shard(const char *revs_dir,
 
   SVN_ERR(svn_stream_close(manifest_stream));
   SVN_ERR(svn_stream_close(pack_stream));
-  SVN_ERR(svn_fs_fs__dup_perms(pack_file_dir, shard_path, pool));
+  SVN_ERR(svn_io_copy_perms(shard_path, pack_file_dir, pool));
 
   /* Update the min-unpacked-rev file to reflect our newly packed shard.
    * (ffd->min_unpacked_rev will be updated by open_pack_or_rev_file().)
@@ -7450,7 +7442,7 @@ pack_revprop_shard(svn_fs_t *fs,
 
   /* Notify caller we're starting to pack this shard. */
   if (notify_func)
-    SVN_ERR(notify_func(notify_baton, shard, svn_fs_pack_notify_start,
+    SVN_ERR(notify_func(notify_baton, shard, svn_fs_pack_notify_start_revprop,
                         pool));
 
   start_rev = (svn_revnum_t) (shard * max_files_per_dir);
@@ -7488,7 +7480,7 @@ pack_revprop_shard(svn_fs_t *fs,
 
   /* Notify caller we're starting to pack this shard. */
   if (notify_func)
-    SVN_ERR(notify_func(notify_baton, shard, svn_fs_pack_notify_end,
+    SVN_ERR(notify_func(notify_baton, shard, svn_fs_pack_notify_end_revprop,
                         pool));
 
   return SVN_NO_ERROR;

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.h?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.h Tue Aug 10 22:07:24 2010
@@ -401,12 +401,6 @@ svn_error_t *svn_fs_fs__move_into_place(
                                         const char *perms_reference,
                                         apr_pool_t *pool);
 
-/* Match the perms on FILENAME to the PERMS_REFERENCE file if we're
-   not on a win32 system.  On win32, this is a no-op. */
-svn_error_t *svn_fs_fs__dup_perms(const char *filename,
-                                  const char *perms_reference,
-                                  apr_pool_t *pool);
-
 /* Sets *PATH to the path of REV in FS, whether in a pack file or not.
    Allocate in POOL. */
 svn_error_t *
@@ -441,9 +435,11 @@ svn_error_t *svn_fs_fs__revision_prop(sv
 /* Change, add, or delete a property on a revision REV in filesystem
    FS.  NAME gives the name of the property, and value, if non-NULL,
    gives the new contents of the property.  If value is NULL, then the
-   property will be deleted.  Do any temporary allocation in POOL.  */
+   property will be deleted.  If OLD_VALUE_P is not NULL, do nothing unless the
+   preexisting value is *OLD_VALUE_P.  Do any temporary allocation in POOL.  */
 svn_error_t *svn_fs_fs__change_rev_prop(svn_fs_t *fs, svn_revnum_t rev,
                                         const char *name,
+                                        const svn_string_t *const *old_value_p,
                                         const svn_string_t *value,
                                         apr_pool_t *pool);
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.c Tue Aug 10 22:07:24 2010
@@ -213,7 +213,7 @@ write_digest_file(apr_hash_t *children,
   SVN_ERR(svn_stream_close(stream));
   SVN_ERR(svn_io_file_rename(tmp_path, digest_path, pool));
   SVN_ERR(svn_fs_fs__path_rev_absolute(&rev_0_path, fs, 0, pool));
-  return svn_fs_fs__dup_perms(digest_path, rev_0_path, pool);
+  return svn_io_copy_perms(rev_0_path, digest_path, pool);
 }
 
 
@@ -325,7 +325,7 @@ set_lock(svn_fs_t *fs,
          apr_pool_t *pool)
 {
   svn_stringbuf_t *this_path = svn_stringbuf_create(lock->path, pool);
-  svn_stringbuf_t *last_child = svn_stringbuf_create("", pool);
+  const char *lock_digest_path = NULL;
   apr_pool_t *subpool;
 
   SVN_ERR_ASSERT(lock);
@@ -356,15 +356,16 @@ set_lock(svn_fs_t *fs,
         {
           this_lock = lock;
           lock = NULL;
-          svn_stringbuf_set(last_child, digest_file);
+          lock_digest_path = apr_pstrdup(pool, digest_file);
         }
       else
         {
           /* If we already have an entry for this path, we're done. */
-          if (apr_hash_get(this_children, last_child->data, last_child->len))
+          if (apr_hash_get(this_children, lock_digest_path,
+                           APR_HASH_KEY_STRING))
             break;
-          apr_hash_set(this_children, last_child->data,
-                       last_child->len, (void *)1);
+          apr_hash_set(this_children, lock_digest_path,
+                       APR_HASH_KEY_STRING, (void *)1);
         }
       SVN_ERR(write_digest_file(this_children, this_lock, fs,
                                 digest_path, subpool));
@@ -387,13 +388,13 @@ delete_lock(svn_fs_t *fs,
             apr_pool_t *pool)
 {
   svn_stringbuf_t *this_path = svn_stringbuf_create(lock->path, pool);
-  svn_stringbuf_t *child_to_kill = svn_stringbuf_create("", pool);
+  const char *child_to_kill = NULL;
   apr_pool_t *subpool;
 
   SVN_ERR_ASSERT(lock);
 
   /* Iterate in reverse, deleting the lock for LOCK->path, and then
-     pruning entries from its parents. */
+     deleting its entry as it appears in each of its parents. */
   subpool = svn_pool_create(pool);
   while (1729)
     {
@@ -411,31 +412,27 @@ delete_lock(svn_fs_t *fs,
       SVN_ERR(read_digest_file(&this_children, &this_lock, fs,
                                digest_path, subpool));
 
-      /* If we are supposed to drop the last entry from this path's
-         children list, do so. */
-      if (child_to_kill->len)
-        apr_hash_set(this_children, child_to_kill->data,
-                     child_to_kill->len, NULL);
-
       /* Delete the lock (first time through only). */
       if (lock)
         {
           this_lock = NULL;
           lock = NULL;
+          child_to_kill = apr_pstrdup(pool, digest_file);
         }
 
+      if (child_to_kill)
+        apr_hash_set(this_children, child_to_kill, APR_HASH_KEY_STRING, NULL);
+
       if (! (this_lock || apr_hash_count(this_children) != 0))
         {
           /* Special case:  no goodz, no file.  And remember to nix
              the entry for it in its parent. */
-          svn_stringbuf_set(child_to_kill, digest_file);
           SVN_ERR(svn_io_remove_file2(digest_path, FALSE, subpool));
         }
       else
         {
           SVN_ERR(write_digest_file(this_children, this_lock, fs,
                                     digest_path, subpool));
-          svn_stringbuf_setempty(child_to_kill);
         }
 
       /* Prep for next iteration, or bail if we're done. */
@@ -901,20 +898,82 @@ svn_fs_fs__get_lock(svn_lock_t **lock_p,
 }
 
 
+/* Baton for get_locks_filter_func(). */
+typedef struct
+{
+  const char *path;
+  svn_depth_t requested_depth;
+  svn_fs_get_locks_callback_t get_locks_func;
+  void *get_locks_baton;
+
+} get_locks_filter_baton_t;
+
+
+/* A wrapper for the GET_LOCKS_FUNC passed to svn_fs_fs__get_locks()
+   which filters out locks on paths that aren't within
+   BATON->requested_depth of BATON->path before called
+   BATON->get_locks_func() with BATON->get_locks_baton.
+
+   NOTE: See issue #3660 for details about how the FSFS lock
+   management code is inconsistent.  Until that inconsistency is
+   resolved, we take this filtering approach rather than honoring
+   depth requests closer to the crawling code.  In other words, once
+   we decide how to resolve issue #3660, there might be a more
+   performant way to honor the depth passed to svn_fs_fs__get_locks().  */
+static svn_error_t *
+get_locks_filter_func(void *baton,
+                      svn_lock_t *lock,
+                      apr_pool_t *pool)
+{
+  get_locks_filter_baton_t *b = baton;
+
+  /* Filter out unwanted paths.  Since Subversion only allows
+     locks on files, we can treat depth=immediates the same as
+     depth=files for filtering purposes.  Meaning, we'll keep
+     this lock if:
+
+     a) its path is the very path we queried, or
+     b) we've asked for a fully recursive answer, or
+     c) we've asked for depth=files or depth=immediates, and this
+        lock is on an immediate child of our query path.
+  */
+  if ((strcmp(b->path, lock->path) == 0) 
+      || (b->requested_depth == svn_depth_infinity))
+    {
+      SVN_ERR(b->get_locks_func(b->get_locks_baton, lock, pool));
+    }
+  else if ((b->requested_depth == svn_depth_files) ||
+           (b->requested_depth == svn_depth_immediates))
+    {
+      const char *rel_uri = svn_uri_is_child(b->path, lock->path, pool);
+      if (rel_uri && (svn_path_component_count(rel_uri) == 1))
+        SVN_ERR(b->get_locks_func(b->get_locks_baton, lock, pool));
+    }
+
+  return SVN_NO_ERROR; 
+}
+
 svn_error_t *
 svn_fs_fs__get_locks(svn_fs_t *fs,
                      const char *path,
+                     svn_depth_t depth,
                      svn_fs_get_locks_callback_t get_locks_func,
                      void *get_locks_baton,
                      apr_pool_t *pool)
 {
   const char *digest_path;
+  get_locks_filter_baton_t glfb;
 
   SVN_ERR(svn_fs__check_fs(fs, TRUE));
   path = svn_fs__canonicalize_abspath(path, pool);
 
+  glfb.path = path;
+  glfb.requested_depth = depth; 
+  glfb.get_locks_func = get_locks_func;
+  glfb.get_locks_baton = get_locks_baton;
+
   /* Get the top digest path in our tree of interest, and then walk it. */
   digest_path = digest_path_from_path(fs, path, pool);
-  return walk_digest_files(fs, digest_path, get_locks_func,
-                           get_locks_baton, FALSE, pool);
+  return walk_digest_files(fs, digest_path, get_locks_filter_func, &glfb,
+                           FALSE, pool);
 }

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.h?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.h Tue Aug 10 22:07:24 2010
@@ -60,6 +60,7 @@ svn_error_t *svn_fs_fs__get_lock(svn_loc
 
 svn_error_t *svn_fs_fs__get_locks(svn_fs_t *fs,
                                   const char *path,
+                                  svn_depth_t depth,
                                   svn_fs_get_locks_callback_t get_locks_func,
                                   void *get_locks_baton,
                                   apr_pool_t *pool);

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/structure
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/structure?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/structure (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/structure Tue Aug 10 22:07:24 2010
@@ -500,7 +500,8 @@ names are the first 3 characters of the 
 
 Also stored in the digest file for a given FS path are pointers to
 other digest files which contain information associated with other FS
-paths that are our path's immediate children.
+paths that are beneath our path (an immediate child thereof, or a
+grandchild, or a great-grandchild, ...).
 
 To answer the question, "Does path FOO have a lock associated with
 it?", one need only generate the MD5 digest of FOO's
@@ -515,4 +516,4 @@ To inquire about locks on children of th
 reference the same path as above, but look for a list of children in
 that file (instead of lock information).  Children are listed as MD5
 digests, too, so you would simply iterate over those digests and
-consult the files they reference, and so on, recursively.
+consult the files they reference for lock information.

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_util/fs-util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_util/fs-util.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_util/fs-util.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_util/fs-util.c Tue Aug 10 22:07:24 2010
@@ -39,7 +39,7 @@ svn_fs__canonicalize_abspath(const char 
 {
   char *newpath;
   size_t path_len;
-  int path_i = 0, newpath_i = 0;
+  size_t path_i = 0, newpath_i = 0;
   svn_boolean_t eating_slashes = FALSE;
 
   /* No PATH?  No problem. */

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.c Tue Aug 10 22:07:24 2010
@@ -1014,13 +1014,26 @@ svn_error_t *svn_ra_get_lock(svn_ra_sess
   return session->vtable->get_lock(session, lock, path, pool);
 }
 
+svn_error_t *svn_ra_get_locks2(svn_ra_session_t *session,
+                               apr_hash_t **locks,
+                               const char *path,
+                               svn_depth_t depth,
+                               apr_pool_t *pool)
+{
+  SVN_ERR_ASSERT(*path != '/');
+  SVN_ERR_ASSERT((depth == svn_depth_empty) ||
+                 (depth == svn_depth_files) ||
+                 (depth == svn_depth_immediates) ||
+                 (depth == svn_depth_infinity));
+  return session->vtable->get_locks(session, locks, path, depth, pool);
+}
+
 svn_error_t *svn_ra_get_locks(svn_ra_session_t *session,
                               apr_hash_t **locks,
                               const char *path,
                               apr_pool_t *pool)
 {
-  SVN_ERR_ASSERT(*path != '/');
-  return session->vtable->get_locks(session, locks, path, pool);
+  return svn_ra_get_locks2(session, locks, path, svn_depth_infinity, pool);
 }
 
 svn_error_t *svn_ra_replay(svn_ra_session_t *session,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.h?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.h Tue Aug 10 22:07:24 2010
@@ -230,6 +230,7 @@ typedef struct svn_ra__vtable_t {
   svn_error_t *(*get_locks)(svn_ra_session_t *session,
                             apr_hash_t **locks,
                             const char *path,
+                            svn_depth_t depth,
                             apr_pool_t *pool);
   svn_error_t *(*replay)(svn_ra_session_t *session,
                          svn_revnum_t revision,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/ra_plugin.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/ra_plugin.c Tue Aug 10 22:07:24 2010
@@ -1323,6 +1323,7 @@ static svn_error_t *
 svn_ra_local__get_locks(svn_ra_session_t *session,
                         apr_hash_t **locks,
                         const char *path,
+                        svn_depth_t depth,
                         apr_pool_t *pool)
 {
   svn_ra_local__session_baton_t *sess = session->priv;
@@ -1330,8 +1331,8 @@ svn_ra_local__get_locks(svn_ra_session_t
 
   /* Kinda silly to call the repos wrapper, since we have no authz
      func to give it.  But heck, why not. */
-  return svn_repos_fs_get_locks(locks, sess->repos, abs_path,
-                                NULL, NULL, pool);
+  return svn_repos_fs_get_locks2(locks, sess->repos, abs_path, depth,
+                                 NULL, NULL, pool);
 }
 
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/split_url.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/split_url.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/split_url.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/split_url.c Tue Aug 10 22:07:24 2010
@@ -24,6 +24,7 @@
 #include "ra_local.h"
 #include <string.h>
 #include "svn_path.h"
+#include "svn_dirent_uri.h"
 #include "svn_private_config.h"
 
 
@@ -35,129 +36,23 @@ svn_ra_local__split_URL(svn_repos_t **re
                         apr_pool_t *pool)
 {
   svn_error_t *err = SVN_NO_ERROR;
-  const char *repos_root;
-  const char *hostname, *path;
+  const char *repos_dirent;
+  const char *repos_root_dirent;
   svn_stringbuf_t *urlbuf;
 
-  /* Verify that the URL is well-formed (loosely) */
-
-  /* First, check for the "file://" prefix. */
-  if (strncmp(URL, "file://", 7) != 0)
-    return svn_error_createf
-      (SVN_ERR_RA_ILLEGAL_URL, NULL,
-       _("Local URL '%s' does not contain 'file://' prefix"), URL);
-
-  /* Then, skip what's between the "file://" prefix and the next
-     occurance of '/' -- this is the hostname, and we are considering
-     everything from that '/' until the end of the URL to be the
-     absolute path portion of the URL.
-     If we got just "file://", treat it the same as "file:///". */
-  hostname = URL + 7;
-  if (*hostname == '\0')
-    {
-      path = "/";
-      hostname = NULL;
-    }
-  else
-    {
-      path = strchr(hostname, '/');
-      if (! path)
-        return svn_error_createf
-          (SVN_ERR_RA_ILLEGAL_URL, NULL,
-           _("Local URL '%s' contains only a hostname, no path"), URL);
-
-      /* Treat localhost as an empty hostname. */
-      if (hostname != path)
-        {
-          hostname = svn_path_uri_decode(apr_pstrmemdup(pool, hostname,
-                                                        path - hostname), pool);
-          if (strncmp(hostname, "localhost", 9) == 0)
-            hostname = NULL;
-        }
-      else
-        hostname = NULL;
-    }
-
-  /* Duplicate the URL, starting at the top of the path.
-     At the same time, we URI-decode the path. */
-#if defined(WIN32) || defined(__CYGWIN__)
-  /* On Windows, we'll typically have to skip the leading / if the
-     path starts with a drive letter.  Like most Web browsers, We
-     support two variants of this scheme:
-
-         file:///X:/path    and
-         file:///X|/path
-
-    Note that, at least on WinNT and above,  file:////./X:/path  will
-    also work, so we must make sure the transformation doesn't break
-    that, and  file:///path  (that looks within the current drive
-    only) should also keep working.
-    If we got a non-empty hostname other than localhost, we convert this
-    into an UNC path.  In this case, we obviously don't strip the slash
-    even if the path looks like it starts with a drive letter.
-    Another thing to remember is that the form file:///\machine/share
-    was the only way to access UNC paths in svn before 1.2.  We
-    need to support that for compatibility with old working copies.
-  */
-  {
-    static const char valid_drive_letters[] =
-      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-    /* Casting away const! */
-    char *dup_path = (char *)svn_path_uri_decode(path, pool);
-    if (!hostname && dup_path[1] && strchr(valid_drive_letters, dup_path[1])
-        && (dup_path[2] == ':' || dup_path[2] == '|')
-        && (dup_path[3] == '/' || dup_path[3] == '\0'))
-      {
-        /* Skip the leading slash. */
-        ++dup_path;
-        /* We're using path below to calculate fs_path, so keep it in sync. */
-        ++path;
-        if (dup_path[1] == '|')
-          dup_path[1] = ':';
-
-        if (dup_path[3] == '\0')
-          {
-            /* A valid dirent for the driveroot must be like "C:/" instead of
-               just "C:" or svn_dirent_join() will use the current directory
-               on the drive instead */
-
-            char *new_path = apr_pcalloc(pool, 4);
-            new_path[0] = dup_path[0];
-            new_path[1] = ':';
-            new_path[2] = '/';
-            new_path[3] = '\0';
-          }
-      }
-    if (hostname)
-      /* We still know that the path starts with a slash. */
-      repos_root = apr_pstrcat(pool, "//", hostname, path, NULL);
-    else
-      repos_root = dup_path;
-  }
-#else
-  /* Currently, the only hostnames we are allowing on non-Win32 platforms
-     are the empty string and 'localhost'. */
-  if (hostname)
-    return svn_error_createf
-      (SVN_ERR_RA_ILLEGAL_URL, NULL,
-       _("Local URL '%s' contains unsupported hostname"), URL);
-
-  repos_root = svn_path_uri_decode(path, pool);
-#endif
+  SVN_ERR(svn_uri_get_dirent_from_file_url(&repos_dirent, URL, pool));
 
   /* Search for a repository in the full path. */
-  repos_root = svn_repos_find_root_path(repos_root, pool);
-  if (!repos_root)
-    return svn_error_createf
-      (SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED, NULL,
-       _("Unable to open repository '%s'"), URL);
+  repos_root_dirent = svn_repos_find_root_path(repos_dirent, pool);
+  if (!repos_root_dirent)
+    return svn_error_createf(SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED, NULL,
+                             _("Unable to open repository '%s'"), URL);
 
   /* Attempt to open a repository at URL. */
-  err = svn_repos_open(repos, repos_root, pool);
+  err = svn_repos_open(repos, repos_root_dirent, pool);
   if (err)
-    return svn_error_createf
-      (SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED, err,
-       _("Unable to open repository '%s'"), URL);
+    return svn_error_createf(SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED, err,
+                             _("Unable to open repository '%s'"), URL);
 
   /* Assert capabilities directly, since client == server. */
   {
@@ -166,26 +61,17 @@ svn_ra_local__split_URL(svn_repos_t **re
     SVN_ERR(svn_repos_remember_client_capabilities(*repos, caps));
   }
 
-  /* What remains of URL after being hacked at in the previous step is
-     REPOS_URL.  FS_PATH is what we've hacked off in the process.
-     Note that path is not encoded and what we gave to svn_root_find_root_path
-     may have been destroyed by that function.  So we have to decode it once
-     more.  But then, it is ours...
-     We want the suffix of path after the repos root part.  Note that
-     repos_root may contain //hostname, but path doesn't.  */
-  *fs_path = svn_path_uri_decode(path, pool)
-    + (strlen(repos_root)
-       - (hostname ? strlen(hostname) + 2 : 0));
-
-  /* Ensure that *FS_PATH has its leading slash. */
-  if (**fs_path != '/')
-    *fs_path = apr_pstrcat(pool, "/", *fs_path, NULL);
+  *fs_path = &repos_dirent[strlen(repos_root_dirent)];
+
+  if (**fs_path == '\0')
+    *fs_path = "/";
 
   /* Remove the path components in *fs_path from the original URL, to get
      the URL to the repository root. */
   urlbuf = svn_stringbuf_create(URL, pool);
   svn_path_remove_components(urlbuf,
-                             svn_path_component_count(*fs_path));
+                             svn_path_component_count(repos_dirent)
+                             - svn_path_component_count(repos_root_dirent));
   *repos_url = urlbuf->data;
 
   return SVN_NO_ERROR;

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/get_locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/get_locks.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/get_locks.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/get_locks.c Tue Aug 10 22:07:24 2010
@@ -85,7 +85,7 @@ static const svn_ra_neon__xml_elm_t getl
  * The get-locks-report xml request body is super-simple.
  * The server doesn't need anything but the URI in the REPORT request line.
  *
- *    <S:get-locks-report xmlns...>
+ *    <S:get-locks-report [depth=DEPTH] xmlns...>
  *    </S:get-locks-report>
  *
  * The get-locks-report xml response is just a list of svn_lock_t's
@@ -121,6 +121,8 @@ static const svn_ra_neon__xml_elm_t getl
 
 /* Context for parsing server's response. */
 typedef struct {
+  const char *path;                /* target of the report */
+  svn_depth_t requested_depth;     /* requested depth of the report */
   svn_lock_t *current_lock;        /* the lock being constructed */
   svn_stringbuf_t *cdata_accum;    /* a place to accumulate cdata */
   const char *encoding;            /* normally NULL, else the value of
@@ -235,8 +237,33 @@ getlocks_end_element(void *userdata, int
         SVN_ERR(svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                  _("Incomplete lock data returned")));
 
-      apr_hash_set(baton->lock_hash, baton->current_lock->path,
-                   APR_HASH_KEY_STRING, baton->current_lock);
+      /* Filter out unwanted paths.  Since Subversion only allows
+         locks on files, we can treat depth=immediates the same as
+         depth=files for filtering purposes.  Meaning, we'll keep
+         this lock if:
+
+         a) its path is the very path we queried, or
+         b) we've asked for a fully recursive answer, or
+         c) we've asked for depth=files or depth=immediates, and this
+            lock is on an immediate child of our query path.
+      */
+      if ((strcmp(baton->path, baton->current_lock->path) == 0)
+          || (baton->requested_depth == svn_depth_infinity))
+        {
+          apr_hash_set(baton->lock_hash, baton->current_lock->path,
+                       APR_HASH_KEY_STRING, baton->current_lock);
+        }
+      else if ((baton->requested_depth == svn_depth_files) ||
+               (baton->requested_depth == svn_depth_immediates))
+        {
+          const char *rel_uri = svn_uri_is_child(baton->path,
+                                                 baton->current_lock->path,
+                                                 baton->scratchpool);
+          if (rel_uri && (svn_path_component_count(rel_uri) == 1))
+            apr_hash_set(baton->lock_hash, baton->current_lock->path,
+                         APR_HASH_KEY_STRING, baton->current_lock);
+          svn_pool_clear(baton->scratchpool);
+        }
       break;
 
     case ELEM_lock_path:
@@ -330,20 +357,30 @@ getlocks_end_element(void *userdata, int
 }
 
 
-
 svn_error_t *
 svn_ra_neon__get_locks(svn_ra_session_t *session,
                        apr_hash_t **locks,
                        const char *path,
+                       svn_depth_t depth,
                        apr_pool_t *pool)
 {
   svn_ra_neon__session_t *ras = session->priv;
-  const char *body, *url;
+  const char *body, *url, *rel_path;
   svn_error_t *err;
   int status_code = 0;
   get_locks_baton_t baton;
 
+  /* We always run the report on the 'public' URL, which represents
+     HEAD anyway.  If the path doesn't exist in HEAD, then there can't
+     possibly be a lock, so we just return no locks. */
+  url = svn_path_url_add_component2(ras->url->data, path, pool);
+
+  SVN_ERR(svn_ra_neon__get_path_relative_to_root(session, &rel_path,
+                                                 url, pool));
+
   baton.lock_hash = apr_hash_make(pool);
+  baton.path = apr_pstrcat(pool, "/", rel_path, NULL);
+  baton.requested_depth = depth;
   baton.pool = pool;
   baton.scratchpool = svn_pool_create(pool);
   baton.current_lock = NULL;
@@ -353,14 +390,9 @@ svn_ra_neon__get_locks(svn_ra_session_t 
   body = apr_psprintf(pool,
                       "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                       "<S:get-locks-report xmlns:S=\"" SVN_XML_NAMESPACE "\" "
-                      "xmlns:D=\"DAV:\">"
-                      "</S:get-locks-report>");
-
-
-  /* We always run the report on the 'public' URL, which represents
-     HEAD anyway.  If the path doesn't exist in HEAD, then there can't
-     possibly be a lock, so we just return no locks. */
-  url = svn_path_url_add_component(ras->url->data, path, pool);
+                      "xmlns:D=\"DAV:\" depth=\"%s\">"
+                      "</S:get-locks-report>",
+                      svn_depth_to_word(depth));
 
   err = svn_ra_neon__parsed_request(ras, "REPORT", url,
                                     body, NULL, NULL,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/ra_neon.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/ra_neon.h?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/ra_neon.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/ra_neon.h Tue Aug 10 22:07:24 2010
@@ -383,6 +383,13 @@ svn_error_t *svn_ra_neon__get_file_revs(
                                         apr_pool_t *pool);
 
 
+/* Local duplicate of svn_ra_get_path_relative_to_root(). */
+svn_error_t *svn_ra_neon__get_path_relative_to_root(svn_ra_session_t *session,
+                                                    const char **rel_path,
+                                                    const char *url,
+                                                    apr_pool_t *pool);
+
+
 /*
 ** SVN_RA_NEON__LP_*: local properties for RA/DAV
 **
@@ -1022,6 +1029,7 @@ svn_error_t *
 svn_ra_neon__get_locks(svn_ra_session_t *session,
                        apr_hash_t **locks,
                        const char *path,
+                       svn_depth_t depth,
                        apr_pool_t *pool);
 
 /*

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/session.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/session.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/session.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/session.c Tue Aug 10 22:07:24 2010
@@ -1128,6 +1128,33 @@ static svn_error_t *svn_ra_neon__get_rep
   return SVN_NO_ERROR;
 }
 
+/* Copied from svn_ra_get_path_relative_to_root() and de-vtable-ized
+   to prevent a dependency cycle. */
+svn_error_t *
+svn_ra_neon__get_path_relative_to_root(svn_ra_session_t *session,
+                                       const char **rel_path,
+                                       const char *url,
+                                       apr_pool_t *pool)
+{
+  const char *root_url;
+
+  SVN_ERR(svn_ra_neon__get_repos_root(session, &root_url, pool));
+  if (strcmp(root_url, url) == 0)
+    {
+      *rel_path = "";
+    }
+  else
+    {
+      *rel_path = svn_uri_is_child(root_url, url, pool);
+      if (! *rel_path)
+        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                                 _("'%s' isn't a child of repository root "
+                                   "URL '%s'"),
+                                 url, root_url);
+      *rel_path = svn_path_uri_decode(*rel_path, pool);
+    }
+  return SVN_NO_ERROR;
+}
 
 static svn_error_t *svn_ra_neon__do_get_uuid(svn_ra_session_t *session,
                                              const char **uuid,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/blame.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/blame.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/blame.c Tue Aug 10 22:07:24 2010
@@ -104,6 +104,7 @@ typedef struct {
   const char *path;
   svn_revnum_t start;
   svn_revnum_t end;
+  svn_boolean_t include_merged_revisions;
 
   /* are we done? */
   svn_boolean_t done;
@@ -381,6 +382,46 @@ cdata_blame(svn_ra_serf__xml_parser_t *p
   return SVN_NO_ERROR;
 }
 
+static serf_bucket_t*
+create_file_revs_body(void *baton,
+                      serf_bucket_alloc_t *alloc,
+                      apr_pool_t *pool)
+{
+  serf_bucket_t *buckets;
+  blame_context_t *blame_ctx = baton;
+
+  buckets = serf_bucket_aggregate_create(alloc);
+
+  svn_ra_serf__add_open_tag_buckets(buckets, alloc,
+                                    "S:file-revs-report",
+                                    "xmlns:S", SVN_XML_NAMESPACE,
+                                    NULL);
+
+  svn_ra_serf__add_tag_buckets(buckets,
+                               "S:start-revision", apr_ltoa(pool, blame_ctx->start),
+                               alloc);
+
+  svn_ra_serf__add_tag_buckets(buckets,
+                               "S:end-revision", apr_ltoa(pool, blame_ctx->end),
+                               alloc);
+
+  if (blame_ctx->include_merged_revisions)
+    {
+      svn_ra_serf__add_tag_buckets(buckets,
+                                   "S:include-merged-revisions", NULL,
+                                   alloc);
+    }
+
+  svn_ra_serf__add_tag_buckets(buckets,
+                               "S:path", blame_ctx->path,
+                               alloc);
+
+  svn_ra_serf__add_close_tag_buckets(buckets, alloc,
+                                     "S:file-revs-report");
+
+  return buckets;
+}
+
 svn_error_t *
 svn_ra_serf__get_file_revs(svn_ra_session_t *ra_session,
                            const char *path,
@@ -395,48 +436,20 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
   svn_ra_serf__xml_parser_t *parser_ctx;
-  serf_bucket_t *buckets;
   const char *relative_url, *basecoll_url, *req_url;
   int status_code;
   svn_error_t *err;
 
   blame_ctx = apr_pcalloc(pool, sizeof(*blame_ctx));
   blame_ctx->pool = pool;
+  blame_ctx->path = path;
   blame_ctx->file_rev = rev_handler;
   blame_ctx->file_rev_baton = rev_handler_baton;
   blame_ctx->start = start;
   blame_ctx->end = end;
+  blame_ctx->include_merged_revisions = include_merged_revisions;
   blame_ctx->done = FALSE;
 
-  buckets = serf_bucket_aggregate_create(session->bkt_alloc);
-
-  svn_ra_serf__add_open_tag_buckets(buckets, session->bkt_alloc,
-                                    "S:file-revs-report",
-                                    "xmlns:S", SVN_XML_NAMESPACE,
-                                    NULL);
-
-  svn_ra_serf__add_tag_buckets(buckets,
-                               "S:start-revision", apr_ltoa(pool, start),
-                               session->bkt_alloc);
-
-  svn_ra_serf__add_tag_buckets(buckets,
-                               "S:end-revision", apr_ltoa(pool, end),
-                               session->bkt_alloc);
-
-  if (include_merged_revisions)
-    {
-      svn_ra_serf__add_tag_buckets(buckets,
-                                   "S:include-merged-revisions", NULL,
-                                   session->bkt_alloc);
-    }
-
-  svn_ra_serf__add_tag_buckets(buckets,
-                               "S:path", path,
-                               session->bkt_alloc);
-
-  svn_ra_serf__add_close_tag_buckets(buckets, session->bkt_alloc,
-                                     "S:file-revs-report");
-
   SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
                                          NULL, session->repos_url.path,
                                          end, NULL, pool));
@@ -446,8 +459,9 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
 
   handler->method = "REPORT";
   handler->path = req_url;
-  handler->body_buckets = buckets;
   handler->body_type = "text/xml";
+  handler->body_delegate = create_file_revs_body;
+  handler->body_delegate_baton = blame_ctx;
   handler->conn = session->conns[0];
   handler->session = session;
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/getlocations.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/getlocations.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/getlocations.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/getlocations.c Tue Aug 10 22:07:24 2010
@@ -63,6 +63,11 @@ typedef struct {
   /* pool to allocate memory from */
   apr_pool_t *pool;
 
+  /* parameters set by our caller */
+  const char *path;
+  const apr_array_header_t *location_revisions;
+  svn_revnum_t peg_revision;
+
   /* Returned location hash */
   apr_hash_t *paths;
 
@@ -175,6 +180,45 @@ end_getloc(svn_ra_serf__xml_parser_t *pa
   return SVN_NO_ERROR;
 }
 
+static serf_bucket_t*
+create_get_locations_body(void *baton,
+                          serf_bucket_alloc_t *alloc,
+                          apr_pool_t *pool)
+{
+  serf_bucket_t *buckets;
+  loc_context_t *loc_ctx = baton;
+  int i;
+
+  buckets = serf_bucket_aggregate_create(alloc);
+
+  svn_ra_serf__add_open_tag_buckets(buckets, alloc,
+                                    "S:get-locations",
+                                    "xmlns:S", SVN_XML_NAMESPACE,
+                                    "xmlns:D", "DAV:",
+                                    NULL);
+
+  svn_ra_serf__add_tag_buckets(buckets,
+                               "S:path", loc_ctx->path,
+                               alloc);
+
+  svn_ra_serf__add_tag_buckets(buckets,
+                               "S:peg-revision", apr_ltoa(pool, loc_ctx->peg_revision),
+                               alloc);
+
+  for (i = 0; i < loc_ctx->location_revisions->nelts; i++)
+    {
+      svn_revnum_t rev = APR_ARRAY_IDX(loc_ctx->location_revisions, i, svn_revnum_t);
+      svn_ra_serf__add_tag_buckets(buckets,
+                                   "S:location-revision", apr_ltoa(pool, rev),
+                                   alloc);
+    }
+
+  svn_ra_serf__add_close_tag_buckets(buckets, alloc,
+                                     "S:get-locations");
+
+  return buckets;
+}
+
 svn_error_t *
 svn_ra_serf__get_locations(svn_ra_session_t *ra_session,
                            apr_hash_t **locations,
@@ -187,45 +231,19 @@ svn_ra_serf__get_locations(svn_ra_sessio
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
   svn_ra_serf__xml_parser_t *parser_ctx;
-  serf_bucket_t *buckets;
   const char *relative_url, *basecoll_url, *req_url;
-  int i;
   svn_error_t *err;
 
   loc_ctx = apr_pcalloc(pool, sizeof(*loc_ctx));
   loc_ctx->pool = pool;
+  loc_ctx->path = path;
+  loc_ctx->peg_revision = peg_revision;
+  loc_ctx->location_revisions = location_revisions;
   loc_ctx->done = FALSE;
   loc_ctx->paths = apr_hash_make(loc_ctx->pool);
 
   *locations = loc_ctx->paths;
 
-  buckets = serf_bucket_aggregate_create(session->bkt_alloc);
-
-  svn_ra_serf__add_open_tag_buckets(buckets, session->bkt_alloc,
-                                    "S:get-locations",
-                                    "xmlns:S", SVN_XML_NAMESPACE,
-                                    "xmlns:D", "DAV:",
-                                    NULL);
-
-  svn_ra_serf__add_tag_buckets(buckets,
-                               "S:path", path,
-                               session->bkt_alloc);
-
-  svn_ra_serf__add_tag_buckets(buckets,
-                               "S:peg-revision", apr_ltoa(pool, peg_revision),
-                               session->bkt_alloc);
-
-  for (i = 0; i < location_revisions->nelts; i++)
-    {
-      svn_revnum_t rev = APR_ARRAY_IDX(location_revisions, i, svn_revnum_t);
-      svn_ra_serf__add_tag_buckets(buckets,
-                                   "S:location-revision", apr_ltoa(pool, rev),
-                                   session->bkt_alloc);
-    }
-
-  svn_ra_serf__add_close_tag_buckets(buckets, session->bkt_alloc,
-                                     "S:get-locations");
-
   SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
                                          NULL, NULL, peg_revision, NULL,
                                          pool));
@@ -236,7 +254,8 @@ svn_ra_serf__get_locations(svn_ra_sessio
 
   handler->method = "REPORT";
   handler->path = req_url;
-  handler->body_buckets = buckets;
+  handler->body_delegate = create_get_locations_body;
+  handler->body_delegate_baton = loc_ctx;
   handler->body_type = "text/xml";
   handler->conn = session->conns[0];
   handler->session = session;

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/getlocationsegments.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/getlocationsegments.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/getlocationsegments.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/getlocationsegments.c Tue Aug 10 22:07:24 2010
@@ -40,6 +40,12 @@
 
 
 typedef struct {
+  /* parameters set by our caller */
+  svn_revnum_t peg_revision;
+  svn_revnum_t start_rev;
+  svn_revnum_t end_rev;
+  const char *path;
+
   /* location segment callback function/baton */
   svn_location_segment_receiver_t receiver;
   void *receiver_baton;
@@ -120,6 +126,46 @@ end_gls(svn_ra_serf__xml_parser_t *parse
   return SVN_NO_ERROR;
 }
 
+static serf_bucket_t *
+create_gls_body(void *baton,
+                serf_bucket_alloc_t *alloc,
+                apr_pool_t *pool)
+{
+  serf_bucket_t *buckets;
+  gls_context_t *gls_ctx = baton;
+
+  buckets = serf_bucket_aggregate_create(alloc);
+
+  svn_ra_serf__add_open_tag_buckets(buckets, alloc,
+                                    "S:get-location-segments",
+                                    "xmlns:S", SVN_XML_NAMESPACE,
+                                    NULL);
+
+  svn_ra_serf__add_tag_buckets(buckets,
+                               "S:path", gls_ctx->path,
+                               alloc);
+
+  svn_ra_serf__add_tag_buckets(buckets,
+                               "S:peg-revision",
+                               apr_ltoa(pool, gls_ctx->peg_revision),
+                               alloc);
+
+  svn_ra_serf__add_tag_buckets(buckets,
+                               "S:start-revision",
+                               apr_ltoa(pool, gls_ctx->start_rev),
+                               alloc);
+
+  svn_ra_serf__add_tag_buckets(buckets,
+                               "S:end-revision",
+                               apr_ltoa(pool, gls_ctx->end_rev),
+                               alloc);
+
+  svn_ra_serf__add_close_tag_buckets(buckets, alloc,
+                                     "S:get-location-segments");
+
+  return buckets;
+}
+
 svn_error_t *
 svn_ra_serf__get_location_segments(svn_ra_session_t *ra_session,
                                    const char *path,
@@ -134,46 +180,20 @@ svn_ra_serf__get_location_segments(svn_r
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
   svn_ra_serf__xml_parser_t *parser_ctx;
-  serf_bucket_t *buckets;
   const char *relative_url, *basecoll_url, *req_url;
   svn_error_t *err;
 
   gls_ctx = apr_pcalloc(pool, sizeof(*gls_ctx));
+  gls_ctx->path = path;
+  gls_ctx->peg_revision = peg_revision;
+  gls_ctx->start_rev = start_rev;
+  gls_ctx->end_rev = end_rev;
   gls_ctx->receiver = receiver;
   gls_ctx->receiver_baton = receiver_baton;
   gls_ctx->subpool = svn_pool_create(pool);
   gls_ctx->inside_report = FALSE;
   gls_ctx->done = FALSE;
 
-  buckets = serf_bucket_aggregate_create(session->bkt_alloc);
-
-  svn_ra_serf__add_open_tag_buckets(buckets, session->bkt_alloc,
-                                    "S:get-location-segments",
-                                    "xmlns:S", SVN_XML_NAMESPACE,
-                                    NULL);
-
-  svn_ra_serf__add_tag_buckets(buckets,
-                               "S:path", path,
-                               session->bkt_alloc);
-
-  svn_ra_serf__add_tag_buckets(buckets,
-                               "S:peg-revision",
-                               apr_ltoa(pool, peg_revision),
-                               session->bkt_alloc);
-
-  svn_ra_serf__add_tag_buckets(buckets,
-                               "S:start-revision",
-                               apr_ltoa(pool, start_rev),
-                               session->bkt_alloc);
-
-  svn_ra_serf__add_tag_buckets(buckets,
-                               "S:end-revision",
-                               apr_ltoa(pool, end_rev),
-                               session->bkt_alloc);
-
-  svn_ra_serf__add_close_tag_buckets(buckets, session->bkt_alloc,
-                                     "S:get-location-segments");
-
   SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
                                          NULL, NULL, peg_revision, NULL, pool));
 
@@ -183,7 +203,8 @@ svn_ra_serf__get_location_segments(svn_r
 
   handler->method = "REPORT";
   handler->path = req_url;
-  handler->body_buckets = buckets;
+  handler->body_delegate = create_gls_body;
+  handler->body_delegate_baton = gls_ctx;
   handler->body_type = "text/xml";
   handler->conn = session->conns[0];
   handler->session = session;

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/getlocks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/getlocks.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/getlocks.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/getlocks.c Tue Aug 10 22:07:24 2010
@@ -76,6 +76,10 @@ typedef struct {
 typedef struct {
   apr_pool_t *pool;
 
+  /* target and requested depth of the operation. */
+  const char *path; 
+  svn_depth_t requested_depth;
+
   /* return hash */
   apr_hash_t *hash;
 
@@ -180,8 +184,32 @@ end_getlocks(svn_ra_serf__xml_parser_t *
   else if (state == LOCK &&
            strcmp(name.name, "lock") == 0)
     {
-      apr_hash_set(lock_ctx->hash, info->lock->path, APR_HASH_KEY_STRING,
-                   info->lock);
+      /* Filter out unwanted paths.  Since Subversion only allows
+         locks on files, we can treat depth=immediates the same as
+         depth=files for filtering purposes.  Meaning, we'll keep
+         this lock if:
+
+         a) its path is the very path we queried, or
+         b) we've asked for a fully recursive answer, or
+         c) we've asked for depth=files or depth=immediates, and this
+            lock is on an immediate child of our query path.
+      */
+      if ((strcmp(lock_ctx->path, info->lock->path) == 0)
+          || (lock_ctx->requested_depth == svn_depth_infinity))
+        {
+          apr_hash_set(lock_ctx->hash, info->lock->path,
+                       APR_HASH_KEY_STRING, info->lock);
+        }
+      else if ((lock_ctx->requested_depth == svn_depth_files) ||
+               (lock_ctx->requested_depth == svn_depth_immediates))
+        {
+          const char *rel_uri = svn_uri_is_child(lock_ctx->path,
+                                                 info->lock->path,
+                                                 info->pool);
+          if (rel_uri && (svn_path_component_count(rel_uri) == 1))
+            apr_hash_set(lock_ctx->hash, info->lock->path,
+                         APR_HASH_KEY_STRING, info->lock);
+        }
 
       svn_ra_serf__xml_pop_state(parser);
     }
@@ -272,13 +300,14 @@ create_getlocks_body(void *baton,
                      serf_bucket_alloc_t *alloc,
                      apr_pool_t *pool)
 {
+  lock_context_t *lock_ctx = baton;
   serf_bucket_t *buckets;
 
   buckets = serf_bucket_aggregate_create(alloc);
 
-  svn_ra_serf__add_open_tag_buckets(buckets, alloc, "S:get-locks-report",
-                                    "xmlns:S", SVN_XML_NAMESPACE,
-                                    NULL);
+  svn_ra_serf__add_open_tag_buckets(
+    buckets, alloc, "S:get-locks-report", "xmlns:S", SVN_XML_NAMESPACE,
+    "depth", svn_depth_to_word(lock_ctx->requested_depth), NULL);
   svn_ra_serf__add_close_tag_buckets(buckets, alloc, "S:get-locks-report");
 
   return buckets;
@@ -288,22 +317,27 @@ svn_error_t *
 svn_ra_serf__get_locks(svn_ra_session_t *ra_session,
                        apr_hash_t **locks,
                        const char *path,
+                       svn_depth_t depth,
                        apr_pool_t *pool)
 {
   lock_context_t *lock_ctx;
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
   svn_ra_serf__xml_parser_t *parser_ctx;
-  const char *req_url;
+  const char *req_url, *rel_path;
   int status_code;
 
+  req_url = svn_path_url_add_component2(session->repos_url.path, path, pool);
+  SVN_ERR(svn_ra_serf__get_relative_path(&rel_path, req_url, session,
+                                         NULL, pool));
+
   lock_ctx = apr_pcalloc(pool, sizeof(*lock_ctx));
   lock_ctx->pool = pool;
+  lock_ctx->path = apr_pstrcat(pool, "/", rel_path, NULL);
+  lock_ctx->requested_depth = depth;
   lock_ctx->hash = apr_hash_make(pool);
   lock_ctx->done = FALSE;
 
-  req_url = svn_path_url_add_component2(session->repos_url.path, path, pool);
-
   handler = apr_pcalloc(pool, sizeof(*handler));
 
   handler->method = "REPORT";

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/locks.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/locks.c Tue Aug 10 22:07:24 2010
@@ -451,6 +451,16 @@ create_getlock_body(void *baton,
   return buckets;
 }
 
+static apr_status_t
+setup_getlock_headers(serf_bucket_t *headers,
+                      void *baton,
+                      apr_pool_t *pool)
+{
+  serf_bucket_headers_set(headers, "Depth", "0");
+
+  return APR_SUCCESS;
+}
+
 static serf_bucket_t*
 create_lock_body(void *baton,
                  serf_bucket_alloc_t *alloc,
@@ -529,23 +539,14 @@ svn_ra_serf__get_lock(svn_ra_session_t *
   handler->body_delegate = create_getlock_body;
   handler->body_delegate_baton = lock_ctx;
 
+  handler->header_delegate = setup_getlock_headers;
+  handler->header_delegate_baton = lock_ctx;
+
   handler->response_handler = handle_lock;
   handler->response_baton = parser_ctx;
 
   svn_ra_serf__request_create(handler);
   err = svn_ra_serf__context_run_wait(&lock_ctx->done, session, pool);
-  if (err)
-    {
-      /* A 403 forbidden error indicates there's no lock, which we can ignore
-         here.
-
-         ### BH: Is this assumption really ok or are we ignoring real errors? */
-      if (lock_ctx->status_code == 403)
-        {
-          svn_error_clear(err);
-          err = NULL;
-        }
-    }
 
   if (status_code == 404)
     {

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/log.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/log.c Tue Aug 10 22:07:24 2010
@@ -86,10 +86,16 @@ typedef struct {
   apr_pool_t *pool;
 
   /* parameters set by our caller */
+  const apr_array_header_t *paths;
+  svn_revnum_t start;
+  svn_revnum_t end;
   int limit;
+  svn_boolean_t changed_paths;
+  svn_boolean_t strict_node_history;
+  svn_boolean_t include_merged_revisions;
+  const apr_array_header_t *revprops;
   int nest_level; /* used to track mergeinfo nesting levels */
   int count; /* only incremented when nest_level == 0 */
-  svn_boolean_t changed_paths;
 
   /* are we done? */
   svn_boolean_t done;
@@ -453,80 +459,137 @@ cdata_log(svn_ra_serf__xml_parser_t *par
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_ra_serf__get_log(svn_ra_session_t *ra_session,
-                     const apr_array_header_t *paths,
-                     svn_revnum_t start,
-                     svn_revnum_t end,
-                     int limit,
-                     svn_boolean_t discover_changed_paths,
-                     svn_boolean_t strict_node_history,
-                     svn_boolean_t include_merged_revisions,
-                     const apr_array_header_t *revprops,
-                     svn_log_entry_receiver_t receiver,
-                     void *receiver_baton,
-                     apr_pool_t *pool)
+static serf_bucket_t *
+create_log_body(void *baton,
+                serf_bucket_alloc_t *alloc,
+                apr_pool_t *pool)
 {
-  log_context_t *log_ctx;
-  svn_ra_serf__session_t *session = ra_session->priv;
-  svn_ra_serf__handler_t *handler;
-  svn_ra_serf__xml_parser_t *parser_ctx;
   serf_bucket_t *buckets;
-  svn_boolean_t want_custom_revprops;
-  svn_revnum_t peg_rev;
-  const char *relative_url, *basecoll_url, *req_url;
+  log_context_t *log_ctx = baton;
 
-  log_ctx = apr_pcalloc(pool, sizeof(*log_ctx));
-  log_ctx->pool = pool;
-  log_ctx->receiver = receiver;
-  log_ctx->receiver_baton = receiver_baton;
-  log_ctx->limit = limit;
-  log_ctx->nest_level = 0;
-  log_ctx->changed_paths = discover_changed_paths;
-  log_ctx->done = FALSE;
+  buckets = serf_bucket_aggregate_create(alloc);
 
-  buckets = serf_bucket_aggregate_create(session->bkt_alloc);
-
-  svn_ra_serf__add_open_tag_buckets(buckets, session->bkt_alloc,
+  svn_ra_serf__add_open_tag_buckets(buckets, alloc,
                                     "S:log-report",
                                     "xmlns:S", SVN_XML_NAMESPACE,
                                     NULL);
 
   svn_ra_serf__add_tag_buckets(buckets,
-                               "S:start-revision", apr_ltoa(pool, start),
-                               session->bkt_alloc);
+                               "S:start-revision",
+                               apr_ltoa(pool, log_ctx->start),
+                               alloc);
   svn_ra_serf__add_tag_buckets(buckets,
-                               "S:end-revision", apr_ltoa(pool, end),
-                               session->bkt_alloc);
+                               "S:end-revision",
+                               apr_ltoa(pool, log_ctx->end),
+                               alloc);
 
-  if (limit)
+  if (log_ctx->limit)
     {
       svn_ra_serf__add_tag_buckets(buckets,
-                                   "S:limit", apr_ltoa(pool, limit),
-                                   session->bkt_alloc);
+                                   "S:limit", apr_ltoa(pool, log_ctx->limit),
+                                   alloc);
     }
 
-  if (discover_changed_paths)
+  if (log_ctx->changed_paths)
     {
       svn_ra_serf__add_tag_buckets(buckets,
                                    "S:discover-changed-paths", NULL,
-                                   session->bkt_alloc);
+                                   alloc);
     }
 
-  if (strict_node_history)
+  if (log_ctx->strict_node_history)
     {
       svn_ra_serf__add_tag_buckets(buckets,
                                    "S:strict-node-history", NULL,
-                                   session->bkt_alloc);
+                                   alloc);
     }
 
-  if (include_merged_revisions)
+  if (log_ctx->include_merged_revisions)
     {
       svn_ra_serf__add_tag_buckets(buckets,
                                    "S:include-merged-revisions", NULL,
-                                   session->bkt_alloc);
+                                   alloc);
     }
 
+  if (log_ctx->revprops)
+    {
+      int i;
+      for (i = 0; i < log_ctx->revprops->nelts; i++)
+        {
+          char *name = APR_ARRAY_IDX(log_ctx->revprops, i, char *);
+          svn_ra_serf__add_tag_buckets(buckets,
+                                       "S:revprop", name,
+                                       alloc);
+        }
+      if (log_ctx->revprops->nelts == 0)
+        {
+          svn_ra_serf__add_tag_buckets(buckets,
+                                       "S:no-revprops", NULL,
+                                       alloc);
+        }
+    }
+  else
+    {
+      svn_ra_serf__add_tag_buckets(buckets,
+                                   "S:all-revprops", NULL,
+                                   alloc);
+    }
+
+  if (log_ctx->paths)
+    {
+      int i;
+      for (i = 0; i < log_ctx->paths->nelts; i++)
+        {
+          svn_ra_serf__add_tag_buckets(buckets,
+                                       "S:path", APR_ARRAY_IDX(log_ctx->paths, i,
+                                                               const char*),
+                                       alloc);
+        }
+    }
+
+  svn_ra_serf__add_close_tag_buckets(buckets, alloc,
+                                     "S:log-report");
+
+  return buckets;
+}
+
+svn_error_t *
+svn_ra_serf__get_log(svn_ra_session_t *ra_session,
+                     const apr_array_header_t *paths,
+                     svn_revnum_t start,
+                     svn_revnum_t end,
+                     int limit,
+                     svn_boolean_t discover_changed_paths,
+                     svn_boolean_t strict_node_history,
+                     svn_boolean_t include_merged_revisions,
+                     const apr_array_header_t *revprops,
+                     svn_log_entry_receiver_t receiver,
+                     void *receiver_baton,
+                     apr_pool_t *pool)
+{
+  log_context_t *log_ctx;
+  svn_ra_serf__session_t *session = ra_session->priv;
+  svn_ra_serf__handler_t *handler;
+  svn_ra_serf__xml_parser_t *parser_ctx;
+  svn_boolean_t want_custom_revprops;
+  svn_revnum_t peg_rev;
+  const char *relative_url, *basecoll_url, *req_url;
+
+  log_ctx = apr_pcalloc(pool, sizeof(*log_ctx));
+  log_ctx->pool = pool;
+  log_ctx->receiver = receiver;
+  log_ctx->receiver_baton = receiver_baton;
+  log_ctx->paths = paths;
+  log_ctx->start = start;
+  log_ctx->end = end;
+  log_ctx->limit = limit;
+  log_ctx->changed_paths = discover_changed_paths;
+  log_ctx->strict_node_history = strict_node_history;
+  log_ctx->include_merged_revisions = include_merged_revisions;
+  log_ctx->revprops = revprops;
+  log_ctx->nest_level = 0;
+  log_ctx->done = FALSE;
+
   want_custom_revprops = FALSE;
   if (revprops)
     {
@@ -534,9 +597,6 @@ svn_ra_serf__get_log(svn_ra_session_t *r
       for (i = 0; i < revprops->nelts; i++)
         {
           char *name = APR_ARRAY_IDX(revprops, i, char *);
-          svn_ra_serf__add_tag_buckets(buckets,
-                                       "S:revprop", name,
-                                       session->bkt_alloc);
           if (strcmp(name, SVN_PROP_REVISION_AUTHOR) == 0)
             log_ctx->want_author = TRUE;
           else if (strcmp(name, SVN_PROP_REVISION_DATE) == 0)
@@ -546,18 +606,9 @@ svn_ra_serf__get_log(svn_ra_session_t *r
           else
             want_custom_revprops = TRUE;
         }
-      if (revprops->nelts == 0)
-        {
-          svn_ra_serf__add_tag_buckets(buckets,
-                                       "S:no-revprops", NULL,
-                                       session->bkt_alloc);
-        }
     }
   else
     {
-      svn_ra_serf__add_tag_buckets(buckets,
-                                   "S:all-revprops", NULL,
-                                   session->bkt_alloc);
       log_ctx->want_author = log_ctx->want_date = log_ctx->want_message = TRUE;
       want_custom_revprops = TRUE;
     }
@@ -572,21 +623,6 @@ svn_ra_serf__get_log(svn_ra_session_t *r
                                 _("Server does not support custom revprops"
                                   " via log"));
     }
-
-  if (paths)
-    {
-      int i;
-      for (i = 0; i < paths->nelts; i++)
-        {
-          svn_ra_serf__add_tag_buckets(buckets,
-                                       "S:path", APR_ARRAY_IDX(paths, i,
-                                                               const char*),
-                                       session->bkt_alloc);
-        }
-    }
-
-  svn_ra_serf__add_close_tag_buckets(buckets, session->bkt_alloc,
-                                     "S:log-report");
   /* At this point, we may have a deleted file.  So, we'll match ra_neon's
    * behavior and use the larger of start or end as our 'peg' rev.
    */
@@ -601,7 +637,8 @@ svn_ra_serf__get_log(svn_ra_session_t *r
 
   handler->method = "REPORT";
   handler->path = req_url;
-  handler->body_buckets = buckets;
+  handler->body_delegate = create_log_body;
+  handler->body_delegate_baton = log_ctx;
   handler->body_type = "text/xml";
   handler->conn = session->conns[0];
   handler->session = session;

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/mergeinfo.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/mergeinfo.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/mergeinfo.c Tue Aug 10 22:07:24 2010
@@ -210,11 +210,9 @@ create_mergeinfo_body(void *baton,
     {
       for (i = 0; i < mergeinfo_ctx->paths->nelts; i++)
         {
-          const char *this_path =
-            apr_xml_quote_string(pool,
-                                 APR_ARRAY_IDX(mergeinfo_ctx->paths,
-                                               i, const char *),
-                                 0);
+          const char *this_path = APR_ARRAY_IDX(mergeinfo_ctx->paths,
+                                                i, const char *);
+
           svn_ra_serf__add_tag_buckets(body_bkt, "S:" SVN_DAV__PATH,
                                        this_path, alloc);
         }

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h Tue Aug 10 22:07:24 2010
@@ -78,7 +78,7 @@ typedef enum
 } svn_ra_serf__authn_types;
 
 /* A serf connection and optionally associated SSL context.  */
-typedef struct {
+typedef struct svn_ra_serf__connection_t {
   /* Our connection to a server. */
   serf_connection_t *conn;
 
@@ -254,7 +254,7 @@ struct svn_ra_serf__session_t {
 /*
  * Structure which represents a DAV element with a NAMESPACE and NAME.
  */
-typedef struct {
+typedef struct svn_ra_serf__dav_props_t {
   /* Element namespace */
   const char *namespace;
   /* Element name */
@@ -466,25 +466,13 @@ typedef apr_status_t
  * Structure that can be passed to our default handler to guide the
  * execution of the request through its lifecycle.
  */
-typedef struct {
+typedef struct svn_ra_serf__handler_t {
   /* The HTTP method string of the request */
   const char *method;
 
   /* The resource to the execute the method on. */
   const char *path;
 
-  /* The request's body buckets.
-   *
-   * May be NULL if there is no body to send or ->body_delegate is set.
-   *
-   * Using the body_delegate function is preferred as it delays the
-   * creation of the body until we're about to deliver the request
-   * instead of creating it earlier.
-   *
-   * @see svn_ra_serf__request_body_delegate_t
-   */
-  serf_bucket_t *body_buckets;
-
   /* The content-type of the request body. */
   const char *body_type;
 
@@ -522,6 +510,9 @@ typedef struct {
    *
    * It will be executed after the request has been set up but before it is
    * delivered.
+   *
+   * May be NULL if there is no body to send.
+   *
    */
   svn_ra_serf__request_body_delegate_t body_delegate;
   void *body_delegate_baton;
@@ -529,9 +520,6 @@ typedef struct {
   /* The connection and session to be used for this request. */
   svn_ra_serf__connection_t *conn;
   svn_ra_serf__session_t *session;
-
-  /* Marks whether a snapshot was set on the body bucket. */
-  svn_boolean_t body_snapshot_set;
 } svn_ra_serf__handler_t;
 
 /*
@@ -664,7 +652,7 @@ struct svn_ra_serf__xml_parser_t {
 /*
  * Parses a server-side error message into a local Subversion error.
  */
-typedef struct {
+typedef struct svn_ra_serf__server_error_t {
   /* Our local representation of the error. */
   svn_error_t *error;
 
@@ -691,7 +679,7 @@ typedef struct {
 } svn_ra_serf__server_error_t;
 
 /* A simple request context that can be passed to handle_status_only. */
-typedef struct {
+typedef struct svn_ra_serf__simple_request_context_t {
   /* The HTTP status code of the response */
   int status;
 
@@ -955,12 +943,16 @@ svn_ra_serf__retrieve_props(apr_hash_t *
                             const svn_ra_serf__dav_props_t *props,
                             apr_pool_t *pool);
 
-/* ### TODO: doco. */
+/* Set PROPS for PATH at REV revision with a NS:NAME VAL.
+ *
+ * The POOL governs allocation.
+ */
 void
 svn_ra_serf__set_ver_prop(apr_hash_t *props,
                           const char *path, svn_revnum_t rev,
                           const char *ns, const char *name,
                           const svn_string_t *val, apr_pool_t *pool);
+#define svn_ra_serf__set_rev_prop svn_ra_serf__set_ver_prop
 
 /** Property walker functions **/
 
@@ -1037,16 +1029,6 @@ svn_ra_serf__get_prop(apr_hash_t *props,
                       const char *ns,
                       const char *name);
 
-/* Set PROPS for PATH at REV revision with a NS:NAME VAL.
- *
- * The POOL governs allocation.
- */
-void
-svn_ra_serf__set_rev_prop(apr_hash_t *props,
-                          const char *path, svn_revnum_t rev,
-                          const char *ns, const char *name,
-                          const svn_string_t *val, apr_pool_t *pool);
-
 /* Same as set_rev_prop, but sets it for the unknown revision. */
 void
 svn_ra_serf__set_prop(apr_hash_t *props, const char *path,
@@ -1365,6 +1347,7 @@ svn_error_t *
 svn_ra_serf__get_locks(svn_ra_session_t *ra_session,
                        apr_hash_t **locks,
                        const char *path,
+                       svn_depth_t depth,
                        apr_pool_t *pool);
 
 svn_error_t * svn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/update.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/update.c Tue Aug 10 22:07:24 2010
@@ -24,6 +24,7 @@
 
 
 #define APR_WANT_STRFUNC
+#include <apr_version.h>
 #include <apr_want.h>
 
 #include <apr_uri.h>
@@ -44,6 +45,7 @@
 #include "svn_props.h"
 
 #include "svn_private_config.h"
+#include "private/svn_dep_compat.h"
 
 #include "ra_serf.h"
 #include "../libsvn_ra/ra_loader.h"
@@ -308,8 +310,12 @@ struct report_context_t {
   const svn_delta_editor_t *update_editor;
   void *update_baton;
 
-  /* The request body for the REPORT. */
-  serf_bucket_t *buckets;
+  /* The file holding request body for the REPORT.
+   *
+   * ### todo: It will be better for performance to store small
+   * request bodies (like 4k) in memory and bigger bodies on disk.
+   */
+  apr_file_t *body_file;
 
   /* root directory object */
   report_dir_t *root_dir;
@@ -2002,6 +2008,18 @@ cdata_report(svn_ra_serf__xml_parser_t *
 
 /** Editor callbacks given to callers to create request body */
 
+/* Helper to create simple xml tag without attributes. */
+static void
+make_simple_xml_tag(svn_stringbuf_t **buf_p,
+                    const char *tagname,
+                    const char *cdata,
+                    apr_pool_t *pool)
+{
+  svn_xml_make_open_tag(buf_p, pool, svn_xml_protect_pcdata, tagname, NULL);
+  svn_xml_escape_cdata_cstring(buf_p, cdata, pool);
+  svn_xml_make_close_tag(buf_p, pool, tagname);
+}
+
 static svn_error_t *
 set_path(void *report_baton,
          const char *path,
@@ -2012,34 +2030,29 @@ set_path(void *report_baton,
          apr_pool_t *pool)
 {
   report_context_t *report = report_baton;
+  svn_stringbuf_t *buf = NULL;
+
+  svn_xml_make_open_tag(&buf, pool, svn_xml_protect_pcdata, "S:entry",
+                        "rev", apr_ltoa(pool, revision),
+                        "lock-token", lock_token,
+                        "depth", svn_depth_to_word(depth),
+                        "start-empty", start_empty ? "true" : NULL,
+                        NULL);
+  svn_xml_escape_cdata_cstring(&buf, path, pool);
+  svn_xml_make_close_tag(&buf, pool, "S:entry");
 
-  /* Copy data to report pool. */
-  lock_token = apr_pstrdup(report->pool, lock_token);
-  path  = apr_pstrdup(report->pool, path);
-
-  svn_ra_serf__add_open_tag_buckets(report->buckets, report->sess->bkt_alloc,
-                                    "S:entry",
-                                    "rev", apr_ltoa(report->pool, revision),
-                                    "lock-token", lock_token,
-                                    "depth", svn_depth_to_word(depth),
-                                    "start-empty", start_empty ? "true" : NULL,
-                                    NULL);
+  SVN_ERR(svn_io_file_write_full(report->body_file, buf->data, buf->len,
+                                 NULL, pool));
 
   if (lock_token)
     {
       apr_hash_set(report->lock_path_tokens,
-                   path,
+                   apr_pstrdup(report->pool, path),
                    APR_HASH_KEY_STRING,
-                   lock_token);
+                   apr_pstrdup(report->pool, lock_token));
     }
 
-  svn_ra_serf__add_cdata_len_buckets(report->buckets, report->sess->bkt_alloc,
-                                     path, strlen(path));
-
-  svn_ra_serf__add_close_tag_buckets(report->buckets, report->sess->bkt_alloc,
-                                     "S:entry");
-
-  return APR_SUCCESS;
+  return SVN_NO_ERROR;
 }
 
 static svn_error_t *
@@ -2048,11 +2061,14 @@ delete_path(void *report_baton,
             apr_pool_t *pool)
 {
   report_context_t *report = report_baton;
+  svn_stringbuf_t *buf = NULL;
 
-  svn_ra_serf__add_tag_buckets(report->buckets, "S:missing",
-                               apr_pstrdup(report->pool, path),
-                               report->sess->bkt_alloc);
-  return APR_SUCCESS;
+  make_simple_xml_tag(&buf, "S:missing", path, pool);
+
+  SVN_ERR(svn_io_file_write_full(report->body_file, buf->data, buf->len,
+                                 NULL, pool));
+
+  return SVN_NO_ERROR;
 }
 
 static svn_error_t *
@@ -2069,6 +2085,7 @@ link_path(void *report_baton,
   const char *link, *report_target;
   apr_uri_t uri;
   apr_status_t status;
+  svn_stringbuf_t *buf = NULL;
 
   /* We need to pass in the baseline relative path.
    *
@@ -2086,34 +2103,29 @@ link_path(void *report_baton,
   SVN_ERR(svn_ra_serf__get_relative_path(&link, uri.path, report->sess,
                                          NULL, pool));
 
-  /* Copy parameters to reporter's pool. */
-  lock_token = apr_pstrdup(report->pool, lock_token);
-  link = apr_pstrcat(report->pool, "/", link, NULL);
-  path = apr_pstrdup(report->pool, path);
-
-  svn_ra_serf__add_open_tag_buckets(report->buckets, report->sess->bkt_alloc,
-                                    "S:entry",
-                                    "rev", apr_ltoa(report->pool, revision),
-                                    "lock-token", lock_token,
-                                    "depth", svn_depth_to_word(depth),
-                                    "start-empty", start_empty ? "true" : NULL,
-                                    "linkpath", link,
-                                    NULL);
+  link = apr_pstrcat(pool, "/", link, NULL);
+
+  svn_xml_make_open_tag(&buf, pool, svn_xml_protect_pcdata, "S:entry",
+                        "rev", apr_ltoa(pool, revision),
+                        "lock-token", lock_token,
+                        "depth", svn_depth_to_word(depth),
+                        "linkpath", link,
+                        "start-empty", start_empty ? "true" : NULL,
+                        NULL);
+  svn_xml_escape_cdata_cstring(&buf, path, pool);
+  svn_xml_make_close_tag(&buf, pool, "S:entry");
+
+  SVN_ERR(svn_io_file_write_full(report->body_file, buf->data, buf->len,
+                                 NULL, pool));
 
   if (lock_token)
     {
       apr_hash_set(report->lock_path_tokens,
-                   path,
+                   apr_pstrdup(report->pool, path),
                    APR_HASH_KEY_STRING,
-                   lock_token);
+                   apr_pstrdup(report->pool, lock_token));
     }
 
-  svn_ra_serf__add_cdata_len_buckets(report->buckets, report->sess->bkt_alloc,
-                                     path, strlen(path));
-
-  svn_ra_serf__add_close_tag_buckets(report->buckets, report->sess->bkt_alloc,
-                                     "S:entry");
-
   return APR_SUCCESS;
 }
 
@@ -2175,6 +2187,21 @@ open_connection_if_needed(svn_ra_serf__s
   return SVN_NO_ERROR;
 }
 
+/* Serf callback to create update request body bucket. */
+static serf_bucket_t *
+create_update_report_body(void *baton,
+                          serf_bucket_alloc_t *alloc,
+                          apr_pool_t *pool)
+{
+  report_context_t *report = baton;
+  apr_off_t offset;
+
+  offset = 0;
+  apr_file_seek(report->body_file, APR_SET, &offset);
+
+  return serf_bucket_file_create(report->body_file, alloc);
+}
+
 static svn_error_t *
 finish_report(void *report_baton,
               apr_pool_t *pool)
@@ -2188,9 +2215,25 @@ finish_report(void *report_baton,
   apr_status_t status;
   svn_boolean_t closed_root;
   int status_code, i;
+  svn_stringbuf_t *buf = NULL;
 
-  svn_ra_serf__add_close_tag_buckets(report->buckets, report->sess->bkt_alloc,
-                                     "S:update-report");
+  svn_xml_make_close_tag(&buf, pool, "S:update-report");
+  SVN_ERR(svn_io_file_write_full(report->body_file, buf->data, buf->len,
+                                 NULL, pool));
+
+  /* We need to flush the file, make it unbuffered (so that it can be
+   * zero-copied via mmap), and reset the position before attempting to
+   * deliver the file.
+   *
+   * N.B. If we have APR 1.3+, we can unbuffer the file to let us use mmap
+   * and zero-copy the PUT body.  However, on older APR versions, we can't
+   * check the buffer status; but serf will fall through and create a file
+   * bucket for us on the buffered svndiff handle.
+   */
+  apr_file_flush(report->body_file);
+#if APR_VERSION_AT_LEAST(1, 3, 0)
+  apr_file_buffer_set(report->body_file, NULL, 0);
+#endif
 
   SVN_ERR(svn_ra_serf__report_resource(&report_target, sess, NULL, pool));
 
@@ -2201,7 +2244,8 @@ finish_report(void *report_baton,
 
   handler->method = "REPORT";
   handler->path = report->path;
-  handler->body_buckets = report->buckets;
+  handler->body_delegate = create_update_report_body;
+  handler->body_delegate_baton = report;
   handler->body_type = "text/xml";
   handler->conn = sess->conns[0];
   handler->session = sess;
@@ -2430,6 +2474,7 @@ make_update_reporter(svn_ra_session_t *r
   svn_boolean_t has_target = *update_target != '\0';
   svn_boolean_t server_supports_depth;
   svn_ra_serf__session_t *sess = ra_session->priv;
+  svn_stringbuf_t *buf = NULL;
 
   SVN_ERR(svn_ra_serf__has_capability(ra_session, &server_supports_depth,
                                       SVN_RA_CAPABILITY_DEPTH, pool));
@@ -2471,65 +2516,53 @@ make_update_reporter(svn_ra_session_t *r
   *reporter = &ra_serf_reporter;
   *report_baton = report;
 
-  report->buckets = serf_bucket_aggregate_create(report->sess->bkt_alloc);
+  SVN_ERR(svn_io_open_unique_file3(&report->body_file, NULL, NULL,
+                                   svn_io_file_del_on_pool_cleanup,
+                                   report->pool, pool));
+
+  svn_xml_make_open_tag(&buf, pool, svn_xml_normal, "S:update-report",
+                        "xmlns:S", SVN_XML_NAMESPACE,
+                        NULL);
 
-  svn_ra_serf__add_open_tag_buckets(report->buckets, report->sess->bkt_alloc,
-                                    "S:update-report",
-                                    "xmlns:S", SVN_XML_NAMESPACE,
-                                    NULL);
-
-  svn_ra_serf__add_tag_buckets(report->buckets,
-                               "S:src-path", report->source,
-                               report->sess->bkt_alloc);
+  make_simple_xml_tag(&buf, "S:src-path", report->source, pool);
 
   if (SVN_IS_VALID_REVNUM(report->target_rev))
     {
-      svn_ra_serf__add_tag_buckets(report->buckets,
-                                   "S:target-revision",
-                                   apr_ltoa(pool, report->target_rev),
-                                   report->sess->bkt_alloc);
+      make_simple_xml_tag(&buf, "S:target-revision",
+                          apr_ltoa(pool, report->target_rev), pool);
     }
 
   if (report->destination && *report->destination)
     {
-      svn_ra_serf__add_tag_buckets(report->buckets,
-                                   "S:dst-path",
-                                   report->destination,
-                                   report->sess->bkt_alloc);
+      make_simple_xml_tag(&buf, "S:dst-path", report->destination, pool);
     }
 
   if (report->update_target && *report->update_target)
     {
-      svn_ra_serf__add_tag_buckets(report->buckets,
-                                   "S:update-target", report->update_target,
-                                   report->sess->bkt_alloc);
+      make_simple_xml_tag(&buf, "S:update-target", report->update_target,
+                          pool);
     }
 
   if (report->ignore_ancestry)
     {
-      svn_ra_serf__add_tag_buckets(report->buckets,
-                                   "S:ignore-ancestry", "yes",
-                                   report->sess->bkt_alloc);
+      make_simple_xml_tag(&buf, "S:ignore-ancestry", "yes", pool);
     }
 
   if (report->send_copyfrom_args)
     {
-      svn_ra_serf__add_tag_buckets(report->buckets,
-                                   "S:send-copyfrom-args", "yes",
-                                   report->sess->bkt_alloc);
+      make_simple_xml_tag(&buf, "S:send-copyfrom-args", "yes", pool);
     }
 
   /* Old servers know "recursive" but not "depth"; help them DTRT. */
   if (depth == svn_depth_files || depth == svn_depth_empty)
     {
-      svn_ra_serf__add_tag_buckets(report->buckets,
-                                   "S:recursive", "no",
-                                   report->sess->bkt_alloc);
+      make_simple_xml_tag(&buf, "S:recursive", "no", pool);
     }
 
-  svn_ra_serf__add_tag_buckets(report->buckets,
-                               "S:depth", svn_depth_to_word(depth),
-                               report->sess->bkt_alloc);
+  make_simple_xml_tag(&buf, "S:depth", svn_depth_to_word(depth), pool);
+
+  SVN_ERR(svn_io_file_write_full(report->body_file, buf->data, buf->len,
+                                 NULL, pool));
 
   return SVN_NO_ERROR;
 }



Mime
View raw message