You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/01/20 18:52:21 UTC

svn commit: r1653314 [15/20] - in /subversion/branches/move-tracking-2: ./ notes/ subversion/ subversion/bindings/swig/ subversion/bindings/swig/include/ subversion/bindings/swig/perl/native/ subversion/bindings/swig/perl/native/t/ subversion/bindings/...

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c Tue Jan 20 17:52:18 2015
@@ -38,6 +38,7 @@
 #include "svn_props.h"
 #include "svn_sorts.h"
 
+#include "private/svn_repos_private.h"
 #include "private/svn_mergeinfo_private.h"
 #include "private/svn_fs_private.h"
 #include "private/svn_sorts_private.h"
@@ -356,6 +357,7 @@ store_delta(apr_file_t **tempfile, svn_f
    with message WARNING_FMT formatted with the remaining variable arguments.
    Send it by calling NOTIFY_FUNC (if not null) with NOTIFY_BATON.
  */
+__attribute__((format(printf, 5, 6)))
 static void
 notify_warning(apr_pool_t *scratch_pool,
                svn_repos_notify_func_t notify_func,
@@ -382,6 +384,126 @@ notify_warning(apr_pool_t *scratch_pool,
 
 /*----------------------------------------------------------------------*/
 
+/* Write to STREAM the header in HEADERS named KEY, if present.
+ */
+static svn_error_t *
+write_header(svn_stream_t *stream,
+             apr_hash_t *headers,
+             const char *key,
+             apr_pool_t *scratch_pool)
+{
+  const char *val = svn_hash_gets(headers, key);
+
+  if (val)
+    {
+      SVN_ERR(svn_stream_printf(stream, scratch_pool,
+                                "%s: %s\n", key, val));
+    }
+  return SVN_NO_ERROR;
+}
+
+/* Write headers, in arbitrary order.
+ * ### TODO: use a stable order
+ * ### Modifies HEADERS.
+ */
+static svn_error_t *
+write_revision_headers(svn_stream_t *stream,
+                       apr_hash_t *headers,
+                       apr_pool_t *scratch_pool)
+{
+  const char **h;
+  apr_hash_index_t *hi;
+
+  static const char *revision_headers_order[] =
+  {
+    SVN_REPOS_DUMPFILE_REVISION_NUMBER,  /* must be first */
+    NULL
+  };
+
+  /* Write some headers in a given order */
+  for (h = revision_headers_order; *h; h++)
+    {
+      SVN_ERR(write_header(stream, headers, *h, scratch_pool));
+      svn_hash_sets(headers, *h, NULL);
+    }
+
+  /* Write any and all remaining headers except Content-length.
+   * ### TODO: use a stable order
+   */
+  for (hi = apr_hash_first(scratch_pool, headers); hi; hi = apr_hash_next(hi))
+    {
+      const char *key = apr_hash_this_key(hi);
+
+      if (strcmp(key, SVN_REPOS_DUMPFILE_CONTENT_LENGTH) != 0)
+        SVN_ERR(write_header(stream, headers, key, scratch_pool));
+    }
+
+  /* Content-length must be last */
+  SVN_ERR(write_header(stream, headers, SVN_REPOS_DUMPFILE_CONTENT_LENGTH,
+                       scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_repos__dump_revision_record(svn_stream_t *dump_stream,
+                                svn_revnum_t revision,
+                                apr_hash_t *extra_headers,
+                                apr_hash_t *revprops,
+                                svn_boolean_t props_section_always,
+                                apr_pool_t *scratch_pool)
+{
+  svn_stringbuf_t *propstring = NULL;
+  apr_hash_t *headers;
+
+  if (extra_headers)
+    headers = apr_hash_copy(scratch_pool, extra_headers);
+  else
+    headers = apr_hash_make(scratch_pool);
+
+  /* ### someday write a revision-content-checksum */
+
+  svn_hash_sets(headers, SVN_REPOS_DUMPFILE_REVISION_NUMBER,
+                apr_psprintf(scratch_pool, "%ld", revision));
+
+  if (apr_hash_count(revprops) || props_section_always)
+    {
+      svn_stream_t *propstream;
+
+      propstring = svn_stringbuf_create_empty(scratch_pool);
+      propstream = svn_stream_from_stringbuf(propstring, scratch_pool);
+      SVN_ERR(svn_hash_write2(revprops, propstream, "PROPS-END", scratch_pool));
+      SVN_ERR(svn_stream_close(propstream));
+
+      svn_hash_sets(headers, SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH,
+                    apr_psprintf(scratch_pool,
+                                 "%" APR_SIZE_T_FMT, propstring->len));
+    }
+
+  /* Write out a regular Content-length header for the benefit of
+     non-Subversion RFC-822 parsers. */
+  svn_hash_sets(headers, SVN_REPOS_DUMPFILE_CONTENT_LENGTH,
+                apr_psprintf(scratch_pool,
+                             "%" APR_SIZE_T_FMT, propstring->len));
+  SVN_ERR(write_revision_headers(dump_stream, headers, scratch_pool));
+
+  /* End of headers */
+  SVN_ERR(svn_stream_puts(dump_stream, "\n"));
+
+  /* Property data. */
+  if (propstring)
+    {
+      SVN_ERR(svn_stream_write(dump_stream, propstring->data, &propstring->len));
+    }
+
+  /* put an end to revision */
+  SVN_ERR(svn_stream_puts(dump_stream, "\n"));
+
+  return SVN_NO_ERROR;
+}
+
+/*----------------------------------------------------------------------*/
+
 /** An editor which dumps node-data in 'dumpfile format' to a file. **/
 
 /* Look, mom!  No file batons! */
@@ -426,10 +548,6 @@ struct edit_baton
      revisions older than OLDEST_DUMPED_REV. */
   svn_boolean_t *found_old_mergeinfo;
 
-  /* reusable buffer for writing file contents */
-  char buffer[SVN__STREAM_CHUNK_SIZE];
-  apr_size_t bufsize;
-
   /* Structure allows us to verify the paths currently being dumped.
      If NULL, validity checks are being skipped. */
   path_tracker_t *path_tracker;
@@ -693,7 +811,6 @@ extract_mergeinfo_paths(void *baton, con
 struct filter_mergeinfo_paths_baton
 {
   apr_hash_t *paths;
-  svn_membuf_t buffer;
 };
 
 /* Compare two sets of denormalized paths from mergeinfo entries,
@@ -800,7 +917,6 @@ check_mergeinfo_normalization(const char
       normalized_paths = extract_baton.result;
 
       filter_baton.paths = added_paths;
-      filter_baton.buffer = extract_baton.buffer;
       SVN_ERR(svn_iter_apr_hash(NULL, oldinfo,
                                 filter_mergeinfo_paths,
                                 &filter_baton, pool));
@@ -826,7 +942,7 @@ check_mergeinfo_normalization(const char
 
    Write out a node record for PATH of type KIND under EB->FS_ROOT.
    ACTION describes what is happening to the node (see enum svn_node_action).
-   Write record to writable EB->STREAM, using EB->BUFFER to write in chunks.
+   Write record to writable EB->STREAM.
 
    If the node was itself copied, IS_COPY is TRUE and the
    path/revision of the copy source are in CMP_PATH/CMP_REV.  If
@@ -977,6 +1093,8 @@ dump_node(struct edit_baton *eb,
 
           /* we can leave this routine quietly now, don't need to dump
              any content;  that was already done in the second record. */
+          /* ### This fall-through results in writing an extra two blank
+             lines. This has been the case since r842476, pre-1.0. */
           must_dump_text = FALSE;
           must_dump_props = FALSE;
         }
@@ -1651,7 +1769,6 @@ get_dump_editor(const svn_delta_editor_t
   eb->notify_func = notify_func;
   eb->notify_baton = notify_baton;
   eb->oldest_dumped_rev = oldest_dumped_rev;
-  eb->bufsize = sizeof(eb->buffer);
   eb->path = apr_pstrdup(pool, root_path);
   SVN_ERR(svn_fs_revision_root(&(eb->fs_root), fs, to_rev, pool));
   eb->fs = fs;
@@ -1712,15 +1829,10 @@ write_revision_record(svn_stream_t *stre
                       svn_revnum_t rev,
                       apr_pool_t *pool)
 {
-  apr_size_t len;
   apr_hash_t *props;
-  svn_stringbuf_t *encoded_prophash;
   apr_time_t timetemp;
   svn_string_t *datevalue;
-  svn_stream_t *propstream;
 
-  /* Read the revision props even if we're aren't going to dump
-     them for verification purposes */
   SVN_ERR(svn_fs_revision_proplist(&props, fs, rev, pool));
 
   /* Run revision date properties through the time conversion to
@@ -1735,33 +1847,10 @@ write_revision_record(svn_stream_t *stre
       svn_hash_sets(props, SVN_PROP_REVISION_DATE, datevalue);
     }
 
-  encoded_prophash = svn_stringbuf_create_ensure(0, pool);
-  propstream = svn_stream_from_stringbuf(encoded_prophash, pool);
-  SVN_ERR(svn_hash_write2(props, propstream, "PROPS-END", pool));
-  SVN_ERR(svn_stream_close(propstream));
-
-  /* ### someday write a revision-content-checksum */
-
-  SVN_ERR(svn_stream_printf(stream, pool,
-                            SVN_REPOS_DUMPFILE_REVISION_NUMBER
-                            ": %ld\n", rev));
-  SVN_ERR(svn_stream_printf(stream, pool,
-                            SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
-                            ": %" APR_SIZE_T_FMT "\n",
-                            encoded_prophash->len));
-
-  /* Write out a regular Content-length header for the benefit of
-     non-Subversion RFC-822 parsers. */
-  SVN_ERR(svn_stream_printf(stream, pool,
-                            SVN_REPOS_DUMPFILE_CONTENT_LENGTH
-                            ": %" APR_SIZE_T_FMT "\n\n",
-                            encoded_prophash->len));
-
-  len = encoded_prophash->len;
-  SVN_ERR(svn_stream_write(stream, encoded_prophash->data, &len));
-
-  len = 1;
-  return svn_stream_write(stream, "\n", &len);
+  SVN_ERR(svn_repos__dump_revision_record(stream, rev, NULL, props,
+                                          TRUE /*props_section_always*/,
+                                          pool));
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/load-fs-vtable.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/load-fs-vtable.c Tue Jan 20 17:52:18 2015
@@ -31,11 +31,9 @@
 #include "svn_string.h"
 #include "svn_props.h"
 #include "repos.h"
-#include "svn_private_config.h"
 #include "svn_mergeinfo.h"
 #include "svn_checksum.h"
 #include "svn_subst.h"
-#include "svn_ctype.h"
 #include "svn_dirent_uri.h"
 
 #include <apr_lib.h>
@@ -43,6 +41,7 @@
 #include "private/svn_fspath.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_mergeinfo_private.h"
+#include "private/svn_repos_private.h"
 
 /*----------------------------------------------------------------------*/
 
@@ -84,9 +83,9 @@ struct parse_baton
      SVN_INVALID_REVNUM. */
   svn_revnum_t last_rev_mapped;
 
-  /* The oldest old revision loaded from the dump stream.  If no revisions
+  /* The oldest revision loaded from the dump stream.  If no revisions
      have been loaded yet, this is set to SVN_INVALID_REVNUM. */
-  svn_revnum_t oldest_old_rev;
+  svn_revnum_t oldest_dumpstream_rev;
 };
 
 struct revision_baton
@@ -194,8 +193,6 @@ change_node_prop(svn_fs_root_t *txn_root
 
 /* Prepend the mergeinfo source paths in MERGEINFO_ORIG with PARENT_DIR, and
    return it in *MERGEINFO_VAL. */
-/* ### FIXME:  Consider somehow sharing code with
-   ### svnrdump/load_editor.c:prefix_mergeinfo_paths() */
 static svn_error_t *
 prefix_mergeinfo_paths(svn_string_t **mergeinfo_val,
                        const svn_string_t *mergeinfo_orig,
@@ -227,13 +224,20 @@ prefix_mergeinfo_paths(svn_string_t **me
 
 /* Examine the mergeinfo in INITIAL_VAL, renumber revisions in rangelists
    as appropriate, and return the (possibly new) mergeinfo in *FINAL_VAL
-   (allocated from POOL). */
-/* ### FIXME:  Consider somehow sharing code with
-   ### svnrdump/load_editor.c:renumber_mergeinfo_revs() */
+   (allocated from POOL).
+
+   Adjust any mergeinfo revisions not older than OLDEST_DUMPSTREAM_REV by
+   using REV_MAP which maps (svn_revnum_t) old rev to (svn_revnum_t) new rev.
+
+   Adjust any mergeinfo revisions older than OLDEST_DUMPSTREAM_REV by
+   (-OLDER_REVS_OFFSET), dropping any that become <= 0.
+ */
 static svn_error_t *
 renumber_mergeinfo_revs(svn_string_t **final_val,
                         const svn_string_t *initial_val,
-                        struct revision_baton *rb,
+                        apr_hash_t *rev_map,
+                        svn_revnum_t oldest_dumpstream_rev,
+                        apr_int32_t older_revs_offset,
                         apr_pool_t *pool)
 {
   apr_pool_t *subpool = svn_pool_create(pool);
@@ -248,19 +252,22 @@ renumber_mergeinfo_revs(svn_string_t **f
      Remove mergeinfo older than the oldest revision in the dump stream
      and adjust its revisions by the difference between the head rev of
      the target repository and the current dump stream rev. */
-  if (rb->pb->oldest_old_rev > 1)
+  if (oldest_dumpstream_rev > 1)
     {
+      /* predates_stream_mergeinfo := mergeinfo that refers to revs before
+         oldest_dumpstream_rev */
       SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
         &predates_stream_mergeinfo, mergeinfo,
-        rb->pb->oldest_old_rev - 1, 0,
+        oldest_dumpstream_rev - 1, 0,
         TRUE, subpool, subpool));
+      /* mergeinfo := mergeinfo that refers to revs >= oldest_dumpstream_rev */
       SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
         &mergeinfo, mergeinfo,
-        rb->pb->oldest_old_rev - 1, 0,
+        oldest_dumpstream_rev - 1, 0,
         FALSE, subpool, subpool));
       SVN_ERR(svn_mergeinfo__adjust_mergeinfo_rangelists(
         &predates_stream_mergeinfo, predates_stream_mergeinfo,
-        -rb->rev_offset, subpool, subpool));
+        -older_revs_offset, subpool, subpool));
     }
   else
     {
@@ -271,7 +278,6 @@ renumber_mergeinfo_revs(svn_string_t **f
     {
       const char *merge_source = apr_hash_this_key(hi);
       svn_rangelist_t *rangelist = apr_hash_this_val(hi);
-      struct parse_baton *pb = rb->pb;
       int i;
 
       /* Possibly renumber revisions in merge source's rangelist. */
@@ -280,27 +286,27 @@ renumber_mergeinfo_revs(svn_string_t **f
           svn_revnum_t rev_from_map;
           svn_merge_range_t *range = APR_ARRAY_IDX(rangelist, i,
                                                    svn_merge_range_t *);
-          rev_from_map = get_revision_mapping(pb->rev_map, range->start);
+          rev_from_map = get_revision_mapping(rev_map, range->start);
           if (SVN_IS_VALID_REVNUM(rev_from_map))
             {
               range->start = rev_from_map;
             }
-          else if (range->start == pb->oldest_old_rev - 1)
+          else if (range->start == oldest_dumpstream_rev - 1)
             {
               /* Since the start revision of svn_merge_range_t are not
                  inclusive there is one possible valid start revision that
-                 won't be found in the PB->REV_MAP mapping of load stream
+                 won't be found in the REV_MAP mapping of load stream
                  revsions to loaded revisions: The revision immediately
                  preceding the oldest revision from the load stream.
                  This is a valid revision for mergeinfo, but not a valid
-                 copy from revision (which PB->REV_MAP also maps for) so it
+                 copy from revision (which REV_MAP also maps for) so it
                  will never be in the mapping.
 
                  If that is what we have here, then find the mapping for the
                  oldest rev from the load stream and subtract 1 to get the
                  renumbered, non-inclusive, start revision. */
-              rev_from_map = get_revision_mapping(pb->rev_map,
-                                                  pb->oldest_old_rev);
+              rev_from_map = get_revision_mapping(rev_map,
+                                                  oldest_dumpstream_rev);
               if (SVN_IS_VALID_REVNUM(rev_from_map))
                 range->start = rev_from_map - 1;
             }
@@ -317,7 +323,7 @@ renumber_mergeinfo_revs(svn_string_t **f
               continue;
             }
 
-          rev_from_map = get_revision_mapping(pb->rev_map, range->end);
+          rev_from_map = get_revision_mapping(rev_map, range->end);
           if (SVN_IS_VALID_REVNUM(rev_from_map))
             range->end = rev_from_map;
         }
@@ -325,19 +331,12 @@ renumber_mergeinfo_revs(svn_string_t **f
     }
 
   if (predates_stream_mergeinfo)
+    {
       SVN_ERR(svn_mergeinfo_merge2(final_mergeinfo, predates_stream_mergeinfo,
                                    subpool, subpool));
+    }
 
-  SVN_ERR(svn_mergeinfo_sort(final_mergeinfo, subpool));
-
-  /* Mergeinfo revision sources for r0 and r1 are invalid; you can't merge r0
-     or r1.  However, svndumpfilter can be abused to produce r1 merge source
-     revs.  So if we encounter any, then strip them out, no need to put them
-     into the load target. */
-  SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(&final_mergeinfo,
-                                                    final_mergeinfo,
-                                                    1, 0, FALSE,
-                                                    subpool, subpool));
+  SVN_ERR(svn_mergeinfo__canonicalize_ranges(final_mergeinfo, subpool));
 
   SVN_ERR(svn_mergeinfo_to_string(final_val, final_mergeinfo, pool));
   svn_pool_destroy(subpool);
@@ -350,6 +349,12 @@ renumber_mergeinfo_revs(svn_string_t **f
 /** vtable for doing commits to a fs **/
 
 
+/* Make a node baton, parsing the relevant HEADERS.
+ *
+ * If RB->pb->parent_dir:
+ *   prefix it to NB->path
+ *   prefix it to NB->copyfrom_path (if present)
+ */
 static svn_error_t *
 make_node_baton(struct node_baton **node_baton_p,
                 apr_hash_t *headers,
@@ -436,6 +441,10 @@ make_node_baton(struct node_baton **node
   return SVN_NO_ERROR;
 }
 
+/* Make a revision baton, parsing the relevant HEADERS.
+ *
+ * Set RB->skipped iff the revision number is outside the range given in PB.
+ */
 static struct revision_baton *
 make_revision_baton(apr_hash_t *headers,
                     struct parse_baton *pb,
@@ -514,8 +523,8 @@ new_revision_record(void **revision_bato
         }
 
       /* Stash the oldest "old" revision committed from the load stream. */
-      if (!SVN_IS_VALID_REVNUM(pb->oldest_old_rev))
-        pb->oldest_old_rev = rb->rev;
+      if (!SVN_IS_VALID_REVNUM(pb->oldest_dumpstream_rev))
+        pb->oldest_dumpstream_rev = rb->rev;
     }
 
   /* If we're skipping this revision, try to notify someone. */
@@ -542,7 +551,11 @@ new_revision_record(void **revision_bato
 
 
 
-/* Factorized helper func for new_node_record() */
+/* Perform a copy or a plain add.
+ *
+ * For a copy, also adjust the copy-from rev, check any copy-source checksum,
+ * and send a notification.
+ */
 static svn_error_t *
 maybe_add_with_history(struct node_baton *nb,
                        struct revision_baton *rb,
@@ -753,6 +766,67 @@ set_revision_property(void *baton,
 }
 
 
+svn_error_t *
+svn_repos__adjust_mergeinfo_property(svn_string_t **new_value_p,
+                                     const svn_string_t *old_value,
+                                     const char *parent_dir,
+                                     apr_hash_t *rev_map,
+                                     svn_revnum_t oldest_dumpstream_rev,
+                                     apr_int32_t older_revs_offset,
+                                     svn_repos_notify_func_t notify_func,
+                                     void *notify_baton,
+                                     apr_pool_t *result_pool,
+                                     apr_pool_t *scratch_pool)
+{
+  svn_string_t prop_val = *old_value;
+
+  /* Tolerate mergeinfo with "\r\n" line endings because some
+     dumpstream sources might contain as much.  If so normalize
+     the line endings to '\n' and notify that we have made this
+     correction. */
+  if (strstr(prop_val.data, "\r"))
+    {
+      const char *prop_eol_normalized;
+
+      SVN_ERR(svn_subst_translate_cstring2(prop_val.data,
+                                           &prop_eol_normalized,
+                                           "\n",  /* translate to LF */
+                                           FALSE, /* no repair */
+                                           NULL,  /* no keywords */
+                                           FALSE, /* no expansion */
+                                           result_pool));
+      prop_val.data = prop_eol_normalized;
+      prop_val.len = strlen(prop_eol_normalized);
+
+      if (notify_func)
+        {
+          svn_repos_notify_t *notify
+                  = svn_repos_notify_create(
+                                svn_repos_notify_load_normalized_mergeinfo,
+                                scratch_pool);
+
+          notify_func(notify_baton, notify, scratch_pool);
+        }
+    }
+
+  /* Renumber mergeinfo as appropriate. */
+  SVN_ERR(renumber_mergeinfo_revs(new_value_p, &prop_val,
+                                  rev_map, oldest_dumpstream_rev,
+                                  older_revs_offset,
+                                  result_pool));
+
+  if (parent_dir)
+    {
+      /* Prefix the merge source paths with PARENT_DIR. */
+      /* ASSUMPTION: All source paths are included in the dump stream. */
+      SVN_ERR(prefix_mergeinfo_paths(new_value_p, *new_value_p,
+                                     parent_dir, result_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
 static svn_error_t *
 set_node_property(void *baton,
                   const char *name,
@@ -766,55 +840,49 @@ set_node_property(void *baton,
   if (rb->skipped)
     return SVN_NO_ERROR;
 
+  /* Adjust mergeinfo. If this fails, presumably because the mergeinfo
+     property has an ill-formed value, then we must not fail to load
+     the repository (at least if it's a simple load with no revision
+     offset adjustments, path changes, etc.) so just warn and leave it
+     as it is. */
   if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
     {
-      svn_string_t prop_val = *value;
-      svn_string_t *renumbered_mergeinfo;
+      svn_string_t *new_value;
+      svn_error_t *err;
 
-      /* Tolerate mergeinfo with "\r\n" line endings because some
-         dumpstream sources might contain as much.  If so normalize
-         the line endings to '\n' and make a notification to
-         PARSE_BATON->FEEDBACK_STREAM that we have made this
-         correction. */
-      if (strstr(prop_val.data, "\r"))
+      err = svn_repos__adjust_mergeinfo_property(&new_value, value,
+                                                 pb->parent_dir,
+                                                 pb->rev_map,
+                                                 pb->oldest_dumpstream_rev,
+                                                 rb->rev_offset,
+                                                 pb->notify_func, pb->notify_baton,
+                                                 nb->pool, pb->notify_pool);
+      svn_pool_clear(pb->notify_pool);
+      if (err)
         {
-          const char *prop_eol_normalized;
-
-          SVN_ERR(svn_subst_translate_cstring2(prop_val.data,
-                                               &prop_eol_normalized,
-                                               "\n",  /* translate to LF */
-                                               FALSE, /* no repair */
-                                               NULL,  /* no keywords */
-                                               FALSE, /* no expansion */
-                                               nb->pool));
-          prop_val.data = prop_eol_normalized;
-          prop_val.len = strlen(prop_eol_normalized);
-
+          if (pb->validate_props)
+            {
+              return svn_error_quick_wrap(
+                       err,
+                       _("Invalid svn:mergeinfo value"));
+            }
           if (pb->notify_func)
             {
-              /* ### TODO: Use proper scratch pool instead of pb->notify_pool */
               svn_repos_notify_t *notify
-                      = svn_repos_notify_create(
-                                    svn_repos_notify_load_normalized_mergeinfo,
-                                    pb->notify_pool);
+                = svn_repos_notify_create(svn_repos_notify_warning,
+                                          pb->notify_pool);
 
+              notify->warning = svn_repos_notify_warning_invalid_mergeinfo;
+              notify->warning_str = _("Invalid svn:mergeinfo value; "
+                                      "leaving unchanged");
               pb->notify_func(pb->notify_baton, notify, pb->notify_pool);
               svn_pool_clear(pb->notify_pool);
             }
+          svn_error_clear(err);
         }
-
-      /* Renumber mergeinfo as appropriate. */
-      SVN_ERR(renumber_mergeinfo_revs(&renumbered_mergeinfo, &prop_val, rb,
-                                      nb->pool));
-      value = renumbered_mergeinfo;
-      if (pb->parent_dir)
+      else
         {
-          /* Prefix the merge source paths with PB->parent_dir. */
-          /* ASSUMPTION: All source paths are included in the dump stream. */
-          svn_string_t *mergeinfo_val;
-          SVN_ERR(prefix_mergeinfo_paths(&mergeinfo_val, value,
-                                         pb->parent_dir, nb->pool));
-          value = mergeinfo_val;
+          value = new_value;
         }
     }
 
@@ -1082,7 +1150,7 @@ close_revision(void *baton)
 
 
 svn_error_t *
-svn_repos_get_fs_build_parser4(const svn_repos_parse_fns3_t **callbacks,
+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,
@@ -1091,6 +1159,9 @@ svn_repos_get_fs_build_parser4(const svn
                                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)
@@ -1132,10 +1203,13 @@ svn_repos_get_fs_build_parser4(const svn
   pb->pool = pool;
   pb->notify_pool = svn_pool_create(pool);
   pb->rev_map = apr_hash_make(pool);
-  pb->oldest_old_rev = SVN_INVALID_REVNUM;
+  pb->oldest_dumpstream_rev = SVN_INVALID_REVNUM;
   pb->last_rev_mapped = SVN_INVALID_REVNUM;
   pb->start_rev = start_rev;
   pb->end_rev = end_rev;
+  pb->use_pre_commit_hook = use_pre_commit_hook;
+  pb->use_post_commit_hook = use_post_commit_hook;
+  pb->ignore_dates = ignore_dates;
 
   *callbacks = parser;
   *parse_baton = pb;
@@ -1162,28 +1236,23 @@ svn_repos_load_fs5(svn_repos_t *repos,
 {
   const svn_repos_parse_fns3_t *parser;
   void *parse_baton;
-  struct parse_baton *pb;
 
   /* This is really simple. */
 
-  SVN_ERR(svn_repos_get_fs_build_parser4(&parser, &parse_baton,
+  SVN_ERR(svn_repos_get_fs_build_parser5(&parser, &parse_baton,
                                          repos,
                                          start_rev, end_rev,
                                          TRUE, /* look for copyfrom revs */
                                          validate_props,
                                          uuid_action,
                                          parent_dir,
+                                         use_pre_commit_hook,
+                                         use_post_commit_hook,
+                                         ignore_dates,
                                          notify_func,
                                          notify_baton,
                                          pool));
 
-  /* Heh.  We know this is a parse_baton.  This file made it.  So
-     cast away, and set our hook booleans.  */
-  pb = parse_baton;
-  pb->use_pre_commit_hook = use_pre_commit_hook;
-  pb->use_post_commit_hook = use_post_commit_hook;
-  pb->ignore_dates = ignore_dates;
-
   return svn_repos_parse_dumpstream3(dumpstream, parser, parse_baton, FALSE,
                                      cancel_func, cancel_baton, pool);
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/log.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/log.c Tue Jan 20 17:52:18 2015
@@ -1070,6 +1070,7 @@ fill_log_entry(svn_log_entry_t *log_entr
 {
   apr_hash_t *r_props, *changed_paths = NULL;
   svn_boolean_t get_revprops = TRUE, censor_revprops = FALSE;
+  svn_boolean_t want_revprops = !revprops || revprops->nelts;
 
   /* Discover changed paths if the user requested them
      or if we need to check that they are readable. */
@@ -1111,7 +1112,7 @@ fill_log_entry(svn_log_entry_t *log_entr
         changed_paths = NULL;
     }
 
-  if (get_revprops)
+  if (get_revprops && want_revprops)
     {
       /* User is allowed to see at least some revprops. */
       SVN_ERR(svn_fs_revision_proplist(&r_props, fs, rev, pool));

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c Tue Jan 20 17:52:18 2015
@@ -31,6 +31,7 @@
 #include "cache.h"
 #include "svn_string.h"
 #include "svn_sorts.h"  /* get the MIN macro */
+#include "private/svn_atomic.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_mutex.h"
 #include "private/svn_pseudo_md5.h"
@@ -364,7 +365,7 @@ typedef struct entry_t
   /* Number of (read) hits for this entry. Will be reset upon write.
    * Only valid for used entries.
    */
-  apr_uint32_t hit_count;
+  svn_atomic_t hit_count;
 
   /* Reference to the next used entry in the order defined by offset.
    * NO_INDEX indicates the end of the list; this entry must be referenced
@@ -557,19 +558,14 @@ struct svn_membuffer_t
    */
   cache_level_t l2;
 
+
   /* Number of used dictionary entries, i.e. number of cached items.
-   * In conjunction with hit_count, this is used calculate the average
-   * hit count as part of the randomized LFU algorithm.
+   * Purely statistical information that may be used for profiling only.
+   * Updates are not synchronized and values may be nonsensicle on some
+   * platforms.
    */
   apr_uint32_t used_entries;
 
-  /* Sum of (read) hit counts of all used dictionary entries.
-   * In conjunction used_entries used_entries, this is used calculate
-   * the average hit count as part of the randomized LFU algorithm.
-   */
-  apr_uint64_t hit_count;
-
-
   /* Total number of calls to membuffer_cache_get.
    * Purely statistical information that may be used for profiling only.
    * Updates are not synchronized and values may be nonsensicle on some
@@ -608,12 +604,6 @@ struct svn_membuffer_t
    */
   svn_boolean_t allow_blocking_writes;
 #endif
-
-  /* All counters that have consistency requirements on thems (currently,
-   * that's only the hit counters) must use this mutex to serialize their
-   * updates.
-   */
-  svn_mutex__t *counter_mutex;
 };
 
 /* Align integer VALUE to the next ITEM_ALIGNMENT boundary.
@@ -715,7 +705,7 @@ unlock_cache(svn_membuffer_t *cache, svn
 #if APR_HAS_THREADS
 #  if USE_SIMPLE_MUTEX
 
-  return svn_mutex__unlock(cache->lock, SVN_NO_ERROR);
+  return svn_mutex__unlock(cache->lock, err);
 
 #  else
 
@@ -1027,7 +1017,6 @@ drop_entry(svn_membuffer_t *cache, entry
   /* update global cache usage counters
    */
   cache->used_entries--;
-  cache->hit_count -= entry->hit_count;
   cache->data_used -= entry->size;
 
   /* extend the insertion window, if the entry happens to border it
@@ -1163,7 +1152,6 @@ let_entry_age(svn_membuffer_t *cache, en
 
   if (hits_removed)
     {
-      cache->hit_count -= hits_removed;
       entry->hit_count -= hits_removed;
     }
   else
@@ -1795,7 +1783,6 @@ svn_cache__membuffer_cache_create(svn_me
       c[seg].max_entry_size = max_entry_size;
 
       c[seg].used_entries = 0;
-      c[seg].hit_count = 0;
       c[seg].total_reads = 0;
       c[seg].total_writes = 0;
       c[seg].total_hits = 0;
@@ -1836,11 +1823,6 @@ svn_cache__membuffer_cache_create(svn_me
        */
       c[seg].allow_blocking_writes = allow_blocking_writes;
 #endif
-
-      /* Since a simple mutex already guarantees fully serialized access,
-         we need this mutex only when we use multple-reader-1-writer locks. */
-      SVN_ERR(svn_mutex__init(&c[seg].counter_mutex,
-                              thread_safe && !USE_SIMPLE_MUTEX, pool));
     }
 
   /* done here
@@ -2067,21 +2049,17 @@ membuffer_cache_set(svn_membuffer_t *cac
 
 /* Count a hit in ENTRY within CACHE.
  */
-static svn_error_t *
+static void
 increment_hit_counters(svn_membuffer_t *cache, entry_t *entry)
 {
   /* To minimize the memory footprint of the cache index, we limit local
-   * hit counters to 32 bits.  These may overflow and we must make sure that
-   * the global sums are still the sum of all local counters. */
-  if (++entry->hit_count == 0)
-    cache->hit_count -= APR_UINT32_MAX;
-  else
-    cache->hit_count++;
+   * hit counters to 32 bits.  These may overflow but we don't really
+   * care because at worst, ENTRY will be dropped from cache once every
+   * few billion hits. */
+  svn_atomic_inc(&entry->hit_count);
 
   /* That one is for stats only. */
   cache->total_hits++;
-
-  return SVN_NO_ERROR;
 }
 
 /* Look for the cache entry in group GROUP_INDEX of CACHE, identified
@@ -2140,8 +2118,7 @@ membuffer_cache_get_internal(svn_membuff
 
   /* update hit statistics
    */
-  SVN_MUTEX__WITH_LOCK(cache->counter_mutex,
-                       increment_hit_counters(cache, entry));
+  increment_hit_counters(cache, entry);
   *item_size = entry->size;
 
   return SVN_NO_ERROR;
@@ -2205,9 +2182,7 @@ membuffer_cache_has_key_internal(svn_mem
          again.  While items in L1 are well protected for a while, L2
          items may get evicted soon.  Thus, mark all them as "hit" to give
          them a higher chance of survival. */
-      SVN_MUTEX__WITH_LOCK(cache->counter_mutex,
-                           increment_hit_counters(cache, entry));
-
+      increment_hit_counters(cache, entry);
       *found = TRUE;
     }
   else
@@ -2276,9 +2251,7 @@ membuffer_cache_get_partial_internal(svn
   else
     {
       *found = TRUE;
-
-      SVN_MUTEX__WITH_LOCK(cache->counter_mutex,
-                           increment_hit_counters(cache, entry));
+      increment_hit_counters(cache, entry);
 
 #ifdef SVN_DEBUG_CACHE_MEMBUFFER
 
@@ -2368,8 +2341,7 @@ membuffer_cache_set_partial_internal(svn
       char *orig_data = data;
       apr_size_t size = entry->size;
 
-      SVN_MUTEX__WITH_LOCK(cache->counter_mutex,
-                           increment_hit_counters(cache, entry));
+      increment_hit_counters(cache, entry);
       cache->total_writes++;
 
 #ifdef SVN_DEBUG_CACHE_MEMBUFFER
@@ -2398,6 +2370,8 @@ membuffer_cache_set_partial_internal(svn
            * We better drop that.
            */
           drop_entry(cache, entry);
+
+          return err;
         }
       else
         {

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/cache.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/cache.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/cache.c Tue Jan 20 17:52:18 2015
@@ -259,15 +259,15 @@ svn_cache__format_info(const svn_cache__
 
       int i;
       int count = sizeof(info->histogram) / sizeof(info->histogram[0]);
-      for (i = 0; i < count; ++i)
+      for (i = count - 1; i >= 0; --i)
         if (info->histogram[i] > 0 || text->len > 0)
           text = svn_stringbuf_createf(result_pool,
                                        i == count - 1
-                                         ? "%12" APR_UINT64_T_FMT
-                                           " buckets with >%d entries\n%s"
-                                         : "%12" APR_UINT64_T_FMT
-                                           " buckets with %d entries\n%s",
-                                        info->histogram[i], i, text->data);
+                                         ? "%s%12" APR_UINT64_T_FMT
+                                           " buckets with >%d entries\n"
+                                         : "%s%12" APR_UINT64_T_FMT
+                                           " buckets with %d entries\n",
+                                       text->data, info->histogram[i], i);
 
       histogram = text->data;
     }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/cache_config.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/cache_config.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/cache_config.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/cache_config.c Tue Jan 20 17:52:18 2015
@@ -27,6 +27,7 @@
 #include "private/svn_cache.h"
 
 #include "svn_pools.h"
+#include "svn_sorts.h"
 
 /* The cache settings as a process-wide singleton.
  */
@@ -80,7 +81,13 @@ initialize_cache(void *baton, apr_pool_t
   svn_membuffer_t **cache_p = baton;
   svn_membuffer_t *cache = NULL;
 
-  apr_uint64_t cache_size = cache_settings.cache_size;
+  /* Limit the cache size to about half the available address space
+   * (typ. 1G under 32 bits).
+   */
+  apr_uint64_t cache_size = MIN(cache_settings.cache_size,
+                                (apr_uint64_t)SVN_MAX_OBJECT_SIZE / 2);
+
+  /* Create caches at all? */
   if (cache_size)
     {
       svn_error_t *err;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/config.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/config.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/config.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/config.c Tue Jan 20 17:52:18 2015
@@ -514,14 +514,15 @@ make_string_from_option(const char **val
           expand_option_value(cfg, section, opt->value, &opt->x_value, tmp_pool);
           opt->expanded = TRUE;
 
-          if (!x_pool)
+          if (x_pool != cfg->x_pool)
             {
               /* Grab the fully expanded value from tmp_pool before its
                  disappearing act. */
               if (opt->x_value)
                 opt->x_value = apr_pstrmemdup(cfg->x_pool, opt->x_value,
                                               strlen(opt->x_value));
-              svn_pool_destroy(tmp_pool);
+              if (!x_pool)
+                svn_pool_destroy(tmp_pool);
             }
         }
       else

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/error.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/error.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/error.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/error.c Tue Jan 20 17:52:18 2015
@@ -288,6 +288,8 @@ svn_error_compose(svn_error_t *chain, sv
       *chain = *new_err;
       if (chain->message)
         chain->message = apr_pstrdup(pool, new_err->message);
+      if (chain->file)
+        chain->file = apr_pstrdup(pool, new_err->file);
       chain->pool = pool;
 #if defined(SVN_DEBUG)
       if (! new_err->child)
@@ -364,6 +366,8 @@ svn_error_dup(const svn_error_t *err)
       tmp_err->pool = pool;
       if (tmp_err->message)
         tmp_err->message = apr_pstrdup(pool, tmp_err->message);
+      if (tmp_err->file)
+        tmp_err->file = apr_pstrdup(pool, tmp_err->file);
     }
 
 #if defined(SVN_DEBUG)
@@ -425,10 +429,8 @@ svn_error_purge_tracing(svn_error_t *err
       if (! err)
         return svn_error_create(
                  SVN_ERR_ASSERTION_ONLY_TRACING_LINKS,
-                 svn_error_compose_create(
-                   svn_error__malfunction(TRUE, __FILE__, __LINE__,
-                                          NULL /* ### say something? */),
-                   err),
+                 svn_error__malfunction(TRUE, __FILE__, __LINE__,
+                                        NULL /* ### say something? */),
                  NULL);
 
       /* Copy the current error except for its child error pointer

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c Tue Jan 20 17:52:18 2015
@@ -1170,10 +1170,10 @@ svn_io_make_dir_recursively(const char *
 }
 
 svn_error_t *
-svn_io_file_create_binary(const char *file,
-                          const char *contents,
-                          apr_size_t length,
-                          apr_pool_t *pool)
+svn_io_file_create_bytes(const char *file,
+                         const void *contents,
+                         apr_size_t length,
+                         apr_pool_t *pool)
 {
   apr_file_t *f;
   apr_size_t written;
@@ -1209,18 +1209,17 @@ svn_io_file_create(const char *file,
                    const char *contents,
                    apr_pool_t *pool)
 {
-  return svn_error_trace(svn_io_file_create_binary(file, contents,
-                                                   contents
-                                                        ? strlen(contents)
-                                                        : 0,
-                                                   pool));
+  return svn_error_trace(svn_io_file_create_bytes(file, contents,
+                                                  contents ? strlen(contents)
+                                                           : 0,
+                                                  pool));
 }
 
 svn_error_t *
 svn_io_file_create_empty(const char *file,
                          apr_pool_t *pool)
 {
-  return svn_error_trace(svn_io_file_create_binary(file, "", 0, pool));
+  return svn_error_trace(svn_io_file_create_bytes(file, NULL, 0, pool));
 }
 
 svn_error_t *

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/mergeinfo.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/mergeinfo.c Tue Jan 20 17:52:18 2015
@@ -99,9 +99,6 @@ parse_pathname(const char **input,
   if (!last_colon)
     return svn_error_create(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                             _("Pathname not terminated by ':'"));
-  if (last_colon == *input)
-    return svn_error_create(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
-                            _("No pathname preceding ':'"));
 
   /* Tolerate relative repository paths, but convert them to absolute.
      ### Efficiency?  1 string duplication here, 2 in canonicalize. */
@@ -612,7 +609,12 @@ svn_rangelist__parse(svn_rangelist_t **r
 }
 
 /* Return TRUE, if all ranges in RANGELIST are in ascending order and do
- * not overlap.  If this returns FALSE, you probaly want to qsort() the
+ * not overlap and are not adjacent.
+ *
+ * ### Can yield false negatives: ranges of differing inheritance are
+ * allowed to be adjacent.
+ *
+ * If this returns FALSE, you probaly want to qsort() the
  * ranges and then call svn_rangelist__combine_adjacent_ranges().
  */
 static svn_boolean_t
@@ -629,6 +631,20 @@ is_rangelist_normalized(svn_rangelist_t
 }
 
 svn_error_t *
+svn_rangelist__canonicalize(svn_rangelist_t *rangelist,
+                            apr_pool_t *scratch_pool)
+{
+  if (! is_rangelist_normalized(rangelist))
+    {
+      svn_sort__array(rangelist, svn_sort_compare_ranges);
+
+      SVN_ERR(svn_rangelist__combine_adjacent_ranges(rangelist, scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_rangelist__combine_adjacent_ranges(svn_rangelist_t *rangelist,
                                        apr_pool_t *scratch_pool)
 {
@@ -715,14 +731,9 @@ parse_revision_line(const char **input,
 
   /* Sort the rangelist, combine adjacent ranges into single ranges, and
      make sure there are no overlapping ranges.  Luckily, most data in
-     svn:mergeinfo will already be in normalized form and we can skip this.
+     svn:mergeinfo will already be in normalized form and this will be quick.
    */
-  if (! is_rangelist_normalized(rangelist))
-    {
-      svn_sort__array(rangelist, svn_sort_compare_ranges);
-
-      SVN_ERR(svn_rangelist__combine_adjacent_ranges(rangelist, scratch_pool));
-    }
+  SVN_ERR(svn_rangelist__canonicalize(rangelist, scratch_pool));
 
   /* Handle any funky mergeinfo with relative merge source paths that
      might exist due to issue #3547.  It's possible that this issue allowed
@@ -1999,6 +2010,22 @@ svn_mergeinfo_sort(svn_mergeinfo_t input
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_mergeinfo__canonicalize_ranges(svn_mergeinfo_t mergeinfo,
+                                   apr_pool_t *scratch_pool)
+{
+  apr_hash_index_t *hi;
+
+  for (hi = apr_hash_first(scratch_pool, mergeinfo); hi; hi = apr_hash_next(hi))
+    {
+      apr_array_header_t *rl = apr_hash_this_val(hi);
+
+      SVN_ERR(svn_rangelist__canonicalize(rl, scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
 svn_mergeinfo_catalog_t
 svn_mergeinfo_catalog_dup(svn_mergeinfo_catalog_t mergeinfo_catalog,
                           apr_pool_t *pool)

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/prefix_string.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/prefix_string.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/prefix_string.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/prefix_string.c Tue Jan 20 17:52:18 2015
@@ -267,7 +267,7 @@ svn_prefix_string__expand(const svn_pref
   apr_size_t len = s->prefix->length + s_len;
   char *buffer = apr_palloc(pool, len + 1);
 
-  svn_string_t *result = apr_pcalloc(pool, sizeof(result));
+  svn_string_t *result = apr_pcalloc(pool, sizeof(*result));
   result->data = buffer;
   result->len = len;
   buffer[len] = '\0';

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/sqlite.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/sqlite.c Tue Jan 20 17:52:18 2015
@@ -189,6 +189,21 @@ struct svn_sqlite__value_t
                              sqlite3_errmsg((db)->db3));          \
 } while (0)
 
+#define SQLITE_ERR_CLOSE(x, db, pool) do                          \
+{                                                                 \
+  int sqlite_err__temp = (x);                                     \
+  if (sqlite_err__temp != SQLITE_OK)                              \
+    {                                                             \
+      const char *sqlite_err__msg                                 \
+        = apr_pstrdup(pool, sqlite3_errmsg((db)->db3));           \
+      return svn_error_compose_create(                            \
+           svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \
+                             NULL, "sqlite[S%d]: %s",             \
+                             sqlite_err__temp, sqlite_err__msg),  \
+           svn_sqlite__close(db));                                \
+    }                                                             \
+} while (0)
+
 #define SQLITE_ERR_MSG(x, msg) do                                \
 {                                                                \
   int sqlite_err__temp = (x);                                    \
@@ -198,6 +213,13 @@ struct svn_sqlite__value_t
                              sqlite_err__temp, msg);             \
 } while (0)
 
+#define SVN_ERR_CLOSE(x, db) do                                       \
+{                                                                     \
+  svn_error_t *svn__err = (x);                                        \
+  if (svn__err)                                                       \
+    return svn_error_compose_create(svn__err, svn_sqlite__close(db)); \
+} while (0)
+
 
 /* Time (in milliseconds) to wait for sqlite locks before giving up. */
 #define BUSY_TIMEOUT 10000
@@ -809,7 +831,7 @@ init_sqlite(void *baton, apr_pool_t *poo
 }
 
 static svn_error_t *
-internal_open(sqlite3 **db3, const char *path, svn_sqlite__mode_t mode,
+internal_open(svn_sqlite__db_t *db, const char *path, svn_sqlite__mode_t mode,
               apr_int32_t timeout, apr_pool_t *scratch_pool)
 {
   {
@@ -856,13 +878,13 @@ internal_open(sqlite3 **db3, const char
 
     /* Open the database. Note that a handle is returned, even when an error
        occurs (except for out-of-memory); thus, we can safely use it to
-       extract an error message and construct an svn_error_t. */
+       extract an error message and construct an svn_error_t.  SQLite always
+       requires sqlite3_close() after sqlite3_open_v2() while Subversion 
+       typically does not require close() after an open() that returns an
+       error.  So we must ensure we close the handle if this function, or
+       the caller svn_sqlite__open, returns an error to the application. */
     {
       const char *vFs = NULL;
-      int err_code;
-      /* We'd like to use SQLITE_ERR here, but we can't since it would
-         just return an error and leave the database open.  So, we need to
-         do this manually. */
 
 #if defined(WIN32) && SQLITE_VERSION_AT_LEAST(3, 8, 1)
       if (strlen(path) > 248)
@@ -886,18 +908,8 @@ internal_open(sqlite3 **db3, const char
 #endif
 
       /* ### SQLITE_CANTOPEN */
-      err_code = sqlite3_open_v2(path, db3, flags, vFs);
-      if (err_code != SQLITE_OK)
-        {
-          /* Save the error message before closing the SQLite handle. */
-          char *msg = apr_pstrdup(scratch_pool, sqlite3_errmsg(*db3));
-
-          /* We don't catch the error here, since we care more about the open
-             error than the close error at this point. */
-          sqlite3_close(*db3);
-
-          SQLITE_ERR_MSG(err_code, msg);
-        }
+      SQLITE_ERR_CLOSE(sqlite3_open_v2(path, &db->db3, flags, vFs),
+                       db, scratch_pool);
     }
   }
 
@@ -905,7 +917,8 @@ internal_open(sqlite3 **db3, const char
     timeout = BUSY_TIMEOUT;
 
   /* Retry until timeout when database is busy. */
-  SQLITE_ERR_MSG(sqlite3_busy_timeout(*db3, timeout), sqlite3_errmsg(*db3));
+  SQLITE_ERR_CLOSE(sqlite3_busy_timeout(db->db3, timeout),
+                   db, scratch_pool);
 
   return SVN_NO_ERROR;
 }
@@ -925,35 +938,29 @@ close_apr(void *data)
   if (db->db3 == NULL)
     return APR_SUCCESS;
 
-  /* Finalize any existing prepared statements. */
-  for (i = 0; i < db->nbr_statements; i++)
+  /* Finalize any prepared statements. */
+  if (db->prepared_stmts)
     {
-      if (db->prepared_stmts[i])
+      for (i = 0; i < db->nbr_statements + STMT_INTERNAL_LAST; i++)
         {
-          if (db->prepared_stmts[i]->needs_reset)
+          if (db->prepared_stmts[i])
             {
+              if (i < db->nbr_statements
+                  && db->prepared_stmts[i]->needs_reset)
+                {
 #ifdef SVN_DEBUG
-              const char *stmt_text = db->statement_strings[i];
-              SVN_UNUSED(stmt_text);
+                  const char *stmt_text = db->statement_strings[i];
+                  SVN_UNUSED(stmt_text);
 
-              SVN_ERR_MALFUNCTION_NO_RETURN();
+                  SVN_ERR_MALFUNCTION_NO_RETURN();
 #else
-              err = svn_error_compose_create(
-                            err,
+                  err = svn_error_compose_create(err,
                             svn_sqlite__reset(db->prepared_stmts[i]));
 #endif
-            }
-          err = svn_error_compose_create(
-                        svn_sqlite__finalize(db->prepared_stmts[i]), err);
-        }
-    }
-  /* And finalize any used internal statements */
-  for (; i < db->nbr_statements + STMT_INTERNAL_LAST; i++)
-    {
-      if (db->prepared_stmts[i])
-        {
-          err = svn_error_compose_create(
+                }
+              err = svn_error_compose_create(
                         svn_sqlite__finalize(db->prepared_stmts[i]), err);
+            }
         }
     }
 
@@ -1081,7 +1088,7 @@ svn_sqlite__open(svn_sqlite__db_t **db,
 
   *db = apr_pcalloc(result_pool, sizeof(**db));
 
-  SVN_ERR(internal_open(&(*db)->db3, path, mode, timeout, scratch_pool));
+  SVN_ERR(internal_open(*db, path, mode, timeout, scratch_pool));
 
 #if SQLITE_VERSION_NUMBER >= 3008000 && SQLITE_VERSION_NUMBER < 3009000
   /* disable SQLITE_ENABLE_STAT3/4 from 3.8.1 - 3.8.3 (but not 3.8.3.1+)
@@ -1102,10 +1109,10 @@ svn_sqlite__open(svn_sqlite__db_t **db,
   svn_membuf__create(&(*db)->sqlext_buf3, 800, result_pool);
 
   /* Register collation and LIKE and GLOB operator replacements. */
-  SQLITE_ERR(sqlite3_create_collation((*db)->db3,
-                                      "svn-ucs-nfd", SQLITE_UTF8,
-                                      *db, collate_ucs_nfd),
-             *db);
+  SQLITE_ERR_CLOSE(sqlite3_create_collation((*db)->db3,
+                                            "svn-ucs-nfd", SQLITE_UTF8,
+                                            *db, collate_ucs_nfd),
+                   db, scratch_pool);
   /* ### Is it really necessary to override these functions?
          I would assume the default implementation to be collation agnostic?
          And otherwise our implementation should be...
@@ -1113,18 +1120,18 @@ svn_sqlite__open(svn_sqlite__db_t **db,
          The default implementation is in some cases index backed, while our
          implementation can't be. With an index based on the collation it could
          be. */
-  SQLITE_ERR(sqlite3_create_function((*db)->db3, "glob", 2,
-                                     SQLITE_UTF8 | SQLITE_DETERMINISTIC,
-                                     *db, glob_ucs_nfd, NULL, NULL),
-             *db);
-  SQLITE_ERR(sqlite3_create_function((*db)->db3, "like", 2,
-                                     SQLITE_UTF8 | SQLITE_DETERMINISTIC,
-                                     *db, like_ucs_nfd, NULL, NULL),
-             *db);
-  SQLITE_ERR(sqlite3_create_function((*db)->db3, "like", 3,
-                                     SQLITE_UTF8 | SQLITE_DETERMINISTIC,
-                                     *db, like_ucs_nfd, NULL, NULL),
-             *db);
+  SQLITE_ERR_CLOSE(sqlite3_create_function((*db)->db3, "glob", 2,
+                                           SQLITE_UTF8 | SQLITE_DETERMINISTIC,
+                                           *db, glob_ucs_nfd, NULL, NULL),
+                   db, scratch_pool);
+  SQLITE_ERR_CLOSE(sqlite3_create_function((*db)->db3, "like", 2,
+                                           SQLITE_UTF8 | SQLITE_DETERMINISTIC,
+                                           *db, like_ucs_nfd, NULL, NULL),
+                   db, scratch_pool);
+  SQLITE_ERR_CLOSE(sqlite3_create_function((*db)->db3, "like", 3,
+                                           SQLITE_UTF8 | SQLITE_DETERMINISTIC,
+                                           *db, like_ucs_nfd, NULL, NULL),
+                   db, scratch_pool);
 #endif /* SVN_UNICODE_NORMALIZATION_FIXES */
 
 #ifdef SQLITE3_DEBUG
@@ -1134,7 +1141,7 @@ svn_sqlite__open(svn_sqlite__db_t **db,
   sqlite3_profile((*db)->db3, sqlite_profiler, (*db)->db3);
 #endif
 
-  SVN_ERR(exec_sql(*db,
+  SVN_ERR_CLOSE(exec_sql(*db,
               /* The default behavior of the LIKE operator is to ignore case
                  for ASCII characters. Hence, by default 'a' LIKE 'A' is true.
                  The case_sensitive_like pragma installs a new application-
@@ -1164,13 +1171,15 @@ svn_sqlite__open(svn_sqlite__db_t **db,
                  affects application(read: Subversion) performance/behavior. */
               "PRAGMA foreign_keys=OFF;"      /* SQLITE_DEFAULT_FOREIGN_KEYS*/
               "PRAGMA locking_mode = NORMAL;" /* SQLITE_DEFAULT_LOCKING_MODE */
-              ));
+                            ),
+                *db);
 
 #if defined(SVN_DEBUG)
   /* When running in debug mode, enable the checking of foreign key
      constraints.  This has possible performance implications, so we don't
      bother to do it for production...for now. */
-  SVN_ERR(exec_sql(*db, "PRAGMA foreign_keys=ON;"));
+  SVN_ERR_CLOSE(exec_sql(*db, "PRAGMA foreign_keys=ON;"),
+                *db);
 #endif
 
 #ifdef SVN_SQLITE_REVERSE_UNORDERED_SELECTS
@@ -1178,7 +1187,8 @@ svn_sqlite__open(svn_sqlite__db_t **db,
      clause to emit their results in the reverse order of what they normally
      would.  This can help detecting invalid assumptions about the result
      order.*/
-  SVN_ERR(exec_sql(*db, "PRAGMA reverse_unordered_selects=ON;"));
+  SVN_ERR_CLOSE(exec_sql(*db, "PRAGMA reverse_unordered_selects=ON;"),
+                *db);
 #endif
 
   /* Store temporary tables in RAM instead of in temporary files, but don't

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c Tue Jan 20 17:52:18 2015
@@ -655,23 +655,18 @@ svn_stringbuf_insert(svn_stringbuf_t *st
   if (count == 0)
     return;
 
+  /* special case: BYTES overlaps with this string -> copy the source */
   if (bytes + count > str->data && bytes < str->data + str->blocksize)
-    {
-      /* special case: BYTES overlaps with this string -> copy the source */
-      const char *temp = apr_pstrndup(str->pool, bytes, count);
-      svn_stringbuf_insert(str, pos, temp, count);
-    }
-  else
-    {
-      if (pos > str->len)
-        pos = str->len;
+    bytes = apr_pmemdup(str->pool, bytes, count);
+
+  if (pos > str->len)
+    pos = str->len;
 
-      svn_stringbuf_ensure(str, str->len + count);
-      memmove(str->data + pos + count, str->data + pos, str->len - pos + 1);
-      memcpy(str->data + pos, bytes, count);
+  svn_stringbuf_ensure(str, str->len + count);
+  memmove(str->data + pos + count, str->data + pos, str->len - pos + 1);
+  memcpy(str->data + pos, bytes, count);
 
-      str->len += count;
-    }
+  str->len += count;
 }
 
 void
@@ -703,32 +698,27 @@ svn_stringbuf_replace(svn_stringbuf_t *s
       return;
     }
 
+  /* special case: BYTES overlaps with this string -> copy the source */
   if (bytes + new_count > str->data && bytes < str->data + str->blocksize)
+    bytes = apr_pmemdup(str->pool, bytes, new_count);
+
+  if (pos > str->len)
+    pos = str->len;
+  if (pos + old_count > str->len)
+    old_count = str->len - pos;
+
+  if (old_count < new_count)
     {
-      /* special case: BYTES overlaps with this string -> copy the source */
-      const char *temp = apr_pstrndup(str->pool, bytes, new_count);
-      svn_stringbuf_replace(str, pos, old_count, temp, new_count);
+      apr_size_t delta = new_count - old_count;
+      svn_stringbuf_ensure(str, str->len + delta);
     }
-  else
-    {
-      if (pos > str->len)
-        pos = str->len;
-      if (pos + old_count > str->len)
-        old_count = str->len - pos;
 
-      if (old_count < new_count)
-        {
-          apr_size_t delta = new_count - old_count;
-          svn_stringbuf_ensure(str, str->len + delta);
-        }
+  if (old_count != new_count)
+    memmove(str->data + pos + new_count, str->data + pos + old_count,
+            str->len - pos - old_count + 1);
 
-      if (old_count != new_count)
-        memmove(str->data + pos + new_count, str->data + pos + old_count,
-                str->len - pos - old_count + 1);
-
-      memcpy(str->data + pos, bytes, new_count);
-      str->len += new_count - old_count;
-    }
+  memcpy(str->data + pos, bytes, new_count);
+  str->len += new_count - old_count;
 }
 
 
@@ -879,7 +869,7 @@ char *
 svn_cstring_tokenize(const char *sep, char **str)
 {
     char *token;
-    const char * next;
+    char *next;
     char csep;
 
     /* check parameters */
@@ -909,8 +899,8 @@ svn_cstring_tokenize(const char *sep, ch
       }
     else
       {
-        *(char *)next = '\0';
-        *str = (char *)next + 1;
+        *next = '\0';
+        *str = next + 1;
       }
 
     return token;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/sysinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/sysinfo.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/sysinfo.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/sysinfo.c Tue Jan 20 17:52:18 2015
@@ -55,6 +55,10 @@
 
 #ifdef SVN_HAVE_MACOS_PLIST
 #include <CoreFoundation/CoreFoundation.h>
+#include <AvailabilityMacros.h>
+# ifndef MAC_OS_X_VERSION_10_6
+#  define MAC_OS_X_VERSION_10_6  1060
+# endif
 #endif
 
 #ifdef SVN_HAVE_MACHO_ITERATE
@@ -927,7 +931,6 @@ system_version_plist(svn_boolean_t *serv
   svn_error_t *err;
   CFPropertyListRef plist = NULL;
   CFMutableDataRef resource = CFDataCreateMutable(kCFAllocatorDefault, 0);
-  CFStringRef errstr = NULL;
 
   /* failed getting the CFMutableDataRef, shouldn't happen */
   if (!resource)
@@ -940,6 +943,7 @@ system_version_plist(svn_boolean_t *serv
       if (!APR_STATUS_IS_ENOENT(err->apr_err))
         {
           svn_error_clear(err);
+          CFRelease(resource);
           return NULL;
         }
       else
@@ -950,6 +954,7 @@ system_version_plist(svn_boolean_t *serv
           if (err)
             {
               svn_error_clear(err);
+              CFRelease(resource);
               return NULL;
             }
 
@@ -972,16 +977,23 @@ system_version_plist(svn_boolean_t *serv
       return NULL;
     }
 
-  /* ### CFPropertyListCreateFromXMLData is obsolete, but its
-         replacement CFPropertyListCreateWithData is only available
-         from Mac OS 10.6 onward. */
+#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+  /* This function is only available from Mac OS 10.6 onward. */
+  plist = CFPropertyListCreateWithData(kCFAllocatorDefault, resource,
+                                       kCFPropertyListImmutable,
+                                       NULL, NULL);
+#else  /* Mac OS 10.5 or earlier */
+  /* This function obsolete and deprecated since Mac OS 10.10. */
   plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resource,
                                           kCFPropertyListImmutable,
-                                          &errstr);
+                                          NULL);
+#endif /* MAC_OS_X_VERSION_10_6 */
+
   if (resource)
     CFRelease(resource);
-  if (errstr)
-    CFRelease(errstr);
+
+  if (!plist)
+    return NULL;
 
   if (CFDictionaryGetTypeID() != CFGetTypeID(plist))
     {

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c Tue Jan 20 17:52:18 2015
@@ -2694,6 +2694,7 @@ resolve_tree_conflict_on_node(svn_boolea
   svn_skel_t *conflicts;
   svn_wc_operation_t operation;
   svn_boolean_t tree_conflicted;
+  const char *src_op_root_abspath;
 
   *did_resolve = FALSE;
 
@@ -2708,7 +2709,8 @@ resolve_tree_conflict_on_node(svn_boolea
   if (!tree_conflicted)
     return SVN_NO_ERROR;
 
-  SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, NULL,
+  SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action,
+                                              &src_op_root_abspath,
                                               db, local_abspath,
                                               conflicts,
                                               scratch_pool, scratch_pool));
@@ -2725,7 +2727,8 @@ resolve_tree_conflict_on_node(svn_boolea
               /* Break moves for any children moved out of this directory,
                * and leave this directory deleted. */
               SVN_ERR(svn_wc__db_resolve_break_moved_away_children(
-                        db, local_abspath, notify_func, notify_baton,
+                        db, local_abspath, src_op_root_abspath,
+                        notify_func, notify_baton,
                         scratch_pool));
               *did_resolve = TRUE;
             }
@@ -2807,6 +2810,7 @@ resolve_tree_conflict_on_node(svn_boolea
                  ### involving the move until
                  ### svn_wc__db_op_mark_resolved. */
               SVN_ERR(svn_wc__db_resolve_break_moved_away(db, local_abspath,
+                                                          src_op_root_abspath,
                                                           notify_func,
                                                           notify_baton,
                                                           scratch_pool));

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c Tue Jan 20 17:52:18 2015
@@ -159,7 +159,7 @@ find_and_remove_externals_revision(int *
 
 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)
@@ -167,8 +167,8 @@ svn_wc_parse_externals_description3(apr_
   int i;
   apr_array_header_t *externals = NULL;
   apr_array_header_t *lines = svn_cstring_split(desc, "\n\r", TRUE, pool);
-  const char *parent_directory_display = svn_path_is_url(parent_directory) ?
-    parent_directory : svn_dirent_local_style(parent_directory, pool);
+  const char *defining_directory_display = svn_path_is_url(defining_directory) ?
+    defining_directory : svn_dirent_local_style(defining_directory, pool);
 
   /* If an error occurs halfway through parsing, *externals_p should stay
    * untouched. So, store the list in a local var first. */
@@ -231,7 +231,7 @@ svn_wc_parse_externals_description3(apr_
           (SVN_ERR_CLIENT_INVALID_EXTERNALS_DESCRIPTION, NULL,
            _("Error parsing %s property on '%s': '%s'"),
            SVN_PROP_EXTERNALS,
-           parent_directory_display,
+           defining_directory_display,
            line);
 
       /* To make it easy to check for the forms, find and remove -r N
@@ -242,7 +242,7 @@ svn_wc_parse_externals_description3(apr_
       SVN_ERR(find_and_remove_externals_revision(&rev_idx,
                                                  (const char **)line_parts,
                                                  num_line_parts, item,
-                                                 parent_directory_display,
+                                                 defining_directory_display,
                                                  line, pool));
 
       token0 = line_parts[0];
@@ -258,7 +258,7 @@ svn_wc_parse_externals_description3(apr_
              "cannot use two absolute URLs ('%s' and '%s') in an external; "
              "one must be a path where an absolute or relative URL is "
              "checked out to"),
-           SVN_PROP_EXTERNALS, parent_directory_display, token0, token1);
+           SVN_PROP_EXTERNALS, defining_directory_display, token0, token1);
 
       if (0 == rev_idx && token1_is_url)
         return svn_error_createf
@@ -266,7 +266,7 @@ svn_wc_parse_externals_description3(apr_
            _("Invalid %s property on '%s': "
              "cannot use a URL '%s' as the target directory for an external "
              "definition"),
-           SVN_PROP_EXTERNALS, parent_directory_display, token1);
+           SVN_PROP_EXTERNALS, defining_directory_display, token1);
 
       if (1 == rev_idx && token0_is_url)
         return svn_error_createf
@@ -274,7 +274,7 @@ svn_wc_parse_externals_description3(apr_
            _("Invalid %s property on '%s': "
              "cannot use a URL '%s' as the target directory for an external "
              "definition"),
-           SVN_PROP_EXTERNALS, parent_directory_display, token0);
+           SVN_PROP_EXTERNALS, defining_directory_display, token0);
 
       /* The appearance of -r N or -rN forces the type of external.
          If -r is at the beginning of the line or the first token is
@@ -316,7 +316,7 @@ svn_wc_parse_externals_description3(apr_
            _("Invalid %s property on '%s': "
              "target '%s' is an absolute path or involves '..'"),
            SVN_PROP_EXTERNALS,
-           parent_directory_display,
+           defining_directory_display,
            item->target_dir);
 
       if (canonicalize_url)

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-queries.sql?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-queries.sql Tue Jan 20 17:52:18 2015
@@ -235,11 +235,11 @@ WHERE wc_id = ?1 AND IS_STRICT_DESCENDAN
 DELETE FROM nodes
 WHERE wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
   AND presence = MAP_BASE_DELETED
-  AND op_depth > 0
+  AND op_depth > ?3
   AND op_depth = (SELECT MIN(op_depth) FROM nodes n
                     WHERE n.wc_id = ?1
                       AND n.local_relpath = nodes.local_relpath
-                      AND op_depth > 0)
+                      AND op_depth > ?3)
 
 -- STMT_DELETE_WORKING_RECURSIVE
 DELETE FROM nodes

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.c Tue Jan 20 17:52:18 2015
@@ -1561,6 +1561,7 @@ svn_wc__db_init(svn_wc__db_t *db,
   svn_wc__db_wcroot_t *wcroot;
   svn_boolean_t sqlite_exclusive = FALSE;
   apr_int32_t sqlite_timeout = 0; /* default timeout */
+  apr_hash_index_t *hi;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(repos_relpath != NULL);
@@ -1593,6 +1594,16 @@ svn_wc__db_init(svn_wc__db_t *db,
   /* The WCROOT is complete. Stash it into DB.  */
   svn_hash_sets(db->dir_data, wcroot->abspath, wcroot);
 
+  /* Any previously cached children now have a new WCROOT. */
+  for (hi = apr_hash_first(scratch_pool, db->dir_data);
+       hi;
+       hi = apr_hash_next(hi))
+    {
+      const char *abspath = apr_hash_this_key(hi);
+      if (svn_dirent_is_ancestor(wcroot->abspath, abspath))
+        svn_hash_sets(db->dir_data, abspath, wcroot);
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -2340,7 +2351,7 @@ db_base_remove(svn_wc__db_wcroot_t *wcro
     {
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_DELETE_WORKING_BASE_DELETE));
-      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath, 0));
       SVN_ERR(svn_sqlite__step_done(stmt));
     }
   else
@@ -7594,7 +7605,11 @@ delete_update_movedto(svn_wc__db_wcroot_
                             op_depth,
                             new_moved_to_relpath));
   SVN_ERR(svn_sqlite__update(&affected, stmt));
-  assert(affected == 1);
+#ifdef SVN_DEBUG
+  /* Not fatal in release mode. The move recording is broken,
+     but the rest of the working copy can handle this. */
+  SVN_ERR_ASSERT(affected == 1);
+#endif
 
   return SVN_NO_ERROR;
 }
@@ -7984,7 +7999,12 @@ delete_node(void *baton,
                                                         child_relpath))
                         child_op_depth = delete_op_depth;
                       else
-                        child_op_depth = relpath_depth(child_relpath);
+                        {
+                          /* Calculate depth of the shadowing at the new location */
+                          child_op_depth = child_op_depth
+                                                - relpath_depth(local_relpath)
+                                                + relpath_depth(b->moved_to_relpath);
+                        }
 
                       fixup = TRUE;
                     }
@@ -13038,6 +13058,15 @@ svn_wc__db_upgrade_get_repos_id(apr_int6
   return svn_error_trace(svn_sqlite__reset(stmt));
 }
 
+svn_error_t *
+svn_wc__db_wq_add_internal(svn_wc__db_wcroot_t *wcroot,
+                           const svn_skel_t *work_item,
+                           apr_pool_t *scratch_pool)
+{
+  /* Add the work item(s) to the WORK_QUEUE.  */
+  return svn_error_trace(add_work_items(wcroot->sdb, work_item,
+                                        scratch_pool));
+}
 
 svn_error_t *
 svn_wc__db_wq_add(svn_wc__db_t *db,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.h?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db.h Tue Jan 20 17:52:18 2015
@@ -3479,6 +3479,7 @@ svn_wc__db_resolve_delete_raise_moved_aw
 svn_error_t *
 svn_wc__db_resolve_break_moved_away(svn_wc__db_t *db,
                                     const char *local_abspath,
+                                    const char *src_op_root_abspath,
                                     svn_wc_notify_func2_t notify_func,
                                     void *notify_baton,
                                     apr_pool_t *scratch_pool);
@@ -3491,6 +3492,7 @@ svn_wc__db_resolve_break_moved_away(svn_
 svn_error_t *
 svn_wc__db_resolve_break_moved_away_children(svn_wc__db_t *db,
                                              const char *local_abspath,
+                                             const char *src_op_root_abspath,
                                              svn_wc_notify_func2_t notify_func,
                                              void *notify_baton,
                                              apr_pool_t *scratch_pool);

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db_private.h?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db_private.h Tue Jan 20 17:52:18 2015
@@ -216,6 +216,13 @@ svn_wc__db_util_open_db(svn_sqlite__db_t
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool);
 
+/* Like svn_wc__db_wq_add() but taking WCROOT */
+svn_error_t *
+svn_wc__db_wq_add_internal(svn_wc__db_wcroot_t *wcroot,
+                           const svn_skel_t *work_item,
+                           apr_pool_t *scratch_pool);
+
+
 /* Like svn_wc__db_read_info(), but taking WCROOT+LOCAL_RELPATH instead of
    DB+LOCAL_ABSPATH, and outputting repos ids instead of URL+UUID. */
 svn_error_t *