You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2014/05/22 07:13:41 UTC

svn commit: r1596751 [3/4] - in /subversion/branches/javahl-1.8-extensions: ./ build/ac-macros/ subversion/bindings/javahl/ subversion/bindings/javahl/native/ subversion/bindings/swig/ subversion/bindings/swig/ruby/libsvn_swig_ruby/ subversion/bindings...

Modified: subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db.h?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db.h Thu May 22 05:13:39 2014
@@ -1909,6 +1909,16 @@ svn_wc__db_read_info(svn_wc__db_status_t
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool);
 
+/* Structure used as linked list in svn_wc__db_info_t to describe all nodes
+   in this location that were moved to another location */
+struct svn_wc__db_moved_to_info_t
+{
+  const char *moved_to_abspath;
+  const char *shadow_op_root_abspath;
+
+  struct svn_wc__db_moved_to_info_t *next;
+};
+
 /* Structure returned by svn_wc__db_read_children_info.  Only has the
    fields needed by status. */
 struct svn_wc__db_info_t {
@@ -1945,7 +1955,10 @@ struct svn_wc__db_info_t {
   svn_wc__db_lock_t *lock;  /* Repository file lock */
   svn_boolean_t incomplete; /* TRUE if a working node is incomplete */
 
-  const char *moved_to_abspath; /* Only on op-roots. See svn_wc_status3_t. */
+  struct svn_wc__db_moved_to_info_t *moved_to; /* A linked list of locations
+                                                 where nodes at this path
+                                                 are moved to. Highest layers
+                                                 first */
   svn_boolean_t moved_here;     /* Only on op-roots. */
 
   svn_boolean_t file_external;
@@ -1967,6 +1980,14 @@ svn_wc__db_read_children_info(apr_hash_t
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool);
 
+/* Like svn_wc__db_read_children_info, but only gets an info node for the root
+   element. */
+svn_error_t *
+svn_wc__db_read_single_info(const struct svn_wc__db_info_t **info,
+                            svn_wc__db_t *db,
+                            const char *local_abspath,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
 
 /* Structure returned by svn_wc__db_read_walker_info.  Only has the
    fields needed by svn_wc__internal_walk_children(). */

Modified: subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db_wcroot.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db_wcroot.c?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db_wcroot.c (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db_wcroot.c Thu May 22 05:13:39 2014
@@ -690,8 +690,12 @@ try_symlink_as_dir:
           svn_error_clear(err);
           *wcroot = NULL;
         }
-      else
-        SVN_ERR(err);
+      else if (err)
+        {
+          /* Close handle if we are not going to use it to support
+             upgrading with exclusive wc locking. */
+          return svn_error_compose_create(err, svn_sqlite__close(sdb));
+        }
     }
   else
     {

Modified: subversion/branches/javahl-1.8-extensions/subversion/mod_dav_svn/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/mod_dav_svn/lock.c?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/mod_dav_svn/lock.c (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/mod_dav_svn/lock.c Thu May 22 05:13:39 2014
@@ -453,7 +453,8 @@ get_locks(dav_lockdb *lockdb,
      lock.  For the --force case, this is required and for the non-force case,
      we allow the filesystem to produce a better error for svn clients.
   */
-  if (info->r->method_number == M_LOCK)
+  if (info->r->method_number == M_LOCK
+      && resource->info->repos->is_svn_client)
     {
       *locks = NULL;
       return 0;
@@ -594,7 +595,8 @@ has_locks(dav_lockdb *lockdb, const dav_
      lock.  For the --force case, this is required and for the non-force case,
      we allow the filesystem to produce a better error for svn clients.
   */
-  if (info->r->method_number == M_LOCK)
+  if (info->r->method_number == M_LOCK
+      && resource->info->repos->is_svn_client)
     {
       *locks_present = 0;
       return 0;

Modified: subversion/branches/javahl-1.8-extensions/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/mod_dav_svn/repos.c?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/mod_dav_svn/repos.c Thu May 22 05:13:39 2014
@@ -1790,14 +1790,97 @@ do_out_of_date_check(dav_resource_combin
                                 "Could not get created rev of "
                                 "resource", r->pool);
 
-  if (comb->priv.version_name < created_rev)
+  if (SVN_IS_VALID_REVNUM(created_rev))
     {
-      serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
-                               "Item '%s' is out of date",
-                               comb->priv.repos_path);
-      return dav_svn__convert_err(serr, HTTP_CONFLICT,
-                                  "Attempting to modify out-of-date resource.",
-                                  r->pool);
+      if (comb->priv.version_name < created_rev)
+        {
+          serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
+                                   comb->res.collection
+                                    ? "Directory '%s' is out of date"
+                                    : (comb->res.exists
+                                        ? "File '%s' is out of date"
+                                        : "'%s' is out of date"),
+                                   comb->priv.repos_path);
+          return dav_svn__convert_err(serr, HTTP_CONFLICT,
+                                      "Attempting to modify out-of-date resource.",
+                                      r->pool);
+        }
+    }
+  else if (SVN_IS_VALID_REVNUM(comb->priv.version_name)
+           && comb->res.collection)
+    {
+      /* Issue #4480: With HTTPv2 we can receive the first change for a
+         directory after it has been made mutable, because one of its
+         descendants was changed before changing the directory.
+
+         We have to check if whatever the node is in HEAD is equivalent
+         to what it was in the provided BASE revision.
+
+         If the node was copied, we would process it before its decendants
+         and we already performed quite a few checks when making it mutable
+         via its descendant, so what we should really check here is if the
+         properties changed since the BASE version.
+
+         ### I think svn_fs_node_relation() checks for more changes than we
+             should check for here. Needs further review. But it looks like\
+             this check matches the checks in the libsvn_fs commit editor.
+
+             For now I would say reporting out of date in a few too many
+             cases is safer than not reporting out of date when we should.
+       */
+      svn_revnum_t txn_base_rev;
+      svn_fs_root_t *txn_base_root;
+      svn_fs_root_t *rev_root;
+      const svn_fs_id_t *txn_base_id;
+      const svn_fs_id_t *rev_id;
+
+      txn_base_rev = svn_fs_txn_base_revision(comb->res.info->root.txn);
+
+      if (comb->priv.version_name == txn_base_rev)
+        return NULL; /* Easy out: Nothing changed */
+
+      serr = svn_fs_revision_root(&txn_base_root, comb->res.info->repos->fs,
+                                  txn_base_rev, r->pool);
+                                  
+      if (!serr)
+        serr = svn_fs_node_id(&txn_base_id, txn_base_root,
+                              comb->priv.repos_path, r->pool);
+
+      if (serr != NULL)
+        {
+          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                      "Could not open youngest revision root "
+                                      "for verification against the base "
+                                      "revision", r->pool);
+        }
+
+      serr = svn_fs_revision_root(&rev_root, comb->res.info->repos->fs,
+                                  comb->priv.version_name, r->pool);
+
+      if (!serr)
+        serr = svn_fs_node_id(&rev_id, rev_root,
+                              comb->priv.repos_path, r->pool);
+
+      if (serr != NULL)
+        {
+          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                      "Could not open the base revision"
+                                      "for verification against the youngest "
+                                      "revision", r->pool);
+        }
+
+      svn_fs_close_root(rev_root);
+      svn_fs_close_root(txn_base_root);
+
+      if (0 != svn_fs_compare_ids(txn_base_id, rev_id))
+        {
+          serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
+                                   "Directory '%s' is out of date",
+                                   comb->priv.repos_path);
+          return dav_svn__convert_err(serr, HTTP_CONFLICT,
+                                      "Attempting to modify out-of-date resource.",
+                                      r->pool);
+        }
     }
 
   return NULL;

Modified: subversion/branches/javahl-1.8-extensions/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/svn/conflict-callbacks.c?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/svn/conflict-callbacks.c Thu May 22 05:13:39 2014
@@ -935,7 +935,7 @@ handle_text_conflict(svn_wc_conflict_res
           /* We only allow the user accept the merged version of
              the file if they've edited it, or at least looked at
              the diff. */
-          if (result->choice == svn_wc_conflict_choose_merged
+          if (opt->choice == svn_wc_conflict_choose_merged
               && ! knows_something)
             {
               SVN_ERR(svn_cmdline_fprintf(

Propchange: subversion/branches/javahl-1.8-extensions/subversion/svn/svn.c
------------------------------------------------------------------------------
  Merged /subversion/branches/1.8.x/subversion/svn/svn.c:r1556176-1591380
  Merged /subversion/branches/1.8.x-r1536931/subversion/svn/svn.c:r1536934-1591145

Modified: subversion/branches/javahl-1.8-extensions/subversion/svndumpfilter/svndumpfilter.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/svndumpfilter/svndumpfilter.c?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/svndumpfilter/svndumpfilter.c (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/svndumpfilter/svndumpfilter.c Thu May 22 05:13:39 2014
@@ -570,6 +570,9 @@ new_node_record(void **node_baton,
     }
   else
     {
+      const char *kind;
+      const char *action;
+
       tcl = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH);
 
       /* Test if this node was copied from dropped source. */
@@ -584,7 +587,6 @@ new_node_record(void **node_baton,
              dumpfile should contain the new contents of the file.  In this
              scenario, we'll just do an add without history using the new
              contents.  */
-          const char *kind;
           kind = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_NODE_KIND);
 
           /* If there is a Text-content-length header, and the kind is
@@ -623,6 +625,30 @@ new_node_record(void **node_baton,
       if (! nb->rb->writing_begun)
         SVN_ERR(output_revision(nb->rb));
 
+      /* A node record is required to begin with 'Node-path', skip the
+         leading '/' to match the form used by 'svnadmin dump'. */
+      SVN_ERR(svn_stream_printf(nb->rb->pb->out_stream,
+                                pool, "%s: %s\n",
+                                SVN_REPOS_DUMPFILE_NODE_PATH, node_path + 1));
+
+      /* Node-kind is next and is optional. */
+      kind = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_NODE_KIND);
+      if (kind)
+        SVN_ERR(svn_stream_printf(nb->rb->pb->out_stream,
+                                  pool, "%s: %s\n",
+                                  SVN_REPOS_DUMPFILE_NODE_KIND, kind));
+
+      /* Node-action is next and required. */
+      action = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_NODE_ACTION);
+      if (action)
+        SVN_ERR(svn_stream_printf(nb->rb->pb->out_stream,
+                                  pool, "%s: %s\n",
+                                  SVN_REPOS_DUMPFILE_NODE_ACTION, action));
+      else
+        return svn_error_createf(SVN_ERR_INCOMPLETE_DATA, 0,
+                                 _("Missing Node-action for path '%s'"),
+                                 node_path);
+
       for (hi = apr_hash_first(pool, headers); hi; hi = apr_hash_next(hi))
         {
           const char *key = svn__apr_hash_index_key(hi);
@@ -638,7 +664,10 @@ new_node_record(void **node_baton,
 
           if ((!strcmp(key, SVN_REPOS_DUMPFILE_CONTENT_LENGTH))
               || (!strcmp(key, SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH))
-              || (!strcmp(key, SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH)))
+              || (!strcmp(key, SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH))
+              || (!strcmp(key, SVN_REPOS_DUMPFILE_NODE_PATH))
+              || (!strcmp(key, SVN_REPOS_DUMPFILE_NODE_KIND))
+              || (!strcmp(key, SVN_REPOS_DUMPFILE_NODE_ACTION)))
             continue;
 
           /* Rewrite Node-Copyfrom-Rev if we are renumbering revisions.

Modified: subversion/branches/javahl-1.8-extensions/subversion/svnrdump/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/svnrdump/util.c?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/svnrdump/util.c (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/svnrdump/util.c Thu May 22 05:13:39 2014
@@ -35,7 +35,7 @@ svn_rdump__normalize_prop(const char *na
                           const svn_string_t **value,
                           apr_pool_t *result_pool)
 {
-  if (svn_prop_needs_translation(name))
+  if (svn_prop_needs_translation(name) && *value)
     {
       const char *cstring;
 

Modified: subversion/branches/javahl-1.8-extensions/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/svnserve/serve.c?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/svnserve/serve.c (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/svnserve/serve.c Thu May 22 05:13:39 2014
@@ -1526,6 +1526,9 @@ static svn_error_t *get_file(svn_ra_svn_
                                   &want_props, &want_contents,
                                   &wants_inherited_props));
 
+  if (wants_inherited_props == SVN_RA_SVN_UNSPECIFIED_NUMBER)
+    wants_inherited_props = FALSE;
+
   full_path = svn_fspath__join(b->fs_path->data,
                                svn_relpath_canonicalize(path, pool), pool);
 
@@ -1545,8 +1548,14 @@ static svn_error_t *get_file(svn_ra_svn_
   SVN_CMD_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5, root,
                                    full_path, TRUE, pool));
   hex_digest = svn_checksum_to_cstring_display(checksum, pool);
+
+  /* Fetch the file's explicit and/or inherited properties if
+     requested.  Although the wants-iprops boolean was added to the
+     protocol in 1.8 a standard 1.8 client never requests iprops. */
   if (want_props || wants_inherited_props)
-    SVN_CMD_ERR(get_props(&props, &inherited_props, &ab, root, full_path,
+    SVN_CMD_ERR(get_props(want_props ? &props : NULL,
+                          wants_inherited_props ? &inherited_props : NULL,
+                          &ab, root, full_path,
                           pool));
   if (want_contents)
     SVN_CMD_ERR(svn_fs_file_contents(&contents, root, full_path, pool));
@@ -1640,6 +1649,9 @@ static svn_error_t *get_dir(svn_ra_svn_c
                                   &dirent_fields_list,
                                   &wants_inherited_props));
 
+  if (wants_inherited_props == SVN_RA_SVN_UNSPECIFIED_NUMBER)
+    wants_inherited_props = FALSE;
+
   if (! dirent_fields_list)
     {
       dirent_fields = SVN_DIRENT_ALL;
@@ -1689,10 +1701,13 @@ static svn_error_t *get_dir(svn_ra_svn_c
   /* Fetch the root of the appropriate revision. */
   SVN_CMD_ERR(svn_fs_revision_root(&root, b->fs, rev, pool));
 
-  /* Fetch the directory's explicit and/or inherited properties
-     if requested. */
+  /* Fetch the directory's explicit and/or inherited properties if
+     requested.  Although the wants-iprops boolean was added to the
+     protocol in 1.8 a standard 1.8 client never requests iprops. */
   if (want_props || wants_inherited_props)
-    SVN_CMD_ERR(get_props(&props, &inherited_props, &ab, root, full_path,
+    SVN_CMD_ERR(get_props(want_props ? &props : NULL,
+                          wants_inherited_props ? &inherited_props : NULL,
+                          &ab, root, full_path,
                           pool));
 
   /* Begin response ... */

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/autoprop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/autoprop_tests.py?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/autoprop_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/autoprop_tests.py Thu May 22 05:13:39 2014
@@ -102,7 +102,9 @@ def autoprops_test(sbox, cmd, cfgenable,
 
   # some directories
   wc_dir = sbox.wc_dir
-  tmp_dir = os.path.abspath(svntest.main.temp_dir)
+  tmp_dir = os.path.join(os.path.abspath(svntest.main.temp_dir), sbox.name)
+  if not os.path.isdir(tmp_dir):
+    os.makedirs(tmp_dir)
   config_dir = os.path.join(tmp_dir, 'autoprops_config_' + sbox.name)
   repos_url = sbox.repo_url
 

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/commit_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/commit_tests.py?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/commit_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/commit_tests.py Thu May 22 05:13:39 2014
@@ -2545,6 +2545,16 @@ def start_commit_hook_test(sbox):
                                            'STDERR',
                                            expected_stderr, actual_stderr)
 
+  # Now list the txns in the repo. The list should be empty.
+  exit_code, output, errput = svntest.main.run_svnadmin('lstxns',
+                                                        sbox.repo_dir)
+  svntest.verify.compare_and_display_lines(
+    "Error running 'svnadmin lstxns'.",
+    'STDERR', [], errput)
+  svntest.verify.compare_and_display_lines(
+    "Output of 'svnadmin lstxns' is unexpected.",
+    'STDOUT', [], output)
+
 #----------------------------------------------------------------------
 @Issue(3553)
 def pre_commit_hook_test(sbox):
@@ -2998,7 +3008,115 @@ def commit_cp_with_deep_delete(sbox):
                                         None,
                                         wc_dir)
 
-  
+def commit_deep_deleted(sbox):
+  "try to commit a deep descendant of a deleted node"
+
+  sbox.build()
+
+  sbox.simple_move('A', 'AA')
+
+  sbox.simple_propset('k', 'v', 'AA/D/G')
+
+  # Committing some added descendant returns a proper error
+  expected_err = ('svn: E200009: \'%s\' is not known to exist in the ' +
+                  'repository and is not part of the commit, yet its ' +
+                  'child \'%s\' is part of the commit') % (
+                    re.escape(os.path.abspath(sbox.ospath('AA'))),
+                    re.escape(os.path.abspath(sbox.ospath('AA/D/G'))))
+
+  svntest.actions.run_and_verify_commit(sbox.wc_dir,
+                                        None,
+                                        None,
+                                        expected_err,
+                                        sbox.ospath('AA/D/G'))
+
+  sbox.simple_propdel('k', 'AA/D/G')
+  sbox.simple_rm('AA/D/G')
+
+  # But a delete fails..
+  # This used to trigger an assertion in Subversion 1.8.0-1.8.8, because
+  # the status walker couldn't find the repository path for AA/D/G
+  svntest.actions.run_and_verify_commit(sbox.wc_dir,
+                                        None,
+                                        None,
+                                        expected_err,
+                                        sbox.ospath('AA/D/G'))
+
+  # And now commit like how a GUI client would do it, but forgetting the move
+  expected_err = ('svn: E200009: Cannot commit \'%s\' because it was moved ' +
+                  'from \'%s\' which is not part of the commit; both sides ' +
+                  'of the move must be committed together') % (
+                     re.escape(os.path.abspath(sbox.ospath('AA'))),
+                     re.escape(os.path.abspath(sbox.ospath('A'))))
+  svntest.actions.run_and_verify_commit(sbox.wc_dir,
+                                        None,
+                                        None,
+                                        expected_err,
+                                        '--depth', 'empty',
+                                        sbox.ospath('AA/D/G'),
+                                        sbox.ospath('AA'))
+
+
+  # And now how it works
+  svntest.actions.run_and_verify_commit(sbox.wc_dir,
+                                        None,
+                                        None,
+                                        [],
+                                        '--depth', 'empty',
+                                        sbox.ospath('AA/D/G'),
+                                        sbox.ospath('AA'),
+                                        sbox.ospath('A'))
+
+@Issue(4480)
+def commit_mergeinfo_ood(sbox):
+  "commit of mergeinfo that should cause out of date"
+
+  sbox.build()
+  sbox.simple_rm('A', 'iota')
+  sbox.simple_commit() # r2
+
+  sbox.simple_mkdir('trunk', 'branch')
+  sbox.simple_commit() # r3
+
+  sbox.simple_append('trunk/a', 'This is a\n')
+  sbox.simple_add('trunk/a')
+  sbox.simple_commit() # r4
+
+  sbox.simple_append('trunk/b', 'This is b\n')
+  sbox.simple_add('trunk/b')
+  sbox.simple_commit() # r5
+
+  sbox.simple_update() # To r5
+
+  expected_output = [
+    '--- Merging r4 into \'%s\':\n' % sbox.ospath('branch'),
+    'A    %s\n' % sbox.ospath('branch/a'),
+    '--- Recording mergeinfo for merge of r4' \
+                                ' into \'%s\':\n' % sbox.ospath('branch'),
+    ' U   %s\n' % sbox.ospath('branch'),
+  ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'merge', '-c4', '^/trunk',
+                                     sbox.ospath('branch'))
+
+  sbox.simple_commit()
+
+  sbox.simple_update(revision='5')
+
+  expected_output = [
+    '--- Merging r5 into \'%s\':\n' % sbox.ospath('branch'),
+    'A    %s\n' % sbox.ospath('branch/b'),
+    '--- Recording mergeinfo for merge of r5 into \'%s\':\n' % sbox.ospath('branch'),
+    ' U   %s\n' % sbox.ospath('branch'),
+  ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'merge', '-c5', '^/trunk',
+                                     sbox.ospath('branch'))
+
+  # Currently this commit succeeds with dav over HTTPv2, while it should really fail
+  expected_err = '.*out of date.*'
+  svntest.actions.run_and_verify_svn(None, None, expected_err,
+                                     'commit', sbox.ospath(''), '-m', 'M')
 
 ########################################################################
 # Run the tests
@@ -3072,6 +3190,8 @@ test_list = [ None,
               commit_danglers,
               last_changed_of_copied_subdir,
               commit_cp_with_deep_delete,
+              commit_deep_deleted,
+              commit_mergeinfo_ood,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/export_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/export_tests.py?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/export_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/export_tests.py Thu May 22 05:13:39 2014
@@ -964,6 +964,114 @@ def export_custom_keywords(sbox):
   if open(export_file).read() != ''.join(alpha_content):
     raise svntest.Failure("wrong keyword expansion")
 
+@Issue(4427)
+def export_file_external(sbox):
+  "export file external from WC and URL"
+  sbox.build()
+
+  wc_dir = sbox.wc_dir
+
+  # Set 'svn:externals' property in 'A/C' to 'A/B/E/alpha'(file external),
+  C_path = os.path.join(wc_dir, 'A', 'C')
+  externals_prop = "^/A/B/E/alpha exfile_alpha"
+
+  tmp_f = sbox.get_tempname('prop')
+  svntest.main.file_append(tmp_f, externals_prop)
+  svntest.main.run_svn(None, 'ps', '-F', tmp_f, 'svn:externals', C_path)
+  svntest.main.run_svn(None,'ci', '-m', 'log msg', '--quiet', C_path)
+
+  # Update the working copy to receive file external
+  svntest.main.run_svn(None, 'up', wc_dir)
+
+  # Update the expected disk tree to include the external.
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.add({
+      'A/C/exfile_alpha'  : Item("This is the file 'alpha'.\n"),
+      })
+
+  # Export from URL
+  export_target = sbox.add_wc_path('export_url')
+  expected_output = svntest.main.greek_state.copy()
+  expected_output.add({
+      'A/C/exfile_alpha'  : Item("This is the file 'alpha'.\r"),
+      })
+  expected_output.wc_dir = export_target
+  expected_output.desc[''] = Item()
+  expected_output.tweak(contents=None, status='A ')
+  svntest.actions.run_and_verify_export(sbox.repo_url,
+                                        export_target,
+                                        expected_output,
+                                        expected_disk)
+
+  # Export from WC
+  export_target = sbox.add_wc_path('export_wc')
+  expected_output = svntest.main.greek_state.copy()
+  expected_output.add({
+      'A/C/exfile_alpha'  : Item("This is the file 'alpha'.\r"),
+      })
+  expected_output.wc_dir = export_target
+  expected_output.desc['A'] = Item()
+  expected_output.tweak(contents=None, status='A ')
+  svntest.actions.run_and_verify_export(wc_dir,
+                                        export_target,
+                                        expected_output,
+                                        expected_disk)
+
+@Issue(4427)
+def export_file_externals2(sbox):
+  "exporting file externals"
+  
+  sbox.build()
+  sbox.simple_mkdir('DIR', 'DIR2')
+  
+  sbox.simple_propset('svn:externals', '^/iota file', 'DIR')
+  sbox.simple_propset('svn:externals', '^/DIR TheDir', 'DIR2')
+  sbox.simple_commit()
+  sbox.simple_update()
+  
+  tmp = sbox.add_wc_path('tmp')
+  os.mkdir(tmp)
+  
+  expected_output = svntest.wc.State(tmp, {
+    'file'          : Item(status='A '),
+  })
+  expected_disk = svntest.wc.State('', {
+    'file': Item(contents="This is the file 'iota'.\n")
+  })
+  # Fails in 1.8.8 and r1575909.
+  # Direct export of file external was just skipped
+  svntest.actions.run_and_verify_export(sbox.ospath('DIR/file'),
+                                        tmp,
+                                        expected_output,
+                                        expected_disk)
+  
+  expected_output = svntest.wc.State(tmp, {
+    'DIR/file'           : Item(status='A '),
+  })
+  expected_disk = svntest.wc.State('', {
+    'file': Item(contents="This is the file 'iota'.\n")
+  })
+  # Fails in 1.8.8 (doesn't export file), passes in r1575909
+  svntest.actions.run_and_verify_export(sbox.ospath('DIR'),
+                                        os.path.join(tmp, 'DIR'),
+                                        expected_output,
+                                        expected_disk)
+                                        
+  expected_output = svntest.wc.State(tmp, {
+    'DIR2/TheDir/file' : Item(status='A '),
+  })
+  expected_disk = svntest.wc.State('', {
+    'TheDir'      : Item(),
+    'TheDir/file' : Item(contents="This is the file 'iota'.\n")
+  })
+  # Fails in 1.8.8 (doesn't export anything),
+  # Fails in r1575909 (exports file twice; once as file; once as external)
+  svntest.actions.run_and_verify_export(sbox.ospath('DIR2'),
+                                        os.path.join(tmp, 'DIR2'),
+                                        expected_output,
+                                        expected_disk)
+
+
 ########################################################################
 # Run the tests
 
@@ -998,6 +1106,8 @@ test_list = [ None,
               export_to_current_dir,
               export_file_overwrite_with_force,
               export_custom_keywords,
+              export_file_external,
+              export_file_externals2
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/lock_tests.py?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/lock_tests.py Thu May 22 05:13:39 2014
@@ -1890,6 +1890,147 @@ def drop_locks_on_parent_deletion(sbox):
                                         wc_dir)
 	
 										
+@SkipUnless(svntest.main.is_ra_type_dav)
+def dav_lock_timeout(sbox):
+  "unlock a lock with timeout"
+
+  import httplib
+  from urlparse import urlparse
+  import base64
+
+  sbox.build()
+  loc = urlparse(sbox.repo_url)
+
+  if loc.scheme == 'http':
+    h = httplib.HTTPConnection(loc.hostname, loc.port)
+  else:
+    h = httplib.HTTPSConnection(loc.hostname, loc.port)
+
+  lock_body = '<?xml version="1.0" encoding="utf-8" ?>' \
+              '<D:lockinfo xmlns:D="DAV:">' \
+              '  <D:lockscope><D:exclusive/></D:lockscope>' \
+              '  <D:locktype><D:write/></D:locktype>' \
+              '  <D:owner>' \
+              '       <D:href>http://a/test</D:href>' \
+              '  </D:owner>' \
+              '</D:lockinfo>'
+
+  lock_headers = {
+    'Authorization': 'Basic ' + base64.b64encode('jconstant:rayjandom'),
+    'Timeout': 'Second-86400'
+  }
+
+  # Enabling the following line makes this test easier to debug
+  h.set_debuglevel(9)
+
+  h.request('LOCK', sbox.repo_url + '/iota', lock_body, lock_headers)
+
+  r = h.getresponse()
+
+  # Verify that there is a lock, by trying to obtain one
+  svntest.actions.run_and_verify_svn2(None, None, ".*locked by user", 0,
+                                      'lock', '-m', '', sbox.ospath('iota'))
+
+  # Before this patch this used to fail with a parse error of the timeout
+  svntest.actions.run_and_verify_svn2(None, None, ".*W160039.*Unlock.*403", 0,
+                                     'unlock', sbox.repo_url + '/iota')
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'unlock', sbox.ospath('iota'), '--force')
+
+
+
+def non_root_locks(sbox):
+  "locks for working copies not at repos root"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'cp', sbox.repo_url, sbox.repo_url + '/X',
+                                     '-m', 'copy greek tree')
+
+  sbox.simple_switch(sbox.repo_url + '/X')  
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+  # Lock a file
+  svntest.actions.run_and_verify_svn(None, ".*locked by user", [],
+                                     'lock', sbox.ospath('A/D/G/pi'),
+                                     '-m', '')
+  expected_status.tweak('A/D/G/pi', writelocked='K')
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+  # Updates don't break the lock
+  sbox.simple_update('A/D')
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+  sbox.simple_update('')
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+  # Break the lock
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'unlock', sbox.repo_url + '/X/A/D/G/pi')
+
+  # Subdir update reports the break
+  sbox.simple_update('A/D')
+  expected_status.tweak('A/D/G/pi', writelocked=None)
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+  # Relock and break
+  svntest.actions.run_and_verify_svn(None, ".*locked by user", [],
+                                     'lock', sbox.ospath('A/D/G/pi'),
+                                     '-m', '')
+  expected_status.tweak('A/D/G/pi', writelocked='K')
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'unlock', sbox.repo_url + '/X/A/D/G/pi')
+
+  # Root update reports the break
+  sbox.simple_update('')
+  expected_status.tweak('A/D/G/pi', writelocked=None)
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+@Issue(3515)
+@SkipUnless(svntest.main.is_ra_type_dav)
+def dav_lock_refresh(sbox):
+  "refresh timeout of DAV lock"
+
+  import httplib
+  from urlparse import urlparse
+  import base64
+
+  sbox.build(create_wc = False)
+
+  # Acquire lock on 'iota'
+  svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
+                                     sbox.repo_url + '/iota')
+
+  # Try to refresh lock using 'If' header
+  loc = urlparse(sbox.repo_url)
+
+  if loc.scheme == 'http':
+    h = httplib.HTTPConnection(loc.hostname, loc.port)
+  else:
+    h = httplib.HTTPSConnection(loc.hostname, loc.port)
+
+  lock_token = svntest.actions.run_and_parse_info(sbox.repo_url + '/iota')[0]['Lock Token']
+
+  lock_headers = {
+    'Authorization': 'Basic ' + base64.b64encode('jrandom:rayjandom'),
+    'If': '(<' + lock_token + '>)',
+    'Timeout': 'Second-7200'
+  }
+
+  # Enabling the following line makes this test easier to debug
+  h.set_debuglevel(9)
+
+  h.request('LOCK', sbox.repo_url + '/iota', '', lock_headers)
+
+  # XFAIL Refreshing of DAV lock fails with error '412 Precondition Failed'
+  r = h.getresponse()
+  if r.status != httplib.OK:
+    raise svntest.Failure('Lock refresh failed: %d %s' % (r.status, r.reason))
+
 ########################################################################
 # Run the tests
 
@@ -1943,6 +2084,9 @@ test_list = [ None,
               lock_unlock_deleted,
               commit_stolen_lock,
               drop_locks_on_parent_deletion,
+              dav_lock_timeout,
+              non_root_locks,
+              dav_lock_refresh,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/merge_automatic_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/merge_automatic_tests.py?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/merge_automatic_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/merge_automatic_tests.py Thu May 22 05:13:39 2014
@@ -1202,6 +1202,132 @@ def effective_sync_results_in_reintegrat
   svntest.actions.run_and_verify_svn(None, expected_output, [], 'merge',
                                      sbox.repo_url + '/branch', A_path)
 
+@Issue(4481)
+def reintegrate_subtree_not_updated(sbox):
+  "reintegrate subtree not updated"
+
+  sbox.build()
+
+  # Create change on branch 'D_1'
+  sbox.simple_copy('A/D', 'D_1')
+  sbox.simple_commit()
+  sbox.simple_append('D_1/G/pi', "D_1/G pi edit\n")
+  sbox.simple_append('D_1/H/chi', "D_1/H chi edit\n")
+  sbox.simple_commit()
+
+  # Merge back to 'D' with two subtree merges
+  expected_output = [
+    "--- Merging r2 through r3 into '"
+    + sbox.ospath('A/D/G') + "':\n",
+    "U    "
+    + sbox.ospath('A/D/G/pi') + "\n",
+    "--- Recording mergeinfo for merge of r2 through r3 into '"
+    + sbox.ospath('A/D/G') + "':\n",
+    " U   "
+    + sbox.ospath('A/D/G') + "\n"]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'merge',
+                                     sbox.repo_url + '/D_1/G',
+                                     sbox.ospath('A/D/G'))
+  expected_output = [
+    "--- Merging r2 through r3 into '"
+    + sbox.ospath('A/D/H') + "':\n",
+    "U    "
+    + sbox.ospath('A/D/H/chi') + "\n",
+    "--- Recording mergeinfo for merge of r2 through r3 into '"
+    + sbox.ospath('A/D/H') + "':\n",
+    " U   "
+    + sbox.ospath('A/D/H') + "\n"]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'merge',
+                                     sbox.repo_url + '/D_1/H',
+                                     sbox.ospath('A/D/H'))
+  sbox.simple_commit()
+  sbox.simple_update()
+
+  # Create branch 'D_2'
+  sbox.simple_copy('A/D', 'D_2')
+  sbox.simple_commit()
+  sbox.simple_update()
+
+  # Create change on 'D_2'
+  sbox.simple_append('D_2/G/pi', "D_2/G pi edit\n")
+  sbox.simple_commit()
+  sbox.simple_update()
+
+  # Create change on 'D'
+  sbox.simple_append('A/D/G/rho', "D/G rho edit\n")
+  sbox.simple_commit()
+  sbox.simple_update()
+
+  # Sync merge to 'D_2' (doesn't record mergeinfo on 'D_2/H' subtree)
+  expected_output = [
+    "--- Merging r5 through r7 into '"
+    + sbox.ospath('D_2') + "':\n",
+    "U    "
+    + sbox.ospath('D_2/G/rho') + "\n",
+    "--- Recording mergeinfo for merge of r5 through r7 into '"
+    + sbox.ospath('D_2') + "':\n",
+    " U   "
+    + sbox.ospath('D_2') + "\n",
+    "--- Recording mergeinfo for merge of r5 through r7 into '"
+    + sbox.ospath('D_2/G') + "':\n",
+    " U   "
+    + sbox.ospath('D_2/G') + "\n"]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'merge',
+                                     sbox.repo_url + '/A/D',
+                                     sbox.ospath('D_2'))
+  sbox.simple_commit()
+  sbox.simple_update()
+
+  # Reintegrate 'D_2' to 'D'
+  expected_output = [
+    "--- Merging differences between repository URLs into '"
+    + sbox.ospath('A/D') + "':\n",
+    "U    "
+    + sbox.ospath('A/D/G/pi') + "\n",
+    " U   "
+    + sbox.ospath('A/D/G') + "\n",
+    "--- Recording mergeinfo for merge between repository URLs into '"
+    + sbox.ospath('A/D') + "':\n",
+    " U   "
+    + sbox.ospath('A/D') + "\n",
+    " U   "
+    + sbox.ospath('A/D/G') + "\n"]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'merge',
+                                     sbox.repo_url + '/D_2',
+                                     sbox.ospath('A/D'))
+  sbox.simple_commit()
+  sbox.simple_update()
+
+  # merge to 'D_2'. This merge previously failed with this error:
+  #
+  # svn: E195016: Reintegrate can only be used if revisions 5 through 9 were
+  # previously merged from [URL]/D_2 to the reintegrate source, but this is
+  # not the case:
+  #   A/D/G
+  #       Missing ranges: /A/D/G:7
+  #
+  expected_output = [
+    "--- Merging differences between repository URLs into '"
+    + sbox.ospath('D_2') + "':\n",
+    " U   "
+    + sbox.ospath('D_2/G') + "\n",
+    "--- Recording mergeinfo for merge between repository URLs into '"
+    + sbox.ospath('D_2') + "':\n",
+    " U   "
+    + sbox.ospath('D_2') + "\n",
+    " G   "
+    + sbox.ospath('D_2/G') + "\n"]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'merge',
+                                     sbox.repo_url + '/A/D',
+                                     sbox.ospath('D_2'))
+  sbox.simple_commit()
+  sbox.simple_update()
+
 ########################################################################
 # Run the tests
 
@@ -1230,6 +1356,7 @@ test_list = [ None,
               merge_replacement,
               auto_merge_handles_replacements_in_merge_source,
               effective_sync_results_in_reintegrate,
+              reintegrate_subtree_not_updated,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/merge_tests.py?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/merge_tests.py Thu May 22 05:13:39 2014
@@ -2047,7 +2047,7 @@ def merge_binary_with_common_ancestry(sb
   # Commit the second branch
   expected_output = wc.State(wc_dir, {
     'L'       : Item(verb='Adding'),
-    'L/theta' : Item(verb='Adding  (bin)'),
+    'L/theta' : Item(verb='Replacing'),
     })
 
   expected_status.add({
@@ -19143,6 +19143,159 @@ def merge_to_empty_target_merge_to_infin
   # Commit the merge.
   #sbox.simple_commit()
 
+def merge_dir_delete_force(sbox):
+  "merge a directory delete with --force"
+
+  sbox.build()
+
+  sbox.simple_rm('A/D/G')
+  sbox.simple_commit() # r2
+
+  sbox.simple_update(revision=1)
+
+  # Just merging r2 on r1 succeeds
+  svntest.actions.run_and_verify_svn(sbox.wc_dir, None, [],
+                                     'merge', '-c2', '^/', sbox.wc_dir,
+                                     '--ignore-ancestry')
+
+  # Bring working copy to r1 again
+  svntest.actions.run_and_verify_svn(sbox.wc_dir, None, [],
+                                     'revert', '-R', sbox.wc_dir)
+
+  # But when using --force this same merge caused a segfault in 1.8.0-1.8.8
+  svntest.actions.run_and_verify_svn(sbox.wc_dir, None, [],
+                                     'merge', '-c2', '^/', sbox.wc_dir,
+                                     '--ignore-ancestry', '--force')
+
+def conflict_naming(sbox):
+  "verify conflict file naming"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  sbox.simple_append('file.txt', 'This is the initial content\n')
+  sbox.simple_add('file.txt')
+  sbox.simple_commit()
+
+  sbox.simple_append('file.txt', 'This is the new content\n', truncate=True)
+  sbox.simple_commit()
+
+  sbox.simple_append('file.txt', 'This is conflicting content\n', truncate=True)
+
+  # Update - no preserve ext
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_disk = svntest.main.greek_state.copy()
+  expected_output = svntest.wc.State(wc_dir, {
+    'file.txt' : Item(status='C ')
+  })
+  expected_status.add({
+    'file.txt' : Item(status='C ', wc_rev='2')
+  })
+
+  expected_disk.add({
+    'file.txt.r3'       : Item(contents="This is the new content\n"),
+    'file.txt.r2'       : Item(contents="This is the initial content\n"),
+    'file.txt'          : Item(contents="<<<<<<< .mine\n" \
+                               "This is conflicting content\n" \
+                               "=======\n" \
+                               "This is the initial content\n" \
+                               ">>>>>>> .r2\n"),
+    'file.txt.mine'     : Item(contents="This is conflicting content\n"),
+  })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output, expected_disk,
+                                        expected_status,
+                                        None, None, None,
+                                        None, None, None,
+                                        wc_dir, '-r', '2')
+
+  sbox.simple_revert('file.txt')
+  sbox.simple_update('', revision=3)
+  sbox.simple_append('file.txt', 'This is conflicting content\n', truncate=True)
+
+  # Update - preserve ext
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_disk = svntest.main.greek_state.copy()
+  expected_output = svntest.wc.State(wc_dir, {
+    'file.txt' : Item(status='C ')
+  })
+  expected_status.add({
+    'file.txt' : Item(status='C ', wc_rev='2')
+  })
+
+  expected_disk.add({
+    'file.txt.r3.txt'   : Item(contents="This is the new content\n"),
+    'file.txt.r2.txt'   : Item(contents="This is the initial content\n"),
+    'file.txt'          : Item(contents="<<<<<<< .mine.txt\n" \
+                               "This is conflicting content\n" \
+                               "=======\n" \
+                               "This is the initial content\n" \
+                               ">>>>>>> .r2.txt\n"),
+    'file.txt.mine.txt' : Item(contents="This is conflicting content\n"),
+  })
+  svntest.actions.run_and_verify_update(
+                      wc_dir,
+                      expected_output, expected_disk, expected_status,
+                      None, None, None, None, None, None,
+                      wc_dir, '-r', '2',
+                      '--config-option',
+                      'config:miscellany:preserved-conflict-file-exts=' +
+                      'c txt h')
+
+  sbox.simple_revert('file.txt')
+  sbox.simple_update('', revision=3)
+  sbox.simple_append('file.txt', 'This is conflicting content\n', truncate=True)
+
+  # Merge - no preserve ext
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
+  expected_disk = svntest.main.greek_state.copy()
+  expected_status.add({
+    'file.txt' : Item(status='C ', wc_rev='3')
+  })
+  expected_disk.add({
+    'file.txt.merge-left.r3' : Item(contents="This is the new content\n"),
+    'file.txt.merge-right.r2': Item(contents="This is the initial content\n"),
+    'file.txt'               : Item(contents="<<<<<<< .working\n" \
+                                    "This is conflicting content\n" \
+                                    "=======\n" \
+                                    "This is the initial content\n" \
+                                    ">>>>>>> .merge-right.r2\n"),
+    'file.txt.working'       : Item(contents="This is conflicting content\n"),
+  })
+
+  svntest.actions.run_and_verify_svn(wc_dir, None, [],
+                                     'merge', '-c-3', '^/', sbox.ospath(''))
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+  svntest.actions.verify_disk(wc_dir, expected_disk)
+
+  sbox.simple_revert('file.txt')
+  sbox.simple_append('file.txt', 'This is conflicting content\n', truncate=True)
+
+  # Merge - preserve ext
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
+  expected_disk = svntest.main.greek_state.copy()
+  expected_status.add({
+    'file.txt' : Item(status='C ', wc_rev='3')
+  })
+  expected_disk.add({
+    'file.txt.merge-left.r3.txt' : Item(contents="This is the new content\n"),
+    'file.txt.merge-right.r2.txt': Item(contents="This is the initial content\n"),
+    'file.txt'                   : Item(contents="<<<<<<< .working.txt\n" \
+                                        "This is conflicting content\n" \
+                                        "=======\n" \
+                                        "This is the initial content\n" \
+                                        ">>>>>>> .merge-right.r2.txt\n"),
+    'file.txt.working.txt'       : Item(contents="This is conflicting content\n"),
+  })
+
+  svntest.actions.run_and_verify_svn(
+                           wc_dir, None, [],
+                           'merge', '-c-3', '^/', sbox.ospath(''),
+                           '--config-option',
+                           'config:miscellany:preserved-conflict-file-exts=' +
+                           'c txt h')
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+  svntest.actions.verify_disk(wc_dir, expected_disk)
+
 ########################################################################
 # Run the tests
 
@@ -19288,6 +19441,8 @@ test_list = [ None,
               single_editor_drive_merge_notifications,
               conflicted_split_merge_with_resolve,
               merge_to_empty_target_merge_to_infinite_target,
+              merge_dir_delete_force,
+              conflict_naming,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/move_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/move_tests.py?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/move_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/move_tests.py Thu May 22 05:13:39 2014
@@ -1396,6 +1396,51 @@ def move_many_update_add(sbox):
                                         None, None, None,
                                         wc_dir, '--accept', 'mine-conflict')
 
+@Issue(4437)
+def move_del_moved(sbox):
+  "delete moved node, still a move"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_mkdir('A/NEW')
+  sbox.simple_move('A/mu', 'A/NEW/mu')
+  sbox.simple_rm('A/NEW/mu')
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='D ')
+  expected_status.add({
+      'A/NEW' : Item(status='A ', wc_rev='-')
+    })
+
+  # A/mu still reports that it is moved to A/NEW/mu, while it is already
+  # deleted there.
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+def copy_move_commit(sbox):
+  "copy, move and commit"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+    #repro
+    # Prepare
+    #   - Create folder aaa
+    #   - Add file bbb.sql
+    #     create table bbb (Id int not null)
+    #   - Commit
+    # Repro Issue 2
+    #    - Copy folder aaa under same parent folder (i.e. as a sibling). (using Ctrl drag/drop). 
+    #      Creates Copy of aaa
+    #    - Rename Copy of aaa to eee
+    #    - Commit
+    #      Get error need to update
+    #    - Update
+    #    - Commit
+    #      Get error need to update
+
+  sbox.simple_copy('A/D/G', 'A/D/GG')
+  sbox.simple_move('A/D/GG', 'A/D/GG-moved')
+  sbox.simple_commit('A/D/GG-moved')
+
 
 def move_to_from_external(sbox):
   "move to and from an external"
@@ -1433,6 +1478,8 @@ test_list = [ None,
               move_missing,
               move_many_update_delete,
               move_many_update_add,
+              move_del_moved,
+              copy_move_commit,
               move_to_from_external,
             ]
 

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/prop_tests.py?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/prop_tests.py Thu May 22 05:13:39 2014
@@ -2612,6 +2612,62 @@ def peg_rev_base_working(sbox):
                                      'propget', '--strict', 'ordinal',
                                      sbox.ospath('iota') + '@BASE')
 
+def iprops_list_abspath(sbox):
+  "test listing iprops via abspath"
+
+  sbox.build()
+
+  sbox.simple_propset('im', 'root', '')
+  sbox.simple_commit()
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'switch', '^/A/D', sbox.ospath(''),
+                                     '--ignore-ancestry')
+
+  sbox.simple_propset('im', 'GammA', 'gamma')
+
+  expected_output = [
+    'Inherited properties on \'%s\',\n' % sbox.ospath('')[:-1],
+    'from \'%s\':\n' % sbox.repo_url,
+    '  im\n',
+    '    root\n',
+    'Properties on \'%s\':\n' % sbox.ospath('gamma'),
+    '  im\n',
+    '    GammA\n'
+  ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'pl', '-R',
+                                     '--show-inherited-props', '-v',
+                                     sbox.ospath(''))
+
+  expected_output = [
+    'Inherited properties on \'%s\',\n' % os.path.abspath(sbox.ospath('')),
+    'from \'%s\':\n' % sbox.repo_url,
+    '  im\n',
+    '    root\n',
+    'Properties on \'%s\':\n' % os.path.abspath(sbox.ospath('gamma')),
+    '  im\n',
+    '    GammA\n'
+  ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'pl', '-R',
+                                     '--show-inherited-props', '-v',
+                                     os.path.abspath(sbox.ospath('')))
+
+def wc_propop_on_url(sbox):
+  "perform wc specific operations on url"
+
+  sbox.build(create_wc = False)
+
+  svntest.actions.run_and_verify_svn(None, None, '.*E195000:.*path',
+                                     'pl', '-r', 'PREV',
+                                     sbox.repo_url)
+
+  svntest.actions.run_and_verify_svn(None, None, '.*E195000:.*path',
+                                     'pg', 'my:Q', '-r', 'PREV',
+                                     sbox.repo_url)
+
+
 ########################################################################
 # Run the tests
 
@@ -2657,6 +2713,8 @@ test_list = [ None,
               inheritable_ignores,
               almost_known_prop_names,
               peg_rev_base_working,
+              iprops_list_abspath,
+              wc_propop_on_url,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/stat_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/stat_tests.py?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/stat_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/stat_tests.py Thu May 22 05:13:39 2014
@@ -2119,6 +2119,95 @@ def status_path_handling(sbox):
   expected_status = svntest.actions.get_virginal_state(rel_wc_dir, 1)
   svntest.actions.run_and_verify_status(rel_wc_dir, expected_status)
 
+def status_move_missing_direct(sbox):
+  "move information when status is called directly"
+  
+  sbox.build()
+  sbox.simple_copy('A', 'Z')
+  sbox.simple_commit('')
+  sbox.simple_update('')
+  
+  sbox.simple_move('Z', 'ZZ')
+  sbox.simple_move('A', 'Z')
+  sbox.simple_move('Z/B', 'ZB')
+  sbox.simple_mkdir('Z/B')
+  sbox.simple_move('ZB/E', 'Z/B/E')
+
+  # Somehow 'svn status' now shows different output for 'ZB/E'
+  # when called directly and via an ancestor, as this handles
+  # multi-layer in a different way
+  
+  # Note that the status output may change over different Subversion revisions,
+  # but the status on a node should be identical anyway 'svn status' is called
+  # on it.
+  
+  expected_output = [
+    'A  +    %s\n' % sbox.ospath('ZB'),
+    '        > moved from %s\n' % os.path.join('..', 'Z', 'B'),    
+    'D  +    %s\n' % sbox.ospath('ZB/E'),
+    '        > moved to %s\n' % os.path.join('..', 'Z', 'B', 'E'),
+  ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'status',
+                                     sbox.ospath('ZB'), '--depth', 'immediates')
+
+  # And calling svn status on just 'ZB/E' should have the same result for this node
+  # except that we calculate the relative path from a different base
+  expected_output = [
+    'D  +    %s\n' % sbox.ospath('ZB/E'),
+    '        > moved to %s\n' % os.path.join('..', '..', 'Z', 'B', 'E'),
+  ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'status',
+                                     sbox.ospath('ZB/E'), '--depth', 'empty')
+
+def status_move_missing_direct_base(sbox):
+  "move when status is called directly with base"
+  
+  sbox.build()
+  sbox.simple_copy('A', 'Z')
+  sbox.simple_mkdir('Q')
+  sbox.simple_mkdir('Q/ZB')
+  sbox.simple_mkdir('Q/ZB/E')
+  sbox.simple_commit('')
+  sbox.simple_update('')
+  
+  sbox.simple_rm('Q')
+  sbox.simple_mkdir('Q')
+  
+  sbox.simple_move('Z', 'ZZ')
+  sbox.simple_move('A', 'Z')
+  sbox.simple_move('Z/B', 'Q/ZB')
+  sbox.simple_mkdir('Z/B')
+  sbox.simple_move('Q/ZB/E', 'Z/B/E')
+
+  # Somehow 'svn status' now shows different output for 'Q/ZB/E'
+  # when called directly and via an ancestor, as this handles
+  # multi-layer in a different way
+  
+  # Note that the status output may change over different Subversion revisions,
+  # but the status on a node should be identical anyway 'svn status' is called
+  # on it.
+  
+  # This test had a different result as status_move_missing_direct at the time of
+  # writing this test.
+  
+  expected_output = [
+    'A  +    %s\n' % sbox.ospath('Q/ZB'),
+    '        > moved from %s\n' % os.path.join('..', '..', 'Z', 'B'),
+    'D  +    %s\n' % sbox.ospath('Q/ZB/E'),
+    '        > moved to %s\n' % os.path.join('..', '..', 'Z', 'B', 'E'),
+  ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'status',
+                                     sbox.ospath('Q/ZB'), '--depth', 'immediates')
+
+  # And calling svn status on just 'ZB/E' should have the same result for this node,
+  # except that the moved_to information is calculated from the node itself
+  expected_output = [
+    'D  +    %s\n' % sbox.ospath('Q/ZB/E'),
+    '        > moved to %s\n' % os.path.join('..', '..', '..', 'Z', 'B', 'E'),
+  ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'status',
+                                     sbox.ospath('Q/ZB/E'), '--depth', 'empty')
+
 ########################################################################
 # Run the tests
 
@@ -2167,6 +2256,8 @@ test_list = [ None,
               status_case_changed,
               move_update_timestamps,
               status_path_handling,
+              status_move_missing_direct,
+              status_move_missing_direct_base,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/svndumpfilter_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/svndumpfilter_tests.py?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/svndumpfilter_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/svndumpfilter_tests.py Thu May 22 05:13:39 2014
@@ -559,7 +559,7 @@ def dropped_but_not_renumbered_empty_rev
   full_dump_contents = open(full_dump).read()
   filtered_dumpfile, filtered_out = filter_and_return_output(
       full_dump_contents,
-      8192, # Set a sufficiently large bufsize to avoid a deadlock
+      16384, # Set a sufficiently large bufsize to avoid a deadlock
       "exclude", "branches/B2",
       "--skip-missing-merge-sources", "--drop-empty-revs")
 

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/upgrade_tests.py?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/upgrade_tests.py Thu May 22 05:13:39 2014
@@ -1428,6 +1428,17 @@ def changelist_upgrade_1_6(sbox):
   if paths != expected_paths:
     raise svntest.Failure("changelist not matched")
 
+
+def upgrade_1_7_dir_external(sbox):
+  "upgrade from 1.7 with dir external"
+
+  sbox.build(create_wc = False)
+  replace_sbox_with_tarfile(sbox, 'upgrade_1_7_dir_external.tar.bz2')
+
+  # This fails for 'make check EXCLUSIVE_WC_LOCKS=1' giving an error:
+  # svn: warning: W200033: sqlite[S5]: database is locked
+  svntest.actions.run_and_verify_svn(None, None, [], 'upgrade', sbox.wc_dir)
+
 ########################################################################
 # Run the tests
 
@@ -1483,6 +1494,7 @@ test_list = [ None,
               iprops_upgrade,
               iprops_upgrade1_6,
               changelist_upgrade_1_6,
+              upgrade_1_7_dir_external,
              ]
 
 

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/wc_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/wc_tests.py?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/wc_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/wc_tests.py Thu May 22 05:13:39 2014
@@ -118,8 +118,13 @@ def add_with_symlink_in_path(sbox):
   sbox.simple_append('A/B/kappa', 'xyz', True)
   sbox.simple_add('Z/B/kappa')
 
+def is_posix_os_and_not_root():
+  if not svntest.main.is_posix_os():
+    return False
+  return os.getuid() != 0
+
 @Issue(4118)
-@SkipUnless(svntest.main.is_posix_os)
+@SkipUnless(is_posix_os_and_not_root)
 def status_with_inaccessible_wc_db(sbox):
   """inaccessible .svn/wc.db"""
 

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_repos/repos-test.c?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_repos/repos-test.c Thu May 22 05:13:39 2014
@@ -3261,6 +3261,65 @@ filename_with_control_chars(const svn_te
 }
 
 
+/* Notification receiver for test_dump_bad_mergeinfo(). This does not
+   need to do anything, it just needs to exist.
+ */
+static void
+dump_r0_mergeinfo_notifier(void *baton,
+                           const svn_repos_notify_t *notify,
+                           apr_pool_t *scratch_pool)
+{
+}
+
+/* Regression test for part the 'dump' part of issue #4476 "Mergeinfo
+   containing r0 makes svnsync and svnadmin dump fail". */
+static svn_error_t *
+test_dump_r0_mergeinfo(const svn_test_opts_t *opts,
+                       apr_pool_t *pool)
+{
+  svn_repos_t *repos;
+  svn_fs_t *fs;
+  svn_fs_txn_t *txn;
+  svn_fs_root_t *txn_root;
+  svn_revnum_t youngest_rev = 0;
+  const svn_string_t *bad_mergeinfo = svn_string_create("/foo:0", pool);
+
+  SVN_ERR(svn_test__create_repos(&repos, "test-repo-dump-r0-mergeinfo",
+                                 opts, pool));
+  fs = svn_repos_fs(repos);
+
+  /* Revision 1:  Any commit will do, here  */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+  SVN_ERR(svn_fs_make_dir(txn_root, "/bar", pool));
+  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
+
+  /* Revision 2:  Add bad mergeinfo */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+  SVN_ERR(svn_fs_change_node_prop(txn_root, "/bar", "svn:mergeinfo", bad_mergeinfo, pool));
+  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
+
+  /* Test that a dump completes without error. In order to exercise the
+     functionality under test -- that is, in order for the dump to try to
+     parse the mergeinfo it is dumping -- the dump must start from a
+     revision greater than 1 and must take a notification callback. */
+  {
+    svn_stringbuf_t *stringbuf = svn_stringbuf_create_empty(pool);
+    svn_stream_t *stream = svn_stream_from_stringbuf(stringbuf, pool);
+
+    SVN_ERR(svn_repos_dump_fs3(repos, stream, 2, SVN_INVALID_REVNUM,
+                               FALSE, FALSE,
+                               dump_r0_mergeinfo_notifier, NULL,
+                               NULL, NULL,
+                               pool));
+  }
+
+  return SVN_NO_ERROR;
+}
+
 /* The test table.  */
 
 struct svn_test_descriptor_t test_funcs[] =
@@ -3306,5 +3365,7 @@ struct svn_test_descriptor_t test_funcs[
                        "test svn_repos_delete"),
     SVN_TEST_OPTS_PASS(filename_with_control_chars,
                        "test filenames with control characters"),
+    SVN_TEST_OPTS_PASS(test_dump_r0_mergeinfo,
+                       "test dumping with r0 mergeinfo"),
     SVN_TEST_NULL
   };

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_wc/conflict-data-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_wc/conflict-data-test.c?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_wc/conflict-data-test.c (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_wc/conflict-data-test.c Thu May 22 05:13:39 2014
@@ -740,7 +740,7 @@ test_prop_conflicts(const svn_test_opts_
   svn_error_t *err;
   const char *lock_abspath;
   test_prop_conflict_baton_t *b = apr_pcalloc(pool, sizeof(*b));
-  svn_wc_conflict_description2_t *desc = apr_pcalloc(pool, sizeof(*b));
+  svn_wc_conflict_description2_t *desc = apr_pcalloc(pool, sizeof(*desc));
 
   SVN_ERR(svn_test__sandbox_create(&sbox, "test_prop_conflicts", opts, pool));
 

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_wc/op-depth-test.c?rev=1596751&r1=1596750&r2=1596751&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_wc/op-depth-test.c Thu May 22 05:13:39 2014
@@ -55,6 +55,14 @@
 #pragma warning(disable: 4221) /* nonstandard extension used */
 #endif
 
+/* This macro is not available in 1.8.x, but let's just use it here */
+#ifndef SVN_VA_NULL
+struct svn_null_pointer_constant_stdarg_sentinel_t;
+
+/** Null pointer constant used as a sentinel in variable argument lists. */
+#define SVN_VA_NULL ((struct svn_null_pointer_constant_stdarg_sentinel_t*)0)
+#endif
+
 /* Compare strings, like strcmp but either or both may be NULL which
  * compares equal to NULL and not equal to any non-NULL string. */
 static int
@@ -8201,11 +8209,156 @@ move_child_to_parent_revert(const svn_te
 }
 
 static svn_error_t *
-move_abspath_more_than_once(const svn_test_opts_t *opts, apr_pool_t *pool)
+move_delete_intermediate(const svn_test_opts_t *opts, apr_pool_t *pool)
 {
   svn_test__sandbox_t b;
 
-  SVN_ERR(svn_test__sandbox_create(&b, "move_child_to_parent_revert", opts,
+  SVN_ERR(svn_test__sandbox_create(&b, "move_delete_intermediate", opts,
+                                   pool));
+
+  SVN_ERR(sbox_wc_mkdir(&b, "A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/A/A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/A/A/A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "B"));
+  SVN_ERR(sbox_wc_mkdir(&b, "B/A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "B/A/A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "B/A/A/A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "C"));
+  SVN_ERR(sbox_wc_mkdir(&b, "C/A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "C/A/A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "C/A/A/A"));
+  SVN_ERR(sbox_wc_commit(&b, ""));
+
+  SVN_ERR(sbox_wc_move(&b, "A/A/A", "AAA_1"));
+
+  SVN_ERR(sbox_wc_delete(&b, "A"));
+  SVN_ERR(sbox_wc_move(&b, "B", "A"));
+
+  SVN_ERR(sbox_wc_move(&b, "A/A/A", "AAA_2"));
+
+  SVN_ERR(sbox_wc_delete(&b, "A/A"));
+  SVN_ERR(sbox_wc_move(&b, "C/A", "A/A"));
+
+  SVN_ERR(sbox_wc_move(&b, "A/A/A", "AAA_3"));
+
+  /* Verify that the move is still recorded correctly */
+  {
+    nodes_row_t nodes[] = {
+
+      {0, "",           "normal",       0, ""},
+
+      {1, "AAA_1",      "normal",       1, "A/A/A",             MOVED_HERE},
+      {1, "AAA_1/A",    "normal",       1, "A/A/A/A",           MOVED_HERE},
+      {1, "AAA_2",      "normal",       1, "B/A/A",             MOVED_HERE},
+      {1, "AAA_2/A",    "normal",       1, "B/A/A/A",           MOVED_HERE},
+      {1, "AAA_3",      "normal",       1, "C/A/A",             MOVED_HERE},
+      {1, "AAA_3/A",    "normal",       1, "C/A/A/A",           MOVED_HERE},
+
+      {0, "A",          "normal",       1, "A"},
+      {0, "A/A",        "normal",       1, "A/A"},
+      {0, "A/A/A",      "normal",       1, "A/A/A"},
+      {0, "A/A/A/A",    "normal",       1, "A/A/A/A"},
+
+      {1, "A",          "normal",       1, "B",                 MOVED_HERE},
+      {1, "A/A",        "normal",       1, "B/A",               MOVED_HERE},
+      {1, "A/A/A",      "normal",       1, "B/A/A", FALSE, "AAA_1",   TRUE},
+      {1, "A/A/A/A",    "normal",       1, "B/A/A/A",           MOVED_HERE},
+
+      {2, "A/A",        "normal",       1, "C/A", MOVED_HERE},
+      {2, "A/A/A",      "normal",       1, "C/A/A", FALSE, "AAA_2",   TRUE},
+      {2, "A/A/A/A",    "normal",       1, "C/A/A/A",           MOVED_HERE},
+
+      {3, "A/A/A",      "base-deleted", NO_COPY_FROM,      "AAA_3"},
+      {3, "A/A/A/A",    "base-deleted", NO_COPY_FROM},
+
+      {0, "B",          "normal",       1, "B"},
+      {0, "B/A",        "normal",       1, "B/A"},
+      {0, "B/A/A",      "normal",       1, "B/A/A"},
+      {0, "B/A/A/A",    "normal",       1, "B/A/A/A"},
+
+      {1, "B",          "base-deleted", NO_COPY_FROM, "A"},
+      {1, "B/A",        "base-deleted", NO_COPY_FROM},
+      {1, "B/A/A",      "base-deleted", NO_COPY_FROM},
+      {1, "B/A/A/A",    "base-deleted", NO_COPY_FROM},
+
+      {0, "C",          "normal",       1, "C"},
+      {0, "C/A",        "normal",       1, "C/A"},
+      {0, "C/A/A",      "normal",       1, "C/A/A"},
+      {0, "C/A/A/A",    "normal",       1, "C/A/A/A"},
+
+      {2, "C/A",        "base-deleted", NO_COPY_FROM, "A/A"},
+      {2, "C/A/A",      "base-deleted", NO_COPY_FROM},
+      {2, "C/A/A/A",    "base-deleted", NO_COPY_FROM},
+
+      {0},
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  /* Ok, now we are in the very ugly case where A/A/A is moved away 3 times */
+
+  /* Let's delete A */
+  SVN_ERR(sbox_wc_delete(&b, "A"));
+
+  /* AAA_1, AAA_2 and AAA_3 should still be moves after deleting A */
+  {
+    nodes_row_t nodes[] = {
+
+      {0, "",           "normal",       0, ""},
+
+      {1, "AAA_1",      "normal",       1, "A/A/A",             MOVED_HERE},
+      {1, "AAA_1/A",    "normal",       1, "A/A/A/A",           MOVED_HERE},
+
+      {1, "AAA_2",      "normal",       1, "B/A/A",             MOVED_HERE},
+      {1, "AAA_2/A",    "normal",       1, "B/A/A/A",           MOVED_HERE},
+
+      {1, "AAA_3",      "normal",       1, "C/A/A",             MOVED_HERE},
+      {1, "AAA_3/A",    "normal",       1, "C/A/A/A",           MOVED_HERE},
+
+      {0, "A",          "normal",       1, "A"},
+      {0, "A/A",        "normal",       1, "A/A"},
+      {0, "A/A/A",      "normal",       1, "A/A/A"},
+      {0, "A/A/A/A",    "normal",       1, "A/A/A/A"},
+
+      {1, "A",          "base-deleted", NO_COPY_FROM},
+      {1, "A/A",        "base-deleted", NO_COPY_FROM},
+      {1, "A/A/A",      "base-deleted", NO_COPY_FROM, "AAA_1"},
+      {1, "A/A/A/A",    "base-deleted", NO_COPY_FROM},
+
+      {0, "B",          "normal",       1, "B"},
+      {0, "B/A",        "normal",       1, "B/A"},
+      {0, "B/A/A",      "normal",       1, "B/A/A"},
+      {0, "B/A/A/A",    "normal",       1, "B/A/A/A"},
+
+      {1, "B",          "base-deleted", NO_COPY_FROM},
+      {1, "B/A",        "base-deleted", NO_COPY_FROM},
+      {1, "B/A/A",      "base-deleted", NO_COPY_FROM, "AAA_2"},
+      {1, "B/A/A/A",    "base-deleted", NO_COPY_FROM},
+
+      {0, "C",          "normal",       1, "C"},
+      {0, "C/A",        "normal",       1, "C/A"},
+      {0, "C/A/A",      "normal",       1, "C/A/A"},
+      {0, "C/A/A/A",    "normal",       1, "C/A/A/A"},
+
+      {2, "C/A",        "base-deleted", NO_COPY_FROM},
+      {2, "C/A/A",      "base-deleted", NO_COPY_FROM, "AAA_3"},
+      {2, "C/A/A/A",    "base-deleted", NO_COPY_FROM},
+
+      {0},
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_revert_intermediate(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "move_revert_intermediate", opts,
                                    pool));
 
   SVN_ERR(sbox_wc_mkdir(&b, "A"));
@@ -8339,6 +8492,413 @@ move_abspath_more_than_once(const svn_te
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+copy_mixed_rev_mods(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "copy_mixed_rev_mods", opts,
+                                   pool));
+
+  SVN_ERR(sbox_wc_mkdir(&b, "A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+  SVN_ERR(sbox_wc_commit(&b, ""));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+  SVN_ERR(sbox_wc_commit(&b, ""));
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+  SVN_ERR(sbox_wc_update(&b, "A/B", 2));
+  SVN_ERR(sbox_wc_delete(&b, "A/B"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",      "normal",       1, ""},
+      {0, "A",     "normal",       1, "A"},
+      {0, "A/B",   "normal",       2, "A/B"},
+      {0, "A/B/C", "normal",       2, "A/B/C"},
+      {2, "A/B",   "normal",       NO_COPY_FROM},
+      {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  SVN_ERR(sbox_wc_copy(&b, "A", "X"));
+  {
+    nodes_row_t nodes[] = {
+      {1, "X",   "normal",      1, "A"},
+      {1, "X/B", "not-present", 2, "A/B"},
+      {2, "X/B", "normal",      NO_COPY_FROM},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "X", nodes));
+  }
+
+  SVN_ERR(sbox_wc_commit(&b, "X"));
+  {
+    nodes_row_t nodes[] = {
+      {0, "X",   "normal", 3, "X"},
+      {0, "X/B", "normal", 3, "X/B"},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "X", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_replace_ancestor_with_child(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+    svn_test__sandbox_t b;
+
+    SVN_ERR(svn_test__sandbox_create(&b, "move_replace_ancestor_with_child", opts,
+        pool));
+
+    SVN_ERR(sbox_wc_mkdir(&b, "A"));
+    SVN_ERR(sbox_wc_mkdir(&b, "A/A"));
+
+    SVN_ERR(sbox_wc_commit(&b, ""));
+    SVN_ERR(sbox_wc_update(&b, "", 1));
+
+    SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+
+    {
+      nodes_row_t nodes[] = {
+
+        { 0, "",            "normal",       1, "" },
+
+        { 0, "A",           "normal",       1, "A"},
+        { 0, "A/A",         "normal",       1, "A/A" },
+
+        { 1, "A",           "base-deleted", NO_COPY_FROM , "A2"},
+        { 1, "A/A",         "base-deleted", NO_COPY_FROM },
+
+        { 1, "A2",          "normal",       1, "A",     MOVED_HERE },
+        { 1, "A2/A",        "normal",       1, "A/A",   MOVED_HERE },
+
+        { 0 },
+      };
+      SVN_ERR(check_db_rows(&b, "", nodes));
+    }
+
+    SVN_ERR(sbox_wc_move(&b, "A2/A", "A"));
+
+    {
+      nodes_row_t nodes[] = {
+        { 0, "",            "normal",       1, "" },
+
+        { 0, "A",           "normal",       1, "A"},
+        { 0, "A/A",         "normal",       1, "A/A" },
+
+        { 1, "A",           "normal",       1, "A/A", FALSE, "A2", TRUE },
+        { 1, "A/A",         "base-deleted", NO_COPY_FROM },
+
+        { 1, "A2",          "normal",       1, "A",     MOVED_HERE },
+        { 1, "A2/A",        "normal",       1, "A/A",   MOVED_HERE },
+
+        { 2, "A2/A",        "base-deleted", NO_COPY_FROM, "A" },
+        { 0 },
+      };
+      SVN_ERR(check_db_rows(&b, "", nodes));
+    }
+
+    /* ### This currently fails with an assertion in maintainer mode */
+    SVN_ERR(sbox_wc_delete(&b, "A2"));
+
+    {
+      nodes_row_t nodes[] = {
+        { 0, "",            "normal",       1, "" },
+
+        { 0, "A",           "normal",       1, "A"},
+        { 0, "A/A",         "normal",       1, "A/A" },
+
+        { 1, "A",           "normal",       1, "A/A", MOVED_HERE },
+        { 1, "A/A",         "base-deleted", NO_COPY_FROM, "A" },
+
+        { 0 },
+      };
+      SVN_ERR(check_db_rows(&b, "", nodes));
+    }
+
+    SVN_ERR(sbox_wc_commit(&b, "A"));
+
+    return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_twice_within_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+    svn_test__sandbox_t b;
+
+    SVN_ERR(svn_test__sandbox_create(&b, "move_twice_within_delete", opts,
+        pool));
+
+    SVN_ERR(sbox_wc_mkdir(&b, "A"));
+    SVN_ERR(sbox_wc_mkdir(&b, "A/A"));
+    SVN_ERR(sbox_wc_mkdir(&b, "A/A/A"));
+
+    SVN_ERR(sbox_wc_commit(&b, ""));
+    SVN_ERR(sbox_wc_update(&b, "", 1));
+
+    SVN_ERR(sbox_wc_mkdir(&b, "B"));
+    SVN_ERR(sbox_wc_move(&b, "A", "B/A"));
+    SVN_ERR(sbox_wc_move(&b, "B/A/A", "B/AA"));
+    SVN_ERR(sbox_wc_move(&b, "B/AA/A", "AA"));
+
+    {
+      nodes_row_t nodes[] = {
+
+        { 0, "",          "normal",       1, "" },
+                          
+        { 0, "A",         "normal",       1, "A" },
+        { 0, "A/A",       "normal",       1, "A/A" },
+        { 0, "A/A/A",     "normal",       1, "A/A/A" },
+                          
+        { 1, "A",         "base-deleted", NO_COPY_FROM, "B/A" },
+        { 1, "A/A",       "base-deleted", NO_COPY_FROM },
+        { 1, "A/A/A",     "base-deleted", NO_COPY_FROM },
+                          
+        { 1, "AA",        "normal",       1, "A/A/A", MOVED_HERE },
+
+        { 1, "B",         "normal",       NO_COPY_FROM },
+        { 2, "B/A",       "normal",       1, "A",       MOVED_HERE },
+        { 2, "B/A/A",     "normal",       1, "A/A",     MOVED_HERE },
+        { 2, "B/A/A/A",   "normal",       1, "A/A/A",   MOVED_HERE },
+
+        { 3, "B/A/A",     "base-deleted", NO_COPY_FROM, "B/AA" },
+        { 3, "B/A/A/A",   "base-deleted", NO_COPY_FROM },
+
+        { 2, "B/AA",      "normal",       1, "A/A", MOVED_HERE},
+        { 2, "B/AA/A",    "normal",       1, "A/A/A", MOVED_HERE },
+
+        { 3, "B/AA/A",    "base-deleted", NO_COPY_FROM, "AA" },
+
+        { 0 },
+      };
+      SVN_ERR(check_db_rows(&b, "", nodes));
+    }
+
+    SVN_ERR(sbox_wc_delete(&b, "B"));
+
+    {
+      nodes_row_t nodes[] = {
+        { 0, "",        "normal", 1, "" },
+
+        { 0, "A",       "normal", 1, "A" },
+        { 0, "A/A",     "normal", 1, "A/A" },
+        { 0, "A/A/A",   "normal", 1, "A/A/A" },
+
+        { 1, "A",       "base-deleted", NO_COPY_FROM },
+        { 1, "A/A",     "base-deleted", NO_COPY_FROM },
+        { 1, "A/A/A",   "base-deleted", NO_COPY_FROM, "AA" },
+
+        { 1, "AA", "normal", 1, "A/A/A", MOVED_HERE },
+
+        { 0 },
+      };
+        SVN_ERR(check_db_rows(&b, "", nodes));
+    }
+
+    return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+repo_wc_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+  const char *repos_dir;
+  const char *new_repos_dir;
+  const char *new_repos_url;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "repo_wc_copy",
+                                   opts, pool));
+  SVN_ERR(sbox_add_and_commit_greek_tree(&b));
+
+  SVN_ERR(sbox_wc_copy_url(&b,
+                           svn_path_url_add_component2(b.repos_url, "A/B",
+                                                       pool),
+                           -1, "AA"));
+
+  {
+    nodes_row_t nodes[] = {
+
+      {1, "AA/lambda",   "normal", 1, "A/B/lambda"},
+      {1, "AA",          "normal", 1, "A/B"},
+      {1, "AA/E/beta",   "normal", 1, "A/B/E/beta"},
+      {1, "AA/E/alpha",  "normal", 1, "A/B/E/alpha"},
+      {1, "AA/F",        "normal", 1, "A/B/F"},
+      {1, "AA/E",        "normal", 1, "A/B/E"},
+
+      { 0 },
+    };
+    SVN_ERR(check_db_rows(&b, "AA", nodes));
+  }
+
+  SVN_ERR(svn_uri_get_dirent_from_file_url(&repos_dir, b.repos_url,
+                                           pool));
+  new_repos_dir = apr_pstrcat(pool, repos_dir, "-2", SVN_VA_NULL);
+  new_repos_url = apr_pstrcat(pool, b.repos_url, "-2", SVN_VA_NULL);
+
+  svn_test_add_dir_cleanup(new_repos_dir);
+
+  SVN_ERR(svn_io_remove_dir2(new_repos_dir, TRUE, NULL, NULL, pool));
+  SVN_ERR(svn_io_copy_dir_recursively(repos_dir,
+                                      svn_dirent_dirname(new_repos_dir, pool),
+                                      svn_dirent_basename(new_repos_dir, pool),
+                                      FALSE, NULL, NULL, pool));
+
+  SVN_ERR(sbox_wc_relocate(&b, new_repos_url));
+
+  /* This produced an invalid copy in Subversion <= 1.8.8.
+     Status would show all descendants as incomplete */
+  SVN_ERR(sbox_wc_copy_url(&b,
+                           svn_path_url_add_component2(b.repos_url, "A/B",
+                                                       pool),
+                           -1, "BB"));
+
+  {
+    nodes_row_t nodes[] = {
+
+      {1, "BB/lambda",   "normal", 1, "A/B/lambda"},
+      {1, "BB",          "normal", 1, "A/B"},
+      {1, "BB/E/beta",   "normal", 1, "A/B/E/beta"},
+      {1, "BB/E/alpha",  "normal", 1, "A/B/E/alpha"},
+      {1, "BB/F",        "normal", 1, "A/B/F"},
+      {1, "BB/E",        "normal", 1, "A/B/E"},
+
+      { 0 },
+    };
+    SVN_ERR(check_db_rows(&b, "BB", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+movedhere_extract_retract(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "movedhere_extract_retract",
+                                   opts, pool));
+
+  SVN_ERR(sbox_wc_mkdir(&b, "A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/B1"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/B2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/B3"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/C1"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/C2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/C3"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/D1"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/D2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/D3"));
+
+  SVN_ERR(sbox_wc_commit(&b, ""));
+
+  SVN_ERR(sbox_wc_propset(&b, "k", "v", "A/B1"));
+  SVN_ERR(sbox_wc_propset(&b, "k", "v", "A/B2"));
+  SVN_ERR(sbox_wc_propset(&b, "k", "v", "A/B3"));
+  SVN_ERR(sbox_wc_delete(&b, "A/C1"));
+  SVN_ERR(sbox_wc_delete(&b, "A/C2"));
+  SVN_ERR(sbox_wc_delete(&b, "A/C3"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/E1"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/E2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/E3"));
+
+  SVN_ERR(sbox_wc_commit(&b, ""));
+
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+
+  SVN_ERR(sbox_wc_move(&b, "A", "Z"));
+
+  SVN_ERR(sbox_wc_delete(&b, "Z/B1"));
+  SVN_ERR(sbox_wc_delete(&b, "Z/C1"));
+  SVN_ERR(sbox_wc_delete(&b, "Z/D1"));
+
+  SVN_ERR(sbox_wc_move(&b, "Z/B2", "B2"));
+  SVN_ERR(sbox_wc_move(&b, "Z/C2", "C2"));
+  SVN_ERR(sbox_wc_move(&b, "Z/D2", "D2"));
+
+  SVN_ERR(sbox_wc_mkdir(&b, "Z/B2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "Z/C2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "Z/D2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "Z/E2"));
+
+  SVN_ERR(sbox_wc_update(&b, "", 2));
+  SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "Z/B1", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "Z/B2", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+
+  SVN_ERR(sbox_wc_resolve(&b, "Z/C1", svn_depth_empty,
+                          svn_wc_conflict_choose_merged));
+  SVN_ERR(sbox_wc_resolve(&b, "Z/C2", svn_depth_empty,
+                          svn_wc_conflict_choose_merged));
+
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity,
+                          svn_wc_conflict_choose_mine_conflict));
+  {
+    nodes_row_t nodes[] = {
+
+      {0, "",       "normal",       2, ""},
+      {0, "A",      "normal",       2, "A"},
+      {0, "A/B1",   "normal",       2, "A/B1", FALSE, NULL, FALSE, "k"},
+      {0, "A/B2",   "normal",       2, "A/B2", FALSE, NULL, FALSE, "k"},
+      {0, "A/B3",   "normal",       2, "A/B3", FALSE, NULL, FALSE, "k"},
+      {0, "A/D1",   "normal",       2, "A/D1"},
+      {0, "A/D2",   "normal",       2, "A/D2"},
+      {0, "A/D3",   "normal",       2, "A/D3"},
+      {0, "A/E1",   "normal",       2, "A/E1"},
+      {0, "A/E2",   "normal",       2, "A/E2"},
+      {0, "A/E3",   "normal",       2, "A/E3"},
+
+      {1, "A",      "base-deleted", NO_COPY_FROM, "Z"},
+      {1, "A/B1",   "base-deleted", NO_COPY_FROM},
+      {1, "A/B2",   "base-deleted", NO_COPY_FROM},
+      {1, "A/B3",   "base-deleted", NO_COPY_FROM},
+
+      {1, "A/D1",   "base-deleted", NO_COPY_FROM},
+      {1, "A/D2",   "base-deleted", NO_COPY_FROM},
+      {1, "A/D3",   "base-deleted", NO_COPY_FROM},
+
+      {1, "A/E1",   "base-deleted", NO_COPY_FROM},
+      {1, "A/E2",   "base-deleted", NO_COPY_FROM},
+      {1, "A/E3",   "base-deleted", NO_COPY_FROM},
+
+      {1, "B2",     "normal",       2, "A/B2", MOVED_HERE, "k"},
+      {1, "C2",     "normal",       1, "A/C2"},
+      {1, "D2",     "normal",       1, "A/D2", MOVED_HERE},
+
+      {1, "Z",      "normal",       2, "A", MOVED_HERE},
+      {1, "Z/B1",   "normal",       2, "A/B1", MOVED_HERE, "k"},
+      {1, "Z/B2",   "normal",       2, "A/B2", MOVED_HERE, "k"},
+      {1, "Z/B3",   "normal",       2, "A/B3", MOVED_HERE, "k"},
+      {1, "Z/D1",   "normal",       2, "A/D1", MOVED_HERE},
+      {1, "Z/D2",   "normal",       2, "A/D2", MOVED_HERE},
+      {1, "Z/D3",   "normal",       2, "A/D3", MOVED_HERE},
+      {1, "Z/E1",   "normal",       2, "A/E1", MOVED_HERE},
+      {1, "Z/E2",   "normal",       2, "A/E2", MOVED_HERE},
+      {1, "Z/E3",   "normal",       2, "A/E3", MOVED_HERE},
+
+      {2, "Z/B2",   "normal",       NO_COPY_FROM, "B2"},
+      {2, "Z/C2",   "normal",       NO_COPY_FROM},
+      {2, "Z/D2",   "normal",       NO_COPY_FROM, "D2"},
+      {2, "Z/E2",   "normal",       NO_COPY_FROM},
+
+      {2, "Z/B1",   "base-deleted", NO_COPY_FROM},
+      {2, "Z/D1",   "base-deleted", NO_COPY_FROM},
+
+      { 0 },
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
 
 /* ---------------------------------------------------------------------- */
 /* The list of test functions */
@@ -8495,7 +9055,19 @@ struct svn_test_descriptor_t test_funcs[
                        "update with tree conflict (issue 4347)"),
     SVN_TEST_OPTS_PASS(move_child_to_parent_revert,
                        "move child to parent and revert (issue 4436)"),
-    SVN_TEST_OPTS_XFAIL(move_abspath_more_than_once,
-                       "move one abspath more than once"),
+    SVN_TEST_OPTS_PASS(move_delete_intermediate,
+                       "move more than once, delete intermediate"),
+    SVN_TEST_OPTS_XFAIL(move_revert_intermediate,
+                       "move more than once, revert intermediate"),
+    SVN_TEST_OPTS_PASS(move_replace_ancestor_with_child,
+                       "move replace ancestor with child"),
+    SVN_TEST_OPTS_PASS(move_twice_within_delete,
+                       "move twice and then delete"),
+    SVN_TEST_OPTS_PASS(repo_wc_copy,
+                       "repo_wc_copy"),
+    SVN_TEST_OPTS_PASS(copy_mixed_rev_mods,
+                       "copy mixed-rev with mods"),
+    SVN_TEST_OPTS_PASS(movedhere_extract_retract,
+                       "movedhere extract retract"),
     SVN_TEST_NULL
   };