subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From futat...@apache.org
Subject svn commit: r1862754 [8/9] - in /subversion/branches/swig-py3: ./ build/ac-macros/ build/generator/ doc/ doc/programmer/ notes/ notes/shelving/ subversion/bindings/cxx/ subversion/bindings/cxxhl/ subversion/bindings/javahl/native/ subversion/bindings/j...
Date Mon, 08 Jul 2019 15:19:05 GMT
Modified: subversion/branches/swig-py3/subversion/tests/cmdline/revert_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/revert_tests.py?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/revert_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/revert_tests.py Mon Jul  8 15:19:03 2019
@@ -46,6 +46,23 @@ Item = svntest.wc.StateItem
 ######################################################################
 # Helpers
 
+def expected_output_revert(reverted_paths, skipped_paths=[]):
+  return svntest.verify.UnorderedRegexListOutput(
+    ["Reverted '%s'\n" % re.escape(path) for path in reverted_paths] +
+    ["Skipped '%s'.*\n" % re.escape(path) for path in skipped_paths])
+
+def run_and_verify_revert(targets, options=[],
+                          reverted_paths=None, skipped_paths=[]):
+  """Run 'svn revert OPTIONS TARGETS'. Verify that the printed output matches
+     REVERTED_PATHS and SKIPPED_PATHS. If REVERTED_PATHS is None, it defaults
+     to TARGETS.
+  """
+  if reverted_paths is None:
+    reverted_paths = targets
+  expected_output = expected_output_revert(reverted_paths, skipped_paths)
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     *(['revert'] + options + targets))
+
 def revert_replacement_with_props(sbox, wc_copy):
   """Helper implementing the core of
   revert_{repos,wc}_to_wc_replace_with_props().
@@ -129,9 +146,7 @@ def revert_replacement_with_props(sbox,
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   expected_status.tweak('A/D/G/rho', status='  ', copied=None, wc_rev='2')
-  expected_output = ["Reverted '" + rho_path + "'\n"]
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', '-R', wc_dir)
+  run_and_verify_revert([wc_dir], ['-R'], [rho_path])
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # Check disk status
@@ -356,8 +371,7 @@ def revert_replaced_file_without_props(s
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # revert file1
-  svntest.actions.run_and_verify_svn(["Reverted '" + file1_path + "'\n"],
-                                     [], 'revert', file1_path)
+  run_and_verify_revert([file1_path])
 
   # test that file1 really was reverted
   expected_status.tweak('file1', status='  ', wc_rev=2)
@@ -402,10 +416,7 @@ def revert_moved_file(sbox):
   actions.run_and_verify_unquiet_status(wc_dir, expected_status)
 
   # svn revert iota
-  expected_stdout = ["Reverted '" + iota + "'\n"]
-
-  actions.run_and_verify_svn2(expected_stdout, [], 0, 'revert',
-    iota)
+  run_and_verify_revert([iota])
 
   # svn st
   expected_status.tweak('iota', status='  ', moved_to=None)
@@ -644,9 +655,7 @@ def revert_propset__dir(sbox):
   wc_dir = sbox.wc_dir
   a_path = os.path.join(wc_dir, 'A')
   svntest.main.run_svn(None, 'propset', 'foo', 'x', a_path)
-  expected_output = re.escape("Reverted '" + a_path + "'")
-  svntest.actions.run_and_verify_svn(expected_output, [], "revert",
-                                     a_path)
+  run_and_verify_revert([a_path])
 
 def revert_propset__file(sbox):
   "revert a simple propset on a file"
@@ -655,9 +664,7 @@ def revert_propset__file(sbox):
   wc_dir = sbox.wc_dir
   iota_path = os.path.join(wc_dir, 'iota')
   svntest.main.run_svn(None, 'propset', 'foo', 'x', iota_path)
-  expected_output = re.escape("Reverted '" + iota_path + "'")
-  svntest.actions.run_and_verify_svn(expected_output, [], "revert",
-                                     iota_path)
+  run_and_verify_revert([iota_path])
 
 def revert_propdel__dir(sbox):
   "revert a simple propdel on a dir"
@@ -669,9 +676,7 @@ def revert_propdel__dir(sbox):
   svntest.main.run_svn(None,
                        'commit', '-m', 'ps', a_path)
   svntest.main.run_svn(None, 'propdel', 'foo', a_path)
-  expected_output = re.escape("Reverted '" + a_path + "'")
-  svntest.actions.run_and_verify_svn(expected_output, [], "revert",
-                                     a_path)
+  run_and_verify_revert([a_path])
 
 def revert_propdel__file(sbox):
   "revert a simple propdel on a file"
@@ -683,9 +688,7 @@ def revert_propdel__file(sbox):
   svntest.main.run_svn(None,
                        'commit', '-m', 'ps', iota_path)
   svntest.main.run_svn(None, 'propdel', 'foo', iota_path)
-  expected_output = re.escape("Reverted '" + iota_path + "'")
-  svntest.actions.run_and_verify_svn(expected_output, [], "revert",
-                                     iota_path)
+  run_and_verify_revert([iota_path])
 
 def revert_replaced_with_history_file_1(sbox):
   "revert a committed replace-with-history == no-op"
@@ -776,9 +779,7 @@ def status_of_missing_dir_after_revert(s
   A_D_G_path = os.path.join(wc_dir, "A", "D", "G")
 
   svntest.actions.run_and_verify_svn(None, [], "rm", A_D_G_path)
-  expected_output = re.escape("Reverted '" + A_D_G_path + "'")
-  svntest.actions.run_and_verify_svn(expected_output, [], "revert",
-                                     A_D_G_path)
+  run_and_verify_revert([A_D_G_path])
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_status.tweak('A/D/G/rho', 'A/D/G/pi', 'A/D/G/tau',
@@ -877,11 +878,7 @@ def status_of_missing_dir_after_revert_r
   revert_paths = [G_path] + [os.path.join(G_path, child)
                              for child in ['alpha', 'beta', 'pi', 'rho', 'tau']]
 
-  expected_output = svntest.verify.UnorderedOutput([
-    "Reverted '%s'\n" % path for path in revert_paths])
-
-  svntest.actions.run_and_verify_svn(expected_output, [], "revert", "-R",
-                                     G_path)
+  run_and_verify_revert([G_path], ["-R"], revert_paths)
 
   svntest.actions.run_and_verify_svn([], [],
                                      "status", wc_dir)
@@ -947,12 +944,6 @@ def revert_tree_conflicts_in_updated_fil
   G2_tau = os.path.join(G2, 'tau')
 
   # Expectations
-  expected_output = svntest.verify.UnorderedOutput(
-   ["Reverted '%s'\n" % G_pi,
-    "Reverted '%s'\n" % G_rho,
-    "Reverted '%s'\n" % G_tau,
-    ])
-
   expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
   expected_status.tweak('A/D/G/pi',  status='  ')
   expected_status.remove('A/D/G/rho')
@@ -965,23 +956,15 @@ def revert_tree_conflicts_in_updated_fil
   expected_disk.remove('A/D/G/tau')
 
   # Revert individually in wc
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', G_pi, G_rho, G_tau)
+  run_and_verify_revert([G_pi, G_rho, G_tau])
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
   svntest.actions.verify_disk(wc_dir, expected_disk)
 
   # Expectations
-  expected_output = svntest.verify.UnorderedOutput(
-   ["Reverted '%s'\n" % G2_pi,
-    "Reverted '%s'\n" % G2_rho,
-    "Reverted '%s'\n" % G2_tau,
-    ])
-
   expected_status.wc_dir = wc_dir_2
 
   # Revert recursively in wc 2
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', '-R', G2)
+  run_and_verify_revert([G2], ['-R'], [G2_pi, G2_rho, G2_tau])
   svntest.actions.run_and_verify_status(wc_dir_2, expected_status)
   svntest.actions.verify_disk(wc_dir_2, expected_disk)
 
@@ -1049,9 +1032,7 @@ def revert_child_of_copy(sbox):
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # First revert removes text change, child is still copied
-  expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B/E2/beta')]
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', sbox.ospath('A/B/E2/beta'))
+  run_and_verify_revert(sbox.ospaths(['A/B/E2/beta']))
   expected_status.tweak('A/B/E2/beta', status='  ')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
@@ -1074,9 +1055,7 @@ def revert_non_recusive_after_delete(sbo
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # This appears to work but gets the op-depth wrong
-  expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B')]
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', sbox.ospath('A/B'))
+  run_and_verify_revert(sbox.ospaths(['A/B']))
   expected_status.tweak('A/B', status='  ')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
@@ -1086,9 +1065,7 @@ def revert_non_recusive_after_delete(sbo
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # Since the op-depth was wrong A/B/E erroneously remains deleted
-  expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B/E')]
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', sbox.ospath('A/B/E'))
+  run_and_verify_revert(sbox.ospaths(['A/B/E']))
   expected_status.tweak('A/B/E', status='  ')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
@@ -1134,17 +1111,13 @@ def revert_permissions_only(sbox):
 
   os.chmod(sbox.ospath('A/B/E/alpha'), svntest.main.S_ALL_READ)  # read-only
   is_readonly(sbox.ospath('A/B/E/alpha'))
-  expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B/E/alpha')]
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', sbox.ospath('A/B/E/alpha'))
+  run_and_verify_revert(sbox.ospaths(['A/B/E/alpha']))
   is_writable(sbox.ospath('A/B/E/alpha'))
 
   if svntest.main.is_posix_os():
     os.chmod(sbox.ospath('A/B/E/beta'), svntest.main.S_ALL_RWX)   # executable
     is_executable(sbox.ospath('A/B/E/beta'))
-    expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B/E/beta')]
-    svntest.actions.run_and_verify_svn(expected_output, [],
-                                       'revert', sbox.ospath('A/B/E/beta'))
+    run_and_verify_revert(sbox.ospaths(['A/B/E/beta']))
     is_non_executable(sbox.ospath('A/B/E/beta'))
 
   svntest.actions.run_and_verify_svn(None, [],
@@ -1167,17 +1140,13 @@ def revert_permissions_only(sbox):
 
   os.chmod(sbox.ospath('A/B/E/alpha'), svntest.main.S_ALL_RW)  # not read-only
   is_writable(sbox.ospath('A/B/E/alpha'))
-  expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B/E/alpha')]
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', sbox.ospath('A/B/E/alpha'))
+  run_and_verify_revert(sbox.ospaths(['A/B/E/alpha']))
   is_readonly(sbox.ospath('A/B/E/alpha'))
 
   if svntest.main.is_posix_os():
     os.chmod(sbox.ospath('A/B/E/beta'), svntest.main.S_ALL_RW)   # not executable
     is_non_executable(sbox.ospath('A/B/E/beta'))
-    expected_output = ["Reverted '%s'\n" % sbox.ospath('A/B/E/beta')]
-    svntest.actions.run_and_verify_svn(expected_output, [],
-                                       'revert', sbox.ospath('A/B/E/beta'))
+    run_and_verify_revert(sbox.ospaths(['A/B/E/beta']))
     is_executable(sbox.ospath('A/B/E/beta'))
 
   # copied file is always writeable
@@ -1212,14 +1181,8 @@ def revert_copy_depth_files(sbox):
     })
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
-  expected_output = svntest.verify.UnorderedOutput([
-    "Reverted '%s'\n" % sbox.ospath(path) for path in ['A/B/E2',
-                                                       'A/B/E2/alpha',
-                                                       'A/B/E2/beta']])
-
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', '--depth', 'files',
-                                     sbox.ospath('A/B/E2'))
+  run_and_verify_revert(sbox.ospaths(['A/B/E2']), ['--depth', 'files'],
+                        sbox.ospaths(['A/B/E2', 'A/B/E2/alpha', 'A/B/E2/beta']))
 
   expected_status.remove('A/B/E2', 'A/B/E2/alpha', 'A/B/E2/beta')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -1242,12 +1205,8 @@ def revert_nested_add_depth_immediates(s
     })
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
-  expected_output = svntest.verify.UnorderedOutput([
-    "Reverted '%s'\n" % sbox.ospath(path) for path in ['A/X', 'A/X/Y']])
-
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', '--depth', 'immediates',
-                                     sbox.ospath('A/X'))
+  run_and_verify_revert(sbox.ospaths(['A/X']), ['--depth', 'immediates'],
+                        sbox.ospaths(['A/X', 'A/X/Y']))
 
   expected_status.remove('A/X', 'A/X/Y')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -1299,9 +1258,7 @@ def revert_empty_actual(sbox):
   wc_dir = sbox.wc_dir
 
   # Non-recursive code path works
-  svntest.actions.run_and_verify_svn(["Reverted '%s'\n" % sbox.ospath('alpha')],
-                                     [],
-                                     'revert', sbox.ospath('alpha'))
+  run_and_verify_revert(sbox.ospaths(['alpha']))
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -1316,9 +1273,7 @@ def revert_empty_actual_recursive(sbox):
 
   # Recursive code path fails, the superfluous actual node suppresses the
   # notification
-  svntest.actions.run_and_verify_svn(["Reverted '%s'\n" % sbox.ospath('alpha')],
-                                     [],
-                                     'revert', '-R', sbox.ospath('alpha'))
+  run_and_verify_revert(sbox.ospaths(['alpha']), ['-R'])
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -1433,7 +1388,7 @@ def revert_tree_conflicts_with_replaceme
   cd_and_status_u('A/D/H')
 
   # Revert everything (i.e., accept "theirs-full").
-  svntest.actions.run_and_verify_revert([
+  reverted_paths = [
     wc('A/B/E'),
     wc('A/B/E/alpha'),   # incoming & local
     wc('A/B/E/beta'),
@@ -1450,7 +1405,8 @@ def revert_tree_conflicts_with_replaceme
     wc('A/D/H/loc_psi'),
     wc('A/D/gamma'),
     wc('A/mu'),
-    ], '-R', wc_dir)
+    ]
+  run_and_verify_revert([wc_dir], ['-R'], reverted_paths)
 
   # Remove a few unversioned files that revert left behind.
   os.remove(wc('A/B/E/loc_beta'))
@@ -1511,10 +1467,7 @@ def revert_no_text_change_conflict(sbox)
   create_no_text_change_conflict(sbox)
   wc_dir = sbox.wc_dir
 
-  svntest.actions.run_and_verify_svn(["Reverted '%s'\n"
-                                      % sbox.ospath('A/B/E/alpha')],
-                                     [],
-                                     'revert', sbox.ospath('A/B/E/alpha'))
+  run_and_verify_revert(sbox.ospaths(['A/B/E/alpha']))
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -1526,10 +1479,7 @@ def revert_no_text_change_conflict_recur
   create_no_text_change_conflict(sbox)
   wc_dir = sbox.wc_dir
 
-  svntest.actions.run_and_verify_svn(["Reverted '%s'\n"
-                                      % sbox.ospath('A/B/E/alpha')],
-                                     [],
-                                     'revert', '-R', wc_dir)
+  run_and_verify_revert(sbox.ospaths(['A/B/E/alpha']), ['-R'])
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -1560,13 +1510,8 @@ def revert_with_unversioned_targets(sbox
     f.write(psi_contents)
 
   # revert
-  expected_output = svntest.verify.UnorderedOutput([
-    "Reverted '%s'\n" % sbox.ospath('A/D/H/chi'),
-    "Skipped '%s'\n" % sbox.ospath('A/D/H/delta'),
-    "Reverted '%s'\n" % sbox.ospath('A/D/H/psi'),
-  ])
-  svntest.actions.run_and_verify_svn(expected_output, [],
-                                     'revert', chi_path, delta_path, psi_path)
+  run_and_verify_revert([chi_path, delta_path, psi_path], [],
+                        [chi_path, psi_path], [delta_path])
 
   # verify status
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
@@ -1585,8 +1530,8 @@ def revert_with_unversioned_targets(sbox
 def revert_nonexistent(sbox):
   'svn revert -R nonexistent'
   sbox.build(read_only=True)
-  svntest.actions.run_and_verify_svn('Skipped.*nonexistent', [],
-                                     'revert', '-R', sbox.ospath('nonexistent'))
+  run_and_verify_revert(sbox.ospaths(['nonexistent']), ['-R'],
+                        [], sbox.ospaths(['nonexistent']))
 
 @Issue(4168)
 def revert_obstructing_wc(sbox):
@@ -1641,6 +1586,33 @@ def revert_moved_dir_partial(sbox):
   sbox.simple_move('A', 'A_')
   svntest.actions.run_and_verify_svn(None, [], 'revert', sbox.ospath('A'))
 
+@XFail()
+@Issue(4798)
+def revert_remove_added(sbox):
+  "revert_remove_added"
+
+  sbox.build(empty=True, read_only=True)
+
+  # We'll test the items named with a '1' as direct targets to 'revert',
+  # and items named with a '2' as items found by recursion.
+  sbox.simple_mkdir('D1', 'D2')
+  sbox.simple_add_text('This is a new file.',
+                       'D1/file', 'file1',
+                       'D2/file', 'file2')
+
+  run_and_verify_revert(sbox.ospaths(['D1']), ['--remove-added', '-R'],
+                        sbox.ospaths(['D1/file', 'D1']))
+  assert(not os.path.exists(sbox.ospath('D1')))
+
+  run_and_verify_revert(sbox.ospaths(['file1']), ['--remove-added'],
+                        sbox.ospaths(['file1']))
+  assert(not os.path.exists(sbox.ospath('file1')))
+
+  run_and_verify_revert(sbox.ospaths(['.']), ['--remove-added', '-R'],
+                        sbox.ospaths(['D2/file', 'D2', 'file2']))
+  assert(not os.path.exists(sbox.ospath('file2')))
+  assert(not os.path.exists(sbox.ospath('D2')))
+
 
 ########################################################################
 # Run the tests
@@ -1683,6 +1655,7 @@ test_list = [ None,
               revert_nonexistent,
               revert_obstructing_wc,
               revert_moved_dir_partial,
+              revert_remove_added,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/shelf_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/shelf_tests.py?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/shelf_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/shelf_tests.py Mon Jul  8 15:19:03 2019
@@ -525,6 +525,7 @@ def shelf_status(sbox):
 
 #----------------------------------------------------------------------
 
+@XFail()
 def shelve_mkdir(sbox):
   "shelve mkdir"
 
@@ -534,7 +535,7 @@ def shelve_mkdir(sbox):
     sbox.simple_mkdir('D', 'D/D2')
     sbox.simple_propset('p', 'v', 'D', 'D/D2')
 
-  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+  shelve_unshelve(sbox, modifier)
 
 #----------------------------------------------------------------------
 
@@ -548,10 +549,11 @@ def shelve_rmdir(sbox):
   def modifier(sbox):
     sbox.simple_rm('A/C', 'A/D/G')
 
-  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+  shelve_unshelve(sbox, modifier)
 
 #----------------------------------------------------------------------
 
+@XFail()
 def shelve_replace_dir(sbox):
   "shelve replace dir"
 
@@ -563,7 +565,7 @@ def shelve_replace_dir(sbox):
     sbox.simple_rm('A/C', 'A/D/G')
     sbox.simple_mkdir('A/C', 'A/C/D2')
 
-  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+  shelve_unshelve(sbox, modifier)
 
 #----------------------------------------------------------------------
 
@@ -576,7 +578,7 @@ def shelve_file_copy(sbox):
     sbox.simple_copy('iota', 'A/ii')
     sbox.simple_propset('p', 'v', 'A/ii')
 
-  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+  shelve_unshelve(sbox, modifier)
 
 #----------------------------------------------------------------------
 
@@ -589,7 +591,7 @@ def shelve_dir_copy(sbox):
     sbox.simple_copy('A/B', 'BB')
     sbox.simple_propset('p', 'v', 'BB')
 
-  shelve_unshelve(sbox, modifier, cannot_shelve=True)
+  shelve_unshelve(sbox, modifier)
 
 #----------------------------------------------------------------------
 
@@ -643,31 +645,21 @@ def refuse_to_shelve_conflict(sbox):
   os.chdir(sbox.wc_dir)
   sbox.wc_dir = ''
 
-  # create a tree conflict victim at an unversioned path
+  # create a conflict
   sbox.simple_mkdir('topdir')
   sbox.simple_commit()
-  sbox.simple_mkdir('topdir/subdir')
-  sbox.simple_commit()
-  sbox.simple_update()
-  sbox.simple_rm('topdir')
-  sbox.simple_commit()
   sbox.simple_update()
   svntest.actions.run_and_verify_svn(
     None, [],
-    'merge', '-c2', '.', '--ignore-ancestry', '--accept', 'postpone')
+    'merge', '-c1', '.', '--ignore-ancestry', '--accept', 'postpone')
+  # check that we did create a conflict
   svntest.actions.run_and_verify_svn(
-    None, 'svn: E155015:.*existing.*conflict.*',
+    None, 'svn: E155035:.*conflict.*',
     'merge', '-c1', '.', '--ignore-ancestry', '--accept', 'postpone')
 
   # attempt to shelve
-  expected_out = svntest.verify.RegexListOutput([
-    r'--- .*',
-    r'--- .*',
-    r'\?     C topdir',
-    r'      > .*',
-    r'      >   not shelved'])
-  svntest.actions.run_and_verify_svn(expected_out,
-                                     '.* 1 path could not be shelved',
+  expected_err = "svn: E155015: .* '.*topdir' remains in conflict"
+  svntest.actions.run_and_verify_svn(None, expected_err,
                                      'x-shelf-save', 'foo')
 
   os.chdir(was_cwd)
@@ -711,6 +703,7 @@ def unshelve_with_merge(sbox, setup, mod
 
   os.chdir(was_cwd)
 
+@XFail()
 def unshelve_text_mod_merge(sbox):
   "unshelve text mod merge"
 
@@ -735,6 +728,7 @@ def unshelve_text_mod_merge(sbox):
 
 #----------------------------------------------------------------------
 
+@XFail()
 def unshelve_text_mod_conflict(sbox):
   "unshelve text mod conflict"
 
@@ -765,6 +759,7 @@ def unshelve_text_mod_conflict(sbox):
 
 #----------------------------------------------------------------------
 
+@XFail()
 def unshelve_undeclared_binary_mod_conflict(sbox):
   "unshelve undeclared binary mod conflict"
 
@@ -795,6 +790,7 @@ def unshelve_undeclared_binary_mod_confl
 
 #----------------------------------------------------------------------
 
+@XFail()
 def unshelve_binary_mod_conflict(sbox):
   "unshelve binary mod conflict"
 
@@ -845,6 +841,7 @@ def unshelve_text_prop_merge(sbox):
 
 #----------------------------------------------------------------------
 
+@XFail()
 def unshelve_text_prop_conflict(sbox):
   "unshelve text prop conflict"
 

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/svnadmin_tests.py?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/svnadmin_tests.py Mon Jul  8 15:19:03 2019
@@ -3920,6 +3920,51 @@ def recover_prunes_rep_cache_when_disabl
 
   check_recover_prunes_rep_cache(sbox, enable_rep_sharing=False)
 
+@Issue(4760)
+def dump_include_copied_directory(sbox):
+  "include copied directory with nested nodes"
+
+  sbox.build(create_wc=False)
+
+  svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], "copy",
+                                     sbox.repo_url + '/A/D',
+                                     sbox.repo_url + '/COPY',
+                                     "-m", "Create branch.")
+
+  # Dump repository with only /COPY path included.
+  _, dump, _ = svntest.actions.run_and_verify_svnadmin(None, [],
+                                                       'dump', '-q',
+                                                       '--include', '/COPY',
+                                                       sbox.repo_dir)
+
+  # Load repository from dump.
+  sbox2 = sbox.clone_dependent()
+  sbox2.build(create_wc=False, empty=True)
+  load_and_verify_dumpstream(sbox2, None, [], None, False, dump)
+
+  # Check log.
+  expected_output = svntest.verify.RegexListOutput([
+    '-+\\n',
+    'r2\ .*\n',
+    # Only '/COPY' is added
+    re.escape('Changed paths:\n'),
+    re.escape('   A /COPY'),
+    re.escape('   A /COPY/G'),
+    re.escape('   A /COPY/G/pi'),
+    re.escape('   A /COPY/G/rho'),
+    re.escape('   A /COPY/G/tau'),
+    re.escape('   A /COPY/H'),
+    re.escape('   A /COPY/H/chi'),
+    re.escape('   A /COPY/H/omega'),
+    re.escape('   A /COPY/H/psi'),
+    re.escape('   A /COPY/gamma'),
+    '-+\\n',
+    'r1\ .*\n',
+    '-+\\n'
+  ])
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', '-v', '-q', sbox2.repo_url)
+
 ########################################################################
 # Run the tests
 
@@ -3997,6 +4042,7 @@ test_list = [ None,
               dump_no_canonicalize_svndate,
               recover_prunes_rep_cache_when_enabled,
               recover_prunes_rep_cache_when_disabled,
+              dump_include_copied_directory,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/svnauthz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/svnauthz_tests.py?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/svnauthz_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/svnauthz_tests.py Mon Jul  8 15:19:03 2019
@@ -965,6 +965,36 @@ def svnauthz_inverted_selector_test(sbox
   os.remove(authz_path)
 
 
+@Issues(4802, 4803)
+def svnauthz_empty_group_test(sbox):
+  "test empty group definition"
+
+  # build an authz file
+  authz_content = ("[groups]\n"
+                   "group1 =\n"
+                   "group2 = @group1\n"
+                   "group3 = @group2, user\n"
+
+
+                   "[A:/]\n"
+                   "@group1 = rw\n"
+                   "@group2 = rw\n"
+                   "@group3 = r\n")
+
+  (authz_fd, authz_path) = tempfile.mkstemp()
+  svntest.main.file_write(authz_path, authz_content)
+
+  expected_stderr = svntest.verify.RegexOutput(
+    r".*warning: W220003:.*", match_all=False)
+
+  svntest.actions.run_and_verify_svnauthz(
+    [], expected_stderr, 0, False, 'validate', authz_path)
+
+  svntest.actions.run_and_verify_svnauthz(
+    'r', expected_stderr, 0, False, 'accessof',
+    '--repository', 'A', '--username', 'user', authz_path)
+
+
 ########################################################################
 # Run the tests
 
@@ -984,6 +1014,7 @@ test_list = [ None,
               svnauthz_compat_mode_file_test,
               svnauthz_compat_mode_repo_test,
               svnauthz_inverted_selector_test,
+              svnauthz_empty_group_test,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/svnserveautocheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/svnserveautocheck.sh?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/svnserveautocheck.sh (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/svnserveautocheck.sh Mon Jul  8 15:19:03 2019
@@ -74,6 +74,28 @@ fail() {
   exit 1
 }
 
+query() {
+    printf "%s" "$SCRIPT: $1 (y/n)? [$2] "
+    if [ -n "$BASH_VERSION" ]; then
+        read -n 1 -t 32
+    else
+        #
+        prog="
+import select as s
+import sys
+import tty, termios
+tty.setcbreak(sys.stdin.fileno(), termios.TCSANOW)
+if s.select([sys.stdin.fileno()], [], [], 32)[0]:
+  sys.stdout.write(sys.stdin.read(1))
+"
+        stty_state=`stty -g`
+        REPLY=`$PYTHON -u -c "$prog" "$@"`
+        stty $stty_state
+    fi
+    echo
+    [ "${REPLY:-$2}" = 'y' ]
+}
+
 # Compute ABS_BUILDDIR and ABS_SRCDIR.
 if [ -x subversion/svn/svn ]; then
   # cwd is build tree root
@@ -92,13 +114,21 @@ if [ ! -e $ABS_SRCDIR/subversion/include
   fail "Run this script from the root of Subversion's build tree!"
 fi
 
+# Create a directory for the PID and log files. If you change this, also make
+# sure to change the svn:ignore entry for it and "make check-clean".
+SVNSERVE_ROOT="$ABS_BUILDDIR/subversion/tests/cmdline/svnserve-$(date '+%Y%m%d-%H%M%S')"
+mkdir "$SVNSERVE_ROOT" \
+    || fail "couldn't create temporary directory '$SVNSERVE_ROOT'"
+
 # If you change this, also make sure to change the svn:ignore entry
 # for it and "make check-clean".
-SVNSERVE_PID=$ABS_BUILDDIR/subversion/tests/svnserveautocheck.pid
+SVNSERVE_PID=$SVNSERVE_ROOT/svnserve.pid
+SVNSERVE_LOG=$SVNSERVE_ROOT/svnserve.log
 
 SERVER_CMD="$ABS_BUILDDIR/subversion/svnserve/svnserve"
 
 rm -f $SVNSERVE_PID
+rm -f $SVNSERVE_LOG
 
 random_port() {
   if [ -n "$BASH_VERSION" ]; then
@@ -140,6 +170,7 @@ fi
             --listen-host 127.0.0.1 \
             --listen-port $SVNSERVE_PORT \
             --pid-file $SVNSERVE_PID \
+            --log-file $SVNSERVE_LOG \
             $SVNSERVE_ARGS &
 
 BASE_URL=svn://127.0.0.1:$SVNSERVE_PORT
@@ -155,5 +186,11 @@ else
   cd - > /dev/null
 fi
 
+query 'Browse server log' n \
+    && less "$SVNSERVE_LOG"
+
+query 'Delete svnserve root directory' y \
+    && rm -fr "$SVNSERVE_ROOT/"
+
 really_cleanup
 exit $r

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/svntest/main.py?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/svntest/main.py Mon Jul  8 15:19:03 2019
@@ -57,7 +57,7 @@ from svntest import Failure
 from svntest import Skip
 from svntest.wc import StateItem as Item
 
-SVN_VER_MINOR = 12
+SVN_VER_MINOR = 13
 
 ######################################################################
 #

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/switch_tests.py?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/switch_tests.py Mon Jul  8 15:19:03 2019
@@ -2027,8 +2027,9 @@ def tolerate_local_mods(sbox):
   svntest.main.run_svn(None, 'add', L_path)
   sbox.simple_commit(message='Commit added folder')
 
-  # locally modified unversioned file
+  # locally modified versioned file
   svntest.main.file_write(LM_path, 'Locally modified file.\n', 'w+')
+  sbox.simple_add('A/L/local_mod')
 
   expected_output = svntest.wc.State(wc_dir, {
     'A/L' : Item(status='  ', treeconflict='C'),
@@ -2044,7 +2045,8 @@ def tolerate_local_mods(sbox):
   expected_status.tweak('', 'iota', wc_rev=1)
   expected_status.tweak('A', switched='S')
   expected_status.add({
-    'A/L' : Item(status='A ', copied='+', treeconflict='C', wc_rev='-')
+    'A/L' : Item(status='A ', copied='+', treeconflict='C', wc_rev='-'),
+    'A/L/local_mod' : Item(status='A ', wc_rev='-'),
   })
 
   # Used to fail with locally modified or unversioned files

Modified: subversion/branches/swig-py3/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/cmdline/update_tests.py?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/swig-py3/subversion/tests/cmdline/update_tests.py Mon Jul  8 15:19:03 2019
@@ -6855,6 +6855,48 @@ def update_add_missing_local_add(sbox):
   
   sbox.simple_update()
 
+# Verify that deleting an unmodified directory leaves behind any unversioned
+# items on disk
+def update_keeps_unversioned_items_in_deleted_dir(sbox):
+  "update keeps unversioned items in deleted dir"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_rm('A/D/G')
+  sbox.simple_commit()
+
+  sbox.simple_update('', revision='1')
+
+  os.mkdir(sbox.ospath('A/D/G/unversioned-dir'))
+  svntest.main.file_write(sbox.ospath('A/D/G/unversioned.txt'),
+                          'unversioned file', 'wb')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/D/G' : Item(status='D '),
+    })
+
+  expected_disk = svntest.main.greek_state.copy()
+  # The unversioned items should be left behind on disk
+  expected_disk.add({
+    'A/D/G/unversioned-dir' : Item(),
+    'A/D/G/unversioned.txt' : Item('unversioned file'),
+    })
+  expected_disk.remove('A/D/G/pi')
+  expected_disk.remove('A/D/G/rho')
+  expected_disk.remove('A/D/G/tau')
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.remove('A/D/G')
+  expected_status.remove('A/D/G/pi')
+  expected_status.remove('A/D/G/rho')
+  expected_status.remove('A/D/G/tau')
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        expected_disk,
+                                        expected_status,
+                                        [], True)
+
 #######################################################################
 # Run the tests
 
@@ -6946,6 +6988,7 @@ test_list = [ None,
               missing_tmp_update,
               update_delete_switched,
               update_add_missing_local_add,
+              update_keeps_unversioned_items_in_deleted_dir,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/swig-py3/subversion/tests/libsvn_client/conflicts-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/libsvn_client/conflicts-test.c?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/libsvn_client/conflicts-test.c (original)
+++ subversion/branches/swig-py3/subversion/tests/libsvn_client/conflicts-test.c Mon Jul  8 15:19:03 2019
@@ -6946,6 +6946,519 @@ test_merge_file_edit_move_vs_file_move_a
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+create_dir_move_vs_dir_move_merge_conflict(svn_client_conflict_t **conflict,
+                                           svn_test__sandbox_t *b,
+                                           svn_client_ctx_t *ctx)
+{
+  svn_opt_revision_t opt_rev;
+  const char *branch_url;
+  apr_array_header_t *options;
+  svn_client_conflict_option_t *option;
+  apr_array_header_t *possible_moved_to_abspaths;
+
+  /* Create a branch of node "A". */
+  SVN_ERR(sbox_wc_copy(b, "A", "A2"));
+  SVN_ERR(sbox_wc_commit(b, "")); /* r2 */
+
+  /* Move a directory on trunk. */
+  SVN_ERR(sbox_wc_move(b, "A/B", "A/B-moved"));
+  SVN_ERR(sbox_wc_commit(b, "")); /* r3 */
+
+  /* Edit a file in the moved directory on trunk. */
+  SVN_ERR(sbox_file_write(b, "A/B-moved/E/alpha",
+                          modified_file_content));
+  SVN_ERR(sbox_wc_commit(b, ""));
+
+  /* Move the same direcotry to a different location on the branch. */
+  SVN_ERR(sbox_wc_move(b, "A2/B", "A2/B-also-moved"));
+  SVN_ERR(sbox_wc_commit(b, ""));
+
+  /* Edit a file in the moved directory on the branch. */
+  SVN_ERR(sbox_file_write(b, "A2/B-also-moved/lambda",
+                          modified_file_content));
+  SVN_ERR(sbox_wc_commit(b, ""));
+
+  /* Merge branch to trunk. */
+  SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM));
+  branch_url = apr_pstrcat(b->pool, b->repos_url, "/A2", SVN_VA_NULL);
+  opt_rev.kind = svn_opt_revision_head;
+  opt_rev.value.number = SVN_INVALID_REVNUM;
+  SVN_ERR(svn_client_merge_peg5(branch_url, NULL, &opt_rev,
+                                sbox_wc_path(b, "A"),
+                                svn_depth_infinity,
+                                FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+                                NULL, ctx, b->pool));
+
+  SVN_ERR(svn_client_conflict_get(conflict, sbox_wc_path(b, "A/B"),
+                                  ctx, b->pool, b->pool));
+  {
+    svn_client_conflict_option_id_t expected_opts[] = {
+      svn_client_conflict_option_postpone,
+      svn_client_conflict_option_accept_current_wc_state,
+      svn_client_conflict_option_incoming_delete_ignore,
+      svn_client_conflict_option_incoming_delete_accept,
+      -1 /* end of list */
+    };
+    SVN_ERR(assert_tree_conflict_options(*conflict, ctx, expected_opts,
+                                         b->pool));
+  }
+
+  SVN_ERR(svn_client_conflict_tree_get_details(*conflict, ctx, b->pool));
+  {
+    svn_client_conflict_option_id_t expected_opts[] = {
+      svn_client_conflict_option_postpone,
+      svn_client_conflict_option_accept_current_wc_state,
+      svn_client_conflict_option_both_moved_dir_merge,
+      svn_client_conflict_option_both_moved_dir_move_merge,
+      -1 /* end of list */
+    };
+    SVN_ERR(assert_tree_conflict_options(*conflict, ctx, expected_opts,
+                                         b->pool));
+  }
+
+  SVN_ERR(svn_client_conflict_tree_get_resolution_options(&options, *conflict,
+                                                          ctx, b->pool,
+                                                          b->pool));
+  option = svn_client_conflict_option_find_by_id(
+             options, svn_client_conflict_option_both_moved_dir_merge);
+  SVN_TEST_ASSERT(option != NULL);
+  SVN_ERR(svn_client_conflict_option_get_moved_to_abspath_candidates(
+            &possible_moved_to_abspaths, option, b->pool, b->pool));
+
+  /* The resolver finds two possible move destinations because both
+   * branches are checked out into the same working copy.
+   *
+   *   Possible working copy destinations for moved-away 'A/B' are:
+   *    (1): 'A/B-also-moved
+   *    (2): 'A2/B-also-moved
+   *   Only one destination can be a move; the others are copies.
+   */
+  SVN_TEST_INT_ASSERT(possible_moved_to_abspaths->nelts, 2);
+  SVN_TEST_STRING_ASSERT(
+    APR_ARRAY_IDX(possible_moved_to_abspaths, 0, const char *),
+    sbox_wc_path(b, "A/B-also-moved"));
+  SVN_TEST_STRING_ASSERT(
+    APR_ARRAY_IDX(possible_moved_to_abspaths, 1, const char *),
+    sbox_wc_path(b, "A2/B-also-moved"));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_merge_dir_move_vs_dir_move(const svn_test_opts_t *opts,
+                                apr_pool_t *pool)
+{
+  svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b));
+  svn_client_ctx_t *ctx;
+  svn_client_conflict_t *conflict;
+  svn_opt_revision_t opt_rev;
+  struct status_baton sb;
+  struct svn_client_status_t *status;
+  svn_stringbuf_t *buf;
+
+  SVN_ERR(svn_test__sandbox_create(b, "merge_dir_move_vs_dir_move",
+                                   opts, pool));
+
+  SVN_ERR(sbox_add_and_commit_greek_tree(b)); /* r1 */
+
+  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+  SVN_ERR(create_dir_move_vs_dir_move_merge_conflict(&conflict, b, ctx));
+
+  SVN_ERR(svn_client_conflict_tree_resolve_by_id(
+            conflict,
+            svn_client_conflict_option_both_moved_dir_merge,
+            ctx, b->pool));
+
+  /* The node "A/B" should not exist. */
+  SVN_TEST_ASSERT_ERROR(svn_client_conflict_get(&conflict,
+                                                sbox_wc_path(b, "A/B"),
+                                                ctx, pool, pool),
+                        SVN_ERR_WC_PATH_NOT_FOUND);
+
+  /* The node "A/B-also-moved" should not exist. */
+  SVN_TEST_ASSERT_ERROR(svn_client_conflict_get(
+                          &conflict,
+                          sbox_wc_path(b, "A/B-also-moved"), ctx, pool, pool),
+                        SVN_ERR_WC_PATH_NOT_FOUND);
+
+  /* Ensure that the merged directory has the expected status. */
+  opt_rev.kind = svn_opt_revision_working;
+  sb.result_pool = b->pool;
+  SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, "A/B-moved"),
+                             &opt_rev, svn_depth_unknown, TRUE, TRUE,
+                             TRUE, TRUE, FALSE, TRUE, NULL,
+                             status_func, &sb, b->pool));
+  status = sb.status;
+  SVN_TEST_ASSERT(status->kind == svn_node_dir);
+  SVN_TEST_ASSERT(status->versioned);
+  SVN_TEST_ASSERT(!status->conflicted);
+  SVN_TEST_ASSERT(status->node_status == svn_wc_status_normal);
+  SVN_TEST_ASSERT(status->text_status == svn_wc_status_normal);
+  SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+  SVN_TEST_ASSERT(!status->copied);
+  SVN_TEST_ASSERT(!status->switched);
+  SVN_TEST_ASSERT(!status->file_external);
+  SVN_TEST_ASSERT(status->moved_from_abspath == NULL);
+  SVN_TEST_ASSERT(status->moved_to_abspath == NULL);
+
+  /* Make sure the edited files have the expected content. */
+  SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, "A/B-moved/lambda"),
+                                   pool));
+  SVN_TEST_STRING_ASSERT(buf->data, modified_file_content);
+  SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, "A/B-moved/E/alpha"),
+                                   pool));
+  SVN_TEST_STRING_ASSERT(buf->data, modified_file_content);
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_merge_dir_move_vs_dir_move_accept_move(const svn_test_opts_t *opts,
+                                            apr_pool_t *pool)
+{
+  svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b));
+  svn_client_ctx_t *ctx;
+  svn_client_conflict_t *conflict;
+  svn_opt_revision_t opt_rev;
+  struct status_baton sb;
+  struct svn_client_status_t *status;
+  svn_stringbuf_t *buf;
+
+  SVN_ERR(svn_test__sandbox_create(b, "merge_dir_move_vs_dir_move_accept_move",
+                                   opts, pool));
+
+  SVN_ERR(sbox_add_and_commit_greek_tree(b)); /* r1 */
+
+  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+  SVN_ERR(create_dir_move_vs_dir_move_merge_conflict(&conflict, b, ctx));
+
+  SVN_ERR(svn_client_conflict_tree_resolve_by_id(
+            conflict,
+            svn_client_conflict_option_both_moved_dir_move_merge,
+            ctx, b->pool));
+
+  /* The node "A/B" should not exist. */
+  SVN_TEST_ASSERT_ERROR(svn_client_conflict_get(&conflict,
+                                                sbox_wc_path(b, "A/B"),
+                                                ctx, pool, pool),
+                        SVN_ERR_WC_PATH_NOT_FOUND);
+
+  /* The node "A/B-moved" should be moved to A/B-also-moved. */
+  opt_rev.kind = svn_opt_revision_working;
+  sb.result_pool = b->pool;
+  SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, "A/B-moved"),
+                             &opt_rev, svn_depth_empty, TRUE, TRUE,
+                             TRUE, TRUE, FALSE, TRUE, NULL,
+                             status_func, &sb, b->pool));
+  status = sb.status;
+  SVN_TEST_ASSERT(status->kind == svn_node_dir);
+  SVN_TEST_ASSERT(status->versioned);
+  SVN_TEST_ASSERT(!status->conflicted);
+  SVN_TEST_ASSERT(status->node_status == svn_wc_status_deleted);
+  SVN_TEST_ASSERT(status->text_status == svn_wc_status_normal);
+  SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+  SVN_TEST_ASSERT(!status->copied);
+  SVN_TEST_ASSERT(!status->switched);
+  SVN_TEST_ASSERT(!status->file_external);
+  SVN_TEST_ASSERT(status->moved_from_abspath == NULL);
+  SVN_TEST_STRING_ASSERT(status->moved_to_abspath,
+                         sbox_wc_path(b, "A/B-also-moved"));
+
+  /* Ensure that the merged directory has the expected status. */
+  SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, "A/B-also-moved"),
+                             &opt_rev, svn_depth_empty, TRUE, TRUE,
+                             TRUE, TRUE, FALSE, TRUE, NULL,
+                             status_func, &sb, b->pool));
+  status = sb.status;
+  SVN_TEST_ASSERT(status->kind == svn_node_dir);
+  SVN_TEST_ASSERT(status->versioned);
+  SVN_TEST_ASSERT(!status->conflicted);
+  SVN_TEST_ASSERT(status->node_status == svn_wc_status_added);
+  SVN_TEST_ASSERT(status->text_status == svn_wc_status_normal);
+  SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+  SVN_TEST_ASSERT(status->copied);
+  SVN_TEST_ASSERT(!status->switched);
+  SVN_TEST_ASSERT(!status->file_external);
+  SVN_TEST_STRING_ASSERT(status->moved_from_abspath,
+                         sbox_wc_path(b, "A/B-moved"));
+  SVN_TEST_ASSERT(status->moved_to_abspath == NULL);
+
+  /* Make sure the edited files have the expected content. */
+  SVN_ERR(svn_stringbuf_from_file2(&buf,
+                                   sbox_wc_path(b, "A/B-also-moved/lambda"),
+                                   pool));
+  SVN_TEST_STRING_ASSERT(buf->data, modified_file_content);
+  SVN_ERR(svn_stringbuf_from_file2(&buf,
+                                   sbox_wc_path(b, "A/B-also-moved/E/alpha"),
+                                   pool));
+  SVN_TEST_STRING_ASSERT(buf->data, modified_file_content);
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+create_file_move_vs_file_move_update_conflict(svn_client_conflict_t **conflict,
+                                              svn_test__sandbox_t *b,
+                                              svn_client_ctx_t *ctx)
+{
+  apr_array_header_t *options;
+  svn_client_conflict_option_t *option;
+  apr_array_header_t *possible_moved_to_abspaths;
+
+  /* Move a file. */
+  SVN_ERR(sbox_wc_move(b, "A/mu", "A/mu-moved"));
+
+  /* Edit moved file. */
+  SVN_ERR(sbox_file_write(b, "A/mu-moved", modified_file_content));
+  SVN_ERR(sbox_wc_commit(b, ""));
+
+  /* Update back to r1, */
+  SVN_ERR(sbox_wc_update(b, "", 1)); /* r2 */
+
+  /* Copy the file to test handling of ambiguous moves. */
+  SVN_ERR(sbox_wc_copy(b, "A/mu", "A/mu-copied"));
+
+  /* Move the same file to a different location. */
+  SVN_ERR(sbox_wc_move(b, "A/mu", "A/mu-also-moved"));
+
+  /* Edit moved file. */
+  SVN_ERR(sbox_file_write(b, "A/mu-also-moved",
+                          modified_file_in_working_copy_content));
+
+  /* Update to r2. */
+  /* This should raise an "incoming delete vs local delete" tree conflict. */
+  SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM));
+
+  SVN_ERR(svn_client_conflict_get(conflict, sbox_wc_path(b, "A/mu"),
+                                  ctx, b->pool, b->pool));
+  {
+    svn_client_conflict_option_id_t expected_opts[] = {
+      svn_client_conflict_option_postpone,
+      svn_client_conflict_option_accept_current_wc_state,
+      svn_client_conflict_option_incoming_delete_ignore,
+      svn_client_conflict_option_incoming_delete_accept,
+      -1 /* end of list */
+    };
+    SVN_ERR(assert_tree_conflict_options(*conflict, ctx, expected_opts,
+                                         b->pool));
+  }
+
+  SVN_ERR(svn_client_conflict_tree_get_details(*conflict, ctx, b->pool));
+  {
+    svn_client_conflict_option_id_t expected_opts[] = {
+      svn_client_conflict_option_postpone,
+      svn_client_conflict_option_accept_current_wc_state,
+      svn_client_conflict_option_both_moved_file_merge,
+      svn_client_conflict_option_both_moved_file_move_merge,
+      -1 /* end of list */
+    };
+    SVN_ERR(assert_tree_conflict_options(*conflict, ctx, expected_opts,
+                                         b->pool));
+  }
+
+  /* Check possible move destinations for the file. */
+  SVN_ERR(svn_client_conflict_tree_get_resolution_options(&options, *conflict,
+                                                          ctx, b->pool,
+                                                          b->pool));
+  option = svn_client_conflict_option_find_by_id(
+             options, svn_client_conflict_option_both_moved_file_merge);
+  SVN_TEST_ASSERT(option != NULL);
+
+  SVN_ERR(svn_client_conflict_option_get_moved_to_abspath_candidates(
+            &possible_moved_to_abspaths, option, b->pool, b->pool));
+
+  /* The resolver finds two possible destinations for the moved file:
+   *
+   *   Possible working copy destinations for moved-away 'A/mu' are:
+   *    (1): 'A/mu-also-moved'
+   *    (2): 'A/mu-copied'
+   *   Only one destination can be a move; the others are copies.
+   */
+  SVN_TEST_INT_ASSERT(possible_moved_to_abspaths->nelts, 2);
+  SVN_TEST_STRING_ASSERT(
+    APR_ARRAY_IDX(possible_moved_to_abspaths, 0, const char *),
+    sbox_wc_path(b, "A/mu-also-moved"));
+  SVN_TEST_STRING_ASSERT(
+    APR_ARRAY_IDX(possible_moved_to_abspaths, 1, const char *),
+    sbox_wc_path(b, "A/mu-copied"));
+
+  return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+test_update_file_move_vs_file_move(const svn_test_opts_t *opts,
+                                   apr_pool_t *pool)
+{
+  svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b));
+  svn_client_ctx_t *ctx;
+  svn_client_conflict_t *conflict;
+  svn_opt_revision_t opt_rev;
+  struct status_baton sb;
+  struct svn_client_status_t *status;
+  svn_stringbuf_t *buf;
+  svn_node_kind_t kind;
+  char *conflicted_content;
+
+  SVN_ERR(svn_test__sandbox_create(b, "update_file_move_vs_file_move",
+                                   opts, pool));
+
+  SVN_ERR(sbox_add_and_commit_greek_tree(b)); /* r1 */
+
+  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+  SVN_ERR(create_file_move_vs_file_move_update_conflict(&conflict, b, ctx));
+
+  SVN_ERR(svn_client_conflict_tree_resolve_by_id(
+            conflict,
+            svn_client_conflict_option_both_moved_file_merge,
+            ctx, b->pool));
+
+  /* The node "A/mu" should no longer exist. */
+  SVN_TEST_ASSERT_ERROR(svn_client_conflict_get(
+                          &conflict, sbox_wc_path(b, "A/mu"), ctx, pool, pool),
+                        SVN_ERR_WC_PATH_NOT_FOUND);
+
+  /* The node "A/mu-moved" should now have moved to "A/mu-also-moved. */
+  SVN_ERR(svn_io_check_path(sbox_wc_path(b, "A/mu"), &kind, b->pool));
+  SVN_TEST_ASSERT(kind == svn_node_none);
+  opt_rev.kind = svn_opt_revision_working;
+  sb.result_pool = b->pool;
+  SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, "A/mu-moved"),
+                             &opt_rev, svn_depth_unknown, TRUE, TRUE,
+                             TRUE, TRUE, FALSE, TRUE, NULL,
+                             status_func, &sb, b->pool));
+  status = sb.status;
+  SVN_TEST_ASSERT(status->kind == svn_node_file);
+  SVN_TEST_ASSERT(status->versioned);
+  SVN_TEST_ASSERT(!status->conflicted);
+  SVN_TEST_ASSERT(status->node_status == svn_wc_status_deleted);
+  SVN_TEST_ASSERT(status->text_status == svn_wc_status_normal);
+  SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+  SVN_TEST_ASSERT(!status->copied);
+  SVN_TEST_ASSERT(!status->switched);
+  SVN_TEST_ASSERT(!status->file_external);
+  SVN_TEST_ASSERT(status->moved_from_abspath == NULL);
+  SVN_TEST_STRING_ASSERT(status->moved_to_abspath,
+                         sbox_wc_path(b, "A/mu-also-moved"));
+
+  /* Ensure that the merged file has the expected status. */
+  opt_rev.kind = svn_opt_revision_working;
+  sb.result_pool = b->pool;
+  SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, "A/mu-also-moved"),
+                             &opt_rev, svn_depth_unknown, TRUE, TRUE,
+                             TRUE, TRUE, FALSE, TRUE, NULL,
+                             status_func, &sb, b->pool));
+  status = sb.status;
+  SVN_TEST_ASSERT(status->kind == svn_node_file);
+  SVN_TEST_ASSERT(status->versioned);
+  SVN_TEST_ASSERT(status->conflicted);
+  SVN_TEST_ASSERT(status->node_status == svn_wc_status_conflicted);
+  SVN_TEST_ASSERT(status->text_status == svn_wc_status_conflicted);
+  SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+  SVN_TEST_ASSERT(status->copied);
+  SVN_TEST_ASSERT(!status->switched);
+  SVN_TEST_ASSERT(!status->file_external);
+  SVN_TEST_STRING_ASSERT(status->moved_from_abspath,
+                         sbox_wc_path(b, "A/mu-moved"));
+  SVN_TEST_ASSERT(status->moved_to_abspath == NULL);
+
+  /* Ensure that the moved+merged file has the expected content. */
+  SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, "A/mu-also-moved"),
+                                   b->pool));
+  conflicted_content = apr_psprintf(b->pool,
+												 "<<<<<<< .working\n"
+												"%s"
+												"||||||| .old\n"
+												"This is the file 'mu'.\n"
+												"=======\n"
+												"%s"
+												">>>>>>> .new\n",
+									      modified_file_in_working_copy_content,
+												modified_file_content);
+  SVN_TEST_STRING_ASSERT(buf->data, conflicted_content);
+
+  return SVN_NO_ERROR;
+}
+
+/* Same test case as above, but accept the incoming move. */
+static svn_error_t *
+test_update_file_move_vs_file_move_accept_move(const svn_test_opts_t *opts,
+                                               apr_pool_t *pool)
+{
+  svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b));
+  svn_client_ctx_t *ctx;
+  svn_client_conflict_t *conflict;
+  svn_opt_revision_t opt_rev;
+  struct status_baton sb;
+  struct svn_client_status_t *status;
+  svn_stringbuf_t *buf;
+  char *conflicted_content;
+
+  SVN_ERR(svn_test__sandbox_create(b,
+                                   "update_file_move_vs_file_move_accept_move",
+                                   opts, pool));
+
+  SVN_ERR(sbox_add_and_commit_greek_tree(b)); /* r1 */
+
+  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+  SVN_ERR(create_file_move_vs_file_move_update_conflict(&conflict, b, ctx));
+
+  SVN_ERR(svn_client_conflict_tree_resolve_by_id(
+            conflict,
+            svn_client_conflict_option_both_moved_file_move_merge,
+            ctx, b->pool));
+
+  /* The node "A/mu" should no longer exist. */
+  SVN_TEST_ASSERT_ERROR(svn_client_conflict_get(
+                          &conflict, sbox_wc_path(b, "A/mu"), ctx, pool, pool),
+                        SVN_ERR_WC_PATH_NOT_FOUND);
+
+  /* The node "A/mu-also-moved" should not exist. */
+  SVN_TEST_ASSERT_ERROR(svn_client_conflict_get(
+                          &conflict, sbox_wc_path(b, "A/mu-also-moved"), ctx,
+                          pool, pool),
+                        SVN_ERR_WC_PATH_NOT_FOUND);
+
+  /* Ensure that the merged file has the expected status. */
+  opt_rev.kind = svn_opt_revision_working;
+  sb.result_pool = b->pool;
+  SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, "A/mu-moved"),
+                             &opt_rev, svn_depth_unknown, TRUE, TRUE,
+                             TRUE, TRUE, FALSE, TRUE, NULL,
+                             status_func, &sb, b->pool));
+  status = sb.status;
+  SVN_TEST_ASSERT(status->kind == svn_node_file);
+  SVN_TEST_ASSERT(status->versioned);
+  SVN_TEST_ASSERT(status->conflicted);
+  SVN_TEST_ASSERT(status->node_status == svn_wc_status_conflicted);
+  SVN_TEST_ASSERT(status->text_status == svn_wc_status_conflicted);
+  SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+  SVN_TEST_ASSERT(!status->copied);
+  SVN_TEST_ASSERT(!status->switched);
+  SVN_TEST_ASSERT(!status->file_external);
+  SVN_TEST_ASSERT(status->moved_from_abspath == NULL);
+  SVN_TEST_ASSERT(status->moved_to_abspath == NULL);
+
+  /* Ensure that the moved+merged file has the expected content. */
+  SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, "A/mu-moved"),
+                                   b->pool));
+  conflicted_content = apr_psprintf(b->pool,
+												 "<<<<<<< .working\n" /* ### labels need fixing */
+												"%s"
+												"||||||| .old\n"
+												"This is the file 'mu'.\n"
+												"=======\n"
+												"%s"
+												">>>>>>> .new\n",
+												modified_file_content,
+									      modified_file_in_working_copy_content);
+  SVN_TEST_STRING_ASSERT(buf->data, conflicted_content);
+
+  return SVN_NO_ERROR;
+}
+
+
 /* ========================================================================== */
 
 
@@ -7066,6 +7579,14 @@ static struct svn_test_descriptor_t test
                        "file move vs file edit-move during merge"),
     SVN_TEST_OPTS_PASS(test_merge_file_edit_move_vs_file_move_accept_move,
                        "file edit-move vs file move merge accept move"),
+    SVN_TEST_OPTS_PASS(test_merge_dir_move_vs_dir_move,
+                       "dir move vs dir move during merge"),
+    SVN_TEST_OPTS_PASS(test_merge_dir_move_vs_dir_move_accept_move,
+                       "dir move vs dir move during merge accept move"),
+    SVN_TEST_OPTS_PASS(test_update_file_move_vs_file_move,
+                       "file move vs file move during update"),
+    SVN_TEST_OPTS_PASS(test_update_file_move_vs_file_move_accept_move,
+                       "file move vs file move during update accept move"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/swig-py3/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/libsvn_fs/fs-test.c?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/swig-py3/subversion/tests/libsvn_fs/fs-test.c Mon Jul  8 15:19:03 2019
@@ -7441,6 +7441,34 @@ test_closest_copy_file_replaced_with_dir
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_unrecognized_ioctl(const svn_test_opts_t *opts,
+                        apr_pool_t *pool)
+{
+  svn_fs_t *fs;
+  svn_error_t *err;
+  svn_fs_ioctl_code_t code = {0};
+
+  SVN_ERR(svn_test__create_fs(&fs, "test-unrecognized-ioctl", opts, pool));
+
+  code.fs_type = "NON-EXISTING";
+  code.code = 98765;
+  err = svn_fs_ioctl(fs, code, NULL, NULL, NULL, NULL, pool, pool);
+  SVN_TEST_ASSERT_ERROR(err, SVN_ERR_FS_UNRECOGNIZED_IOCTL_CODE);
+
+  code.fs_type = "NON-EXISTING";
+  code.code = 98765;
+  err = svn_fs_ioctl(NULL, code, NULL, NULL, NULL, NULL, pool, pool);
+  SVN_TEST_ASSERT_ERROR(err, SVN_ERR_FS_UNKNOWN_FS_TYPE);
+
+  code.fs_type = opts->fs_type;
+  code.code = 98765;
+  err = svn_fs_ioctl(NULL, code, NULL, NULL, NULL, NULL, pool, pool);
+  SVN_TEST_ASSERT_ERROR(err, SVN_ERR_FS_UNRECOGNIZED_IOCTL_CODE);
+
+  return SVN_NO_ERROR;
+}
+
 /* ------------------------------------------------------------------------ */
 
 /* The test table.  */
@@ -7587,6 +7615,8 @@ static struct svn_test_descriptor_t test
                        "test issue SVN-4677 regression"),
     SVN_TEST_OPTS_PASS(test_closest_copy_file_replaced_with_dir,
                        "svn_fs_closest_copy after replacing file with dir"),
+    SVN_TEST_OPTS_PASS(test_unrecognized_ioctl,
+                       "test svn_fs_ioctl with unrecognized code"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/swig-py3/subversion/tests/libsvn_fs/locks-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/libsvn_fs/locks-test.c?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/libsvn_fs/locks-test.c (original)
+++ subversion/branches/swig-py3/subversion/tests/libsvn_fs/locks-test.c Mon Jul  8 15:19:03 2019
@@ -1089,6 +1089,9 @@ lock_cb_error(const svn_test_opts_t *opt
   return SVN_NO_ERROR;
 }
 
+/* XXX NOTE:
+   This test will fail on most Unix-like systems when run as the
+   root user, because flock() will ignore file permissions. */
 static svn_error_t *
 obtain_write_lock_failure(const svn_test_opts_t *opts,
                           apr_pool_t *pool)

Modified: subversion/branches/swig-py3/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c (original)
+++ subversion/branches/swig-py3/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c Mon Jul  8 15:19:03 2019
@@ -199,8 +199,10 @@ get_repo_stats(const svn_test_opts_t *op
   svn_repos_t *repos;
   svn_revnum_t rev;
   apr_size_t i;
-  svn_fs_fs__stats_t *stats;
   svn_fs_fs__extension_info_t *extension_info;
+  svn_fs_fs__ioctl_get_stats_input_t input = {0};
+  svn_fs_fs__ioctl_get_stats_output_t *output;
+  const svn_fs_fs__stats_t *stats;
 
   /* Bail (with success) on known-untestable scenarios */
   if (strcmp(opts->fs_type, "fsfs") != 0)
@@ -211,8 +213,9 @@ get_repo_stats(const svn_test_opts_t *op
   SVN_ERR(create_greek_repo(&repos, &rev, opts, REPO_NAME, pool, pool));
 
   /* Gather statistics info on that repo. */
-  SVN_ERR(svn_fs_fs__get_stats(&stats, svn_repos_fs(repos), NULL, NULL,
-                               NULL, NULL, pool, pool));
+  SVN_ERR(svn_fs_ioctl(svn_repos_fs(repos), SVN_FS_FS__IOCTL_GET_STATS,
+                       &input, (void**)&output, NULL, NULL, pool, pool));
+  stats = output->stats;
 
   /* Check that the stats make sense. */
   SVN_TEST_ASSERT(stats->total_size > 1000 && stats->total_size < 10000);
@@ -324,6 +327,7 @@ dump_index(const svn_test_opts_t *opts,
   svn_repos_t *repos;
   svn_revnum_t rev;
   dump_baton_t baton;
+  svn_fs_fs__ioctl_dump_index_input_t input = {0};
 
   /* Bail (with success) on known-untestable scenarios */
   if (strcmp(opts->fs_type, "fsfs") != 0)
@@ -342,8 +346,12 @@ dump_index(const svn_test_opts_t *opts,
   baton.offset = 0;
   baton.revision = rev;
   baton.numbers_seen = svn_bit_array__create(100, pool);
-  SVN_ERR(svn_fs_fs__dump_index(svn_repos_fs(repos), rev, dump_index_entry,
-                                &baton, NULL, NULL, pool));
+
+  input.revision = rev;
+  input.callback_func = dump_index_entry;
+  input.callback_baton = &baton;
+  SVN_ERR(svn_fs_ioctl(svn_repos_fs(repos), SVN_FS_FS__IOCTL_DUMP_INDEX,
+                       &input, NULL, NULL, NULL, pool, pool));
 
   /* Check that we've got all data (20 noderevs + 20 reps + 1 changes list). */
   SVN_TEST_ASSERT(baton.invocations == 41);
@@ -377,6 +385,8 @@ load_index(const svn_test_opts_t *opts,
   apr_array_header_t *entries = apr_array_make(pool, 41, sizeof(void *));
   apr_array_header_t *alt_entries = apr_array_make(pool, 1, sizeof(void *));
   svn_fs_fs__p2l_entry_t entry;
+  svn_fs_fs__ioctl_dump_index_input_t dump_input = {0};
+  svn_fs_fs__ioctl_load_index_input_t load_input = {0};
 
   /* Bail (with success) on known-untestable scenarios */
   if (strcmp(opts->fs_type, "fsfs") != 0)
@@ -391,8 +401,11 @@ load_index(const svn_test_opts_t *opts,
   SVN_ERR(create_greek_repo(&repos, &rev, opts, REPO_NAME, pool, pool));
 
   /* Read the original index contents for REV in ENTRIES. */
-  SVN_ERR(svn_fs_fs__dump_index(svn_repos_fs(repos), rev, receive_index,
-                                entries, NULL, NULL, pool));
+  dump_input.revision = rev;
+  dump_input.callback_func = receive_index;
+  dump_input.callback_baton = entries;
+  SVN_ERR(svn_fs_ioctl(svn_repos_fs(repos), SVN_FS_FS__IOCTL_DUMP_INDEX,
+                       &dump_input, NULL, NULL, NULL, pool, pool));
 
   /* Replace it with an index that declares the whole revision contents as
    * "unused". */
@@ -404,14 +417,21 @@ load_index(const svn_test_opts_t *opts,
   entry.item.revision = SVN_INVALID_REVNUM;
   APR_ARRAY_PUSH(alt_entries, svn_fs_fs__p2l_entry_t *) = &entry;
 
-  SVN_ERR(svn_fs_fs__load_index(svn_repos_fs(repos), rev, alt_entries, pool));
+  load_input.revision = rev;
+  load_input.entries = alt_entries;
+  SVN_ERR(svn_fs_ioctl(svn_repos_fs(repos), SVN_FS_FS__IOCTL_LOAD_INDEX,
+                       &load_input, NULL, NULL, NULL, pool, pool));
+
   SVN_TEST_ASSERT_ERROR(svn_repos_verify_fs3(repos, rev, rev, FALSE, FALSE,
                                              NULL, NULL, NULL, NULL, NULL,
                                              NULL, pool),
                         SVN_ERR_FS_INDEX_CORRUPTION);
 
   /* Restore the original index. */
-  SVN_ERR(svn_fs_fs__load_index(svn_repos_fs(repos), rev, entries, pool));
+  load_input.revision = rev;
+  load_input.entries = entries;
+  SVN_ERR(svn_fs_ioctl(svn_repos_fs(repos), SVN_FS_FS__IOCTL_LOAD_INDEX,
+                       &load_input, NULL, NULL, NULL, pool, pool));
   SVN_ERR(svn_repos_verify_fs3(repos, rev, rev, FALSE, FALSE, NULL, NULL,
                                NULL, NULL, NULL, NULL, pool));
 

Modified: subversion/branches/swig-py3/subversion/tests/libsvn_ra/ra-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/libsvn_ra/ra-test.c?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/libsvn_ra/ra-test.c (original)
+++ subversion/branches/swig-py3/subversion/tests/libsvn_ra/ra-test.c Mon Jul  8 15:19:03 2019
@@ -94,6 +94,41 @@ commit_changes(svn_ra_session_t *session
   return SVN_NO_ERROR;
 }
 
+/* Commit two revisions: add 'B', then delete 'A' */
+static svn_error_t *
+commit_two_changes(svn_ra_session_t *session,
+                   apr_pool_t *pool)
+{
+  apr_hash_t *revprop_table = apr_hash_make(pool);
+  const svn_delta_editor_t *editor;
+  void *edit_baton;
+  void *root_baton, *dir_baton;
+
+  /* mkdir B */
+  SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton,
+                                    revprop_table,
+                                    NULL, NULL, NULL, TRUE, pool));
+  SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM,
+                            pool, &root_baton));
+  SVN_ERR(editor->add_directory("B", root_baton, NULL, SVN_INVALID_REVNUM,
+                               pool, &dir_baton));
+  SVN_ERR(editor->close_directory(dir_baton, pool));
+  SVN_ERR(editor->close_directory(root_baton, pool));
+  SVN_ERR(editor->close_edit(edit_baton, pool));
+
+  /* delete A */
+  SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton,
+                                    revprop_table,
+                                    NULL, NULL, NULL, TRUE, pool));
+  SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM,
+                            pool, &root_baton));
+  SVN_ERR(editor->delete_entry("A", SVN_INVALID_REVNUM, root_baton, pool));
+  SVN_ERR(editor->close_directory(root_baton, pool));
+  SVN_ERR(editor->close_edit(edit_baton, pool));
+
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 commit_tree(svn_ra_session_t *session,
             apr_pool_t *pool)
@@ -1784,6 +1819,63 @@ commit_locked_file(const svn_test_opts_t
   return SVN_NO_ERROR;
 }
 
+/* Cases of 'get-deleted-rev' that should return SVN_INVALID_REVNUM. */
+static svn_error_t *
+test_get_deleted_rev_no_delete(const svn_test_opts_t *opts,
+                               apr_pool_t *pool)
+{
+  svn_ra_session_t *ra_session;
+  svn_revnum_t revision_deleted;
+
+  SVN_ERR(make_and_open_repos(&ra_session,
+                              "test-repo-get-deleted-rev-no-delete", opts,
+                              pool));
+  SVN_ERR(commit_changes(ra_session, pool));
+  SVN_ERR(commit_two_changes(ra_session, pool));
+
+  /* expect 'no deletion' in the range up to r2, when it is deleted in r3 */
+  /* This was failing over RA-SVN where the 'get-deleted-rev' wire command's
+     prototype cannot directly represent that result. A new enough client and
+     server collaborate on a work-around implemented using an error code. */
+  SVN_ERR(svn_ra_get_deleted_rev(ra_session, "A", 1, 2,
+                                 &revision_deleted, pool));
+  SVN_TEST_INT_ASSERT(revision_deleted, SVN_INVALID_REVNUM);
+
+  /* this connection should still be open: a simple case should still work */
+  SVN_ERR(svn_ra_get_deleted_rev(ra_session, "A", 1, 3,
+                                 &revision_deleted, pool));
+  SVN_TEST_INT_ASSERT(revision_deleted, 3);
+
+  return SVN_NO_ERROR;
+}
+
+/* Cases of 'get-deleted-rev' that should return an error. */
+static svn_error_t *
+test_get_deleted_rev_errors(const svn_test_opts_t *opts,
+                               apr_pool_t *pool)
+{
+  svn_ra_session_t *ra_session;
+  svn_revnum_t revision_deleted;
+  svn_error_t *err;
+
+  SVN_ERR(make_and_open_repos(&ra_session,
+                              "test-repo-get-deleted-rev-errors", opts, pool));
+  SVN_ERR(commit_changes(ra_session, pool));
+
+  /* expect an error when searching up to r3, when repository head is r1 */
+  err = svn_ra_get_deleted_rev(ra_session, "A", 1, 3, &revision_deleted, pool);
+
+  /* mod_dav_svn returns a generic error code for "500 Internal Server Error";
+   * the other RA layers return the specific error code for "no such revision".
+   * We should make these consistent, but for now that's how it is. */
+  if (opts->repos_url && strncmp(opts->repos_url, "http", 4) == 0)
+    SVN_TEST_ASSERT_ERROR(err, SVN_ERR_RA_DAV_REQUEST_FAILED);
+  else
+    SVN_TEST_ASSERT_ERROR(err, SVN_ERR_FS_NO_SUCH_REVISION);
+
+  return SVN_NO_ERROR;
+}
+
 
 /* The test table.  */
 
@@ -1820,6 +1912,10 @@ static struct svn_test_descriptor_t test
                        "check how last change applies to empty commit"),
     SVN_TEST_OPTS_PASS(commit_locked_file,
                        "check commit editor for a locked file"),
+    SVN_TEST_OPTS_PASS(test_get_deleted_rev_no_delete,
+                       "test get-deleted-rev no delete"),
+    SVN_TEST_OPTS_PASS(test_get_deleted_rev_errors,
+                       "test get-deleted-rev errors"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/swig-py3/subversion/tests/libsvn_repos/authz-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/libsvn_repos/authz-test.c?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/libsvn_repos/authz-test.c (original)
+++ subversion/branches/swig-py3/subversion/tests/libsvn_repos/authz-test.c Mon Jul  8 15:19:03 2019
@@ -212,7 +212,7 @@ test_authz_parse(const svn_test_opts_t *
                            APR_READ, APR_OS_DEFAULT,
                            pool));
   groups = svn_stream_from_aprfile2(groups_file, FALSE, pool);
-  SVN_ERR(svn_authz__parse(&authz, rules, groups, pool, pool));
+  SVN_ERR(svn_authz__parse(&authz, rules, groups, NULL, NULL, pool, pool));
 
   printf("Access check for ('%s', '%s')\n", check_user, check_repo);
 
@@ -304,7 +304,7 @@ run_global_rights_tests(const char *cont
 
   svn_stringbuf_t *buffer = svn_stringbuf_create(contents, pool);
   svn_stream_t *stream = svn_stream_from_stringbuf(buffer, pool);
-  SVN_ERR(svn_repos_authz_parse(&authz, stream, NULL, pool));
+  SVN_ERR(svn_repos_authz_parse2(&authz, stream, NULL, NULL, NULL, pool, pool));
 
   for (; test_cases->repos; ++test_cases)
     {
@@ -463,7 +463,7 @@ issue_4741_groups(apr_pool_t *pool)
    svn_authz_t *authz;
    svn_boolean_t access_granted;
 
-   SVN_ERR(svn_repos_authz_parse(&authz, stream, NULL, pool));
+   SVN_ERR(svn_repos_authz_parse2(&authz, stream, NULL, NULL, NULL, pool, pool));
 
    SVN_ERR(svn_repos_authz_check_access(authz, "repo", "/", "userA",
                                         svn_authz_write, &access_granted,
@@ -500,7 +500,7 @@ reposful_reposless_stanzas_inherit(apr_p
    svn_authz_t *authz;
    svn_boolean_t access_granted;
 
-   SVN_ERR(svn_repos_authz_parse(&authz, stream, NULL, pool));
+   SVN_ERR(svn_repos_authz_parse2(&authz, stream, NULL, NULL, NULL, pool, pool));
 
    SVN_ERR(svn_repos_authz_check_access(authz, "project1", "/foo", "user1",
                                         svn_authz_write | svn_authz_recursive,

Modified: subversion/branches/swig-py3/subversion/tests/libsvn_subr/dirent_uri-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/libsvn_subr/dirent_uri-test.c?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/libsvn_subr/dirent_uri-test.c (original)
+++ subversion/branches/swig-py3/subversion/tests/libsvn_subr/dirent_uri-test.c Mon Jul  8 15:19:03 2019
@@ -36,6 +36,7 @@
 
 #include "svn_pools.h"
 #include "svn_dirent_uri.h"
+#include "private/svn_dirent_uri_private.h"
 #include "private/svn_fspath.h"
 #include "private/svn_cert.h"
 
@@ -2331,11 +2332,12 @@ test_relpath_internal_style(apr_pool_t *
 
   for (i = 0; i < COUNT_OF(tests); i++)
     {
-      const char *internal = svn_relpath__internal_style(tests[i].path, pool);
+      const char *internal;
+      SVN_ERR(svn_relpath__make_internal(&internal, tests[i].path, pool, pool));
 
       if (strcmp(internal, tests[i].result))
         return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
-                                 "svn_relpath__internal_style(\"%s\") returned "
+                                 "svn_relpath__make_internal(\"%s\") returned "
                                  "\"%s\" expected \"%s\"",
                                  tests[i].path, internal, tests[i].result);
     }

Modified: subversion/branches/swig-py3/subversion/tests/libsvn_subr/io-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/libsvn_subr/io-test.c?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/libsvn_subr/io-test.c (original)
+++ subversion/branches/swig-py3/subversion/tests/libsvn_subr/io-test.c Mon Jul  8 15:19:03 2019
@@ -211,6 +211,38 @@ create_comparison_candidates(struct test
   return err;
 }
 
+/* Create an on-disk tree with optional read-only attributes on some
+   files and/or directories. */
+static svn_error_t *
+create_dir_tree(const char **dir_path,
+                const char *testname,
+                svn_boolean_t dir_readonly,
+                svn_boolean_t file_readonly,
+                apr_pool_t *pool)
+{
+  const char *test_dir_path;
+  const char *sub_dir_path;
+  const char *file_path;
+
+  SVN_ERR(svn_test_make_sandbox_dir(&test_dir_path, testname, pool));
+
+  sub_dir_path = svn_dirent_join(test_dir_path, "dir", pool);
+  SVN_ERR(svn_io_dir_make(sub_dir_path, APR_OS_DEFAULT, pool));
+
+  file_path = svn_dirent_join(sub_dir_path, "file", pool);
+  SVN_ERR(svn_io_file_create_empty(file_path, pool));
+
+  if (file_readonly)
+    SVN_ERR(svn_io_set_file_read_only(file_path, FALSE, pool));
+
+  if (dir_readonly)
+    SVN_ERR(svn_io_set_file_read_only(sub_dir_path, FALSE, pool));
+
+  *dir_path = sub_dir_path;
+  return SVN_NO_ERROR;
+}
+
+
 
 /* Functions to check the 2-way and 3-way file comparison functions.  */
 
@@ -1147,6 +1179,56 @@ test_apr_trunc_workaround(apr_pool_t *po
   return SVN_NO_ERROR;  
 }
 
+
+/* Issue #4806 */
+static svn_error_t *
+test_rmtree_all_writable(apr_pool_t *pool)
+{
+  const char *dir_path = NULL;
+
+  SVN_ERR(create_dir_tree(&dir_path, "test_rmtree_all_writable",
+                          FALSE, FALSE, pool));
+  SVN_ERR(svn_io_remove_dir2(dir_path, FALSE, NULL, NULL, pool));
+  return SVN_NO_ERROR;
+}
+
+/* Issue #4806 */
+static svn_error_t *
+test_rmtree_file_readonly(apr_pool_t *pool)
+{
+  const char *dir_path = NULL;
+
+  SVN_ERR(create_dir_tree(&dir_path, "test_rmtree_file_readonly",
+                          FALSE, TRUE, pool));
+  SVN_ERR(svn_io_remove_dir2(dir_path, FALSE, NULL, NULL, pool));
+  return SVN_NO_ERROR;
+}
+
+/* Issue #4806 */
+static svn_error_t *
+test_rmtree_dir_readonly(apr_pool_t *pool)
+{
+  const char *dir_path = NULL;
+
+  SVN_ERR(create_dir_tree(&dir_path, "test_rmtree_dir_readonly",
+                          TRUE, FALSE, pool));
+  SVN_ERR(svn_io_remove_dir2(dir_path, FALSE, NULL, NULL, pool));
+  return SVN_NO_ERROR;
+}
+
+/* Issue #4806 */
+static svn_error_t *
+test_rmtree_all_readonly(apr_pool_t *pool)
+{
+  const char *dir_path = NULL;
+
+  SVN_ERR(create_dir_tree(&dir_path, "test_rmtree_all_readonly",
+                          TRUE, TRUE, pool));
+  SVN_ERR(svn_io_remove_dir2(dir_path, FALSE, NULL, NULL, pool));
+  return SVN_NO_ERROR;
+}
+
+
 /* The test table.  */
 
 static int max_threads = 3;
@@ -1184,6 +1266,14 @@ static struct svn_test_descriptor_t test
                    "test svn_io_open_uniquely_named()"),
     SVN_TEST_PASS2(test_apr_trunc_workaround,
                    "test workaround for APR in svn_io_file_trunc"),
+    SVN_TEST_PASS2(test_rmtree_all_writable,
+                   "test svn_io_remove_dir2() with writable tree"),
+    SVN_TEST_PASS2(test_rmtree_file_readonly,
+                   "test svn_io_remove_dir2() with read-only file"),
+    SVN_TEST_PASS2(test_rmtree_dir_readonly,
+                   "test svn_io_remove_dir2() with read-only directory"),
+    SVN_TEST_PASS2(test_rmtree_all_readonly,
+                   "test svn_io_remove_dir2() with read-only tree"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/swig-py3/subversion/tests/libsvn_wc/wc-queries-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/tests/libsvn_wc/wc-queries-test.c (original)
+++ subversion/branches/swig-py3/subversion/tests/libsvn_wc/wc-queries-test.c Mon Jul  8 15:19:03 2019
@@ -100,6 +100,7 @@ static const int slow_statements[] =
   STMT_SELECT_UPDATE_MOVE_LIST,
   STMT_FIND_REPOS_PATH_IN_WC,
   STMT_SELECT_PRESENT_HIGHEST_WORKING_NODES_BY_BASENAME_AND_KIND,
+  STMT_SELECT_COPIES_OF_REPOS_RELPATH,
 
   /* Designed as slow to avoid penalty on other queries */
   STMT_SELECT_UNREFERENCED_PRISTINES,
@@ -266,6 +267,14 @@ struct explanation_item
   const char *compound_right;
   svn_boolean_t create_btree;
 
+  svn_boolean_t create_union;
+  svn_boolean_t union_all;
+
+  svn_boolean_t merge;
+
+  svn_boolean_t multi_index;
+  svn_boolean_t multi_index_or;
+
   int expression_vars;
   int expected_rows;
 };
@@ -312,6 +321,18 @@ parse_explanation_item(struct explanatio
           item->table = apr_psprintf(result_pool, "SUBQUERY-%s",
                                      apr_strtok(NULL, " ", &last));
         }
+      else if (MATCH_TOKEN(token, "CONSTANT"))
+        {
+          item->table = "sqlite_master"; /* not worth checking. 
+                                            Just a lookup */
+          token = apr_strtok(NULL, " ", &last);
+          if (!MATCH_TOKEN(token, "ROW"))
+            {
+              printf("DBG: Expected 'ROW', got '%s' in '%s'\n",
+                     token, text);
+              return SVN_NO_ERROR;
+            }
+        }
       else
         {
           printf("DBG: Expected 'TABLE', got '%s' in '%s'\n", token, text);
@@ -433,39 +454,44 @@ parse_explanation_item(struct explanatio
       /* Handling temporary table (E.g. UNION) */
 
       token = apr_strtok(NULL, " ", &last);
-      if (!MATCH_TOKEN(token, "SUBQUERIES"))
-        {
-          printf("DBG: Expected 'SUBQUERIES', got '%s' in '%s'\n", token,
-                 text);
-          return SVN_NO_ERROR;
-        }
-
-      item->compound_left = apr_strtok(NULL, " ", &last);
-      token = apr_strtok(NULL, " ", &last);
-
-      if (!MATCH_TOKEN(token, "AND"))
-        {
-          printf("DBG: Expected 'AND', got '%s' in '%s'\n", token, text);
-          return SVN_NO_ERROR;
-        }
-
-      item->compound_right = apr_strtok(NULL, " ", &last);
-
-      token = apr_strtok(NULL, " ", &last);
-      if (MATCH_TOKEN(token, "USING"))
+      if (MATCH_TOKEN(token, "SUBQUERIES"))
         {
+          item->compound_left = apr_strtok(NULL, " ", &last);
           token = apr_strtok(NULL, " ", &last);
-          if (!MATCH_TOKEN(token, "TEMP"))
+
+          if (!MATCH_TOKEN(token, "AND"))
             {
-              printf("DBG: Expected 'TEMP', got '%s' in '%s'\n", token, text);
+              printf("DBG: Expected 'AND', got '%s' in '%s'\n", token, text);
+              return SVN_NO_ERROR;
             }
+
+          item->compound_right = apr_strtok(NULL, " ", &last);
+
           token = apr_strtok(NULL, " ", &last);
-          if (!MATCH_TOKEN(token, "B-TREE"))
+          if (MATCH_TOKEN(token, "USING"))
             {
-              printf("DBG: Expected 'B-TREE', got '%s' in '%s'\n", token,
-                     text);
+              token = apr_strtok(NULL, " ", &last);
+              if (!MATCH_TOKEN(token, "TEMP"))
+                {
+                  printf("DBG: Expected 'TEMP', got '%s' in '%s'\n", token, text);
+                }
+              token = apr_strtok(NULL, " ", &last);
+              if (!MATCH_TOKEN(token, "B-TREE"))
+                {
+                  printf("DBG: Expected 'B-TREE', got '%s' in '%s'\n", token,
+                         text);
+                }
+              item->create_btree = TRUE;
             }
-          item->create_btree = TRUE;
+        }
+      else if (MATCH_TOKEN(token, "QUERY"))
+        {
+        }
+      else
+        {
+          printf("DBG: Expected 'SUBQUERIES', got '%s' in '%s'\n", token,
+                 text);
+          return SVN_NO_ERROR;
         }
     }
   else if (MATCH_TOKEN(item->operation, "USE"))
@@ -474,6 +500,48 @@ parse_explanation_item(struct explanatio
       /* ### Need parsing */
       item->create_btree = TRUE;
     }
+  else if (MATCH_TOKEN(item->operation, "UNION"))
+    {
+      item->create_union = TRUE;
+
+      token = apr_strtok(NULL, " ", &last);
+      if (MATCH_TOKEN(token, "ALL"))
+        item->union_all = TRUE;
+      else
+        item->union_all = FALSE;
+    }
+  else if (MATCH_TOKEN(item->operation, "INDEX"))
+    {
+      
+    }
+  else if (MATCH_TOKEN(item->operation, "MULTI-INDEX"))
+    {
+      item->multi_index = TRUE;
+      token = apr_strtok(NULL, " ", &last);
+      if (MATCH_TOKEN(token, "OR"))
+        item->multi_index_or = TRUE;
+    }
+  else if (MATCH_TOKEN(item->operation, "MERGE"))
+    {
+      item->merge = TRUE;
+    }
+  else if (MATCH_TOKEN(item->operation, "LEFT")
+           || MATCH_TOKEN(item->operation, "RIGHT"))
+    {
+    }
+  else if (MATCH_TOKEN(item->operation, "CORRELATED"))
+    {
+      item->merge = TRUE;
+    }
+  else if (MATCH_TOKEN(item->operation, "CO-ROUTINE"))
+    {
+    }
+  else if (MATCH_TOKEN(item->operation, "SCALAR"))
+    {      
+    }
+  else if (MATCH_TOKEN(item->operation, "LEFT-MOST"))
+    {
+    }
   else
     {
       printf("DBG: Unhandled sqlite operation '%s' in explanation\n", item->operation);
@@ -670,7 +738,20 @@ test_query_expectations(apr_pool_t *scra
                        || (item->expression_vars < 1))
                    && !is_result_table(item->table))
             {
-              if (in_list(primary_key_statements, i))
+              if (MATCH_TOKEN(item->table, "sqlite_master"))
+                {
+                  /* The sqlite_master table does not have an index.
+                     Query explanations that say 'SCAN TABLE sqlite_master'
+                     will appear if SQLite was compiled with the option
+                     SQLITE_ENABLE_STMT_SCANSTATUS, for queries such
+                     as 'DROP TABLE foo', but the performance of such
+                     statements is not our concern here. */
+
+                  /* "Slow" statements do expect too see a warning, however. */
+                  if (is_slow_statement(i))
+                    warned = TRUE;
+                }
+              else if (in_list(primary_key_statements, i))
                 {
                   /* Reported as primary key index usage in Sqlite 3.7,
                      as table scan in 3.8+, while the execution plan is

Modified: subversion/branches/swig-py3/tools/client-side/bash_completion
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/client-side/bash_completion?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/client-side/bash_completion (original)
+++ subversion/branches/swig-py3/tools/client-side/bash_completion Mon Jul  8 15:19:03 2019
@@ -1139,7 +1139,7 @@ _svnadmin ()
 	# Possible expansions, without pure-prefix abbreviations such as "h".
 	cmds='crashtest create delrevprop deltify dump dump-revprops freeze \
 	      help hotcopy info list-dblogs list-unused-dblogs \
-	      load load-revprops lock lslocks lstxns pack recover rmlocks \
+	      load load-revprops lock lslocks lstxns pack recover rev-size rmlocks \
 	      rmtxns setlog setrevprop setuuid unlock upgrade verify --version'
 
 	if [[ $COMP_CWORD -eq 1 ]] ; then
@@ -1211,6 +1211,9 @@ _svnadmin ()
 	recover)
 		cmdOpts="--wait"
 		;;
+	rev-size)
+		cmdOpts="-r --revision -M --memory-cache-size -q --quiet"
+		;;
 	rmlocks)
 		cmdOpts="-q --quiet"
 		;;

Modified: subversion/branches/swig-py3/tools/client-side/svn-mergeinfo-normalizer/svn-mergeinfo-normalizer.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/client-side/svn-mergeinfo-normalizer/svn-mergeinfo-normalizer.c?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/client-side/svn-mergeinfo-normalizer/svn-mergeinfo-normalizer.c (original)
+++ subversion/branches/swig-py3/tools/client-side/svn-mergeinfo-normalizer/svn-mergeinfo-normalizer.c Mon Jul  8 15:19:03 2019
@@ -566,7 +566,8 @@ sub_main(int *exit_code, int argc, const
         break;
       case opt_config_dir:
         SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
-        opt_state.config_dir = svn_dirent_internal_style(utf8_opt_arg, pool);
+        SVN_ERR(svn_dirent_internal_style_safe(&opt_state.config_dir, NULL,
+                                               utf8_opt_arg, pool, pool));
         break;
       case opt_config_options:
         if (!opt_state.config_options)

Modified: subversion/branches/swig-py3/tools/client-side/svnconflict/svnconflict.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/client-side/svnconflict/svnconflict.c?rev=1862754&r1=1862753&r2=1862754&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/client-side/svnconflict/svnconflict.c (original)
+++ subversion/branches/swig-py3/tools/client-side/svnconflict/svnconflict.c Mon Jul  8 15:19:03 2019
@@ -717,7 +717,8 @@ sub_main(int *exit_code, int argc, const
         break;
       case opt_config_dir:
         SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
-        opt_state.config_dir = svn_dirent_internal_style(utf8_opt_arg, pool);
+        SVN_ERR(svn_dirent_internal_style_safe(&opt_state.config_dir, NULL,
+                                               utf8_opt_arg, pool, pool));
         break;
       case opt_config_options:
         if (!opt_state.config_options)



Mime
View raw message