Modified: 
subversion/branches/remove-log-addressing/subversion/include/svn_repos.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/include/svn_repos.h?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/include/svn_repos.h 
(original)
+++ subversion/branches/remove-log-addressing/subversion/include/svn_repos.h 
Mon Feb  9 11:23:39 2015
@@ -287,7 +287,14 @@ typedef enum svn_repos_notify_warning_t
    *
    * @since New in 1.9.
    */
-  svn_repos_notify_warning_mergeinfo_collision
+  svn_repos_notify_warning_mergeinfo_collision,
+
+  /**
+   * Detected invalid mergeinfo.
+   *
+   * @since New in 1.9.
+   */
+  svn_repos_notify_warning_invalid_mergeinfo
 } svn_repos_notify_warning_t;
 
 /**
@@ -1491,10 +1498,9 @@ svn_repos_replay(svn_fs_root_t *root,
  * filesystem of @a repos, beginning at location 'rev:@a base_path',
  * where "rev" is the argument given to open_root().
  *
- * @a repos is a previously opened repository.  @a repos_url is the
+ * @a repos is a previously opened repository.  @a repos_url_decoded is the
  * decoded URL to the base of the repository, and is used to check
- * copyfrom paths.  copyfrom paths passed to the editor must be full,
- * URI-encoded, URLs.  @a txn is a filesystem transaction object to use
+ * copyfrom paths.  @a txn is a filesystem transaction object to use
  * during the commit, or @c NULL to indicate that this function should
  * create (and fully manage) a new transaction.
  *
@@ -1530,15 +1536,19 @@ svn_repos_replay(svn_fs_root_t *root,
  *
  * @since New in 1.5.
  *
- * @note Yes, @a repos_url is a <em>decoded</em> URL.  We realize
+ * @note Yes, @a repos_url_decoded is a <em>decoded</em> URL.  We realize
  * that's sorta wonky.  Sorry about that.
+ *
+ * @note Like most commit editors, the returned editor requires that the
+ * @c copyfrom_path parameter passed to its @c add_file and @c add_directory
+ * methods is a full, URI-encoded URL, not a relative path.
  */
 svn_error_t *
 svn_repos_get_commit_editor5(const svn_delta_editor_t **editor,
                              void **edit_baton,
                              svn_repos_t *repos,
                              svn_fs_txn_t *txn,
-                             const char *repos_url,
+                             const char *repos_url_decoded,
                              const char *base_path,
                              apr_hash_t *revprop_table,
                              svn_commit_callback2_t commit_callback,
@@ -3086,7 +3096,7 @@ svn_repos_load_fs5(svn_repos_t *repos,
 /** Similar to svn_repos_load_fs5(), but with @a ignore_dates
  * always passed as FALSE.
  *
- * @since New in 1.9.
+ * @since New in 1.8.
  * @deprecated Provided for backward compatibility with the 1.8 API.
  */
 SVN_DEPRECATED
@@ -3333,20 +3343,65 @@ svn_repos_parse_dumpstream3(svn_stream_t
  * @a end_rev).  They refer to dump stream revision numbers rather than
  * committed revision numbers.
  *
- * If @a use_history is set, then the parser will require relative
- * 'copyfrom' history to exist in the repository when it encounters
- * nodes that are added-with-history.
+ * If @a use_history is true, then when the parser encounters a node that
+ * is added-with-history, it will require 'copy-from' history to exist in
+ * the repository at the relative (adjusted) copy-from revision and path.
+ * It will perform a copy from that source location, and will fail if no
+ * suitable source exists there. If @a use_history is false, then it will
+ * instead convert every copy to a plain add.
+ *
+ * ### The 'use_history=FALSE' case is unused and untested in Subversion.
+ *     It seems to me it would not work with a deltas dumpfile (a driver
+ *     that calls the @c apply_textdelta method), as it would not have
+ *     access to the delta base text.
+ *
+ * If @a use_pre_commit_hook is set, call the repository's pre-commit
+ * hook before committing each loaded revision.
+ *
+ * If @a use_post_commit_hook is set, call the repository's
+ * post-commit hook after committing each loaded revision.
  *
  * If @a validate_props is set, then validate Subversion revision and
  * node properties (those in the svn: namespace) against established
  * rules for those things.
  *
+ * If @a ignore_dates is set, ignore any revision datestamps found in
+ * @a dumpstream, allowing the revisions created by the load process
+ * to be stamped as if they were newly created via the normal commit
+ * process.
+ *
  * If @a parent_dir is not NULL, then the parser will reparent all the
  * loaded nodes, from root to @a parent_dir.  The directory @a parent_dir
  * must be an existing directory in the repository.
  *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_repos_get_fs_build_parser5(const svn_repos_parse_fns3_t **callbacks,
+                               void **parse_baton,
+                               svn_repos_t *repos,
+                               svn_revnum_t start_rev,
+                               svn_revnum_t end_rev,
+                               svn_boolean_t use_history,
+                               svn_boolean_t validate_props,
+                               enum svn_repos_load_uuid uuid_action,
+                               const char *parent_dir,
+                               svn_boolean_t use_pre_commit_hook,
+                               svn_boolean_t use_post_commit_hook,
+                               svn_boolean_t ignore_dates,
+                               svn_repos_notify_func_t notify_func,
+                               void *notify_baton,
+                               apr_pool_t *pool);
+
+/**
+ * Similar to svn_repos_get_fs_build_parser5(), but with the
+ * @c use_pre_commit_hook, @c use_post_commit_hook and @c ignore_dates
+ * arguments all false.
+ *
  * @since New in 1.8.
+ * @deprecated Provided for backward compatibility with the 1.8 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_repos_get_fs_build_parser4(const svn_repos_parse_fns3_t **parser,
                                void **parse_baton,

Modified: 
subversion/branches/remove-log-addressing/subversion/include/svn_string.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/include/svn_string.h?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/include/svn_string.h 
(original)
+++ subversion/branches/remove-log-addressing/subversion/include/svn_string.h 
Mon Feb  9 11:23:39 2015
@@ -170,7 +170,11 @@ svn_string_createv(apr_pool_t *pool, con
 svn_boolean_t
 svn_string_isempty(const svn_string_t *str);
 
-/** Return a duplicate of @a original_string. */
+/** Return a duplicate of @a original_string.
+ *
+ * @since Since 1.9, @a original_string can be NULL in which case NULL will
+ * be returned.
+ */
 svn_string_t *
 svn_string_dup(const svn_string_t *original_string, apr_pool_t *pool);
 
@@ -308,7 +312,7 @@ void
 svn_stringbuf_appendbyte(svn_stringbuf_t *targetstr,
                          char byte);
 
-/** Append an array of bytes onto @a targetstr.
+/** Append the array of bytes @a bytes of length @a count onto @a targetstr.
  *
  * reallocs if necessary. @a targetstr is affected, nothing else is.
  *
@@ -345,14 +349,15 @@ void
 svn_stringbuf_appendcstr(svn_stringbuf_t *targetstr,
                          const char *cstr);
 
-/** Read @a count bytes from @a bytes and insert them into @a str at
- * position @a pos and following.  The resulting string will be
- * @c count+str->len bytes long.  If @c pos is larger or equal to the
- * number of bytes currently used in @a str,  simply append @a bytes.
+/** Insert into @a str at position @a pos an array of bytes @a bytes
+ * which is @a count bytes long.
+ *
+ * The resulting string will be @c count+str->len bytes long.  If
+ * @a pos is larger than or equal to @c str->len, simply append @a bytes.
  *
  * Reallocs if necessary. @a str is affected, nothing else is.
  *
- * @note The inserted string may be a sub-range if @a str.
+ * @note The inserted string may be a sub-range of @a str.
  *
  * @since New in 1.8.
  *
@@ -364,9 +369,10 @@ svn_stringbuf_insert(svn_stringbuf_t *st
                      const char *bytes,
                      apr_size_t count);
 
-/** Removes @a count bytes from @a str, starting at position @a pos.
- * If that range exceeds the current string data,  @a str gets truncated
- * at @a pos.  If the latter is larger or equal to @c str->pos, this will
+/** Remove @a count bytes from @a str, starting at position @a pos.
+ *
+ * If that range exceeds the current string data, truncate @a str at
+ * @a pos.  If @a pos is larger than or equal to @c str->len, this will
  * be a no-op.  Otherwise, the resulting string will be @c str->len-count
  * bytes long.
  *
@@ -378,8 +384,8 @@ svn_stringbuf_remove(svn_stringbuf_t *st
                      apr_size_t count);
 
 /** Replace in @a str the substring which starts at @a pos and is @a
- * old_count bytes long with a new substring @a bytes (which is @a
- * new_count bytes long).
+ * old_count bytes long with a new substring @a bytes which is @a
+ * new_count bytes long.
  *
  * This is faster but functionally equivalent to the following sequence:
  * @code

Modified: 
subversion/branches/remove-log-addressing/subversion/include/svn_version.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/include/svn_version.h?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/include/svn_version.h 
(original)
+++ subversion/branches/remove-log-addressing/subversion/include/svn_version.h 
Mon Feb  9 11:23:39 2015
@@ -82,7 +82,7 @@ extern "C" {
 
 /** Version tag: a string describing the version.
  *
- * This tag remains " (dev build)" in the repository so that we can
+ * This tag remains " (under development)" in the repository so that we can
  * always see from "svn --version" that the software has been built
  * from the repository rather than a "blessed" distribution.
  *
@@ -175,10 +175,25 @@ struct svn_version_t
  * Generate the implementation of a version query function.
  *
  * @since New in 1.1.
+ * @since Since 1.9, embeds a string into the compiled object
+ *        file that can be queried with the 'what' utility.
  */
-#define SVN_VERSION_BODY \
-  SVN_VERSION_DEFINE(versioninfo);              \
-  return &versioninfo
+#define SVN_VERSION_BODY            \
+  static struct versioninfo_t       \
+    {                               \
+      const char *const str;        \
+      const svn_version_t num;      \
+    } const versioninfo =           \
+    {                               \
+      "@(#)" SVN_VERSION,           \
+      {                             \
+        SVN_VER_MAJOR,              \
+        SVN_VER_MINOR,              \
+        SVN_VER_PATCH,              \
+        SVN_VER_NUMTAG              \
+      }                             \
+    };                              \
+  return &versioninfo.num
 
 /**
  * Check library version compatibility. Return #TRUE if the client's
@@ -291,6 +306,11 @@ typedef struct svn_version_extended_t sv
  * retrieve (for example, the OS release name, list of shared
  * libraries, etc.).  Use @a pool for all allocations.
  *
+ * @note This function may allocate significant auxiliary resources
+ * (memory and file descriptors) in @a pool.  It is recommended to
+ * copy the returned data to suitable longer-lived memory and clear
+ * @a pool after calling this function.
+ *
  * @since New in 1.8.
  */
 const svn_version_extended_t *

Modified: subversion/branches/remove-log-addressing/subversion/include/svn_wc.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/include/svn_wc.h?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/include/svn_wc.h 
(original)
+++ subversion/branches/remove-log-addressing/subversion/include/svn_wc.h Mon 
Feb  9 11:23:39 2015
@@ -907,13 +907,15 @@ svn_wc_external_item_dup(const svn_wc_ex
  *
  * Allocate the table, keys, and values in @a pool.
  *
- * Use @a parent_directory only in constructing error strings.
+ * @a defining_directory is the path or URL of the directory on which
+ * the svn:externals property corresponding to @a desc is set.
+ * @a defining_directory is only used when constructing error strings.
  *
  * @since New in 1.5.
  */
 svn_error_t *
 svn_wc_parse_externals_description3(apr_array_header_t **externals_p,
-                                    const char *parent_directory,
+                                    const char *defining_directory,
                                     const char *desc,
                                     svn_boolean_t canonicalize_url,
                                     apr_pool_t *pool);
@@ -7537,6 +7539,10 @@ svn_wc_relocate(const char *path,
  * If @a clear_changelists is TRUE, then changelist information for the
  * paths is cleared.
  *
+ * If @a metadata_only is TRUE, the working copy files are untouched, but
+ * if there are conflict marker files attached to these files these
+ * markers are removed.
+ *
  * If @a cancel_func is non-NULL, call it with @a cancel_baton at
  * various points during the reversion process.  If it returns an
  * error (typically #SVN_ERR_CANCELLED), return that error
@@ -7562,6 +7568,7 @@ svn_wc_revert5(svn_wc_context_t *wc_ctx,
                svn_boolean_t use_commit_times,
                const apr_array_header_t *changelist_filter,
                svn_boolean_t clear_changelists,
+               svn_boolean_t metadata_only,
                svn_cancel_func_t cancel_func,
                void *cancel_baton,
                svn_wc_notify_func2_t notify_func,
@@ -7569,7 +7576,7 @@ svn_wc_revert5(svn_wc_context_t *wc_ctx,
                apr_pool_t *scratch_pool);
 
 /** Similar to svn_wc_revert5() but with @a clear_changelists always set to
- * FALSE.
+ * FALSE and @a metadata_only set to FALSE.
  *
  * @since New in 1.7.
  * @deprecated Provided for backward compatibility with the 1.8 API.

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/add.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/add.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/add.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/add.c 
Mon Feb  9 11:23:39 2015
@@ -1270,11 +1270,7 @@ svn_client__make_local_parents(const cha
   else
     SVN_ERR(svn_io_dir_make(local_abspath, APR_OS_DEFAULT, scratch_pool));
 
-  /* Should no longer use svn_depth_empty to indicate that only the directory
-     itself is added, since it not only constraints the operation depth, but
-     also defines the depth of the target directory now. Moreover, the new
-     directory will have no children at all.*/
-  err = svn_client_add5(local_abspath, svn_depth_infinity, FALSE, FALSE, FALSE,
+  err = svn_client_add5(local_abspath, svn_depth_empty, FALSE, FALSE, FALSE,
                         make_parents, ctx, scratch_pool);
 
   /* If we created a new directory, but couldn't add it to version

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/client.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/client.h?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/client.h 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/client.h 
Mon Feb  9 11:23:39 2015
@@ -45,6 +45,35 @@
 extern "C" {
 #endif /* __cplusplus */
 
+
+/* Private client context.
+ *
+ * This is what is actually allocated by svn_client_create_context2(),
+ * which then returns the address of the public_ctx member. */
+typedef struct svn_client__private_ctx_t
+{
+  /* Reserved field, always zero, to detect misuse of the private
+     context as a public client context. */
+  apr_uint64_t magic_null;
+
+  /* Reserved field, always set to a known magic number, to identify
+     this struct as the private client context. */
+  apr_uint64_t magic_id;
+
+  /* Total number of bytes transferred over network across all RA sessions. */
+  apr_off_t total_progress;
+
+  /* The public context. */
+  svn_client_ctx_t public_ctx;
+} svn_client__private_ctx_t;
+
+
+/* Given a public client context CTX, return the private context
+   within which it is allocated. */
+svn_client__private_ctx_t *
+svn_client__get_private_ctx(svn_client_ctx_t *ctx);
+
+
 /* Set *REVNUM to the revision number identified by REVISION.
 
    If REVISION->kind is svn_opt_revision_number, just use

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/copy.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/copy.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/copy.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/copy.c 
Mon Feb  9 11:23:39 2015
@@ -1058,8 +1058,13 @@ repos_to_repos_copy(const apr_array_head
       SVN_ERR(svn_ra_check_path(ra_session, dst_rel, SVN_INVALID_REVNUM,
                                 &dst_kind, pool));
       if (dst_kind != svn_node_none)
-        return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL,
-                                 _("Path '%s' already exists"), dst_rel);
+        {
+          const char *path = svn_uri_skip_ancestor(repos_root,
+                                                   pair->dst_abspath_or_url,
+                                                   pool);
+          return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL,
+                                   _("Path '/%s' already exists"), path);
+        }
 
       /* More info for our INFO structure.  */
       info->src_path = src_rel;
@@ -1088,6 +1093,7 @@ repos_to_repos_copy(const apr_array_head
 
               item = svn_client_commit_item3_create(pool);
               item->url = svn_path_url_add_component2(top_url, relpath, pool);
+              item->kind = svn_node_dir;
               item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;
               APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
             }
@@ -1101,6 +1107,7 @@ repos_to_repos_copy(const apr_array_head
           item = svn_client_commit_item3_create(pool);
           item->url = svn_path_url_add_component2(top_url, info->dst_path,
                                                   pool);
+          item->kind = info->src_kind;
           item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD
                               | SVN_CLIENT_COMMIT_ITEM_IS_COPY;
           item->copyfrom_url = info->src_url;
@@ -1112,6 +1119,7 @@ repos_to_repos_copy(const apr_array_head
               item = svn_client_commit_item3_create(pool);
               item->url = svn_path_url_add_component2(top_url, info->src_path,
                                                       pool);
+              item->kind = info->src_kind;
               item->state_flags = SVN_CLIENT_COMMIT_ITEM_DELETE;
               APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
             }
@@ -1342,52 +1350,6 @@ wc_to_repos_copy(const apr_array_header_
         }
     }
 
-  if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx))
-    {
-      /* Produce a list of new paths to add, and provide it to the
-         mechanism used to acquire a log message. */
-      svn_client_commit_item3_t *item;
-      const char *tmp_file;
-      commit_items = apr_array_make(scratch_pool, copy_pairs->nelts,
-                                    sizeof(item));
-
-      /* Add any intermediate directories to the message */
-      if (make_parents)
-        {
-          for (i = 0; i < new_dirs->nelts; i++)
-            {
-              const char *url = APR_ARRAY_IDX(new_dirs, i, const char *);
-
-              item = svn_client_commit_item3_create(scratch_pool);
-              item->url = url;
-              item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;
-              APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
-            }
-        }
-
-      for (i = 0; i < copy_pairs->nelts; i++)
-        {
-          svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
-                                            svn_client__copy_pair_t *);
-
-          item = svn_client_commit_item3_create(scratch_pool);
-          item->url = pair->dst_abspath_or_url;
-          item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;
-          APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
-        }
-
-      SVN_ERR(svn_client__get_log_msg(&message, &tmp_file, commit_items,
-                                      ctx, scratch_pool));
-      if (! message)
-        {
-          svn_pool_destroy(iterpool);
-          svn_pool_destroy(session_pool);
-          return SVN_NO_ERROR;
-        }
-    }
-  else
-    message = "";
-
   cukb.session = ra_session;
   SVN_ERR(svn_ra_get_repos_root2(ra_session, &cukb.repos_root_url, 
session_pool));
   cukb.should_reparent = FALSE;
@@ -1418,6 +1380,7 @@ wc_to_repos_copy(const apr_array_header_
 
           item = svn_client_commit_item3_create(scratch_pool);
           item->url = url;
+          item->kind = svn_node_dir;
           item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;
           item->incoming_prop_changes = apr_array_make(scratch_pool, 1,
                                                        sizeof(svn_prop_t *));
@@ -1445,8 +1408,6 @@ wc_to_repos_copy(const apr_array_header_
 
       /* Set the mergeinfo for the destination to the combined merge
          info known to the WC and the repository. */
-      item->outgoing_prop_changes = apr_array_make(scratch_pool, 1,
-                                                   sizeof(svn_prop_t *));
       /* Repository mergeinfo (or NULL if it's locally added)... */
       if (src_origin)
         SVN_ERR(svn_client__get_repos_mergeinfo(
@@ -1463,18 +1424,24 @@ wc_to_repos_copy(const apr_array_header_
                                      iterpool));
       else if (! mergeinfo)
         mergeinfo = wc_mergeinfo;
+
       if (mergeinfo)
         {
           /* Push a mergeinfo prop representing MERGEINFO onto the
            * OUTGOING_PROP_CHANGES array. */
 
           svn_prop_t *mergeinfo_prop
-            = apr_palloc(item->outgoing_prop_changes->pool,
-                         sizeof(svn_prop_t));
+                            = apr_palloc(scratch_pool, 
sizeof(*mergeinfo_prop));
           svn_string_t *prop_value;
 
           SVN_ERR(svn_mergeinfo_to_string(&prop_value, mergeinfo,
-                                          item->outgoing_prop_changes->pool));
+                                          scratch_pool));
+
+          if (!item->outgoing_prop_changes)
+            {
+              item->outgoing_prop_changes = apr_array_make(scratch_pool, 1,
+                                                           sizeof(svn_prop_t 
*));
+            }
 
           mergeinfo_prop->name = SVN_PROP_MERGEINFO;
           mergeinfo_prop->value = prop_value;
@@ -1483,6 +1450,22 @@ wc_to_repos_copy(const apr_array_header_
         }
     }
 
+  if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx))
+    {
+      const char *tmp_file;
+
+      SVN_ERR(svn_client__get_log_msg(&message, &tmp_file, commit_items,
+                                      ctx, scratch_pool));
+      if (! message)
+        {
+          svn_pool_destroy(iterpool);
+          svn_pool_destroy(session_pool);
+          return SVN_NO_ERROR;
+        }
+    }
+  else
+    message = "";
+
   /* Sort and condense our COMMIT_ITEMS. */
   SVN_ERR(svn_client__condense_commit_items(&top_dst_url,
                                             commit_items, scratch_pool));
@@ -1997,7 +1980,7 @@ try_copy(svn_boolean_t *timestamp_sleep,
         {
           svn_client_copy_source_t *source = APR_ARRAY_IDX(sources, i,
                                                svn_client_copy_source_t *);
-          svn_client__copy_pair_t *pair = apr_palloc(pool, sizeof(*pair));
+          svn_client__copy_pair_t *pair = apr_pcalloc(pool, sizeof(*pair));
           const char *src_basename;
           svn_boolean_t src_is_url = svn_path_is_url(source->path);
 
@@ -2019,6 +2002,7 @@ try_copy(svn_boolean_t *timestamp_sleep,
 
           pair->src_op_revision = *source->revision;
           pair->src_peg_revision = *source->peg_revision;
+          pair->src_kind = svn_node_unknown;
 
           SVN_ERR(svn_opt_resolve_revisions(&pair->src_peg_revision,
                                             &pair->src_op_revision,
@@ -2047,7 +2031,7 @@ try_copy(svn_boolean_t *timestamp_sleep,
   else
     {
       /* Only one source path. */
-      svn_client__copy_pair_t *pair = apr_palloc(pool, sizeof(*pair));
+      svn_client__copy_pair_t *pair = apr_pcalloc(pool, sizeof(*pair));
       svn_client_copy_source_t *source =
         APR_ARRAY_IDX(sources, 0, svn_client_copy_source_t *);
       svn_boolean_t src_is_url = svn_path_is_url(source->path);
@@ -2059,6 +2043,7 @@ try_copy(svn_boolean_t *timestamp_sleep,
                                         source->path, pool));
       pair->src_op_revision = *source->revision;
       pair->src_peg_revision = *source->peg_revision;
+      pair->src_kind = svn_node_unknown;
 
       SVN_ERR(svn_opt_resolve_revisions(&pair->src_peg_revision,
                                         &pair->src_op_revision,

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/ctx.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/ctx.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/ctx.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/ctx.c 
Mon Feb  9 11:23:39 2015
@@ -27,6 +27,7 @@
 
 /*** Includes. ***/
 
+#include <stddef.h>
 #include <apr_pools.h>
 #include "svn_hash.h"
 #include "svn_client.h"
@@ -34,6 +35,8 @@
 
 #include "private/svn_wc_private.h"
 
+#include "client.h"
+
 
 /*** Code. ***/
 
@@ -76,6 +79,20 @@ call_conflict_func(svn_wc_conflict_resul
   return SVN_NO_ERROR;
 }
 
+/* The magic number in client_ctx_t.magic_id. */
+#define CLIENT_CTX_MAGIC APR_UINT64_C(0xDEADBEEF600DF00D)
+
+svn_client__private_ctx_t *
+svn_client__get_private_ctx(svn_client_ctx_t *ctx)
+{
+  svn_client__private_ctx_t *const private_ctx =
+    (void*)((char *)ctx - offsetof(svn_client__private_ctx_t, public_ctx));
+  SVN_ERR_ASSERT_NO_RETURN(&private_ctx->public_ctx == ctx);
+  SVN_ERR_ASSERT_NO_RETURN(0 == private_ctx->magic_null);
+  SVN_ERR_ASSERT_NO_RETURN(CLIENT_CTX_MAGIC == private_ctx->magic_id);
+  return private_ctx;
+}
+
 svn_error_t *
 svn_client_create_context2(svn_client_ctx_t **ctx,
                            apr_hash_t *cfg_hash,
@@ -83,23 +100,29 @@ svn_client_create_context2(svn_client_ct
 {
   svn_config_t *cfg_config;
 
-  *ctx = apr_pcalloc(pool, sizeof(svn_client_ctx_t));
+  svn_client__private_ctx_t *const private_ctx =
+    apr_pcalloc(pool, sizeof(*private_ctx));
+  svn_client_ctx_t *const public_ctx = &private_ctx->public_ctx;
+
+  private_ctx->magic_null = 0;
+  private_ctx->magic_id = CLIENT_CTX_MAGIC;
 
-  (*ctx)->notify_func2 = call_notify_func;
-  (*ctx)->notify_baton2 = *ctx;
+  public_ctx->notify_func2 = call_notify_func;
+  public_ctx->notify_baton2 = public_ctx;
 
-  (*ctx)->conflict_func2 = call_conflict_func;
-  (*ctx)->conflict_baton2 = *ctx;
+  public_ctx->conflict_func2 = call_conflict_func;
+  public_ctx->conflict_baton2 = public_ctx;
 
-  (*ctx)->config = cfg_hash;
+  public_ctx->config = cfg_hash;
 
   if (cfg_hash)
     cfg_config = svn_hash_gets(cfg_hash, SVN_CONFIG_CATEGORY_CONFIG);
   else
     cfg_config = NULL;
 
-  SVN_ERR(svn_wc_context_create(&(*ctx)->wc_ctx, cfg_config, pool,
-                                pool));
+  SVN_ERR(svn_wc_context_create(&public_ctx->wc_ctx, cfg_config,
+                                pool, pool));
+  *ctx = public_ctx;
 
   return SVN_NO_ERROR;
 }

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/deprecated.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/deprecated.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- 
subversion/branches/remove-log-addressing/subversion/libsvn_client/deprecated.c 
(original)
+++ 
subversion/branches/remove-log-addressing/subversion/libsvn_client/deprecated.c 
Mon Feb  9 11:23:39 2015
@@ -2821,6 +2821,7 @@ svn_client_revert2(const apr_array_heade
                                             depth,
                                             changelists,
                                             FALSE /* clear_changelists */,
+                                            FALSE /* metadata_only */,
                                             ctx,
                                             pool));
 }
@@ -2862,7 +2863,7 @@ svn_client_uuid_from_url(const char **uu
   /* destroy the RA session */
   svn_pool_destroy(subpool);
 
-  return svn_error_trace(err);;
+  return svn_error_trace(err);
 }
 
 svn_error_t *

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/diff.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/diff.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/diff.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/diff.c 
Mon Feb  9 11:23:39 2015
@@ -52,6 +52,7 @@
 #include "private/svn_diff_private.h"
 #include "private/svn_subr_private.h"
 #include "private/svn_io_private.h"
+#include "private/svn_ra_private.h"
 
 #include "svn_private_config.h"
 
@@ -154,9 +155,6 @@ adjust_paths_for_diff_labels(const char
         new_path = ".";
       else
         return MAKE_ERR_BAD_RELATIVE_PATH(new_path, relative_to_dir);
-
-      child_path = svn_dirent_is_child(relative_to_dir, new_path1,
-                                       result_pool);
     }
 
   {
@@ -1808,8 +1806,8 @@ diff_repos_repos(const char **root_relpa
   /* Now, we open an extra RA session to the correct anchor
      location for URL1.  This is used during the editor calls to fetch file
      contents.  */
-  SVN_ERR(svn_ra_dup_session(&extra_ra_session, ra_session, anchor1,
-                             scratch_pool, scratch_pool));
+  SVN_ERR(svn_ra__dup_session(&extra_ra_session, ra_session, anchor1,
+                              scratch_pool, scratch_pool));
 
   if (ddi)
     {

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/externals.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/externals.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- 
subversion/branches/remove-log-addressing/subversion/libsvn_client/externals.c 
(original)
+++ 
subversion/branches/remove-log-addressing/subversion/libsvn_client/externals.c 
Mon Feb  9 11:23:39 2015
@@ -146,6 +146,7 @@ relegate_dir_external(svn_wc_context_t *
 static svn_error_t *
 switch_dir_external(const char *local_abspath,
                     const char *url,
+                    const char *url_from_externals_definition,
                     const svn_opt_revision_t *peg_revision,
                     const svn_opt_revision_t *revision,
                     const char *defining_abspath,
@@ -197,7 +198,16 @@ switch_dir_external(const char *local_ab
       SVN_ERR(svn_wc__get_wcroot(&defining_wcroot_abspath, ctx->wc_ctx,
                                  defining_abspath, pool, pool));
       if (strcmp(wcroot_abspath, defining_wcroot_abspath) == 0)
-        return svn_error_create(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, NULL);
+        return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
+                                 _("The external '%s' defined in %s at '%s' "
+                                   "cannot be checked out because '%s' is "
+                                   "already a versioned path."),
+                                   url_from_externals_definition,
+                                   SVN_PROP_EXTERNALS,
+                                   svn_dirent_local_style(defining_abspath,
+                                                          pool),
+                                   svn_dirent_local_style(local_abspath,
+                                                          pool));
     }
 
   /* If path is a directory, try to update/switch to the correct URL
@@ -379,14 +389,15 @@ switch_dir_external(const char *local_ab
   return SVN_NO_ERROR;
 }
 
-/* Try to update a file external at LOCAL_ABSPATH to URL at REVISION using a
-   access baton that has a write lock.  Use SCRATCH_POOL for temporary
+/* Try to update a file external at LOCAL_ABSPATH to SWITCH_LOC. This function
+   assumes caller has a write lock in CTX.  Use SCRATCH_POOL for temporary
    allocations, and use the client context CTX. */
 static svn_error_t *
 switch_file_external(const char *local_abspath,
-                     const char *url,
-                     const svn_opt_revision_t *peg_revision,
-                     const svn_opt_revision_t *revision,
+                     const svn_client__pathrev_t *switch_loc,
+                     const char *record_url,
+                     const svn_opt_revision_t *record_peg_revision,
+                     const svn_opt_revision_t *record_revision,
                      const char *def_dir_abspath,
                      svn_ra_session_t *ra_session,
                      svn_client_ctx_t *ctx,
@@ -463,7 +474,8 @@ switch_file_external(const char *local_a
               SVN_ERR_CLIENT_FILE_EXTERNAL_OVERWRITE_VERSIONED, 0,
              _("The file external from '%s' cannot overwrite the existing "
                "versioned item at '%s'"),
-             url, svn_dirent_local_style(local_abspath, scratch_pool));
+             switch_loc->url,
+             svn_dirent_local_style(local_abspath, scratch_pool));
         }
     }
   else
@@ -485,25 +497,17 @@ switch_file_external(const char *local_a
     void *report_baton;
     const svn_delta_editor_t *switch_editor;
     void *switch_baton;
-    svn_client__pathrev_t *switch_loc;
     svn_revnum_t revnum;
     apr_array_header_t *inherited_props;
-    const char *dir_abspath;
-    const char *target;
+    const char *target = svn_dirent_basename(local_abspath, scratch_pool);
 
-    svn_dirent_split(&dir_abspath, &target, local_abspath, scratch_pool);
-
-    /* Open an RA session to 'source' URL */
-    SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &switch_loc,
-                                              url, dir_abspath,
-                                              peg_revision, revision,
-                                              ctx, scratch_pool));
     /* Get the external file's iprops. */
     SVN_ERR(svn_ra_get_inherited_props(ra_session, &inherited_props, "",
                                        switch_loc->rev,
                                        scratch_pool, scratch_pool));
 
-    SVN_ERR(svn_ra_reparent(ra_session, svn_uri_dirname(url, scratch_pool),
+    SVN_ERR(svn_ra_reparent(ra_session,
+                            svn_uri_dirname(switch_loc->url, scratch_pool),
                             scratch_pool));
 
     SVN_ERR(svn_wc__get_file_external_editor(&switch_editor, &switch_baton,
@@ -517,7 +521,9 @@ switch_file_external(const char *local_a
                                              use_commit_times,
                                              diff3_cmd, preserved_exts,
                                              def_dir_abspath,
-                                             url, peg_revision, revision,
+                                             record_url,
+                                             record_peg_revision,
+                                             record_revision,
                                              ctx->cancel_func,
                                              ctx->cancel_baton,
                                              ctx->notify_func2,
@@ -528,7 +534,7 @@ switch_file_external(const char *local_a
      invalid revnum, that means RA will use the latest revision. */
     SVN_ERR(svn_ra_do_switch3(ra_session, &reporter, &report_baton,
                               switch_loc->rev,
-                              target, svn_depth_unknown, url,
+                              target, svn_depth_unknown, switch_loc->url,
                               FALSE /* send_copyfrom */,
                               TRUE /* ignore_ancestry */,
                               switch_editor, switch_baton,
@@ -741,6 +747,8 @@ handle_external_item_change(svn_client_c
                                                   &(new_item->peg_revision),
                                                   &(new_item->revision), ctx,
                                                   scratch_pool));
+
+          SVN_ERR(svn_ra_reparent(ra_session, new_loc->url, scratch_pool));
         }
     }
 
@@ -794,6 +802,7 @@ handle_external_item_change(svn_client_c
     {
       case svn_node_dir:
         SVN_ERR(switch_dir_external(local_abspath, new_loc->url,
+                                    new_item->url,
                                     &(new_item->peg_revision),
                                     &(new_item->revision),
                                     parent_dir_abspath,
@@ -855,6 +864,7 @@ handle_external_item_change(svn_client_c
           }
 
         SVN_ERR(switch_file_external(local_abspath,
+                                     new_loc,
                                      new_url,
                                      &new_item->peg_revision,
                                      &new_item->revision,
@@ -1187,6 +1197,17 @@ svn_client__export_externals(apr_hash_t
                                                                  sub_iterpool),
                                               sub_iterpool));
 
+          /* First notify that we're about to handle an external. */
+          if (ctx->notify_func2)
+            {
+              ctx->notify_func2(
+                       ctx->notify_baton2,
+                       svn_wc_create_notify(item_abspath,
+                                            svn_wc_notify_update_external,
+                                            sub_iterpool),
+                       sub_iterpool);
+            }
+
           SVN_ERR(wrap_external_error(
                           ctx, item_abspath,
                           svn_client_export5(NULL, new_url, item_abspath,

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/import.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/import.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/import.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/import.c 
Mon Feb  9 11:23:39 2015
@@ -832,6 +832,8 @@ svn_client_import5(const char *path,
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
 
+  SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
+
   /* Create a new commit item and add it to the array. */
   if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx))
     {
@@ -845,6 +847,8 @@ svn_client_import5(const char *path,
 
       item = svn_client_commit_item3_create(scratch_pool);
       item->path = local_abspath;
+      item->url = url;
+      item->kind = kind;
       item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;
       APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
 
@@ -860,8 +864,6 @@ svn_client_import5(const char *path,
         }
     }
 
-  SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
-
   SVN_ERR(svn_client_open_ra_session2(&ra_session, url, NULL,
                                       ctx, scratch_pool, iterpool));
 

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/info.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/info.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/info.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/info.c 
Mon Feb  9 11:23:39 2015
@@ -388,8 +388,7 @@ svn_client_info4(const char *abspath_or_
   SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &pathrev,
                                             abspath_or_url, NULL, peg_revision,
                                             revision, ctx, pool));
-
-  svn_uri_split(NULL, &base_name, pathrev->url, pool);
+  base_name = svn_uri_basename(pathrev->url, pool);
 
   /* Get the dirent for the URL itself. */
   SVN_ERR(svn_ra_stat(ra_session, "", pathrev->rev, &the_ent, pool));

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/locking_commands.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/locking_commands.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- 
subversion/branches/remove-log-addressing/subversion/libsvn_client/locking_commands.c
 (original)
+++ 
subversion/branches/remove-log-addressing/subversion/libsvn_client/locking_commands.c
 Mon Feb  9 11:23:39 2015
@@ -402,10 +402,9 @@ organize_lock_targets(apr_array_header_t
                                 _("Unable to lock/unlock across multiple "
                                   "repositories"));
 
-      /* Now we need to create a couple of different hash mappings. */
+      /* Now we need to create our mapping. */
       rel_fs_paths = apr_hash_make(result_pool);
-      target_urls = apr_array_make(scratch_pool, targets->nelts,
-                                   sizeof(const char *));
+
       for (hi = apr_hash_first(scratch_pool, wc_info);
            hi;
            hi = apr_hash_next(hi))

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/log.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/log.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/log.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/log.c 
Mon Feb  9 11:23:39 2015
@@ -852,10 +852,12 @@ svn_client_log5(const apr_array_header_t
   svn_ra_session_t *ra_session;
   const char *old_session_url;
   const char *ra_target;
+  const char *path_or_url;
   svn_opt_revision_t youngest_opt_rev;
   svn_revnum_t youngest_rev;
   svn_revnum_t oldest_rev;
   svn_opt_revision_t peg_rev;
+  svn_client__pathrev_t *ra_session_loc;
   svn_client__pathrev_t *actual_loc;
   apr_array_header_t *log_segments;
   apr_array_header_t *revision_ranges;
@@ -875,7 +877,7 @@ svn_client_log5(const apr_array_header_t
   SVN_ERR(resolve_log_targets(&relative_targets, &ra_target, &peg_rev,
                               targets, ctx, pool, pool));
 
-  SVN_ERR(svn_client__ra_session_from_path2(&ra_session, NULL,
+  SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &ra_session_loc,
                                             ra_target, NULL, &peg_rev, 
&peg_rev,
                                             ctx, pool));
 
@@ -889,11 +891,22 @@ svn_client_log5(const apr_array_header_t
                                                    opt_rev_ranges, &peg_rev,
                                                    ctx, pool,  pool));
 
+  /* For some peg revisions we must resolve revision and url via a local path
+     so use the original RA_TARGET. For others, use the potentially corrected
+     (redirected) ra session URL. */
+  if (peg_rev.kind == svn_opt_revision_previous ||
+      peg_rev.kind == svn_opt_revision_base ||
+      peg_rev.kind == svn_opt_revision_committed ||
+      peg_rev.kind == svn_opt_revision_working)
+    path_or_url = ra_target;
+  else
+    path_or_url = ra_session_loc->url;
+
   /* Make ACTUAL_LOC and RA_SESSION point to the youngest operative rev. */
   youngest_opt_rev.kind = svn_opt_revision_number;
   youngest_opt_rev.value.number = youngest_rev;
   SVN_ERR(svn_client__resolve_rev_and_url(&actual_loc, ra_session,
-                                          ra_target, &peg_rev,
+                                          path_or_url, &peg_rev,
                                           &youngest_opt_rev, ctx, pool));
   SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url, ra_session,
                                             actual_loc->url, pool));

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/mergeinfo.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/mergeinfo.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- 
subversion/branches/remove-log-addressing/subversion/libsvn_client/mergeinfo.c 
(original)
+++ 
subversion/branches/remove-log-addressing/subversion/libsvn_client/mergeinfo.c 
Mon Feb  9 11:23:39 2015
@@ -2130,7 +2130,7 @@ svn_client__mergeinfo_log(svn_boolean_t
         svn_rangelist__initialize(youngest_range->end - 1,
                                   youngest_range->end,
                                   youngest_range->inheritable,
-                                  scratch_pool);;
+                                  scratch_pool);
 
       for (hi = apr_hash_first(scratch_pool, source_history);
            hi;

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/mtcc.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/mtcc.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/mtcc.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/mtcc.c 
Mon Feb  9 11:23:39 2015
@@ -337,7 +337,6 @@ svn_client__mtcc_create(svn_client__mtcc
 
   *mtcc = apr_pcalloc(mtcc_pool, sizeof(**mtcc));
   (*mtcc)->pool = mtcc_pool;
-  (*mtcc)->base_revision = base_revision;
 
   (*mtcc)->root_op = mtcc_op_create(NULL, FALSE, TRUE, mtcc_pool);
 
@@ -350,9 +349,12 @@ svn_client__mtcc_create(svn_client__mtcc
   SVN_ERR(svn_ra_get_latest_revnum((*mtcc)->ra_session, 
&(*mtcc)->head_revision,
                                    scratch_pool));
 
-  if (! SVN_IS_VALID_REVNUM(base_revision))
-    base_revision = (*mtcc)->head_revision;
-  else if (base_revision > (*mtcc)->head_revision)
+  if (SVN_IS_VALID_REVNUM(base_revision))
+    (*mtcc)->base_revision = base_revision;
+  else
+    (*mtcc)->base_revision = (*mtcc)->head_revision;
+
+  if ((*mtcc)->base_revision > (*mtcc)->head_revision)
     return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
                              _("No such revision %ld (HEAD is %ld)"),
                              base_revision, (*mtcc)->head_revision);
@@ -461,8 +463,8 @@ mtcc_verify_create(svn_client__mtcc_t *m
         return SVN_NO_ERROR; /* Node is explicitly deleted. We can replace */
     }
 
-  /* mod_dav_svn allows overwriting existing directories. Let's hide that
-     for users of this api */
+  /* mod_dav_svn used to allow overwriting existing directories. Let's hide
+     that for users of this api */
   SVN_ERR(svn_client__mtcc_check_path(&kind, new_relpath, FALSE,
                                       mtcc, scratch_pool));
 
@@ -708,8 +710,7 @@ mtcc_prop_getter(const svn_string_t **mi
 
               if (! strcmp(mod->name, SVN_PROP_MIME_TYPE))
                 {
-                  *mime_type = mod->value ? svn_string_dup(mod->value, pool)
-                                          : NULL;
+                  *mime_type = svn_string_dup(mod->value, pool);
                   mime_type = NULL;
                 }
             }

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/patch.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/patch.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/patch.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/patch.c 
Mon Feb  9 11:23:39 2015
@@ -48,6 +48,7 @@
 #include "private/svn_dep_compat.h"
 #include "private/svn_string_private.h"
 #include "private/svn_subr_private.h"
+#include "private/svn_sorts_private.h"
 
 typedef struct hunk_info_t {
   /* The hunk. */
@@ -1578,7 +1579,8 @@ match_existing_target(svn_boolean_t *mat
 /* Determine the line at which a HUNK applies to CONTENT of the TARGET
  * file, and return an appropriate hunk_info object in *HI, allocated from
  * RESULT_POOL. Use fuzz factor FUZZ. Set HI->FUZZ to FUZZ. If no correct
- * line can be determined, set HI->REJECTED to TRUE.
+ * line can be determined, set HI->REJECTED to TRUE.  PREVIOUS_OFFSET
+ * is the offset at which the previous matching hunk was applied, or zero.
  * IGNORE_WHITESPACE tells whether whitespace should be considered when
  * matching. IS_PROP_HUNK indicates whether the hunk patches file content
  * or a property.
@@ -1590,6 +1592,7 @@ static svn_error_t *
 get_hunk_info(hunk_info_t **hi, patch_target_t *target,
               target_content_t *content,
               svn_diff_hunk_t *hunk, svn_linenum_t fuzz,
+              apr_int64_t previous_offset,
               svn_boolean_t ignore_whitespace,
               svn_boolean_t is_prop_hunk,
               svn_cancel_func_t cancel_func, void *cancel_baton,
@@ -1599,7 +1602,7 @@ get_hunk_info(hunk_info_t **hi, patch_ta
   svn_linenum_t original_start;
   svn_boolean_t already_applied;
 
-  original_start = svn_diff_hunk_get_original_start(hunk);
+  original_start = svn_diff_hunk_get_original_start(hunk) + previous_offset;
   already_applied = FALSE;
 
   /* An original offset of zero means that this hunk wants to create
@@ -1707,7 +1710,9 @@ get_hunk_info(hunk_info_t **hi, patch_ta
               modified_start = svn_diff_hunk_get_modified_start(hunk);
               if (modified_start == 0)
                 {
-                  /* Patch wants to delete the file. */
+                  /* Patch wants to delete the file.
+
+                     ### locally_deleted is always false here? */
                   already_applied = target->locally_deleted;
                 }
               else
@@ -1728,27 +1733,85 @@ get_hunk_info(hunk_info_t **hi, patch_ta
 
           if (! already_applied)
             {
-              /* Scan the whole file again from the start. */
-              SVN_ERR(seek_to_line(content, 1, scratch_pool));
+              int i;
+              svn_linenum_t search_start = 1, search_end = 0;
+              svn_linenum_t matched_line2;
+
+              /* Search for closest match before or after original
+                 start.  We have no backward search so search forwards
+                 from the previous match (or start of file) to the
+                 original start looking for the last match.  Then
+                 search forwards from the original start looking for a
+                 better match.  Finally search forwards from the start
+                 of file to the previous hunk if that could result in
+                 a better match. */
+
+              for (i = content->hunks->nelts; i > 0; --i)
+                {
+                  const hunk_info_t *prev
+                    = APR_ARRAY_IDX(content->hunks, i - 1, const hunk_info_t 
*);
+                  if (!prev->rejected)
+                    {
+                      svn_linenum_t length;
+
+                      length = svn_diff_hunk_get_original_length(prev->hunk);
+                      search_start = prev->matched_line + length;
+                      break;
+                    }
+                }
 
-              /* Scan forward towards the hunk's line and look for a line
-               * where the hunk matches. */
+              /* Search from the previous match, or start of file,
+                 towards the original location. */
+              SVN_ERR(seek_to_line(content, search_start, scratch_pool));
               SVN_ERR(scan_for_match(&matched_line, content, hunk, FALSE,
                                      original_start, fuzz,
                                      ignore_whitespace, FALSE,
                                      cancel_func, cancel_baton,
                                      scratch_pool));
 
-              /* In tie-break situations, we arbitrarily prefer early matches
-               * to save us from scanning the rest of the file. */
-              if (matched_line == 0)
+              /* If a match we only need to search forwards for a
+                 better match, otherwise to the end of the file. */
+              if (matched_line)
+                search_end = original_start + (original_start - matched_line);
+
+              /* Search from original location, towards the end. */
+              SVN_ERR(seek_to_line(content, original_start + 1, scratch_pool));
+              SVN_ERR(scan_for_match(&matched_line2, content, hunk,
+                                     TRUE, search_end, fuzz, ignore_whitespace,
+                                     FALSE, cancel_func, cancel_baton,
+                                     scratch_pool));
+
+              /* Chose the forward match if it is closer than the
+                 backward match or if there is no backward match. */
+              if (matched_line2
+                  && (!matched_line
+                      || (matched_line2 - original_start
+                          < original_start - matched_line)))
+                  matched_line = matched_line2;
+
+              /* Search from before previous hunk if there could be a
+                 better match. */
+              if (search_start > 1
+                  && (!matched_line
+                      || (matched_line > original_start
+                          && (matched_line - original_start
+                              > original_start - search_start)))) 
                 {
-                  /* Scan forward towards the end of the file and look
-                   * for a line where the hunk matches. */
-                  SVN_ERR(scan_for_match(&matched_line, content, hunk,
-                                         TRUE, 0, fuzz, ignore_whitespace,
-                                         FALSE, cancel_func, cancel_baton,
+                  svn_linenum_t search_start2 = 1;
+
+                  if (matched_line
+                      && matched_line - original_start < original_start)
+                    search_start2
+                      = original_start - (matched_line - original_start) + 1;
+
+                  SVN_ERR(seek_to_line(content, search_start2, scratch_pool));
+                  SVN_ERR(scan_for_match(&matched_line2, content, hunk, FALSE,
+                                         search_start - 1, fuzz,
+                                         ignore_whitespace, FALSE,
+                                         cancel_func, cancel_baton,
                                          scratch_pool));
+                  if (matched_line2)
+                    matched_line = matched_line2;
                 }
             }
         }
@@ -2139,6 +2202,48 @@ send_patch_notification(const patch_targ
   return SVN_NO_ERROR;
 }
 
+/* Implements the callback for svn_sort__array.  Puts hunks that match
+   before hunks that do not match, puts hunks that match in order
+   based on postion matched, puts hunks that do not match in order
+   based on original position. */
+static int
+sort_matched_hunks(const void *a, const void *b)
+{
+  const hunk_info_t *item1 = *((const hunk_info_t * const *)a);
+  const hunk_info_t *item2 = *((const hunk_info_t * const *)b);
+  svn_boolean_t matched1 = !item1->rejected && !item1->already_applied;
+  svn_boolean_t matched2 = !item2->rejected && !item2->already_applied;
+  svn_linenum_t original1, original2;
+
+  if (matched1 && matched2)
+    {
+      /* Both match so use order matched in file. */
+      if (item1->matched_line > item2->matched_line)
+        return 1;
+      else if (item1->matched_line == item2->matched_line)
+        return 0;
+      else
+        return -1;
+    }
+  else if (matched2)
+    /* Only second matches, put it before first. */
+    return 1;
+  else if (matched1)
+    /* Only first matches, put it before second. */
+    return -1;
+
+  /* Neither matches, sort by original_start. */
+  original1 = svn_diff_hunk_get_original_start(item1->hunk);
+  original2 = svn_diff_hunk_get_original_start(item2->hunk);
+  if (original1 > original2)
+    return 1;
+  else if (original1 == original2)
+    return 0;
+  else
+    return -1;
+}
+
+
 /* Apply a PATCH to a working copy at ABS_WC_PATH and put the result
  * into temporary files, to be installed in the working copy later.
  * Return information about the patch target in *PATCH_TARGET, allocated
@@ -2167,6 +2272,7 @@ apply_one_patch(patch_target_t **patch_t
   int i;
   static const svn_linenum_t MAX_FUZZ = 2;
   apr_hash_index_t *hash_index;
+  apr_int64_t previous_offset = 0;
 
   SVN_ERR(init_patch_target(&target, patch, abs_wc_path, wc_ctx, strip_count,
                             remove_tempfiles, result_pool, scratch_pool));
@@ -2209,6 +2315,7 @@ apply_one_patch(patch_target_t **patch_t
       do
         {
           SVN_ERR(get_hunk_info(&hi, target, target->content, hunk, fuzz,
+                                previous_offset,
                                 ignore_whitespace,
                                 FALSE /* is_prop_hunk */,
                                 cancel_func, cancel_baton,
@@ -2217,9 +2324,17 @@ apply_one_patch(patch_target_t **patch_t
         }
       while (hi->rejected && fuzz <= MAX_FUZZ && ! hi->already_applied);
 
+      if (hi->matched_line)
+        previous_offset
+          = hi->matched_line - svn_diff_hunk_get_original_start(hunk);
+
       APR_ARRAY_PUSH(target->content->hunks, hunk_info_t *) = hi;
     }
 
+  /* Hunks are applied in the order determined by the matched line and
+     this may be different from the order of the original lines. */
+  svn_sort__array(target->content->hunks, sort_matched_hunks);
+
   /* Apply or reject hunks. */
   for (i = 0; i < target->content->hunks->nelts; i++)
     {
@@ -2291,7 +2406,7 @@ apply_one_patch(patch_target_t **patch_t
           do
             {
               SVN_ERR(get_hunk_info(&hi, target, prop_target->content,
-                                    hunk, fuzz,
+                                    hunk, fuzz, 0,
                                     ignore_whitespace,
                                     TRUE /* is_prop_hunk */,
                                     cancel_func, cancel_baton,

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/prop_commands.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/prop_commands.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- 
subversion/branches/remove-log-addressing/subversion/libsvn_client/prop_commands.c
 (original)
+++ 
subversion/branches/remove-log-addressing/subversion/libsvn_client/prop_commands.c
 Mon Feb  9 11:23:39 2015
@@ -206,6 +206,7 @@ propset_on_url(const char *propname,
 
       item = svn_client_commit_item3_create(pool);
       item->url = target;
+      item->kind = node_kind;
       item->state_flags = SVN_CLIENT_COMMIT_ITEM_PROP_MODS;
       APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
       SVN_ERR(svn_client__get_log_msg(&message, &tmp_file, commit_items,
@@ -528,9 +529,10 @@ svn_client_revprop_set2(const char *prop
 
 /* Helper for the remote case of svn_client_propget.
  *
- * If PROPS is not null, then get the value of property PROPNAME in REVNUM,
-   using RA_LIB and SESSION.  Store the value ('svn_string_t *') in PROPS,
-   under the path key "TARGET_PREFIX/TARGET_RELATIVE" ('const char *').
+ * If PROPS is not null, then get the value of property PROPNAME in
+ * REVNUM, using RA_SESSION.  Store the value ('svn_string_t *') in
+ * PROPS, under the path key "TARGET_PREFIX/TARGET_RELATIVE"
+ * ('const char *').
  *
  * If INHERITED_PROPS is not null, then set *INHERITED_PROPS to a
  * depth-first ordered array of svn_prop_inherited_item_t * structures

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/ra.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/ra.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/ra.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/ra.c Mon 
Feb  9 11:23:39 2015
@@ -299,17 +299,20 @@ progress_func(apr_off_t progress,
               apr_pool_t *pool)
 {
   callback_baton_t *b = baton;
-  svn_client_ctx_t *ctx = b->ctx;
+  svn_client_ctx_t *public_ctx = b->ctx;
+  svn_client__private_ctx_t *private_ctx =
+    svn_client__get_private_ctx(public_ctx);
 
-  ctx->progress += (progress - b->last_progress);
+  private_ctx->total_progress += (progress - b->last_progress);
   b->last_progress = progress;
 
-  if (ctx->progress_func)
+  if (public_ctx->progress_func)
     {
       /* All RA implementations currently provide -1 for total. So it doesn't
          make sense to develop some complex logic to combine total across all
          RA sessions. */
-      ctx->progress_func(ctx->progress, -1, ctx->progress_baton, pool);
+      public_ctx->progress_func(private_ctx->total_progress, -1,
+                                public_ctx->progress_baton, pool);
     }
 }
 

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/repos_diff.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/repos_diff.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- 
subversion/branches/remove-log-addressing/subversion/libsvn_client/repos_diff.c 
(original)
+++ 
subversion/branches/remove-log-addressing/subversion/libsvn_client/repos_diff.c 
Mon Feb  9 11:23:39 2015
@@ -389,6 +389,10 @@ remove_non_prop_changes(apr_hash_t *pris
 {
   int i;
 
+  /* For added nodes, there is nothing to filter. */
+  if (apr_hash_count(pristine_props) == 0)
+    return;
+
   for (i = 0; i < changes->nelts; i++)
     {
       svn_prop_t *change = &APR_ARRAY_IDX(changes, i, svn_prop_t);
@@ -1162,7 +1166,7 @@ change_file_prop(void *file_baton,
 
   propchange = apr_array_push(fb->propchanges);
   propchange->name = apr_pstrdup(fb->pool, name);
-  propchange->value = value ? svn_string_dup(value, fb->pool) : NULL;
+  propchange->value = svn_string_dup(value, fb->pool);
 
   return SVN_NO_ERROR;
 }
@@ -1192,7 +1196,7 @@ change_dir_prop(void *dir_baton,
 
   propchange = apr_array_push(db->propchanges);
   propchange->name = apr_pstrdup(db->pool, name);
-  propchange->value = value ? svn_string_dup(value, db->pool) : NULL;
+  propchange->value = svn_string_dup(value, db->pool);
 
   return SVN_NO_ERROR;
 }

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/revert.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/revert.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/revert.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/revert.c 
Mon Feb  9 11:23:39 2015
@@ -50,6 +50,7 @@ struct revert_with_write_lock_baton {
   svn_boolean_t use_commit_times;
   const apr_array_header_t *changelists;
   svn_boolean_t clear_changelists;
+  svn_boolean_t metadata_only;
   svn_client_ctx_t *ctx;
 };
 
@@ -85,6 +86,7 @@ revert(void *baton, apr_pool_t *result_p
                        b->use_commit_times,
                        b->changelists,
                        b->clear_changelists,
+                       b->metadata_only,
                        b->ctx->cancel_func, b->ctx->cancel_baton,
                        b->ctx->notify_func2, b->ctx->notify_baton2,
                        scratch_pool);
@@ -98,11 +100,18 @@ revert(void *baton, apr_pool_t *result_p
           || err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
         {
           if (b->ctx->notify_func2)
-            b->ctx->notify_func2(
-               b->ctx->notify_baton2,
-               svn_wc_create_notify(b->local_abspath, svn_wc_notify_skip,
-                                    scratch_pool),
-               scratch_pool);
+            {
+              svn_wc_notify_t *notify;
+
+              notify = svn_wc_create_notify(b->local_abspath,
+                                            svn_wc_notify_skip,
+                                            scratch_pool);
+
+              notify->err = err;
+
+              b->ctx->notify_func2(b->ctx->notify_baton2,
+                                   notify, scratch_pool);
+            }
           svn_error_clear(err);
         }
       else
@@ -118,10 +127,11 @@ svn_client_revert3(const apr_array_heade
                    svn_depth_t depth,
                    const apr_array_header_t *changelists,
                    svn_boolean_t clear_changelists,
+                   svn_boolean_t metadata_only,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *pool)
 {
-  apr_pool_t *subpool;
+  apr_pool_t *iterpool;
   svn_error_t *err = SVN_NO_ERROR;
   int i;
   svn_config_t *cfg;
@@ -148,7 +158,7 @@ svn_client_revert3(const apr_array_heade
                               SVN_CONFIG_OPTION_USE_COMMIT_TIMES,
                               FALSE));
 
-  subpool = svn_pool_create(pool);
+  iterpool = svn_pool_create(pool);
 
   for (i = 0; i < paths->nelts; i++)
     {
@@ -156,14 +166,14 @@ svn_client_revert3(const apr_array_heade
       const char *local_abspath, *lock_target;
       svn_boolean_t wc_root;
 
-      svn_pool_clear(subpool);
+      svn_pool_clear(iterpool);
 
       /* See if we've been asked to cancel this operation. */
       if ((ctx->cancel_func)
           && ((err = ctx->cancel_func(ctx->cancel_baton))))
         goto errorful;
 
-      err = svn_dirent_get_absolute(&local_abspath, path, pool);
+      err = svn_dirent_get_absolute(&local_abspath, path, iterpool);
       if (err)
         goto errorful;
 
@@ -172,15 +182,17 @@ svn_client_revert3(const apr_array_heade
       baton.use_commit_times = use_commit_times;
       baton.changelists = changelists;
       baton.clear_changelists = clear_changelists;
+      baton.metadata_only = metadata_only;
       baton.ctx = ctx;
 
-      err = svn_wc__is_wcroot(&wc_root, ctx->wc_ctx, local_abspath, pool);
+      err = svn_wc__is_wcroot(&wc_root, ctx->wc_ctx, local_abspath, iterpool);
       if (err)
         goto errorful;
       lock_target = wc_root ? local_abspath
                             : svn_dirent_dirname(local_abspath, pool);
       err = svn_wc__call_with_write_lock(revert, &baton, ctx->wc_ctx,
-                                         lock_target, FALSE, pool, pool);
+                                         lock_target, FALSE,
+                                         iterpool, iterpool);
       if (err)
         goto errorful;
     }
@@ -196,10 +208,10 @@ svn_client_revert3(const apr_array_heade
     if (paths->nelts == 1)
       sleep_path = APR_ARRAY_IDX(paths, 0, const char *);
 
-    svn_io_sleep_for_timestamps(sleep_path, subpool);
+    svn_io_sleep_for_timestamps(sleep_path, iterpool);
   }
 
-  svn_pool_destroy(subpool);
+  svn_pool_destroy(iterpool);
 
   return svn_error_trace(err);
 }

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_client/util.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_client/util.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_client/util.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_client/util.c 
Mon Feb  9 11:23:39 2015
@@ -142,6 +142,7 @@ svn_client_commit_item3_create(apr_pool_
 
   item->revision = SVN_INVALID_REVNUM;
   item->copyfrom_rev = SVN_INVALID_REVNUM;
+  item->kind = svn_node_unknown;
 
   return item;
 }

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_delta/path_driver.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_delta/path_driver.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- 
subversion/branches/remove-log-addressing/subversion/libsvn_delta/path_driver.c 
(original)
+++ 
subversion/branches/remove-log-addressing/subversion/libsvn_delta/path_driver.c 
Mon Feb  9 11:23:39 2015
@@ -187,7 +187,7 @@ svn_delta_path_driver2(const svn_delta_e
      driving the editor. */
   for (; i < paths->nelts; i++)
     {
-      const char *pdir, *bname;
+      const char *pdir;
       const char *common = "";
       size_t common_len;
 
@@ -224,9 +224,10 @@ svn_delta_path_driver2(const svn_delta_e
       /*** Step C - Open any directories between the common ancestor
            and the parent of the current path. ***/
       if (*path == '/')
-        svn_fspath__split(&pdir, &bname, path, iterpool);
+        pdir = svn_fspath__dirname(path, iterpool);
       else
-        svn_relpath_split(&pdir, &bname, path, iterpool);
+        pdir = svn_relpath_dirname(path, iterpool);
+
       if (strlen(pdir) > common_len)
         {
           const char *piece = pdir + common_len + 1;

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_diff/diff_file.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_diff/diff_file.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- 
subversion/branches/remove-log-addressing/subversion/libsvn_diff/diff_file.c 
(original)
+++ 
subversion/branches/remove-log-addressing/subversion/libsvn_diff/diff_file.c 
Mon Feb  9 11:23:39 2015
@@ -544,7 +544,6 @@ find_identical_suffix(apr_off_t *suffix_
   int suffix_lines_to_keep = SUFFIX_LINES_TO_KEEP;
   svn_boolean_t is_match;
   apr_off_t lines = 0;
-  svn_boolean_t had_cr;
   svn_boolean_t had_nl;
   apr_size_t i;
 
@@ -685,7 +684,6 @@ find_identical_suffix(apr_off_t *suffix_
 
           /* We skipped some bytes, so there are no closing EOLs */
           had_nl = FALSE;
-          had_cr = FALSE;
         }
 
       /* The > min_curp[i] check leaves at least one final byte for checking
@@ -712,7 +710,7 @@ find_identical_suffix(apr_off_t *suffix_
      one file reaches its end. */
   do
     {
-      had_cr = FALSE;
+      svn_boolean_t had_cr = FALSE;
       while (!is_one_at_eof(file_for_suffix, file_len)
              && *file_for_suffix[0].curp != '\n'
              && *file_for_suffix[0].curp != '\r')

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_fs/fs-loader.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_fs/fs-loader.h?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_fs/fs-loader.h 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_fs/fs-loader.h 
Mon Feb  9 11:23:39 2015
@@ -548,7 +548,8 @@ struct svn_fs_access_t
   const char *username;
 
   /* A collection of lock-tokens supplied by the fs caller.
-     Hash maps (const char *) UUID --> (void *) 1
+     Hash maps (const char *) UUID --> path where path can be the
+     magic value (void *) 1 if no path was specified.
      fs functions should really only be interested whether a UUID
      exists as a hash key at all;  the value is irrelevant. */
   apr_hash_t *lock_tokens;

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_fs_base/dag.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_fs_base/dag.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_fs_base/dag.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_fs_base/dag.c 
Mon Feb  9 11:23:39 2015
@@ -1028,12 +1028,14 @@ svn_fs_base__dag_delete_if_mutable(svn_f
               void *val;
               svn_fs_dirent_t *dirent;
 
+              svn_pool_clear(subpool);
               apr_hash_this(hi, NULL, NULL, &val);
               dirent = val;
               SVN_ERR(svn_fs_base__dag_delete_if_mutable(fs, dirent->id,
                                                          txn_id, trail,
                                                          subpool));
             }
+          svn_pool_destroy(subpool);
         }
     }
 

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_fs_base/fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_fs_base/fs.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_fs_base/fs.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_fs_base/fs.c 
Mon Feb  9 11:23:39 2015
@@ -1516,6 +1516,7 @@ svn_fs_base__init(const svn_version_t *l
     {
       { "svn_subr",  svn_subr_version },
       { "svn_delta", svn_delta_version },
+      { "svn_fs_util", svn_fs_util__version },
       { NULL, NULL }
     };
 

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_fs_base/tree.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_fs_base/tree.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_fs_base/tree.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_fs_base/tree.c 
Mon Feb  9 11:23:39 2015
@@ -1237,7 +1237,7 @@ base_node_prop(svn_string_t **value_p,
   args.propname = propname;
   SVN_ERR(svn_fs_base__retry_txn(root->fs, txn_body_node_prop, &args,
                                  FALSE, scratch_pool));
-  *value_p = value ? svn_string_dup(value, pool) : NULL;
+  *value_p = svn_string_dup(value, pool);
   svn_pool_destroy(scratch_pool);
   return SVN_NO_ERROR;
 }

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/cached_data.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/cached_data.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- 
subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/cached_data.c 
(original)
+++ 
subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/cached_data.c 
Mon Feb  9 11:23:39 2015
@@ -2325,7 +2325,7 @@ get_dir_contents(apr_array_header_t **en
          changes we've made in this transaction. */
       SVN_ERR(svn_stream_open_readonly(&contents, filename, scratch_pool,
                                        scratch_pool));
-      SVN_ERR(read_dir_entries(*entries, contents, TRUE,  noderev->id,
+      SVN_ERR(read_dir_entries(*entries, contents, TRUE, noderev->id,
                                result_pool, scratch_pool));
       SVN_ERR(svn_stream_close(contents));
     }
@@ -2389,7 +2389,7 @@ locate_dir_cache(svn_fs_t *fs,
              A NULL key causes a cache miss. */
           *key = NULL;
         }
-      
+
       return ffd->dir_cache;
     }
 }

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/caching.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/caching.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/caching.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/caching.c 
Mon Feb  9 11:23:39 2015
@@ -620,12 +620,44 @@ struct txn_cleanup_baton_t
 
   /* the position where to reset it */
   svn_cache__t **to_reset;
+
+  /* pool that TXN_CACHE was allocated in */
+  apr_pool_t *txn_pool;
+
+  /* pool that the FS containing the TO_RESET pointer was allocator */
+  apr_pool_t *fs_pool;
 };
 
+/* Forward declaration. */
+static apr_status_t
+remove_txn_cache_fs(void *baton_void);
+
 /* APR pool cleanup handler that will reset the cache pointer given in
-   BATON_VOID. */
+   BATON_VOID when the TXN_POOL gets cleaned up. */
 static apr_status_t
-remove_txn_cache(void *baton_void)
+remove_txn_cache_txn(void *baton_void)
+{
+  struct txn_cleanup_baton_t *baton = baton_void;
+
+  /* be careful not to hurt performance by resetting newer txn's caches. */
+  if (*baton->to_reset == baton->txn_cache)
+    {
+      /* This is equivalent to calling svn_fs_fs__reset_txn_caches(). */
+      *baton->to_reset = NULL;
+    }
+
+  /* It's cleaned up now. Prevent double cleanup. */
+  apr_pool_cleanup_kill(baton->fs_pool,
+                        baton,
+                        remove_txn_cache_fs);
+
+  return  APR_SUCCESS;
+}
+
+/* APR pool cleanup handler that will reset the cache pointer given in
+   BATON_VOID when the FS_POOL gets cleaned up. */
+static apr_status_t
+remove_txn_cache_fs(void *baton_void)
 {
   struct txn_cleanup_baton_t *baton = baton_void;
 
@@ -633,19 +665,25 @@ remove_txn_cache(void *baton_void)
   if (*baton->to_reset == baton->txn_cache)
     {
      /* This is equivalent to calling svn_fs_fs__reset_txn_caches(). */
-      *baton->to_reset  = NULL;
+      *baton->to_reset = NULL;
     }
 
+  /* It's cleaned up now. Prevent double cleanup. */
+  apr_pool_cleanup_kill(baton->txn_pool,
+                        baton,
+                        remove_txn_cache_txn);
+
   return  APR_SUCCESS;
 }
 
 /* This function sets / registers the required callbacks for a given
- * transaction-specific *CACHE object, if CACHE is not NULL and a no-op
- * otherwise. In particular, it will ensure that *CACHE gets reset to NULL
- * upon POOL destruction latest.
+ * transaction-specific *CACHE object in FS, if CACHE is not NULL and
+ * a no-op otherwise. In particular, it will ensure that *CACHE gets
+ * reset to NULL upon POOL or FS->POOL destruction latest.
  */
 static void
-init_txn_callbacks(svn_cache__t **cache,
+init_txn_callbacks(svn_fs_t *fs,
+                   svn_cache__t **cache,
                    apr_pool_t *pool)
 {
   if (*cache != NULL)
@@ -655,10 +693,20 @@ init_txn_callbacks(svn_cache__t **cache,
       baton = apr_palloc(pool, sizeof(*baton));
       baton->txn_cache = *cache;
       baton->to_reset = cache;
+      baton->txn_pool = pool;
+      baton->fs_pool = fs->pool;
 
+      /* If any of these pools gets cleaned, we must reset the cache.
+       * We don't know which one will get cleaned up first, so register
+       * cleanup actions for both and during the cleanup action, unregister
+       * the respective other action. */
       apr_pool_cleanup_register(pool,
                                 baton,
-                                remove_txn_cache,
+                                remove_txn_cache_txn,
+                                apr_pool_cleanup_null);
+      apr_pool_cleanup_register(fs->pool,
+                                baton,
+                                remove_txn_cache_fs,
                                 apr_pool_cleanup_null);
     }
 }
@@ -708,7 +756,7 @@ svn_fs_fs__initialize_txn_caches(svn_fs_
                        pool, pool));
 
   /* reset the transaction-specific cache if the pool gets cleaned up. */
-  init_txn_callbacks(&(ffd->txn_dir_cache), pool);
+  init_txn_callbacks(fs, &(ffd->txn_dir_cache), pool);
 
   return SVN_NO_ERROR;
 }

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/dag.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/dag.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/dag.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/dag.c Mon 
Feb  9 11:23:39 2015
@@ -866,14 +866,20 @@ svn_fs_fs__dag_delete_if_mutable(svn_fs_
     {
       apr_array_header_t *entries;
       int i;
+      apr_pool_t *iterpool = svn_pool_create(pool);
 
       /* Loop over directory entries */
       SVN_ERR(svn_fs_fs__dag_dir_entries(&entries, node, pool));
       if (entries)
         for (i = 0; i < entries->nelts; ++i)
-          SVN_ERR(svn_fs_fs__dag_delete_if_mutable(fs,
-                        APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *)->id,
-                        pool));
+          {
+            svn_pool_clear(iterpool);
+            SVN_ERR(svn_fs_fs__dag_delete_if_mutable(fs,
+                          APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *)->id,
+                          iterpool));
+          }
+
+      svn_pool_destroy(iterpool);
     }
 
   /* ... then delete the node itself, after deleting any mutable

Modified: subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/fs.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/fs.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/fs.c Mon 
Feb  9 11:23:39 2015
@@ -595,6 +595,7 @@ svn_fs_fs__init(const svn_version_t *loa
     {
       { "svn_subr",  svn_subr_version },
       { "svn_delta", svn_delta_version },
+      { "svn_fs_util", svn_fs_util__version },
       { NULL, NULL }
     };
 

Modified: 
subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/fs_fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/fs_fs.c?rev=1658362&r1=1658361&r2=1658362&view=diff
==============================================================================
--- subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/fs_fs.c 
(original)
+++ subversion/branches/remove-log-addressing/subversion/libsvn_fs_fs/fs_fs.c 
Mon Feb  9 11:23:39 2015
@@ -26,6 +26,7 @@
 
 #include "svn_private_config.h"
 
+#include "svn_checksum.h"
 #include "svn_hash.h"
 #include "svn_props.h"
 #include "svn_time.h"
@@ -1211,10 +1212,45 @@ svn_fs_fs__file_length(svn_filesize_t *l
                        node_revision_t *noderev,
                        apr_pool_t *pool)
 {
-  if (noderev->data_rep)
-    *length = noderev->data_rep->expanded_size;
+  representation_t *data_rep = noderev->data_rep;
+  if (!data_rep)
+    {
+      /* Treat "no representation" as "empty file". */
+      *length = 0;
+    }
+  else if (data_rep->expanded_size)
+    {
+      /* Standard case: a non-empty file. */
+      *length = data_rep->expanded_size;
+    }
   else
-    *length = 0;
+    {
+      /* Work around a FSFS format quirk (see issue #4554).
+
+         A plain representation may specify its EXPANDED LENGTH as "0"
+         in which case, the SIZE value is what we want.
+
+         Because EXPANDED_LENGTH will also be 0 for empty files, while
+         SIZE is non-null, we need to check wether the content is
+         actually empty.  We simply compare with the MD5 checksum of
+         empty content (sha-1 is not always available).
+       */
+      svn_checksum_t *empty_md5
+        = svn_checksum_empty_checksum(svn_checksum_md5, pool);
+
+      if (memcmp(empty_md5->digest, data_rep->md5_digest,
+                 sizeof(data_rep->md5_digest)))
+        {
+          /* Contents is not empty, i.e. EXPANDED_LENGTH cannot be the
+             actual file length. */
+          *length = data_rep->size;
+        }
+      else
+        {
+          /* Contents is empty. */
+          *length = 0;
+        }
+    }
 
   return SVN_NO_ERROR;
 }


Reply via email to