subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject svn commit: r1200926 [7/12] - in /subversion/branches/moves-scan-log: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ notes/ subversion/bindings/javahl/native/ subversion/include/ subversio...
Date Fri, 11 Nov 2011 16:06:51 GMT
Modified: subversion/branches/moves-scan-log/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_repos/load-fs-vtable.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_repos/load-fs-vtable.c Fri Nov 11 16:06:45 2011
@@ -63,6 +63,12 @@ struct parse_baton
   svn_repos_notify_t *notify;
   apr_pool_t *pool;
 
+  /* Start and end (inclusive) of revision range we'll pay attention
+     to, or a pair of SVN_INVALID_REVNUMs if we're not filtering by
+     revisions. */
+  svn_revnum_t start_rev;
+  svn_revnum_t end_rev;
+
   /* A hash mapping copy-from revisions and mergeinfo range revisions
      (svn_revnum_t *) in the dump stream to their corresponding revisions
      (svn_revnum_t *) in the loaded repository.  The hash and its
@@ -84,13 +90,13 @@ struct parse_baton
 struct revision_baton
 {
   svn_revnum_t rev;
-
   svn_fs_txn_t *txn;
   svn_fs_root_t *txn_root;
 
   const svn_string_t *datestamp;
 
   apr_int32_t rev_offset;
+  svn_boolean_t skipped;
 
   struct parse_baton *pb;
   apr_pool_t *pool;
@@ -451,7 +457,14 @@ make_revision_baton(apr_hash_t *headers,
 
   if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_REVISION_NUMBER,
                           APR_HASH_KEY_STRING)))
-    rb->rev = SVN_STR_TO_REV(val);
+    {
+      rb->rev = SVN_STR_TO_REV(val);
+
+      /* If we're filtering revisions, is this one we'll skip? */
+      rb->skipped = (SVN_IS_VALID_REVNUM(pb->start_rev)
+                     && ((rb->rev < pb->start_rev) ||
+                         (rb->rev > pb->end_rev)));
+    }
 
   return rb;
 }
