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 2013/10/24 01:57:51 UTC

svn commit: r1535214 [3/3] - in /subversion/branches/javahl-1.8-extensions: ./ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_fs/ subversion/libsvn_fs_fs/ subversion/libsvn_ra_local/ subversion/libsvn_ra_ser...

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/authz_tests.py?rev=1535214&r1=1535213&r2=1535214&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/authz_tests.py Wed Oct 23 23:57:49 2013
@@ -1551,6 +1551,44 @@ def log_diff_dontdothat(sbox):
                                       'log', ddt_url,
                                       '-c', 1, '--diff')
 
+@Issue(4422)
+@Skip(svntest.main.is_ra_type_file)
+def authz_file_external_to_authz(sbox):
+  "replace file external with authz node"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  repo_url = sbox.repo_url
+
+  write_authz_file(sbox, {"/": "* = rw"})
+  write_restrictive_svnserve_conf(sbox.repo_dir)
+
+  sbox.simple_propset('svn:externals', 'Z ' + repo_url + '/iota', '')
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('', status=' M')
+  expected_status.add({
+    'Z' : Item(status='  ', wc_rev='1', switched='X'),
+  })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        None, None, expected_status)
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'cp', repo_url + '/A',
+                                           repo_url + '/Z',
+                                      '-m', 'Add Z')
+
+  write_authz_file(sbox, {"/": "* = rw", "/Z": "* = "})
+
+  expected_status.tweak(wc_rev=2)
+
+  # ### This used to assert with
+  # ### svn: E235000: In file 'update_editor.c' line 3043: assertion failed
+  # ###               (status != svn_wc__db_status_normal)
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        None, None, expected_status)
+
 
 ########################################################################
 # Run the tests
@@ -1585,6 +1623,7 @@ test_list = [ None,
               authz_svnserve_groups,
               authz_del_from_subdir,
               log_diff_dontdothat,
+              authz_file_external_to_authz,
              ]
 serial_only = True
 

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/checkout_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/checkout_tests.py?rev=1535214&r1=1535213&r2=1535214&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/checkout_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/checkout_tests.py Wed Oct 23 23:57:49 2013
@@ -1052,7 +1052,7 @@ def checkout_wc_from_drive(sbox):
   svntest.main.safe_rmtree(sbox.wc_dir)
   os.mkdir(sbox.wc_dir)
 
-  # create a virtual drive to the working copy folder
+  # create a virtual drive to the repository folder
   drive = find_the_next_available_drive_letter()
   if drive is None:
     raise svntest.Skip
@@ -1088,8 +1088,49 @@ def checkout_wc_from_drive(sbox):
     })
     svntest.actions.run_and_verify_checkout(repo_url, wc_dir,
                                             expected_output, expected_wc,
-                                            None, None, None, None,
-                                            '--force')
+                                            None, None, None, None)
+
+    wc2_dir = sbox.add_wc_path('2')
+    expected_output = wc.State(wc2_dir, {
+      'D'                 : Item(status='A '),
+      'D/H'               : Item(status='A '),
+      'D/H/psi'           : Item(status='A '),
+      'D/H/chi'           : Item(status='A '),
+      'D/H/omega'         : Item(status='A '),
+      'D/G'               : Item(status='A '),
+      'D/G/tau'           : Item(status='A '),
+      'D/G/pi'            : Item(status='A '),
+      'D/G/rho'           : Item(status='A '),
+      'D/gamma'           : Item(status='A '),
+      'C'                 : Item(status='A '),
+      'mu'                : Item(status='A '),
+      'B'                 : Item(status='A '),
+      'B/E'               : Item(status='A '),
+      'B/E/alpha'         : Item(status='A '),
+      'B/E/beta'          : Item(status='A '),
+      'B/F'               : Item(status='A '),
+      'B/lambda'          : Item(status='A '),
+    })
+    svntest.actions.run_and_verify_checkout(repo_url + '/A', wc2_dir,
+                                            expected_output, None,
+                                            None, None, None, None)
+
+    wc3_dir = sbox.add_wc_path('3')
+    expected_output = wc.State(wc3_dir, {
+      'H'                 : Item(status='A '),
+      'H/psi'             : Item(status='A '),
+      'H/chi'             : Item(status='A '),
+      'H/omega'           : Item(status='A '),
+      'G'                 : Item(status='A '),
+      'G/tau'             : Item(status='A '),
+      'G/pi'              : Item(status='A '),
+      'G/rho'             : Item(status='A '),
+      'gamma'             : Item(status='A '),
+    })
+
+    svntest.actions.run_and_verify_checkout(repo_url + '/A/D', wc3_dir,
+                                            expected_output, None,
+                                            None, None, None, None)
 
   finally:
     os.chdir(was_cwd)

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=1535214&r1=1535213&r2=1535214&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 Wed Oct 23 23:57:49 2013
@@ -1250,7 +1250,7 @@ def commit_add_file_twice(sbox):
   svntest.actions.run_and_verify_commit(wc_dir,
                                         None,
                                         None,
-                                        "already exists",
+                                        "E160020: File.*already exists",
                                         wc_dir)
 
 #----------------------------------------------------------------------

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=1535214&r1=1535213&r2=1535214&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 Wed Oct 23 23:57:49 2013
@@ -1234,6 +1234,169 @@ def move_missing(sbox):
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
 
+def setup_move_many(sbox):
+  "helper function which creates a wc with node A/A/A which is moved 3 times"
+
+  sbox.simple_rm('A', 'iota')
+  sbox.simple_mkdir('A',
+                    'A/A',
+                    'A/A/A',
+                    'A/A/A/A',
+                    'B',
+                    'B/A',
+                    'B/A/A',
+                    'B/A/A/A',
+                    'C',
+                    'C/A',
+                    'C/A/A',
+                    'C/A/A/A')
+  sbox.simple_commit()
+  sbox.simple_update()
+
+  sbox.simple_move('A/A/A', 'AAA_1')
+
+  sbox.simple_rm('A')
+  sbox.simple_move('B', 'A')
+
+  sbox.simple_move('A/A/A', 'AAA_2')
+
+  sbox.simple_rm('A/A')
+  sbox.simple_move('C/A', 'A/A')
+
+  sbox.simple_move('A/A/A', 'AAA_3')
+
+def move_many_status(wc_dir):
+  "obtain standard status after setup_move_many"
+
+  return svntest.wc.State(wc_dir, {
+      ''                  : Item(status='  ', wc_rev='2'),
+
+      'AAA_1'             : Item(status='A ', copied='+', moved_from='A/A/A', wc_rev='-'),
+      'AAA_1/A'           : Item(status='  ', copied='+', wc_rev='-'),
+
+      'AAA_2'             : Item(status='A ', copied='+', moved_from='A/A/A', wc_rev='-'),
+      'AAA_2/A'           : Item(status='  ', copied='+', wc_rev='-'),
+
+      'AAA_3'             : Item(status='A ', copied='+', moved_from='A/A/A', wc_rev='-'),
+      'AAA_3/A'           : Item(status='  ', copied='+', wc_rev='-'),
+
+      'A'                 : Item(status='R ', copied='+', moved_from='B', wc_rev='-'),
+      'A/A'               : Item(status='R ', copied='+', moved_from='C/A', wc_rev='-'),
+      'A/A/A'             : Item(status='D ', copied='+', wc_rev='-', moved_to='AAA_3'),
+      'A/A/A/A'           : Item(status='D ', copied='+', wc_rev='-'),
+
+      'B'                 : Item(status='D ', wc_rev='2', moved_to='A'),
+      'B/A'               : Item(status='D ', wc_rev='2'),
+      'B/A/A'             : Item(status='D ', wc_rev='2'),
+      'B/A/A/A'           : Item(status='D ', wc_rev='2'),
+
+      'C'                 : Item(status='  ', wc_rev='2'),
+      'C/A'               : Item(status='D ', wc_rev='2', moved_to='A/A'),
+      'C/A/A'             : Item(status='D ', wc_rev='2'),
+      'C/A/A/A'           : Item(status='D ', wc_rev='2'),
+    })
+
+def move_many_update_delete(sbox):
+  "move many and delete-on-update"
+
+  sbox.build()
+  setup_move_many(sbox)
+
+  wc_dir = sbox.wc_dir
+
+  # Verify start situation
+  expected_status = move_many_status(wc_dir)
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+  # And now create a tree conflict
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'rm', sbox.repo_url + '/B',
+                                     '-m', '')
+
+  expected_output = svntest.wc.State(wc_dir, {
+     'B'                 : Item(status='  ', treeconflict='C'),
+    })
+
+
+  expected_status.tweak('', 'C', 'C/A', 'C/A/A', 'C/A/A/A', wc_rev='3')
+  expected_status.tweak('A', moved_from=None)
+  expected_status.remove('B/A', 'B/A/A', 'B/A/A/A')
+  expected_status.tweak('B', status='! ', treeconflict='C', wc_rev=None, moved_to=None)
+
+  svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+                                        expected_status)
+
+  # Would be nice if we could run the resolver as a separate step, 
+  # but 'svn resolve' just fails for any value but working
+
+@XFail()
+def move_many_update_add(sbox):
+  "move many and add-on-update"
+
+  sbox.build()
+  setup_move_many(sbox)
+
+  wc_dir = sbox.wc_dir
+
+  # Verify start situation
+  expected_status = move_many_status(wc_dir)
+  #svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+  # And now create a tree conflict
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'mkdir', sbox.repo_url + '/B/A/A/BB',
+                                     '-m', '')
+
+  expected_output = svntest.wc.State(wc_dir, {
+     'B'                 : Item(status='  ', treeconflict='C'),
+     'B/A'               : Item(status='  ', treeconflict='U'),
+     'B/A/A'             : Item(status='  ', treeconflict='U'),
+     'B/A/A/BB'          : Item(status='  ', treeconflict='A'),
+     # And while resolving
+     'A/A/'              : Item(status='  ', treeconflict='C')
+    })
+
+  expected_status.tweak('',
+                        'B', 'B/A', 'B/A/A', 'B/A/A/A',
+                        'C', 'C/A', 'C/A/A', 'C/A/A/A',
+                        wc_rev='3')
+
+  expected_status.tweak('A/A', treeconflict='C')
+  expected_status.add({
+        'A/A/A/BB'          : Item(status='D ', copied='+', wc_rev='-'),
+        'B/A/A/BB'          : Item(status='D ', wc_rev='3'),
+    })
+
+  svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+                                        expected_status,
+                                        None, None, None,
+                                        None, None, None,
+                                        wc_dir, '--accept', 'mine-conflict')
+
+  # And another one
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'mkdir', sbox.repo_url + '/C/A/A/BB',
+                                     '-m', '')
+
+  expected_status.tweak('',
+                        'B', 'B/A', 'B/A/A', 'B/A/A/A',
+                        'C', 'C/A', 'C/A/A', 'C/A/A/A',
+                        wc_rev='4')
+
+  expected_output = svntest.wc.State(wc_dir, {
+     'C/A'               : Item(status='  ', treeconflict='C'),
+     'C/A/A'             : Item(status='  ', treeconflict='U'),
+     'C/A/A/BB'          : Item(status='  ', treeconflict='A'),
+    })
+
+  # This currently triggers an assertion failure
+  svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+                                        expected_status,
+                                        None, None, None,
+                                        None, None, None,
+                                        wc_dir, '--accept', 'mine-conflict')
+
+
 #######################################################################
 # Run the tests
 