@@ -476,7 +489,7 @@ new_revision_record(void **revision_bato
      It might be positive or negative. */
   rb->rev_offset = (apr_int32_t) (rb->rev) - (head_rev + 1);
 
-  if (rb->rev > 0)
+  if ((rb->rev > 0) && (! rb->skipped))
     {
       /* Create a new fs txn. */
       SVN_ERR(svn_fs_begin_txn2(&(rb->txn), pb->fs, head_rev, 0, pool));
@@ -493,6 +506,14 @@ new_revision_record(void **revision_bato
       if (!SVN_IS_VALID_REVNUM(pb->oldest_old_rev))
         pb->oldest_old_rev = rb->rev;
     }
+  
+  /* If we're skipping this revision, try to notify someone. */
+  if (rb->skipped && pb->notify_func)
+    {
+      pb->notify->action = svn_repos_notify_load_skipped_rev;
+      pb->notify->old_revision = rb->rev;
+      pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
+    }
 
   /* If we're parsing revision 0, only the revision are (possibly)
      interesting to us: when loading the stream into an empty
@@ -607,6 +628,13 @@ new_node_record(void **node_baton,
 
   SVN_ERR(make_node_baton(&nb, headers, rb, pool));
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    {
+      *node_baton = nb;
+      return SVN_NO_ERROR;
+    }
+
   /* Make sure we have an action we recognize. */
   if (nb->action < svn_node_action_change
         || nb->action > svn_node_action_replace)
@@ -652,6 +680,10 @@ set_revision_property(void *baton,
 {
   struct revision_baton *rb = baton;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    return SVN_NO_ERROR;
+
   if (rb->rev > 0)
     {
       if (rb->pb->validate_props)
@@ -691,6 +723,10 @@ set_node_property(void *baton,
   struct revision_baton *rb = nb->rb;
   struct parse_baton *pb = rb->pb;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    return SVN_NO_ERROR;
+
   if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
     {
       svn_string_t *renumbered_mergeinfo;
@@ -764,6 +800,10 @@ remove_node_props(void *baton)
   apr_hash_t *proplist;
   apr_hash_index_t *hi;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    return SVN_NO_ERROR;
+
   SVN_ERR(svn_fs_node_proplist(&proplist,
                                rb->txn_root, nb->path, nb->pool));
 
@@ -788,6 +828,10 @@ apply_textdelta(svn_txdelta_window_handl
   struct node_baton *nb = node_baton;
   struct revision_baton *rb = nb->rb;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    return SVN_NO_ERROR;
+
   return svn_fs_apply_textdelta(handler, handler_baton,
                                 rb->txn_root, nb->path,
                                 svn_checksum_to_cstring(nb->base_checksum,
@@ -805,6 +849,10 @@ set_fulltext(svn_stream_t **stream,
   struct node_baton *nb = node_baton;
   struct revision_baton *rb = nb->rb;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    return SVN_NO_ERROR;
+
   return svn_fs_apply_text(stream,
                            rb->txn_root, nb->path,
                            svn_checksum_to_cstring(nb->result_checksum,
@@ -820,6 +868,10 @@ close_node(void *baton)
   struct revision_baton *rb = nb->rb;
   struct parse_baton *pb = rb->pb;
 
+  /* If we're skipping this revision, we're done here. */
+  if (rb->skipped)
+    return SVN_NO_ERROR;
+
   if (pb->notify_func)
     {
       pb->notify->action = svn_repos_notify_load_node_done;
@@ -839,7 +891,9 @@ close_revision(void *baton)
   svn_revnum_t committed_rev;
   svn_error_t *err;
 
-  if (rb->rev <= 0)
+  /* If we're skipping this revision or it has an invalid revision
+     number, we're done here. */
+  if (rb->skipped || (rb->rev <= 0))
     return SVN_NO_ERROR;
 
   /* Run the pre-commit hook, if so commanded. */
@@ -943,9 +997,11 @@ close_revision(void *baton)
 
 
 svn_error_t *
-svn_repos_get_fs_build_parser3(const svn_repos_parse_fns2_t **callbacks,
+svn_repos_get_fs_build_parser4(const svn_repos_parse_fns2_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,
@@ -960,6 +1016,13 @@ svn_repos_get_fs_build_parser3(const svn
   if (parent_dir)
     parent_dir = svn_relpath_canonicalize(parent_dir, pool);
 
+  SVN_ERR_ASSERT((SVN_IS_VALID_REVNUM(start_rev) &&
+                  SVN_IS_VALID_REVNUM(end_rev))
+                 || ((! SVN_IS_VALID_REVNUM(start_rev)) &&
+                     (! SVN_IS_VALID_REVNUM(end_rev))));
+  if (SVN_IS_VALID_REVNUM(start_rev))
+    SVN_ERR_ASSERT(start_rev <= end_rev);
+
   parser->new_revision_record = new_revision_record;
   parser->new_node_record = new_node_record;
   parser->uuid_record = uuid_record;
@@ -985,6 +1048,8 @@ svn_repos_get_fs_build_parser3(const svn
   pb->rev_map = apr_hash_make(pool);
   pb->oldest_old_rev = SVN_INVALID_REVNUM;
   pb->last_rev_mapped = SVN_INVALID_REVNUM;
+  pb->start_rev = start_rev;
+  pb->end_rev = end_rev;
 
   *callbacks = parser;
   *parse_baton = pb;
@@ -994,8 +1059,10 @@ svn_repos_get_fs_build_parser3(const svn
 
 
 svn_error_t *
-svn_repos_load_fs3(svn_repos_t *repos,
+svn_repos_load_fs4(svn_repos_t *repos,
                    svn_stream_t *dumpstream,
+                   svn_revnum_t start_rev,
+                   svn_revnum_t end_rev,
                    enum svn_repos_load_uuid uuid_action,
                    const char *parent_dir,
                    svn_boolean_t use_pre_commit_hook,
@@ -1013,8 +1080,9 @@ svn_repos_load_fs3(svn_repos_t *repos,
 
   /* This is really simple. */
 
-  SVN_ERR(svn_repos_get_fs_build_parser3(&parser, &parse_baton,
+  SVN_ERR(svn_repos_get_fs_build_parser4(&parser, &parse_baton,
                                          repos,
+                                         start_rev, end_rev,
                                          TRUE, /* look for copyfrom revs */
                                          validate_props,
                                          uuid_action,

Modified: subversion/branches/moves-scan-log/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_repos/log.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_repos/log.c Fri Nov 11 16:06:45 2011
@@ -663,9 +663,9 @@ fs_mergeinfo_changed(svn_mergeinfo_catal
           svn_mergeinfo_catalog_t tmp_catalog;
 
           APR_ARRAY_PUSH(query_paths, const char *) = changed_path;
-          SVN_ERR(svn_fs_get_mergeinfo(&tmp_catalog, root,
-                                       query_paths, svn_mergeinfo_inherited,
-                                       FALSE, iterpool));
+          SVN_ERR(svn_fs_get_mergeinfo2(&tmp_catalog, root,
+                                        query_paths, svn_mergeinfo_inherited,
+                                        FALSE, TRUE, iterpool, iterpool));
           tmp_mergeinfo = apr_hash_get(tmp_catalog, changed_path,
                                         APR_HASH_KEY_STRING);
           if (tmp_mergeinfo)
@@ -682,9 +682,9 @@ fs_mergeinfo_changed(svn_mergeinfo_catal
           svn_mergeinfo_catalog_t tmp_catalog;
 
           APR_ARRAY_PUSH(query_paths, const char *) = base_path;
-          SVN_ERR(svn_fs_get_mergeinfo(&tmp_catalog, base_root,
-                                       query_paths, svn_mergeinfo_inherited,
-                                       FALSE, iterpool));
+          SVN_ERR(svn_fs_get_mergeinfo2(&tmp_catalog, base_root,
+                                        query_paths, svn_mergeinfo_inherited,
+                                        FALSE, TRUE, iterpool, iterpool));
           tmp_mergeinfo = apr_hash_get(tmp_catalog, base_path,
                                         APR_HASH_KEY_STRING);
           if (tmp_mergeinfo)
@@ -711,17 +711,16 @@ fs_mergeinfo_changed(svn_mergeinfo_catal
           if (prev_mergeinfo_value)
             SVN_ERR(svn_mergeinfo_parse(&prev_mergeinfo,
                                         prev_mergeinfo_value->data, iterpool));
-          SVN_ERR(svn_mergeinfo_diff(&deleted, &added, prev_mergeinfo,
-                                     mergeinfo, FALSE, iterpool));
+          SVN_ERR(svn_mergeinfo_diff2(&deleted, &added, prev_mergeinfo,
+                                      mergeinfo, FALSE, result_pool,
+                                      iterpool));
 
           /* Toss interesting stuff into our return catalogs. */
           hash_path = apr_pstrdup(result_pool, changed_path);
           apr_hash_set(*deleted_mergeinfo_catalog, hash_path,
-                       APR_HASH_KEY_STRING, svn_mergeinfo_dup(deleted,
-                                                              result_pool));
+                       APR_HASH_KEY_STRING, deleted);
           apr_hash_set(*added_mergeinfo_catalog, hash_path,
-                       APR_HASH_KEY_STRING, svn_mergeinfo_dup(added,
-                                                              result_pool));
+                       APR_HASH_KEY_STRING, added);
         }
     }
 
@@ -795,8 +794,9 @@ get_combined_mergeinfo_changes(svn_merge
       const char *prev_path;
       svn_revnum_t appeared_rev, prev_rev;
       svn_fs_root_t *prev_root;
-      svn_mergeinfo_catalog_t catalog;
-      svn_mergeinfo_t prev_mergeinfo, mergeinfo, deleted, added;
+      svn_mergeinfo_catalog_t catalog, inherited_catalog;
+      svn_mergeinfo_t prev_mergeinfo, mergeinfo, deleted, added,
+        prev_inherited_mergeinfo, inherited_mergeinfo;
       apr_array_header_t *query_paths;
 
       svn_pool_clear(iterpool);
@@ -835,8 +835,9 @@ get_combined_mergeinfo_changes(svn_merge
       SVN_ERR(svn_fs_revision_root(&prev_root, fs, prev_rev, iterpool));
       query_paths = apr_array_make(iterpool, 1, sizeof(const char *));
       APR_ARRAY_PUSH(query_paths, const char *) = prev_path;
-      err = svn_fs_get_mergeinfo(&catalog, prev_root, query_paths,
-                                 svn_mergeinfo_inherited, FALSE, iterpool);
+      err = svn_fs_get_mergeinfo2(&catalog, prev_root, query_paths,
+                                  svn_mergeinfo_inherited, FALSE, TRUE,
+                                  iterpool, iterpool);
       if (err && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
                   err->apr_err == SVN_ERR_FS_NOT_DIRECTORY ||
                   err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR))
@@ -846,26 +847,64 @@ get_combined_mergeinfo_changes(svn_merge
           continue;
         }
       SVN_ERR(err);
+
+      /* Issue #4022 'svn log -g interprets change in inherited mergeinfo due
+         to move as a merge': A copy where the source and destination inherit
+         mergeinfo from the same parent means the inherited mergeinfo of the
+         source and destination will differ, but this diffrence is not
+         indicative of a merge unless the mergeinfo on the inherited parent
+         has actually changed.
+
+         To check for this we must fetch the "raw" previous inherited
+         mergeinfo and the "raw" mergeinfo @REV then compare these. */
+      SVN_ERR(svn_fs_get_mergeinfo2(&inherited_catalog, prev_root, query_paths,
+                                    svn_mergeinfo_nearest_ancestor, FALSE,
+                                    FALSE, /* adjust_inherited_mergeinfo */
+                                    iterpool, iterpool));
+
       prev_mergeinfo = apr_hash_get(catalog, prev_path, APR_HASH_KEY_STRING);
+      prev_inherited_mergeinfo = apr_hash_get(inherited_catalog, prev_path, APR_HASH_KEY_STRING);
 
       /* Fetch the current mergeinfo (as of REV, and including
          inherited stuff) for this path. */
       APR_ARRAY_IDX(query_paths, 0, const char *) = path;
-      SVN_ERR(svn_fs_get_mergeinfo(&catalog, root, query_paths,
-                                   svn_mergeinfo_inherited, FALSE, iterpool));
+      SVN_ERR(svn_fs_get_mergeinfo2(&catalog, root, query_paths,
+                                    svn_mergeinfo_inherited, FALSE, TRUE,
+                                    iterpool, iterpool));
+
+      /* Issue #4022 again, fetch the raw inherited mergeinfo. */
+      SVN_ERR(svn_fs_get_mergeinfo2(&inherited_catalog, root, query_paths,
+                                    svn_mergeinfo_nearest_ancestor, FALSE,
+                                    FALSE, /* adjust_inherited_mergeinfo */
+                                    iterpool, iterpool));
+
       mergeinfo = apr_hash_get(catalog, path, APR_HASH_KEY_STRING);
+      inherited_mergeinfo = apr_hash_get(inherited_catalog, path, APR_HASH_KEY_STRING);
 
       if (!prev_mergeinfo && !mergeinfo)
         continue;
 
+      /* Last bit of issue #4022 checking. */
+      if (prev_inherited_mergeinfo && inherited_mergeinfo)
+        {
+          svn_boolean_t inherits_same_mergeinfo;
+
+          SVN_ERR(svn_mergeinfo__equals(&inherits_same_mergeinfo,
+                                        prev_inherited_mergeinfo,
+                                        inherited_mergeinfo,
+                                        TRUE, iterpool));
+          /* If a copy rather than an actual merge brought about an
+             inherited mergeinfo change then we are finished. */
+          if (inherits_same_mergeinfo)
+            continue;
+        }
+
       /* Compare, constrast, and combine the results. */
-      SVN_ERR(svn_mergeinfo_diff(&deleted, &added, prev_mergeinfo,
-                                 mergeinfo, FALSE, iterpool));
-      SVN_ERR(svn_mergeinfo_merge2(*deleted_mergeinfo,
-                                   svn_mergeinfo_dup(deleted, result_pool),
+      SVN_ERR(svn_mergeinfo_diff2(&deleted, &added, prev_mergeinfo,
+                                  mergeinfo, FALSE, result_pool, iterpool));
+      SVN_ERR(svn_mergeinfo_merge2(*deleted_mergeinfo, deleted,
                                    result_pool, iterpool));
-      SVN_ERR(svn_mergeinfo_merge2(*added_mergeinfo,
-                                   svn_mergeinfo_dup(added, result_pool),
+      SVN_ERR(svn_mergeinfo_merge2(*added_mergeinfo, added,
                                    result_pool, iterpool));
      }
 
@@ -888,7 +927,7 @@ get_combined_mergeinfo_changes(svn_merge
       for (i = 0; i < paths->nelts; i++)
         {
           const char *path = APR_ARRAY_IDX(paths, i, const char *);
-          if (! svn_dirent_is_ancestor(path, changed_path))
+          if (! svn_fspath__skip_ancestor(path, changed_path))
             continue;
           svn_pool_clear(iterpool);
           deleted = apr_hash_get(deleted_mergeinfo_catalog, key, klen);
@@ -1103,8 +1142,7 @@ send_log(svn_revnum_t rev,
               apr_array_header_t *rangelist =
                 svn__apr_hash_index_val(hi2);
 
-              if (svn_fspath__is_ancestor(mergeinfo_path,
-                                          changed_path))
+              if (svn_fspath__skip_ancestor(mergeinfo_path, changed_path))
                 {
                   int i;
 

Modified: subversion/branches/moves-scan-log/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_repos/replay.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_repos/replay.c Fri Nov 11 16:06:45 2011
@@ -573,8 +573,9 @@ path_driver_cb_func(void **dir_baton,
                                                   struct copy_info);
           if (info->copyfrom_path)
             {
-              const char *relpath = svn_relpath__is_child(info->path,
-                                                          edit_path, pool);
+              const char *relpath = svn_relpath_skip_ancestor(info->path,
+                                                              edit_path);
+              SVN_ERR_ASSERT(relpath && *relpath);
               SVN_ERR(svn_fs_revision_root(&source_root,
                                            svn_fs_root_fs(root),
                                            info->copyfrom_rev, pool));

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

Propchange: subversion/branches/moves-scan-log/subversion/libsvn_subr/adler32.c
            ('svn:mergeinfo' removed)

Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/cmdline.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/cmdline.c Fri Nov 11 16:06:45 2011
@@ -637,7 +637,7 @@ svn_cmdline__print_xml_prop(svn_stringbu
   const char *encoding = NULL;
 
   if (*outstr == NULL)
-    *outstr = svn_stringbuf_create("", pool);
+    *outstr = svn_stringbuf_create_empty(pool);
 
   if (svn_xml_is_xml_safe(propval->data, propval->len))
     {

Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/config.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/config.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/config.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/config.c Fri Nov 11 16:06:45 2011
@@ -88,8 +88,8 @@ svn_config_create(svn_config_t **cfgp,
   cfg->pool = result_pool;
   cfg->x_pool = svn_pool_create(result_pool);
   cfg->x_values = FALSE;
-  cfg->tmp_key = svn_stringbuf_create("", result_pool);
-  cfg->tmp_value = svn_stringbuf_create("", result_pool);
+  cfg->tmp_key = svn_stringbuf_create_empty(result_pool);
+  cfg->tmp_value = svn_stringbuf_create_empty(result_pool);
   cfg->section_names_case_sensitive = section_names_case_sensitive;
 
   *cfgp = cfg;

Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/config_file.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/config_file.c Fri Nov 11 16:06:45 2011
@@ -386,9 +386,9 @@ svn_config__parse_file(svn_config_t *cfg
                                            pool);
   ctx.line = 1;
   ctx.have_ungotten_char = FALSE;
-  ctx.section = svn_stringbuf_create("", pool);
-  ctx.option = svn_stringbuf_create("", pool);
-  ctx.value = svn_stringbuf_create("", pool);
+  ctx.section = svn_stringbuf_create_empty(pool);
+  ctx.option = svn_stringbuf_create_empty(pool);
+  ctx.value = svn_stringbuf_create_empty(pool);
 
   do
     {

Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/config_win.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/config_win.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/config_win.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/config_win.c Fri Nov 11 16:06:45 2011
@@ -200,9 +200,9 @@ svn_config__parse_registry(svn_config_t 
 
 
   subpool = svn_pool_create(pool);
-  section = svn_stringbuf_create("", subpool);
-  option = svn_stringbuf_create("", subpool);
-  value = svn_stringbuf_create("", subpool);
+  section = svn_stringbuf_create_empty(subpool);
+  option = svn_stringbuf_create_empty(subpool);
+  value = svn_stringbuf_create_empty(subpool);
 
   /* The top-level values belong to the [DEFAULT] section */
   svn_err = parse_section(cfg, hkey, SVN_CONFIG__DEFAULT_SECTION,

Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/dirent_uri.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/dirent_uri.c Fri Nov 11 16:06:45 2011
@@ -884,10 +884,10 @@ svn_dirent_local_style(const char *diren
 }
 
 const char *
-svn_relpath__internal_style(const char *dirent,
-                           apr_pool_t *pool)
+svn_relpath__internal_style(const char *relpath,
+                            apr_pool_t *pool)
 {
-  return svn_relpath_canonicalize(internal_style(dirent, pool), pool);
+  return svn_relpath_canonicalize(internal_style(relpath, pool), pool);
 }
 
 
@@ -1403,34 +1403,6 @@ svn_dirent_is_child(const char *parent_d
 }
 
 const char *
-svn_relpath__is_child(const char *parent_relpath,
-                      const char *child_relpath,
-                      apr_pool_t *pool)
-{
-  /* assert(relpath_is_canonical(parent_relpath)); */
-  /* assert(relpath_is_canonical(child_relpath)); */
-
-  return is_child(type_relpath, parent_relpath, child_relpath, pool);
-}
-
-const char *
-svn_uri__is_child(const char *parent_uri,
-                  const char *child_uri,
-                  apr_pool_t *pool)
-{
-  const char *relpath;
-
-  assert(pool); /* hysterical raisins. */
-  assert(svn_uri_is_canonical(parent_uri, NULL));
-  assert(svn_uri_is_canonical(child_uri, NULL));
-
-  relpath = is_child(type_uri, parent_uri, child_uri, pool);
-  if (relpath)
-    relpath = svn_path_uri_decode(relpath, pool);
-  return relpath;
-}
-
-const char *
 svn_dirent_skip_ancestor(const char *parent_dirent,
                          const char *child_dirent)
 {
@@ -1547,12 +1519,6 @@ svn_dirent_is_ancestor(const char *paren
 }
 
 svn_boolean_t
-svn_relpath__is_ancestor(const char *parent_relpath, const char *child_relpath)
-{
-  return svn_relpath_skip_ancestor(parent_relpath, child_relpath) != NULL;
-}
-
-svn_boolean_t
 svn_uri__is_ancestor(const char *parent_uri, const char *child_uri)
 {
   return uri_skip_ancestor(parent_uri, child_uri) != NULL;
@@ -1653,7 +1619,7 @@ svn_dirent_canonicalize(const char *dire
 }
 
 svn_boolean_t
-svn_dirent_is_canonical(const char *dirent, apr_pool_t *pool)
+svn_dirent_is_canonical(const char *dirent, apr_pool_t *scratch_pool)
 {
   const char *ptr = dirent;
   if (*ptr == '/')
@@ -1666,7 +1632,8 @@ svn_dirent_is_canonical(const char *dire
           /* TODO: Scan hostname and sharename and fall back to part code */
 
           /* ### Fall back to old implementation */
-          return (strcmp(dirent, svn_dirent_canonicalize(dirent, pool)) == 0);
+          return (strcmp(dirent, svn_dirent_canonicalize(dirent, scratch_pool))
+                  == 0);
         }
 #endif /* SVN_USE_DOS_PATHS */
     }
@@ -1740,7 +1707,7 @@ svn_relpath_is_canonical(const char *rel
 }
 
 svn_boolean_t
-svn_uri_is_canonical(const char *uri, apr_pool_t *pool)
+svn_uri_is_canonical(const char *uri, apr_pool_t *scratch_pool)
 {
   const char *ptr = uri, *seg = uri;
   const char *schema_data = NULL;
@@ -2459,21 +2426,6 @@ svn_fspath__is_root(const char *fspath, 
 
 
 const char *
-svn_fspath__is_child(const char *parent_fspath,
-                     const char *child_fspath,
-                     apr_pool_t *pool)
-{
-  const char *result;
-  assert(svn_fspath__is_canonical(parent_fspath));
-  assert(svn_fspath__is_canonical(child_fspath));
-
-  result = svn_relpath__is_child(parent_fspath + 1, child_fspath + 1, pool);
-
-  assert(result == NULL || svn_relpath_is_canonical(result));
-  return result;
-}
-
-const char *
 svn_fspath__skip_ancestor(const char *parent_fspath,
                           const char *child_fspath)
 {
@@ -2483,16 +2435,6 @@ svn_fspath__skip_ancestor(const char *pa
   return svn_relpath_skip_ancestor(parent_fspath + 1, child_fspath + 1);
 }
 
-svn_boolean_t
-svn_fspath__is_ancestor(const char *parent_fspath,
-                        const char *child_fspath)
-{
-  assert(svn_fspath__is_canonical(parent_fspath));
-  assert(svn_fspath__is_canonical(child_fspath));
-
-  return svn_relpath__is_ancestor(parent_fspath + 1, child_fspath + 1);
-}
-
 
 const char *
 svn_fspath__dirname(const char *fspath,

Propchange: subversion/branches/moves-scan-log/subversion/libsvn_subr/hash.c
            ('svn:mergeinfo' removed)

Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/log.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/log.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/log.c Fri Nov 11 16:06:45 2011
@@ -121,7 +121,7 @@ svn_log__get_mergeinfo(const apr_array_h
 {
   int i;
   apr_pool_t *iterpool = svn_pool_create(pool);
-  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool);
 
   for (i = 0; i < paths->nelts; i++)
     {
@@ -210,8 +210,8 @@ svn_log__log(const apr_array_header_t *p
 {
   int i;
   apr_pool_t *iterpool = svn_pool_create(pool);
-  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create("", pool);
-  svn_stringbuf_t *options = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool);
+  svn_stringbuf_t *options = svn_stringbuf_create_empty(pool);
 
   for (i = 0; i < paths->nelts; i++)
     {
@@ -264,7 +264,7 @@ svn_log__get_locations(const char *path,
 {
   const svn_revnum_t *revision_ptr, *revision_ptr_start, *revision_ptr_end;
   apr_pool_t *iterpool = svn_pool_create(pool);
-  svn_stringbuf_t *space_separated_revnums = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *space_separated_revnums = svn_stringbuf_create_empty(pool);
 
   revision_ptr_start = (const svn_revnum_t *)location_revisions->elts;
   revision_ptr = revision_ptr_start;
@@ -311,7 +311,7 @@ svn_log__lock(const apr_array_header_t *
 {
   int i;
   apr_pool_t *iterpool = svn_pool_create(pool);
-  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool);
 
   for (i = 0; i < paths->nelts; i++)
     {
@@ -334,7 +334,7 @@ svn_log__unlock(const apr_array_header_t
 {
   int i;
   apr_pool_t *iterpool = svn_pool_create(pool);
-  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool);
 
   for (i = 0; i < paths->nelts; i++)
     {

Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/mergeinfo.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/mergeinfo.c Fri Nov 11 16:06:45 2011
@@ -488,13 +488,10 @@ range_to_string(const svn_merge_range_t 
    revisionlist -> (revisionelement)(COMMA revisionelement)*
    revisionrange -> REVISION "-" REVISION("*")
    revisionelement -> revisionrange | REVISION("*")
-
-   PATHNAME is the path this revisionlist is mapped to.  It is
-   used only for producing a more descriptive error message.
 */
 static svn_error_t *
 parse_rangelist(const char **input, const char *end,
-                apr_array_header_t *rangelist, const char *pathname,
+                apr_array_header_t *rangelist,
                 apr_pool_t *pool)
 {
   const char *curr = *input;
@@ -507,9 +504,7 @@ parse_rangelist(const char **input, cons
     {
       /* Empty range list. */
       *input = curr;
-      return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
-                               _("Mergeinfo for '%s' maps to an "
-                                 "empty revision range"), pathname);
+      return SVN_NO_ERROR;
     }
 
   while (curr < end && *curr != '\n')
@@ -603,6 +598,18 @@ parse_rangelist(const char **input, cons
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_rangelist__parse(apr_array_header_t **rangelist,
+                     const char *str,
+                     apr_pool_t *result_pool)
+{
+  const char *s = str;
+
+  *rangelist = apr_array_make(result_pool, 1, sizeof(svn_merge_range_t *));
+  SVN_ERR(parse_rangelist(&s, s + strlen(s), *rangelist, result_pool));
+  return SVN_NO_ERROR;
+}
+
 /* revisionline -> PATHNAME COLON revisionlist */
 static svn_error_t *
 parse_revision_line(const char **input, const char *end, svn_mergeinfo_t hash,
@@ -621,8 +628,12 @@ parse_revision_line(const char **input, 
 
   *input = *input + 1;
 
-  SVN_ERR(parse_rangelist(input, end, rangelist, pathname, scratch_pool));
+  SVN_ERR(parse_rangelist(input, end, rangelist, scratch_pool));
 
+  if (rangelist->nelts == 0)
+      return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
+                               _("Mergeinfo for '%s' maps to an "
+                                 "empty revision range"), pathname);
   if (*input != end && *(*input) != '\n')
     return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                              _("Could not find end of line in range list line "
@@ -1842,7 +1853,7 @@ svn_rangelist_to_string(svn_string_t **o
                         const apr_array_header_t *rangelist,
                         apr_pool_t *pool)
 {
-  svn_stringbuf_t *buf = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *buf = svn_stringbuf_create_empty(pool);
 
   if (rangelist->nelts > 0)
     {
@@ -1879,7 +1890,7 @@ mergeinfo_to_stringbuf(svn_stringbuf_t *
                        const char *prefix,
                        apr_pool_t *pool)
 {
-  *output = svn_stringbuf_create("", pool);
+  *output = svn_stringbuf_create_empty(pool);
 
   if (apr_hash_count(input) > 0)
     {
@@ -1912,16 +1923,10 @@ svn_error_t *
 svn_mergeinfo_to_string(svn_string_t **output, svn_mergeinfo_t input,
                         apr_pool_t *pool)
 {
-  if (apr_hash_count(input) > 0)
-    {
-      svn_stringbuf_t *mergeinfo_buf;
-      SVN_ERR(mergeinfo_to_stringbuf(&mergeinfo_buf, input, NULL, pool));
-      *output = svn_stringbuf__morph_into_string(mergeinfo_buf);
-    }
-  else
-    {
-      *output = svn_string_create("", pool);
-    }
+  svn_stringbuf_t *mergeinfo_buf;
+
+  SVN_ERR(mergeinfo_to_stringbuf(&mergeinfo_buf, input, NULL, pool));
+  *output = svn_stringbuf__morph_into_string(mergeinfo_buf);
   return SVN_NO_ERROR;
 }
 
@@ -2120,7 +2125,7 @@ svn_mergeinfo__remove_prefix_from_catalo
       apr_ssize_t padding = 0;
 
       SVN_ERR_ASSERT(klen >= prefix_len);
-      SVN_ERR_ASSERT(svn_fspath__is_ancestor(prefix_path, original_path));
+      SVN_ERR_ASSERT(svn_fspath__skip_ancestor(prefix_path, original_path));
 
       /* If the ORIGINAL_PATH doesn't match the PREFIX_PATH exactly
          and we're not simply removing a single leading slash (such as
@@ -2167,6 +2172,36 @@ svn_mergeinfo__add_prefix_to_catalog(svn
 }
 
 svn_error_t *
+svn_mergeinfo__relpaths_to_urls(apr_hash_t **out_mergeinfo,
+                                svn_mergeinfo_t mergeinfo,
+                                const char *repos_root_url,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool)
+{
+  *out_mergeinfo = NULL;
+  if (mergeinfo)
+    {
+      apr_hash_index_t *hi;
+      apr_hash_t *full_path_mergeinfo = apr_hash_make(result_pool);
+
+      for (hi = apr_hash_first(scratch_pool, mergeinfo);
+           hi; hi = apr_hash_next(hi))
+        {
+          const char *key = svn__apr_hash_index_key(hi);
+          void *val = svn__apr_hash_index_val(hi);
+
+          apr_hash_set(full_path_mergeinfo,
+                       svn_path_url_add_component2(repos_root_url, key + 1,
+                                                   result_pool),
+                       APR_HASH_KEY_STRING, val);
+        }
+      *out_mergeinfo = full_path_mergeinfo;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_mergeinfo__add_suffix_to_mergeinfo(svn_mergeinfo_t *out_mergeinfo,
                                        svn_mergeinfo_t mergeinfo,
                                        const char *suffix_relpath,
@@ -2183,13 +2218,13 @@ svn_mergeinfo__add_suffix_to_mergeinfo(s
        hi;
        hi = apr_hash_next(hi))
     {
-      const char *path = svn__apr_hash_index_key(hi);
+      const char *fspath = svn__apr_hash_index_key(hi);
       apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
 
       apr_hash_set(*out_mergeinfo,
-                   svn_dirent_join(path, suffix_relpath, result_pool),
+                   svn_fspath__join(fspath, suffix_relpath, result_pool),
                    APR_HASH_KEY_STRING,
-                   svn_rangelist_dup(rangelist, result_pool));
+                   rangelist);
     }
 
   return SVN_NO_ERROR;
@@ -2248,7 +2283,7 @@ svn_mergeinfo__catalog_to_formatted_stri
       apr_array_header_t *sorted_catalog =
         svn_sort__hash(catalog, svn_sort_compare_items_as_paths, pool);
 
-      output_buf = svn_stringbuf_create("", pool);
+      output_buf = svn_stringbuf_create_empty(pool);
       for (i = 0; i < sorted_catalog->nelts; i++)
         {
           svn_sort__item_t elt =
@@ -2321,7 +2356,7 @@ svn_mergeinfo__to_formatted_string(svn_s
 #endif
 
   *output = output_buf ? svn_stringbuf__morph_into_string(output_buf)
-                       : svn_string_create("", pool);
+                       : svn_string_create_empty(pool);
   return SVN_NO_ERROR;
 }
 

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

Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/prompt.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/prompt.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/prompt.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/prompt.c Fri Nov 11 16:06:45 2011
@@ -95,7 +95,7 @@ prompt(const char **result,
   apr_file_t *fp;
   char c;
 
-  svn_stringbuf_t *strbuf = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *strbuf = svn_stringbuf_create_empty(pool);
 
   status = apr_file_open_stdin(&fp, pool);
   if (status)

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

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

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

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

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

Propchange: subversion/branches/moves-scan-log/subversion/libsvn_subr/svn_temp_serializer.c
            ('svn:mergeinfo' removed)

Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/target.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/target.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/target.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/target.c Fri Nov 11 16:06:45 2011
@@ -303,18 +303,12 @@ svn_path_remove_redundancies(apr_array_h
           if (is_url != keeper_is_url)
             continue;
 
-          /* Quit here if we find this path already in the keepers. */
-          if (strcmp(keeper, abs_path) == 0)
-            {
-              keep_me = FALSE;
-              break;
-            }
-
-          /* Quit here if this path is a child of one of the keepers. */
+          /* Quit here if this path is the same as or a child of one of the
+             keepers. */
           if (is_url)
-            child_relpath = svn_uri__is_child(keeper, abs_path, temp_pool);
+            child_relpath = svn_uri_skip_ancestor(keeper, abs_path, temp_pool);
           else
-            child_relpath = svn_dirent_is_child(keeper, abs_path, temp_pool);
+            child_relpath = svn_dirent_skip_ancestor(keeper, abs_path);
           if (child_relpath)
             {
               keep_me = FALSE;

Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/win32_xlate.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/win32_xlate.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/win32_xlate.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/win32_xlate.c Fri Nov 11 16:06:45 2011
@@ -185,7 +185,7 @@ svn_subr__win32_xlate_to_stringbuf(win32
 
   if (src_length == 0)
   {
-    *dest = svn_stringbuf_create("", pool);
+    *dest = svn_stringbuf_create_empty(pool);
     return APR_SUCCESS;
   }
 

Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/xml.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/xml.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/xml.c Fri Nov 11 16:06:45 2011
@@ -115,7 +115,7 @@ xml_escape_cdata(svn_stringbuf_t **outst
   const char *p = data, *q;
 
   if (*outstr == NULL)
-    *outstr = svn_stringbuf_create("", pool);
+    *outstr = svn_stringbuf_create_empty(pool);
 
   while (1)
     {
@@ -277,7 +277,7 @@ svn_xml_fuzzy_escape(const char *string,
   if (q == end)
     return string;
 
-  outstr = svn_stringbuf_create("", pool);
+  outstr = svn_stringbuf_create_empty(pool);
   while (1)
     {
       q = p;
@@ -479,7 +479,7 @@ svn_xml_make_header2(svn_stringbuf_t **s
 {
 
   if (*str == NULL)
-    *str = svn_stringbuf_create("", pool);
+    *str = svn_stringbuf_create_empty(pool);
   svn_stringbuf_appendcstr(*str, "<?xml version=\"1.0\"");
   if (encoding)
     {
@@ -646,7 +646,7 @@ void svn_xml_make_close_tag(svn_stringbu
                             const char *tagname)
 {
   if (*str == NULL)
-    *str = svn_stringbuf_create("", pool);
+    *str = svn_stringbuf_create_empty(pool);
 
   svn_stringbuf_appendcstr(*str, "</");
   svn_stringbuf_appendcstr(*str, tagname);

Modified: subversion/branches/moves-scan-log/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/adm_crawler.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_wc/adm_crawler.c Fri Nov 11 16:06:45 2011
@@ -420,9 +420,8 @@ report_revisions_and_depths(svn_wc__db_t
         }
       else
         {
-          const char *childname = svn_relpath__is_child(dir_repos_relpath,
-                                                        ths->repos_relpath,
-                                                        NULL);
+          const char *childname
+            = svn_relpath_skip_ancestor(dir_repos_relpath, ths->repos_relpath);
 
           if (childname == NULL || strcmp(childname, child) != 0)
             {

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

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

Modified: subversion/branches/moves-scan-log/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/copy.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_wc/copy.c Fri Nov 11 16:06:45 2011
@@ -496,6 +496,15 @@ copy_versioned_dir(svn_wc__db_t *db,
           /* Don't recurse on children while all we do is creating not-present
              children */
         }
+      else if (child_status == svn_wc__db_status_incomplete)
+        {
+          /* Should go ahead and copy incomplete to incomplete? Try to
+             copy as much as possible, or give up early? */
+          return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
+                                   _("Cannot handle status of '%s'"),
+                                   svn_dirent_local_style(src_abspath,
+                                                          iterpool));
+        }
       else
         {
           SVN_ERR_ASSERT(child_status == svn_wc__db_status_server_excluded);

Modified: subversion/branches/moves-scan-log/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/diff_editor.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_wc/diff_editor.c Fri Nov 11 16:06:45 2011
@@ -1880,6 +1880,8 @@ svn_wc_get_diff_editor6(const svn_delta_
   void *inner_baton;
   svn_delta_editor_t *tree_editor;
   const svn_delta_editor_t *inner_editor;
+  svn_delta_shim_callbacks_t *shim_callbacks =
+                                svn_delta_shim_callbacks_default(result_pool);
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(anchor_abspath));
 
@@ -1932,8 +1934,7 @@ svn_wc_get_diff_editor6(const svn_delta_
                                             result_pool));
 
   SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
-                                   NULL, NULL, NULL, NULL,
-                                   result_pool, scratch_pool));
+                                   shim_callbacks, result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/moves-scan-log/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/entries.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_wc/entries.c Fri Nov 11 16:06:45 2011
@@ -1672,6 +1672,13 @@ write_entry(struct write_baton **entry_n
 
       case svn_wc_schedule_add:
         working_node = MAYBE_ALLOC(working_node, result_pool);
+        if (entry->deleted)
+          {
+            if (parent_node->base)
+              base_node = MAYBE_ALLOC(base_node, result_pool);
+            else
+              below_working_node = MAYBE_ALLOC(below_working_node, result_pool);
+          }
         break;
 
       case svn_wc_schedule_delete:
@@ -1695,9 +1702,12 @@ write_entry(struct write_baton **entry_n
      BASE node to indicate the not-present node.  */
   if (entry->deleted)
     {
-      SVN_ERR_ASSERT(base_node && !working_node && !below_working_node);
+      SVN_ERR_ASSERT(base_node || below_working_node);
       SVN_ERR_ASSERT(!entry->incomplete);
-      base_node->presence = svn_wc__db_status_not_present;
+      if (base_node)
+        base_node->presence = svn_wc__db_status_not_present;
+      else
+        below_working_node->presence = svn_wc__db_status_not_present;
     }
   else if (entry->absent)
     {
@@ -1710,16 +1720,10 @@ write_entry(struct write_baton **entry_n
     {
       if (entry->copyfrom_url)
         {
-          const char *relpath;
-
           working_node->repos_id = repos_id;
-          relpath = svn_uri__is_child(this_dir->repos,
-                                      entry->copyfrom_url,
-                                      result_pool);
-          if (relpath == NULL)
-            working_node->repos_relpath = "";
-          else
-            working_node->repos_relpath = relpath;
+          working_node->repos_relpath = svn_uri_skip_ancestor(
+                                          this_dir->repos, entry->copyfrom_url,
+                                          result_pool);
           working_node->revision = entry->copyfrom_rev;
           working_node->op_depth
             = svn_wc__db_op_depth_for_upgrade(local_relpath);
@@ -1977,17 +1981,16 @@ write_entry(struct write_baton **entry_n
 
           if (entry->url != NULL)
             {
-              const char *relpath = svn_uri__is_child(this_dir->repos,
-                                                      entry->url,
-                                                      result_pool);
-              base_node->repos_relpath = relpath ? relpath : "";
+              base_node->repos_relpath = svn_uri_skip_ancestor(
+                                           this_dir->repos, entry->url,
+                                           result_pool);
             }
           else
             {
-              const char *relpath = svn_uri__is_child(this_dir->repos,
-                                                      this_dir->url,
-                                                      scratch_pool);
-              if (relpath == NULL)
+              const char *relpath = svn_uri_skip_ancestor(this_dir->repos,
+                                                          this_dir->url,
+                                                          scratch_pool);
+              if (relpath == NULL || *relpath == '\0')
                 base_node->repos_relpath = entry->name;
               else
                 base_node->repos_relpath =

Modified: subversion/branches/moves-scan-log/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/externals.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_wc/externals.c Fri Nov 11 16:06:45 2011
@@ -609,8 +609,8 @@ close_file(void *file_baton,
     const svn_checksum_t *original_checksum = NULL;
 
     svn_boolean_t added = !SVN_IS_VALID_REVNUM(eb->original_revision);
-    const char *repos_relpath = svn_uri__is_child(eb->repos_root_url,
-                                                  eb->url, pool);
+    const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url,
+                                                      eb->url, pool);
 
     if (! added)
       {
@@ -901,8 +901,8 @@ svn_wc__get_file_external_editor(const s
   eb->diff3cmd = diff3_cmd;
 
   eb->record_ancestor_abspath = apr_pstrdup(edit_pool,record_ancestor_abspath);
-  eb->recorded_repos_relpath = svn_uri__is_child(repos_root_url, recorded_url,
-                                                 edit_pool);
+  eb->recorded_repos_relpath = svn_uri_skip_ancestor(repos_root_url, recorded_url,
+                                                     edit_pool);
 
   eb->changed_rev = SVN_INVALID_REVNUM;
 
@@ -1115,6 +1115,110 @@ svn_wc__read_external_info(svn_node_kind
   return SVN_NO_ERROR;
 }
 
+/* Return TRUE in *IS_ROLLED_OUT iff a node exists at XINFO->LOCAL_ABSPATH and
+ * if that node's origin corresponds with XINFO->REPOS_ROOT_URL and
+ * XINFO->REPOS_RELPATH.  All allocations are made in SCRATCH_POOL. */
+static svn_error_t *
+is_external_rolled_out(svn_boolean_t *is_rolled_out,
+                       svn_wc_context_t *wc_ctx,
+                       svn_wc__committable_external_info_t *xinfo,
+                       apr_pool_t *scratch_pool)
+{
+  const char *x_repos_relpath;
+  const char *x_repos_root_url;
+  svn_error_t *err;
+
+  *is_rolled_out = FALSE;
+
+  err = svn_wc__node_get_origin(NULL, NULL,
+                                &x_repos_relpath,
+                                &x_repos_root_url,
+                                NULL,
+                                wc_ctx, xinfo->local_abspath,
+                                FALSE, /* scan_deleted */
+                                scratch_pool, scratch_pool);
+
+  if (err)
+    {
+      if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+        {
+          svn_error_clear(err);
+          return SVN_NO_ERROR;
+        }
+      SVN_ERR(err);
+    }
+
+  *is_rolled_out = (strcmp(xinfo->repos_root_url, x_repos_root_url) == 0 &&
+                    strcmp(xinfo->repos_relpath, x_repos_relpath) == 0);
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__committable_externals_below(apr_array_header_t **externals,
+                                    svn_wc_context_t *wc_ctx,
+                                    const char *local_abspath,
+                                    svn_depth_t depth,
+                                    apr_pool_t *result_pool,
+                                    apr_pool_t *scratch_pool)
+{
+  apr_array_header_t *orig_externals;
+  int i;
+  apr_pool_t *iterpool;
+
+  /* For svn_depth_files, this also fetches dirs. They are filtered later. */
+  SVN_ERR(svn_wc__db_committable_externals_below(&orig_externals,
+                                                 wc_ctx->db,
+                                                 local_abspath,
+                                                 depth != svn_depth_infinity,
+                                                 result_pool, scratch_pool));
+  
+  if (orig_externals == NULL)
+    return SVN_NO_ERROR;
+
+  iterpool = svn_pool_create(scratch_pool);
+
+  for (i = 0; i < orig_externals->nelts; i++)
+    {
+      svn_boolean_t is_rolled_out;
+
+      svn_wc__committable_external_info_t *xinfo =
+        APR_ARRAY_IDX(orig_externals, i,
+                      svn_wc__committable_external_info_t *);
+
+      /* Discard dirs for svn_depth_files (s.a.). */
+      if (depth == svn_depth_files
+          && xinfo->kind == svn_kind_dir)
+        continue;
+
+      svn_pool_clear(iterpool);
+
+      /* Discard those externals that are not currently checked out. */
+      SVN_ERR(is_external_rolled_out(&is_rolled_out, wc_ctx, xinfo,
+                                     iterpool));
+      if (! is_rolled_out)
+        continue;
+
+      if (*externals == NULL)
+        *externals = apr_array_make(
+                               result_pool, 0,
+                               sizeof(svn_wc__committable_external_info_t *));
+
+      APR_ARRAY_PUSH(*externals,
+                     svn_wc__committable_external_info_t *) = xinfo;
+
+      if (depth != svn_depth_infinity)
+        continue;
+
+      /* Are there any nested externals? */
+      SVN_ERR(svn_wc__committable_externals_below(externals, wc_ctx,
+                                                  xinfo->local_abspath,
+                                                  svn_depth_infinity,
+                                                  result_pool, iterpool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_wc__externals_defined_below(apr_hash_t **externals,
                                 svn_wc_context_t *wc_ctx,

Modified: subversion/branches/moves-scan-log/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/node.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_wc/node.c Fri Nov 11 16:06:45 2011
@@ -214,6 +214,8 @@ svn_wc__internal_get_repos_info(const ch
                                        db, local_abspath,
                                        result_pool, scratch_pool));
 
+  SVN_ERR_ASSERT(repos_root_url == NULL || *repos_root_url != NULL);
+  SVN_ERR_ASSERT(repos_uuid == NULL || *repos_uuid != NULL);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/moves-scan-log/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/props.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_wc/props.c Fri Nov 11 16:06:45 2011
@@ -145,8 +145,8 @@ diff_mergeinfo_props(svn_mergeinfo_t *de
       svn_mergeinfo_t from, to;
       SVN_ERR(svn_mergeinfo_parse(&from, from_prop_val->data, pool));
       SVN_ERR(svn_mergeinfo_parse(&to, to_prop_val->data, pool));
-      SVN_ERR(svn_mergeinfo_diff(deleted, added, from, to,
-                                 TRUE, pool));
+      SVN_ERR(svn_mergeinfo_diff2(deleted, added, from, to,
+                                  TRUE, pool, pool));
     }
   return SVN_NO_ERROR;
 }
@@ -595,9 +595,9 @@ prop_conflict_from_skel(const svn_string
                                   incoming_base, scratch_pool);
 
   if (mine == NULL)
-    mine = svn_string_create("", scratch_pool);
+    mine = svn_string_create_empty(scratch_pool);
   if (incoming == NULL)
-    incoming = svn_string_create("", scratch_pool);
+    incoming = svn_string_create_empty(scratch_pool);
 
   /* Pick a suitable base for the conflict diff.
    * The incoming value is always a change,
@@ -607,7 +607,7 @@ prop_conflict_from_skel(const svn_string
       if (incoming_base)
         original = incoming_base;
       else
-        original = svn_string_create("", scratch_pool);
+        original = svn_string_create_empty(scratch_pool);
     }
   else if (incoming_base && svn_string_compare(original, mine))
     original = incoming_base;

Modified: subversion/branches/moves-scan-log/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/status.c?rev=1200926&r1=1200925&r2=1200926&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_wc/status.c Fri Nov 11 16:06:45 2011
@@ -2456,6 +2456,8 @@ svn_wc_get_status_editor5(const svn_delt
   svn_delta_editor_t *tree_editor = svn_delta_default_editor(result_pool);
   void *inner_baton;
   const svn_delta_editor_t *inner_editor;
+  svn_delta_shim_callbacks_t *shim_callbacks =
+                                svn_delta_shim_callbacks_default(result_pool);
 
   /* Construct an edit baton. */
   eb = apr_pcalloc(result_pool, sizeof(*eb));
@@ -2544,7 +2546,7 @@ svn_wc_get_status_editor5(const svn_delt
     *set_locks_baton = eb;
 
   SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
-                                   NULL, NULL, NULL, NULL,
+                                   shim_callbacks,
                                    result_pool, scratch_pool));
 
   return SVN_NO_ERROR;



Mime
View raw message