@@ -1245,6 +1408,8 @@ test_list = [ None,
               deeper_move_file_test,
               property_merge,
               move_missing,
+              move_many_update_delete,
+              move_many_update_add,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/revert_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/revert_tests.py?rev=1535214&r1=1535213&r2=1535214&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/revert_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/revert_tests.py Wed Oct 23 23:57:49 2013
@@ -1644,6 +1644,8 @@ def revert_obstructing_wc(sbox):
                                      'revert', '-R', wc_dir)
 
 
+
+
 ########################################################################
 # Run the tests
 
@@ -1683,7 +1685,7 @@ test_list = [ None,
               revert_no_text_change_conflict_recursive,
               revert_with_unversioned_targets,
               revert_nonexistent,
-              revert_obstructing_wc
+              revert_obstructing_wc,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/svnadmin_tests.py?rev=1535214&r1=1535213&r2=1535214&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/cmdline/svnadmin_tests.py Wed Oct 23 23:57:49 2013
@@ -1616,7 +1616,7 @@ def hotcopy_incremental_packed(sbox):
   cwd = os.getcwd()
   # Configure two files per shard to trigger packing
   format_file = open(os.path.join(sbox.repo_dir, 'db', 'format'), 'wb')
-  format_file.write("4\nlayout sharded 2\n")
+  format_file.write("6\nlayout sharded 2\n")
   format_file.close()
 
   # Pack revisions 0 and 1.

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=1535214&r1=1535213&r2=1535214&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 Wed Oct 23 23:57:49 2013
@@ -430,7 +430,10 @@ def basic_upgrade_1_0(sbox):
 
   url = sbox.repo_url
 
-  xml_entries_relocate(sbox.wc_dir, 'file:///1.0.0/repos', url)
+  # This is non-canonical by the rules of svn_uri_canonicalize, it gets
+  # written into the entries file and upgrade has to canonicalize.
+  non_canonical_url = url[:-1] + '%%%02x' % ord(url[-1])
+  xml_entries_relocate(sbox.wc_dir, 'file:///1.0.0/repos', non_canonical_url)
 
   # Attempt to use the working copy, this should give an error
   expected_stderr = wc_is_too_old_regex

Modified: subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_subr/dirent_uri-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_subr/dirent_uri-test.c?rev=1535214&r1=1535213&r2=1535214&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_subr/dirent_uri-test.c (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/tests/libsvn_subr/dirent_uri-test.c Wed Oct 23 23:57:49 2013
@@ -911,6 +911,9 @@ static const testcase_canonicalize_t uri
     { "file:///C:/temp/REPOS", "file:///C:/temp/REPOS" },
     { "file:///c:/",           "file:///c:" },
 #endif /* SVN_USE_DOS_PATHS */
+    /* Hostnames that look like non-canonical paths */
+    { "file://./foo",             "file://./foo" },
+    { "http://./foo",             "http://./foo" },
   /* svn_uri_is_canonical() was a private function in the 1.6 API, and
      has since taken a MAJOR change of direction, namely that only
      absolute URLs are considered canonical uris now. */

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=1535214&r1=1535213&r2=1535214&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 Wed Oct 23 23:57:49 2013
@@ -8149,6 +8149,197 @@ update_with_tree_conflict(const svn_test
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+move_child_to_parent_revert(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,
+                                   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_move(&b, "A/B", "B"));
+  SVN_ERR(sbox_wc_delete(&b, "A"));
+
+  /* Verify that the move is still recorded correctly */
+  {
+    nodes_row_t nodes[] = {
+      {0, "",    "normal", 0, ""},
+      {0, "A",   "normal", 1, "A"},
+      {0, "A/B", "normal", 1, "A/B"},
+
+      {1, "A",   "base-deleted", NO_COPY_FROM},
+      {1, "A/B", "base-deleted", NO_COPY_FROM, "B"},
+
+      {1, "B", "normal", 1, "A/B", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  SVN_ERR(sbox_wc_revert(&b, "A", svn_depth_infinity));
+
+  /* Verify that the move is now just a copy */
+  {
+    nodes_row_t nodes[] = {
+      {0, "",    "normal", 0, ""},
+      {0, "A",   "normal", 1, "A"},
+      {0, "A/B", "normal", 1, "A/B"},
+
+      {1, "B", "normal", 1, "A/B"},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_abspath_more_than_once(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,
+                                   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 revert A */
+  SVN_ERR(sbox_wc_revert(&b, "A", svn_depth_infinity));
+
+  /* AAA_1 should now be a copy, but AAA_2 and AAA_3 should still be moves,
+     but now from the original location instead of from "A/A/A" */
+  {
+    nodes_row_t nodes[] = {
+
+      {0, "",           "normal",       0, ""},
+
+      {1, "AAA_1",      "normal",       1, "A/A/A",},
+      {1, "AAA_1/A",    "normal",       1, "A/A/A/A"},
+      {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"},
+
+      {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;
+}
+
+
 /* ---------------------------------------------------------------------- */
 /* The list of test functions */
 
@@ -8302,5 +8493,9 @@ struct svn_test_descriptor_t test_funcs[
                        "move/delete file externals (issue 4293)"),
     SVN_TEST_OPTS_PASS(update_with_tree_conflict,
                        "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_NULL
   };