Modified: 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
 Thu Feb  1 20:04:07 2024
@@ -275,14 +275,10 @@ svn_swig_py_unwrap_struct_ptr(PyObject *
 
 /* make an editor that "thunks" from C callbacks up to Python */
 void svn_swig_py_make_editor(const svn_delta_editor_t **editor,
-                             void **edit_baton,
-                             PyObject *py_editor,
                              apr_pool_t *pool);
 
 /* make a parse vtable that "thunks" from C callbacks up to Python */
 void svn_swig_py_make_parse_fns3(const svn_repos_parse_fns3_t **parse_fns3,
-                                 void **parse_baton,
-                                 PyObject *py_parse_fns3,
                                  apr_pool_t *pool);
 
 apr_file_t *svn_swig_py_make_file(PyObject *py_file,

Modified: 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/svn/delta.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/svn/delta.py?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/svn/delta.py
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/svn/delta.py
 Thu Feb  1 20:04:07 2024
@@ -77,5 +77,6 @@ class Editor:
     pass
 
 
-def make_editor(editor, pool=None):
-  return svn_swig_py_make_editor(editor, pool)
+def make_editor(editor, pool=None, baton=None):
+  from libsvn.delta import _AncBaton
+  return svn_swig_py_make_editor(pool), _AncBaton(editor, pool, baton)

Modified: 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/svn/fs.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/svn/fs.py?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/svn/fs.py
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/svn/fs.py
 Thu Feb  1 20:04:07 2024
@@ -23,6 +23,7 @@
 #    under the License.
 ######################################################################
 
+import errno
 from libsvn.fs import *
 
 ######################################################################
@@ -158,6 +159,18 @@ class FileDiff:
     return self.tempfile1, self.tempfile2
 
   def get_pipe(self):
+    """Perform diff and return a file object from which the output can
+    be read.
+
+    When DIFFOPTIONS is None (the default), use svn's internal diff.
+
+    With any other DIFFOPTIONS, exec the external diff found on PATH,
+    passing it DIFFOPTIONS. On Windows, exec diff.exe rather than
+    diff. If a diff utility is not installed or found on PATH, throws
+    FileNotFoundError. Caveat: On some systems, including Windows, an
+    external diff may not be available unless installed and added to
+    PATH manually.
+    """
     self.get_files()
 
     # If diffoptions were provided, then the diff command needs to be
@@ -170,8 +183,17 @@ class FileDiff:
             + [self.tempfile1, self.tempfile2]
 
       # open the pipe, and return the file object for reading from the child.
-      p = _subprocess.Popen(cmd, stdout=_subprocess.PIPE, bufsize=-1,
-                            close_fds=_sys.platform != "win32")
+      try:
+        p = _subprocess.Popen(cmd, stdout=_subprocess.PIPE, bufsize=-1,
+                              close_fds=_sys.platform != "win32")
+      # When removing Python 2 support: Change to FileNotFoundError and 
+      # remove check for ENOENT (FileNotFoundError "Corresponds to errno
+      # ENOENT" according to documentation)
+      except OSError as err:
+        if err.errno == errno.ENOENT:
+          err.strerror = "External diff command not found in PATH"
+        raise err
+
       return _PopenStdoutWrapper(p)
 
     else:

Modified: 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/svn/repos.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/svn/repos.py?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/svn/repos.py
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/svn/repos.py
 Thu Feb  1 20:04:07 2024
@@ -336,5 +336,16 @@ class ParseFns3:
         pass
 
 
-def make_parse_fns3(parse_fns3, pool=None):
-    return svn_swig_py_make_parse_fns3(parse_fns3, pool)
+def make_parse_fns3(parse_fns3, pool=None, baton=None):
+  from libsvn.delta import _AncBaton
+
+  class _ParseBaton(_AncBaton):
+    # Drive _close_dumpstream method when the instance is deleted.
+    # For backward compatibility before Subversion 1.15, we call it even if
+    # the instance would not be used by C API, or the C API would cause
+    # some error.
+    def __del__(self):
+      self.editor._close_dumpstream()
+
+  parse_baton = _ParseBaton(parse_fns3, pool, baton)
+  return svn_swig_py_make_parse_fns3(pool), parse_baton

Modified: 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/delta.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/delta.py?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/delta.py
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/delta.py
 Thu Feb  1 20:04:07 2024
@@ -21,6 +21,7 @@
 import unittest, setup_path
 import os
 import tempfile
+import weakref
 import svn.delta
 import svn.core
 from sys import version_info # For Python version check
@@ -117,6 +118,19 @@ class DeltaTestCase(unittest.TestCase):
     # Check that the ops inherit the window's pool
     self.assertEqual(window.ops[0]._parent_pool, window._parent_pool)
 
+  def testMakeEditorLeak(self):
+    """Issue 4916, check ref-count leak on svn.delta.make_editor()"""
+    pool = svn.core.Pool()
+    editor = svn.delta.Editor()
+    editor_ref = weakref.ref(editor)
+    e_ptr, e_baton = svn.delta.make_editor(editor, pool)
+    del e_ptr, e_baton
+    self.assertNotEqual(editor_ref(), None)
+    del pool
+    self.assertNotEqual(editor_ref(), None)
+    del editor
+    self.assertEqual(editor_ref(), None)
+
 def suite():
   return unittest.defaultTestLoader.loadTestsFromTestCase(DeltaTestCase)
 

Modified: 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/fs.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/fs.py?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/fs.py
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/fs.py
 Thu Feb  1 20:04:07 2024
@@ -308,6 +308,9 @@ class SubversionFSTestCase(unittest.Test
     try:
       diffout, differr = Popen(["diff"], stdin=PIPE, stderr=PIPE).communicate()
 
+    # When removing Python 2 support: Change to FileNotFoundError and 
+    # remove check for ENOENT (FileNotFoundError "Corresponds to errno
+    # ENOENT" according to documentation)
     except OSError as err:
       if err.errno == errno.ENOENT:
         self.skipTest("'diff' command not present")

Modified: 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/repository.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/repository.py?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/repository.py
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/repository.py
 Thu Feb  1 20:04:07 2024
@@ -18,11 +18,11 @@
 # under the License.
 #
 #
-import unittest, setup_path, os, sys
+import unittest, setup_path, os, sys, weakref
 from sys import version_info # For Python version check
 from io import BytesIO
 from svn import core, repos, fs, delta
-from svn.core import SubversionException
+from svn.core import SubversionException, Pool
 import utils
 
 class ChangeReceiver(delta.Editor):
@@ -40,9 +40,20 @@ class ChangeReceiver(delta.Editor):
     return textdelta_handler
 
 class DumpStreamParser(repos.ParseFns3):
-  def __init__(self):
+  def __init__(self, stream=None, pool=None):
     repos.ParseFns3.__init__(self)
+    self.stream = stream
     self.ops = []
+    # for leak checking only. If the parse_fns3 object holds some proxy
+    # object allocated from 'pool' or the 'pool' itself, the 'pool' is not
+    # destroyed until the parse_fns3 object is removed.
+    self.pool = pool
+  def _close_dumpstream(self):
+    if self.stream:
+      self.stream.close()
+      self.stream = None
+    if self.pool:
+      self.pool = None
   def magic_header_record(self, version, pool=None):
     self.ops.append((b"magic-header", version))
   def uuid_record(self, uuid, pool=None):
@@ -74,6 +85,76 @@ class DumpStreamParser(repos.ParseFns3):
     self.ops.append((b"set-fulltext", node_baton[0], node_baton[1]))
     return None
 
+class BatonCollector(repos.ChangeCollector):
+  """A ChangeCollector with collecting batons, too"""
+  def __init__(self, fs_ptr, root, pool=None, notify_cb=None):
+    repos.ChangeCollector.__init__(self, fs_ptr, root, pool, notify_cb)
+    self.batons = []
+    self.close_called = False
+    self.abort_called = False
+
+  def open_root(self, base_revision, dir_pool=None):
+    bt = repos.ChangeCollector.open_root(self, base_revision, dir_pool)
+    self.batons.append((b'dir baton', b'', bt, sys.getrefcount(bt)))
+    return bt
+
+  def add_directory(self, path, parent_baton,
+                    copyfrom_path, copyfrom_revision, dir_pool=None):
+    bt = repos.ChangeCollector.add_directory(self, path, parent_baton,
+                                             copyfrom_path,
+                                             copyfrom_revision,
+                                             dir_pool)
+    self.batons.append((b'dir baton', path, bt, sys.getrefcount(bt)))
+    return bt
+
+  def open_directory(self, path, parent_baton, base_revision,
+                     dir_pool=None):
+    bt = repos.ChangeCollector.open_directory(self, path, parent_baton,
+                                              base_revision, dir_pool)
+    self.batons.append((b'dir baton', path, bt, sys.getrefcount(bt)))
+    return bt
+
+  def add_file(self, path, parent_baton,
+               copyfrom_path, copyfrom_revision, file_pool=None):
+    bt = repos.ChangeCollector.add_file(self, path, parent_baton,
+                                        copyfrom_path, copyfrom_revision,
+                                        file_pool)
+    self.batons.append((b'file baton', path, bt, sys.getrefcount(bt)))
+    return bt
+
+  def open_file(self, path, parent_baton, base_revision, file_pool=None):
+    bt = repos.ChangeCollector.open_file(self, path, parent_baton,
+                                         base_revision, file_pool)
+    self.batons.append((b'file baton', path, bt, sys.getrefcount(bt)))
+    return bt
+
+  def close_edit(self, pool=None):
+    self.close_called = True
+    return
+
+  def abort_edit(self, pool=None):
+    self.abort_called = True
+    return
+
+class BatonCollectorErrorOnClose(BatonCollector):
+  """Same as BatonCollector, but raises an Exception when close the
+     file/dir specfied by error_path"""
+  def __init__(self, fs_ptr, root, pool=None, notify_cb=None, error_path=b''):
+    BatonCollector.__init__(self, fs_ptr, root, pool, notify_cb)
+    self.error_path = error_path
+
+  def close_directory(self, dir_baton):
+    if dir_baton[0] == self.error_path:
+      raise SubversionException('A Dummy Exception!', core.SVN_ERR_BASE)
+    else:
+      BatonCollector.close_directory(self, dir_baton)
+
+  def close_file(self, file_baton, text_checksum):
+    if file_baton[0] == self.error_path:
+      raise SubversionException('A Dummy Exception!', core.SVN_ERR_BASE)
+    else:
+      return BatonCollector.close_file(self, file_baton, text_checksum)
+
 
 def _authz_callback(root, path, pool):
   "A dummy authz callback which always returns success."
@@ -175,13 +256,15 @@ class SubversionRepositoryTestCase(unitt
     def is_cancelled():
       self.cancel_calls += 1
       return None
+    pool = Pool()
+    subpool = Pool(pool)
     dump_path = os.path.join(os.path.dirname(sys.argv[0]),
         "trac/versioncontrol/tests/svnrepos.dump")
     stream = open(dump_path, 'rb')
-    dsp = DumpStreamParser()
-    ptr, baton = repos.make_parse_fns3(dsp)
+    dsp = DumpStreamParser(stream, subpool)
+    dsp_ref = weakref.ref(dsp)
+    ptr, baton = repos.make_parse_fns3(dsp, subpool)
     repos.parse_dumpstream3(stream, ptr, baton, False, is_cancelled)
-    stream.close()
     self.assertEqual(self.cancel_calls, 76)
     expected_list = [
         (b"magic-header", 2),
@@ -226,6 +309,13 @@ class SubversionRepositoryTestCase(unitt
     # the comparison list gets too long.
     self.assertEqual(dsp.ops[:len(expected_list)], expected_list)
 
+    # _close_dumpstream should be invoked after 'baton' is removed.
+    self.assertEqual(False, stream.closed)
+    del ptr, baton, subpool, dsp
+    self.assertEqual(True, stream.closed)
+    # Issue SVN-4918
+    self.assertEqual(None, dsp_ref())
+
   def test_parse_fns3_invalid_set_fulltext(self):
     class DumpStreamParserSubclass(DumpStreamParser):
       def set_fulltext(self, node_baton):
@@ -241,6 +331,33 @@ class SubversionRepositoryTestCase(unitt
     finally:
       stream.close()
 
+  def test_parse_fns3_apply_textdelta_handler_refcount(self):
+    handler = lambda node_baton: None
+    handler_ref = weakref.ref(handler)
+
+    class ParseFns3(repos.ParseFns3):
+      def __init__(self, handler):
+        self.called = set()
+        self.handler = handler
+      def apply_textdelta(self, node_baton):
+        self.called.add('apply_textdelta')
+        return self.handler
+
+    dumpfile = os.path.join(os.path.dirname(__file__), 'data',
+                            'repository-deltas.dump')
+    pool = Pool()
+    subpool = Pool(pool)
+    parser = ParseFns3(handler)
+    ptr, baton = repos.make_parse_fns3(parser, subpool)
+    with open(dumpfile, "rb") as stream:
+      repos.parse_dumpstream3(stream, ptr, baton, False, None)
+    del ptr, baton, stream
+
+    self.assertIn('apply_textdelta', parser.called)
+    self.assertNotEqual(None, handler_ref())
+    del parser, handler, subpool, ParseFns3
+    self.assertEqual(None, handler_ref())
+
   def test_get_logs(self):
     """Test scope of get_logs callbacks"""
     logs = []
@@ -290,6 +407,79 @@ class SubversionRepositoryTestCase(unitt
       repos.dir_delta(prev_root, b'', b'', this_root, b'', e_ptr, e_baton,
               _authz_callback, 1, 1, 0, 0)
 
+  def test_delta_editor_leak_with_change_collector(self):
+    pool = Pool()
+    subpool = Pool(pool)
+    root = fs.revision_root(self.fs, self.rev, subpool)
+    editor = repos.ChangeCollector(self.fs, root, subpool)
+    editor_ref = weakref.ref(editor)
+    e_ptr, e_baton = delta.make_editor(editor, subpool)
+    repos.replay(root, e_ptr, e_baton, subpool)
+
+    fs.close_root(root)
+    del root
+    self.assertNotEqual(None, editor_ref())
+
+    del e_ptr, e_baton, editor
+    del subpool
+    self.assertEqual(None, editor_ref())
+
+  def test_replay_batons_refcounts(self):
+    """Issue SVN-4917: check ref-count of batons created and used in 
callbacks"""
+    root = fs.revision_root(self.fs, self.rev)
+    editor = BatonCollector(self.fs, root)
+    e_ptr, e_baton = delta.make_editor(editor)
+    repos.replay(root, e_ptr, e_baton)
+    for baton in editor.batons:
+      self.assertEqual(sys.getrefcount(baton[2]), 2,
+                       "leak on baton %s after replay without errors"
+                       % repr(baton))
+    del e_baton
+    self.assertEqual(sys.getrefcount(e_ptr), 2,
+                     "leak on editor baton after replay without errors")
+
+    editor = BatonCollectorErrorOnClose(self.fs, root,
+                                        error_path=b'branches/v1x')
+    e_ptr, e_baton = delta.make_editor(editor)
+    self.assertRaises(SubversionException, repos.replay, root, e_ptr, e_baton)
+    batons = editor.batons
+    # As svn_repos_replay calls neither close_edit callback nor abort_edit
+    # if an error has occured during processing, references of Python objects
+    # in decendant batons may live until e_baton is deleted.
+    del e_baton
+    for baton in batons:
+      self.assertEqual(sys.getrefcount(baton[2]), 2,
+                       "leak on baton %s after replay with an error"
+                       % repr(baton))
+    self.assertEqual(sys.getrefcount(e_ptr), 2,
+                     "leak on editor baton after replay with an error")
+
+  def test_delta_editor_apply_textdelta_handler_refcount(self):
+    handler = lambda textdelta: None
+    handler_ref = weakref.ref(handler)
+
+    class Editor(delta.Editor):
+      def __init__(self, handler):
+        self.called = set()
+        self.handler = handler
+      def apply_textdelta(self, file_baton, base_checksum, pool=None):
+        self.called.add('apply_textdelta')
+        return self.handler
+
+    pool = Pool()
+    subpool = Pool(pool)
+    root = fs.revision_root(self.fs, 3)  # change of trunk/README.txt
+    editor = Editor(handler)
+    e_ptr, e_baton = delta.make_editor(editor, subpool)
+    repos.replay(root, e_ptr, e_baton, subpool)
+    del e_ptr, e_baton
+
+    self.assertIn('apply_textdelta', editor.called)
+    self.assertNotEqual(None, handler_ref())
+    del root, editor, handler, Editor
+    del subpool
+    self.assertEqual(None, handler_ref())
+
   def test_retrieve_and_change_rev_prop(self):
     """Test playing with revprops"""
     self.assertEqual(repos.fs_revision_prop(self.repos, self.rev, b"svn:log",

Modified: 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/wc.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/wc.py?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/wc.py
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/python/tests/wc.py
 Thu Feb  1 20:04:07 2024
@@ -180,9 +180,9 @@ class SubversionWorkingCopyTestCase(unit
         self.assertTrue(target.startswith(self.path))
 
   def test_status_editor_callback_exception(self):
-      """test case for status_editor call back not to be crashed by Python 
exception"""
+      """test case for status_editor callback not to be crashed by Python 
exception"""
       def status_func(target, status):
-        # Note: exception with in this call back doesn't propagate to
+        # Note: exception with in this callback doesn't propagate to
         # the caller
         raise AssertionError('intentional exception')
 

Modified: 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c
 Thu Feb  1 20:04:07 2024
@@ -788,7 +788,7 @@ svn_swig_rb_set_pool(VALUE target, VALUE
     struct rb_set_pool_for_hash_arg arg;
     arg.set = FALSE;
     arg.pool = pool;
-    rb_hash_foreach(target, rb_set_pool_for_hash_callback, (VALUE)&arg);
+    rb_hash_foreach(target, (int(*)(ANYARGS))rb_set_pool_for_hash_callback, 
(VALUE)&arg);
     return arg.set;
   } else {
     return rb_set_pool_if_swig_type_object(target, pool);
@@ -806,7 +806,7 @@ svn_swig_rb_set_pool_for_no_swig_type(VA
     target = rb_ary_new3(1, target);
   }
 
-  rb_iterate(rb_each, target, rb_set_pool, pool);
+  rb_iterate((VALUE(*)())rb_each, target, (VALUE(*)())rb_set_pool, pool);
 }
 
 void
@@ -1070,7 +1070,8 @@ svn_swig_rb_to_apr_array_row_prop(VALUE
     result = apr_array_make(pool, 0, sizeof(svn_prop_t));
     arg.array = result;
     arg.pool = pool;
-    rb_hash_foreach(array_or_hash, svn_swig_rb_to_apr_array_row_prop_callback,
+    rb_hash_foreach(array_or_hash,
+                    
(int(*)(ANYARGS))svn_swig_rb_to_apr_array_row_prop_callback,
                     (VALUE)&arg);
     return result;
   } else {
@@ -1125,7 +1126,8 @@ svn_swig_rb_to_apr_array_prop(VALUE arra
     result = apr_array_make(pool, 0, sizeof(svn_prop_t *));
     arg.array = result;
     arg.pool = pool;
-    rb_hash_foreach(array_or_hash, svn_swig_rb_to_apr_array_prop_callback,
+    rb_hash_foreach(array_or_hash,
+                    (int(*)(ANYARGS))svn_swig_rb_to_apr_array_prop_callback,
                     (VALUE)&arg);
     return result;
   } else {
@@ -1548,7 +1550,7 @@ r2c_hash(VALUE hash, r2c_func func, void
     data.func = func;
     data.pool = pool;
 
-    rb_hash_foreach(hash, r2c_hash_i, (VALUE)&data);
+    rb_hash_foreach(hash, (int(*)(ANYARGS))r2c_hash_i, (VALUE)&data);
 
     return apr_hash;
   }
@@ -1570,7 +1572,9 @@ svn_swig_rb_hash_to_apr_hash_svn_string(
 apr_hash_t *
 svn_swig_rb_hash_to_apr_hash_swig_type(VALUE hash, const char *typename, 
apr_pool_t *pool)
 {
-  return r2c_hash(hash, r2c_swig_type, (void *)typename, pool);
+  /* Note: casting to r2c_cunc for r2c_swig_type may unsafe, because
+         it contains the cast from "const void *" to "void *" */
+  return r2c_hash(hash, (r2c_func)r2c_swig_type, (void *)typename, pool);
 }
 
 apr_hash_t *
@@ -1651,7 +1655,8 @@ invoke_callback(VALUE baton, VALUE pool)
   argv[0] = pool;
   svn_swig_rb_get_pool(1, argv, Qnil, &subpool, NULL);
   cbb->pool = subpool;
-  return rb_ensure(callback, baton, callback_ensure, subpool);
+  return rb_ensure((VALUE(*)(ANYARGS))callback, baton,
+                   (VALUE(*)(ANYARGS))callback_ensure, subpool);
 }
 
 static VALUE
@@ -1660,9 +1665,9 @@ callback_handle_error(VALUE baton, ...)
   callback_handle_error_baton_t *handle_error_baton;
   handle_error_baton = (callback_handle_error_baton_t *)baton;
 
-  return rb_rescue2(callback,
+  return rb_rescue2((VALUE(*)(ANYARGS))callback,
                     (VALUE)(handle_error_baton->callback_baton),
-                    callback_rescue,
+                    (VALUE(*)(ANYARGS))callback_rescue,
                     (VALUE)(handle_error_baton->rescue_baton),
                     rb_svn_error(),
                     (VALUE)0);
@@ -1681,8 +1686,9 @@ invoke_callback_handle_error(VALUE baton
   handle_error_baton.callback_baton = cbb;
   handle_error_baton.rescue_baton = &rescue_baton;
 
-  return rb_ensure(callback_handle_error, (VALUE)&handle_error_baton,
-                   callback_ensure, pool);
+  return rb_ensure((VALUE(*)(ANYARGS))callback_handle_error,
+                   (VALUE)&handle_error_baton,
+                   (VALUE(*)(ANYARGS))callback_ensure, pool);
 }
 
 
@@ -1735,7 +1741,8 @@ svn_swig_rb_set_baton(VALUE target, VALU
     target = rb_ary_new3(1, target);
   }
 
-  rb_iterate(rb_each, target, add_baton_if_delta_editor, baton);
+  rb_iterate((VALUE(*)())rb_each, target,
+             (VALUE(*)())add_baton_if_delta_editor, baton);
 }
 
 

Modified: 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/svn_delta.i
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/bindings/swig/svn_delta.i?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/svn_delta.i 
(original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/svn_delta.i 
Thu Feb  1 20:04:07 2024
@@ -68,8 +68,6 @@
    ### There must be a cleaner way to implement this? 
    ### Maybe follow Ruby by wrapping it where passing an editor? */
 void svn_swig_py_make_editor(const svn_delta_editor_t **editor,
-                             void **edit_baton,
-                             PyObject *py_editor,
                              apr_pool_t *pool);
 #endif
 
@@ -207,6 +205,49 @@ void _ops_get(int *num_ops, const svn_tx
 
 #ifdef SWIGPYTHON
 %pythoncode %{
+# Baton container class for editor/parse_fns3 batons and their decendants.
+class _ItemBaton:
+  def __init__(self, editor, pool, baton=None):
+    self.pool = pool if pool else libsvn.core.svn_pool_create()
+    self.baton = baton
+    self.editor = editor
+
+  def get_ancestor(self):
+    raise NotImplementedError
+
+  def make_decendant(self, pool, baton=None):
+    return _DecBaton(self, pool, baton)
+
+
+class _DecBaton(_ItemBaton):
+  def __init__(self, parent, pool, baton=None):
+    import weakref
+    _ItemBaton.__init__(self, parent.editor, pool, baton)
+    self._anc = weakref.ref(parent.get_ancestor())
+    self._anc().hold_baton(self)
+
+  def get_ancestor(self):
+    return self._anc()
+
+  def release_self(self):
+    self._anc().release_baton(self)
+
+
+class _AncBaton(_ItemBaton):
+  def __init__(self, editor, pool, baton=None):
+    _ItemBaton.__init__(self, editor, pool, baton)
+    self._dec = {}     # hold decendant batons.
+
+  def get_ancestor(self):
+    return self
+
+  def hold_baton(self, baton):
+    self._dec[id(baton)] = baton
+
+  def release_baton(self, baton):
+    del self._dec[id(baton)]
+
+
 # This function is for backwards compatibility only.
 # Use svn_txdelta_window_t.ops instead.
 svn_txdelta_window_t_ops_get = svn_txdelta_window_t._ops_get

Modified: 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/svn_repos.i
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/bindings/swig/svn_repos.i?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/svn_repos.i 
(original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/bindings/swig/svn_repos.i 
Thu Feb  1 20:04:07 2024
@@ -162,8 +162,6 @@ svn_error_t *svn_repos_dump_fs2(svn_repo
 #ifdef SWIGPYTHON
 /* Make swig wrap this function for us, to allow making a vtable in python */
 void svn_swig_py_make_parse_fns3(const svn_repos_parse_fns3_t **parse_fns3,
-                                 void **parse_baton,
-                                 PyObject *py_parse_fns3,
                                  apr_pool_t *pool);
 #endif
 

Modified: subversion/branches/pristine-checksum-salt/subversion/include/svn_wc.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/include/svn_wc.h?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/include/svn_wc.h 
(original)
+++ subversion/branches/pristine-checksum-salt/subversion/include/svn_wc.h Thu 
Feb  1 20:04:07 2024
@@ -993,6 +993,7 @@ typedef enum svn_wc_notify_action_t
   svn_wc_notify_restore,
 
   /** Reverting a modified path. */
+  /* See also svn_wc_notify_revert_noaccess */
   svn_wc_notify_revert,
 
   /** A revert operation has failed. */
@@ -1325,6 +1326,12 @@ typedef enum svn_wc_notify_action_t
    * @since New in 1.15. */
   svn_wc_notify_warning,
 
+  /** A file is readonly for the user but isn't svn:needs-lock.
+   * So we want to restore RW, but fail since the file has W bits,
+   * just not for the current user. 
+   * @since New in 1.15. */
+  svn_wc_notify_revert_noaccess,
+
 } svn_wc_notify_action_t;
 
 

Modified: 
subversion/branches/pristine-checksum-salt/subversion/libsvn_client/copy.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/libsvn_client/copy.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/libsvn_client/copy.c 
(original)
+++ subversion/branches/pristine-checksum-salt/subversion/libsvn_client/copy.c 
Thu Feb  1 20:04:07 2024
@@ -3077,7 +3077,7 @@ try_copy(svn_boolean_t *timestamp_sleep,
       APR_ARRAY_PUSH(copy_pairs, svn_client__copy_pair_t *) = pair;
     }
 
-  if (!srcs_are_urls && !dst_is_url)
+  if (is_move || (!srcs_are_urls && !dst_is_url))
     {
       apr_pool_t *iterpool = svn_pool_create(pool);
 
@@ -3092,9 +3092,15 @@ try_copy(svn_boolean_t *timestamp_sleep,
                                   pair->dst_abspath_or_url, iterpool))
             return svn_error_createf
               (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-               _("Cannot copy path '%s' into its own child '%s'"),
-               svn_dirent_local_style(pair->src_abspath_or_url, pool),
-               svn_dirent_local_style(pair->dst_abspath_or_url, pool));
+               is_move ?
+                 _("Cannot move path '%s' into its own child '%s'") :
+                 _("Cannot copy path '%s' into its own child '%s'"),
+               svn_path_is_url(pair->src_abspath_or_url) ?
+                 pair->src_abspath_or_url :
+                 svn_dirent_local_style(pair->src_abspath_or_url, pool),
+               svn_path_is_url(pair->dst_abspath_or_url) ?
+                 pair->dst_abspath_or_url :
+                 svn_dirent_local_style(pair->dst_abspath_or_url, pool));
         }
 
       svn_pool_destroy(iterpool);

Modified: 
subversion/branches/pristine-checksum-salt/subversion/libsvn_client/externals.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/libsvn_client/externals.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/libsvn_client/externals.c 
(original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/libsvn_client/externals.c 
Thu Feb  1 20:04:07 2024
@@ -919,7 +919,7 @@ handle_external_item_change(svn_client_c
 
         SVN_ERR(switch_file_external(local_abspath,
                                      new_loc,
-                                     new_url,
+                                     new_loc->url,
                                      &new_item->peg_revision,
                                      &new_item->revision,
                                      parent_dir_abspath,

Modified: 
subversion/branches/pristine-checksum-salt/subversion/libsvn_repos/load-fs-vtable.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/libsvn_repos/load-fs-vtable.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/libsvn_repos/load-fs-vtable.c
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/libsvn_repos/load-fs-vtable.c
 Thu Feb  1 20:04:07 2024
@@ -42,6 +42,7 @@
 #include "private/svn_dep_compat.h"
 #include "private/svn_mergeinfo_private.h"
 #include "private/svn_repos_private.h"
+#include "private/svn_subr_private.h"
 
 /*----------------------------------------------------------------------*/
 
@@ -77,6 +78,8 @@ struct parse_baton
      contents are allocated in POOL. */
   /* ### See https://issues.apache.org/jira/browse/SVN-3903
      ### for discussion about improving the memory costs of this mapping. */
+  /* Using svn_revnum_t as a key can interact badly with APR's default hash
+     see tools/dev/hash-test.c. Use svn_hash__make to get a suitable hash. */
   apr_hash_t *rev_map;
 
   /* The most recent (youngest) revision from the dump stream mapped in
@@ -1255,7 +1258,7 @@ svn_repos_get_fs_build_parser6(const svn
   pb->parent_dir = parent_dir;
   pb->pool = pool;
   pb->notify_pool = svn_pool_create(pool);
-  pb->rev_map = apr_hash_make(pool);
+  pb->rev_map = svn_hash__make(pool);
   pb->oldest_dumpstream_rev = SVN_INVALID_REVNUM;
   pb->last_rev_mapped = SVN_INVALID_REVNUM;
   pb->start_rev = start_rev;

Modified: 
subversion/branches/pristine-checksum-salt/subversion/libsvn_repos/reporter.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/libsvn_repos/reporter.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/libsvn_repos/reporter.c 
(original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/libsvn_repos/reporter.c 
Thu Feb  1 20:04:07 2024
@@ -138,7 +138,8 @@ typedef struct report_baton_t
   svn_fs_root_t *s_roots[NUM_CACHED_SOURCE_ROOTS];
 
   /* Cache for revision properties. This is used to eliminate redundant
-     revprop fetching. */
+     revprop fetching. svn_revnum_t keys so use svn_hash__make to get a
+     suitable hash function. */
   apr_hash_t *revision_infos;
 
   /* This will not change. So, fetch it once and reuse it. */
@@ -1628,7 +1629,7 @@ svn_repos_begin_report3(void **report_ba
   b->edit_baton = edit_baton;
   b->authz_read_func = authz_read_func;
   b->authz_read_baton = authz_read_baton;
-  b->revision_infos = apr_hash_make(pool);
+  b->revision_infos = svn_hash__make(pool);
   b->pool = pool;
   b->reader = svn_spillbuf__reader_create(1000 /* blocksize */,
                                           1000000 /* maxsize */,

Modified: subversion/branches/pristine-checksum-salt/subversion/libsvn_subr/io.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/libsvn_subr/io.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/libsvn_subr/io.c 
(original)
+++ subversion/branches/pristine-checksum-salt/subversion/libsvn_subr/io.c Thu 
Feb  1 20:04:07 2024
@@ -2531,27 +2531,14 @@ svn_io__is_finfo_read_only(svn_boolean_t
                            apr_pool_t *pool)
 {
 #if defined(APR_HAS_USER) && !defined(WIN32) &&!defined(__OS2__)
-  apr_status_t apr_err;
-  apr_uid_t uid;
-  apr_gid_t gid;
-
-  *read_only = FALSE;
-
-  apr_err = apr_uid_current(&uid, &gid, pool);
-
-  if (apr_err)
-    return svn_error_wrap_apr(apr_err, _("Error getting UID of process"));
-
-  /* Check write bit for current user. */
-  if (apr_uid_compare(uid, file_info->user) == APR_SUCCESS)
-    *read_only = !(file_info->protection & APR_UWRITE);
-
-  else if (apr_gid_compare(gid, file_info->group) == APR_SUCCESS)
-    *read_only = !(file_info->protection & APR_GWRITE);
-
-  else
-    *read_only = !(file_info->protection & APR_WWRITE);
-
+  *read_only = (access(file_info->fname, W_OK) != 0);
+  /* svn_io__is_finfo_read_only can be called with a dangling
+   * symlink. access() will check the permission on the missing
+   * target and return -1 and errno = ENOENT. Check for ENOENT
+   * and pretend the file is writeable, otherwise we will get
+   * spurious Reverted messages on the symlink.
+   */
+  if (*read_only && errno == ENOENT) *read_only = FALSE;
 #else  /* WIN32 || __OS2__ || !APR_HAS_USER */
   *read_only = (file_info->protection & APR_FREADONLY);
 #endif
@@ -2564,33 +2551,7 @@ svn_io__is_finfo_executable(svn_boolean_
                             apr_finfo_t *file_info,
                             apr_pool_t *pool)
 {
-#if defined(APR_HAS_USER) && !defined(WIN32) &&!defined(__OS2__)
-  apr_status_t apr_err;
-  apr_uid_t uid;
-  apr_gid_t gid;
-
-  *executable = FALSE;
-
-  apr_err = apr_uid_current(&uid, &gid, pool);
-
-  if (apr_err)
-    return svn_error_wrap_apr(apr_err, _("Error getting UID of process"));
-
-  /* Check executable bit for current user. */
-  if (apr_uid_compare(uid, file_info->user) == APR_SUCCESS)
-    *executable = (file_info->protection & APR_UEXECUTE);
-
-  else if (apr_gid_compare(gid, file_info->group) == APR_SUCCESS)
-    *executable = (file_info->protection & APR_GEXECUTE);
-
-  else
-    *executable = (file_info->protection & APR_WEXECUTE);
-
-#else  /* WIN32 || __OS2__ || !APR_HAS_USER */
-  *executable = FALSE;
-#endif
-
-  return SVN_NO_ERROR;
+  return svn_io_is_file_executable(executable, file_info->fname, pool);
 }
 
 svn_error_t *
@@ -2599,12 +2560,7 @@ svn_io_is_file_executable(svn_boolean_t
                           apr_pool_t *pool)
 {
 #if defined(APR_HAS_USER) && !defined(WIN32) &&!defined(__OS2__)
-  apr_finfo_t file_info;
-
-  SVN_ERR(svn_io_stat(&file_info, path, APR_FINFO_PROT | APR_FINFO_OWNER,
-                      pool));
-  SVN_ERR(svn_io__is_finfo_executable(executable, &file_info, pool));
-
+  *executable = (access(path, X_OK) == 0);
 #else  /* WIN32 || __OS2__ || !APR_HAS_USER */
   *executable = FALSE;
 #endif

Modified: 
subversion/branches/pristine-checksum-salt/subversion/libsvn_subr/sysinfo.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/libsvn_subr/sysinfo.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/libsvn_subr/sysinfo.c 
(original)
+++ subversion/branches/pristine-checksum-salt/subversion/libsvn_subr/sysinfo.c 
Thu Feb  1 20:04:07 2024
@@ -1404,13 +1404,10 @@ release_name_from_version(int major, int
             }
           break;
 
-        case 11:
-          return "Big Sur";
-          break;
-
-        case 12:
-          return "Monterey";
-          break;
+        case 11: return "Big Sur";
+        case 12: return "Monterey";
+        case 13: return "Ventura";
+        case 14: return "Sonoma";
         }
     }
   return NULL;

Modified: 
subversion/branches/pristine-checksum-salt/subversion/libsvn_subr/version.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/libsvn_subr/version.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/libsvn_subr/version.c 
(original)
+++ subversion/branches/pristine-checksum-salt/subversion/libsvn_subr/version.c 
Thu Feb  1 20:04:07 2024
@@ -143,7 +143,7 @@ svn_version_extended(svn_boolean_t verbo
   info->build_time = __TIME__;
   info->build_host = SVN_BUILD_HOST;
   info->copyright = apr_pstrdup
-    (pool, _("Copyright (C) 2022 The Apache Software Foundation.\n"
+    (pool, _("Copyright (C) 2023 The Apache Software Foundation.\n"
              "This software consists of contributions made by many people;\n"
              "see the NOTICE file for more information.\n"
              "Subversion is open source software, see "

Modified: 
subversion/branches/pristine-checksum-salt/subversion/libsvn_wc/revert.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/libsvn_wc/revert.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/libsvn_wc/revert.c 
(original)
+++ subversion/branches/pristine-checksum-salt/subversion/libsvn_wc/revert.c 
Thu Feb  1 20:04:07 2024
@@ -263,6 +263,7 @@ revert_restore_handle_copied_dirs(svn_bo
 static svn_error_t *
 revert_wc_data(svn_boolean_t *run_wq,
                svn_boolean_t *notify_required,
+               svn_boolean_t *notify_noaccess,
                svn_wc__db_t *db,
                const char *local_abspath,
                svn_wc__db_status_t status,
@@ -309,6 +310,7 @@ revert_restore(svn_boolean_t *run_wq,
   svn_wc__db_status_t status;
   svn_node_kind_t kind;
   svn_boolean_t notify_required;
+  svn_boolean_t notify_noaccess;
   const apr_array_header_t *conflict_files;
   svn_filesize_t recorded_size;
   apr_time_t recorded_time;
@@ -398,7 +400,7 @@ revert_restore(svn_boolean_t *run_wq,
   if (!metadata_only)
     {
       SVN_ERR(revert_wc_data(run_wq,
-                             &notify_required,
+                             &notify_required, &notify_noaccess,
                              db, local_abspath, status, kind,
                              reverted_kind, recorded_size, recorded_time,
                              copied_here, use_commit_times,
@@ -419,12 +421,19 @@ revert_restore(svn_boolean_t *run_wq,
         }
     }
 
-  if (notify_func && notify_required)
-    notify_func(notify_baton,
-                svn_wc_create_notify(local_abspath, svn_wc_notify_revert,
-                                     scratch_pool),
-                scratch_pool);
-
+  if (notify_func)
+    {
+      if (notify_required)
+        notify_func(notify_baton,
+                    svn_wc_create_notify(local_abspath, svn_wc_notify_revert,
+                                         scratch_pool),
+                    scratch_pool);
+      else if (notify_noaccess)
+        notify_func(notify_baton,
+                    svn_wc_create_notify(local_abspath, 
svn_wc_notify_revert_noaccess,
+                                         scratch_pool),
+                    scratch_pool);
+    }
   if (depth == svn_depth_infinity && kind == svn_node_dir)
     {
       apr_pool_t *iterpool = svn_pool_create(scratch_pool);
@@ -482,6 +491,7 @@ revert_restore(svn_boolean_t *run_wq,
 static svn_error_t *
 revert_wc_data(svn_boolean_t *run_wq,
                svn_boolean_t *notify_required,
+               svn_boolean_t *notify_noaccess,
                svn_wc__db_t *db,
                const char *local_abspath,
                svn_wc__db_status_t status,
@@ -502,6 +512,8 @@ revert_wc_data(svn_boolean_t *run_wq,
   svn_boolean_t special;
 #endif
 
+  *notify_noaccess = FALSE; /* notify_required is reset elsewhere */
+  
   /* Would be nice to use svn_io_dirent2_t here, but the performance
      improvement that provides doesn't work, because we need the read
      only and executable bits later on, in the most likely code path */
@@ -661,11 +673,23 @@ revert_wc_data(svn_boolean_t *run_wq,
                         }
                       else if (!needs_lock_prop && read_only)
                         {
-                          SVN_ERR(svn_io_set_file_read_write(local_abspath,
-                                                             FALSE,
-                                                             scratch_pool));
-                          *notify_required = TRUE;
-                        }
+                          /* If there is already W on the file, it is owned by
+                          * some other user. Then svn_io_set_file_read_write
+                          * will return without making any changes and the 
+                          * user will get a spurious "Reverted" message.
+                          * Only checking for user's W since that is the only
+                          * one set by svn_io_set_file_read_write()
+                          * Issue #4622 */
+                          if (finfo.protection & APR_UWRITE)
+                            *notify_noaccess = TRUE;
+                          else
+                            {
+                              SVN_ERR(svn_io_set_file_read_write(local_abspath,
+                                                                 FALSE,
+                                                                 
scratch_pool));
+                              *notify_required = TRUE;
+                            }
+                       }
                     }
 
 #if !defined(WIN32) && !defined(__OS2__)

Modified: 
subversion/branches/pristine-checksum-salt/subversion/libsvn_wc/workqueue.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/libsvn_wc/workqueue.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/libsvn_wc/workqueue.c 
(original)
+++ subversion/branches/pristine-checksum-salt/subversion/libsvn_wc/workqueue.c 
Thu Feb  1 20:04:07 2024
@@ -566,20 +566,6 @@ run_file_install(work_item_baton_t *wqb,
                                          db, wcroot_abspath,
                                          scratch_pool, scratch_pool));
 
-  SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, &repos_relpath,
-                               &repos_root_url, NULL, &changed_rev, NULL,
-                               &changed_author, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, &lock, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               db, local_abspath,
-                               scratch_pool, scratch_pool));
-  /* Handle special statuses (e.g. added) */
-  if (!repos_relpath)
-     SVN_ERR(svn_wc__db_read_repos_info(NULL, &repos_relpath,
-                                        &repos_root_url, NULL,
-                                        db, local_abspath,
-                                        scratch_pool, scratch_pool));
-
   is_special = svn_prop_get_value(props, SVN_PROP_SPECIAL) != NULL;
   is_executable = svn_prop_get_value(props, SVN_PROP_EXECUTABLE) != NULL;
   needs_lock = svn_prop_get_value(props, SVN_PROP_NEEDS_LOCK) != NULL;
@@ -588,10 +574,30 @@ run_file_install(work_item_baton_t *wqb,
   svn_subst_eol_style_from_value(&eol_style, &eol, eol_propval);
 
   keywords_propval = svn_prop_get_value(props, SVN_PROP_KEYWORDS);
+
+  /* Avoid this db work unless needed, in this hot codepath. */
+  if (keywords_propval || needs_lock)
+    SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, &repos_relpath,
+                                 &repos_root_url, NULL, &changed_rev, NULL,
+                                 &changed_author, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, &lock, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
NULL,
+                                 db, local_abspath,
+                                 scratch_pool, scratch_pool));
+ 
   if (keywords_propval)
     {
-      const char *url =
-        svn_path_url_add_component2(repos_root_url, repos_relpath, 
scratch_pool);
+      const char *url;
+                                           
+      /* Handle special statuses (e.g. added) */
+      if (!repos_relpath)
+        SVN_ERR(svn_wc__db_read_repos_info(NULL, &repos_relpath,
+                                           &repos_root_url, NULL,
+                                           db, local_abspath,
+                                           scratch_pool, scratch_pool));
+
+      url = svn_path_url_add_component2(repos_root_url, repos_relpath,
+                                        scratch_pool);
 
       SVN_ERR(svn_subst_build_keywords3(&keywords, keywords_propval,
                                         apr_psprintf(scratch_pool, "%ld",

Modified: subversion/branches/pristine-checksum-salt/subversion/svn/cl.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/svn/cl.h?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/svn/cl.h (original)
+++ subversion/branches/pristine-checksum-salt/subversion/svn/cl.h Thu Feb  1 
20:04:07 2024
@@ -881,7 +881,7 @@ typedef enum svn_cl__prop_use_e
 svn_cl__prop_use_t;
 
 /* If PROPNAME looks like but is not identical to one of the svn:
- * poperties, raise an error and suggest a better spelling. Names that
+ * properties, raise an error and suggest a better spelling. Names that
  * raise errors look like this:
  *
  *   - start with svn: but do not exactly match a known property; or,

Modified: subversion/branches/pristine-checksum-salt/subversion/svn/info-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/svn/info-cmd.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/svn/info-cmd.c 
(original)
+++ subversion/branches/pristine-checksum-salt/subversion/svn/info-cmd.c Thu 
Feb  1 20:04:07 2024
@@ -1294,10 +1294,16 @@ print_info_item(void *baton,
       break;
 
     case info_item_wc_root:
-      SVN_ERR(print_info_item_string(
-                  (info->wc_info && info->wc_info->wcroot_abspath
-                   ? info->wc_info->wcroot_abspath : NULL),
-                  target_path, pool));
+      {
+        const char *wc_root;
+
+        if (info->wc_info && info->wc_info->wcroot_abspath)
+          wc_root = svn_dirent_local_style(info->wc_info->wcroot_abspath, 
pool);
+        else
+          wc_root = NULL;
+
+        SVN_ERR(print_info_item_string(wc_root, target_path, pool));
+      }
       break;
 
     case info_item_schedule:

Modified: subversion/branches/pristine-checksum-salt/subversion/svn/notify.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/svn/notify.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/svn/notify.c 
(original)
+++ subversion/branches/pristine-checksum-salt/subversion/svn/notify.c Thu Feb  
1 20:04:07 2024
@@ -450,6 +450,11 @@ notify_body(struct notify_baton *nb,
                                  path_local));
       break;
 
+    case svn_wc_notify_revert_noaccess:
+      SVN_ERR(svn_cmdline_printf(pool, _("User doesn't have WRITE permissions 
to file '%s' and the file isn't svn:needslock. But the file is already 
writeable. Probably owned by another user."),
+                             path_local));
+      break;
+
     case svn_wc_notify_failed_revert:
       SVN_ERR(svn_cmdline_printf(pool, _("Failed to revert '%s' -- "
                                          "try updating instead.\n"),

Modified: subversion/branches/pristine-checksum-salt/subversion/svn/svn.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/svn/svn.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/svn/svn.c (original)
+++ subversion/branches/pristine-checksum-salt/subversion/svn/svn.c Thu Feb  1 
20:04:07 2024
@@ -424,7 +424,7 @@ svn_cl__cmd_table_main[] =
 {
   { "add", svn_cl__add, {0}, {N_(
      "Put new files and directories under version control.\n"
-     "usage: add PATH...\n"
+     "usage: add PATH[@]...\n"
      "\n"), N_(
      "  Schedule unversioned PATHs for addition, so they will become versioned 
and\n"
      "  be added to the repository in the next commit. Recurse into 
directories by\n"
@@ -444,7 +444,9 @@ svn_cl__cmd_table_main[] =
      "\n"), N_(
      "  The selection of items to add may be influenced by the 'ignores' 
feature.\n"
      "  Properties may be attached to the items as configured by the 
'auto-props'\n"
-     "  feature.\n"
+     "  feature.\n"), N_(
+     "  If PATH contains an @ character, an additional @ must be specified at 
the\n"
+     "  end of PATH to avoid interpreting the first @ as a peg revision 
indicator.\n"
     )},
     {opt_targets, 'N', opt_depth, 'q', opt_force, opt_no_ignore, opt_autoprops,
      opt_no_autoprops, opt_parents },
@@ -516,8 +518,11 @@ svn_cl__cmd_table_main[] =
   { "changelist", svn_cl__changelist, {"cl"}, {N_(
      "Associate (or dissociate) changelist CLNAME with the named\n"
      "files.\n"
-     "usage: 1. changelist CLNAME PATH...\n"
-     "       2. changelist --remove PATH...\n"
+     "usage: 1. changelist CLNAME PATH[@]...\n"
+     "       2. changelist --remove PATH[@]...\n"
+    ), N_(
+     "  If PATH contains an @ character, an additional @ must be specified at 
the\n"
+     "  end of PATH to avoid interpreting the first @ as a peg revision 
indicator.\n"
     )},
     { 'q', 'R', opt_depth, opt_remove, opt_targets, opt_changelist} },
 
@@ -539,6 +544,8 @@ svn_cl__cmd_table_main[] =
      "  out into a sub-directory of PATH, with the name of the sub-directory\n"
      "  being the basename of the URL.\n"
      "\n"), N_(
+     "  If PATH contains an @ character, an additional @ must be specified at 
the\n"
+     "  end of PATH to avoid interpreting the first @ as a peg revision 
indicator.\n"), N_(
      "  If --force is used, unversioned obstructing paths in the working\n"
      "  copy destination do not automatically cause the check out to fail.\n"
      "  If the obstructing path is the same type (file or directory) as the\n"
@@ -560,10 +567,10 @@ svn_cl__cmd_table_main[] =
   { "cleanup", svn_cl__cleanup, {0}, {N_(
      "Either recover from an interrupted operation that left the working\n"
      "copy locked, or remove unwanted files.\n"
-     "usage: 1. cleanup [WCPATH...]\n"
-     "       2. cleanup --remove-unversioned [WCPATH...]\n"
-     "          cleanup --remove-ignored [WCPATH...]\n"
-     "       3. cleanup --vacuum-pristines [WCPATH...]\n"
+     "usage: 1. cleanup [WCPATH[@]...]\n"
+     "       2. cleanup --remove-unversioned [WCPATH[@]...]\n"
+     "          cleanup --remove-ignored [WCPATH[@]...]\n"
+     "       3. cleanup --vacuum-pristines [WCPATH[@]...]\n"
      "\n"), N_(
      "  1. When none of the options --remove-unversioned, --remove-ignored, 
and\n"
      "    --vacuum-pristines is specified, remove all write locks (shown as 
'L' by\n"
@@ -583,7 +590,9 @@ svn_cl__cmd_table_main[] =
      "\n"), N_(
      "  3. If the --vacuum-pristines option is given, remove pristine copies 
of\n"
      "    files which are stored inside the .svn directory and which are no 
longer\n"
-     "    referenced by any file in the working copy.\n"
+     "    referenced by any file in the working copy.\n"), N_(
+     "  If WCPATH contains an @ character, an additional @ must be specified 
at the\n"
+     "  end of WCPATH to avoid interpreting the first @ as a peg revision 
indicator.\n"
     )},
     { opt_remove_unversioned, opt_remove_ignored, opt_vacuum_pristines,
       opt_include_externals, 'q', opt_merge_cmd },
@@ -591,7 +600,7 @@ svn_cl__cmd_table_main[] =
 
   { "commit", svn_cl__commit, {"ci"}, {N_(
      "Send changes from your working copy to the repository.\n"
-     "usage: commit [PATH...]\n"
+     "usage: commit [PATH[@]...]\n"
      "\n"), N_(
      "  A log message must be provided, but it can be empty.  If it is not\n"
      "  given by a --message or --file option, an editor will be started.\n"
@@ -601,7 +610,9 @@ svn_cl__cmd_table_main[] =
      "\n"), N_(
      "  If --include-externals is given, also commit file and directory\n"
      "  externals reached by recursion. Do not commit externals with a\n"
-     "  fixed revision.\n"
+     "  fixed revision.\n"), N_(
+     "  If PATH contains an @ character, an additional @ must be specified at 
the\n"
+     "  end of PATH to avoid interpreting the first @ as a peg revision 
indicator.\n"
     )},
     {'q', 'N', opt_depth, opt_targets, opt_no_unlock, SVN_CL__LOG_MSG_OPTIONS,
      opt_changelist, opt_keep_changelists, opt_include_externals},
@@ -609,7 +620,7 @@ svn_cl__cmd_table_main[] =
 
   { "copy", svn_cl__copy, {"cp"}, {N_(
      "Copy files and directories in a working copy or repository.\n"
-     "usage: copy SRC[@REV]... DST\n"
+     "usage: copy SRC[@REV]... DST[@]\n"
      "\n"), N_(
      "  SRC and DST can each be either a working copy (WC) path or URL:\n"
      "    WC  -> WC:   copy and schedule for addition (with history)\n"
@@ -620,6 +631,8 @@ svn_cl__cmd_table_main[] =
      "  the sources will be added as children of DST. When copying multiple\n"
      "  sources, DST must be an existing directory.\n"
      "\n"), N_(
+     "  If DST contains an @ character, an additional @ must be specified at 
the\n"
+     "  end of DST to avoid interpreting the first @ as a peg revision 
indicator.\n"), N_(
      "  WARNING: For compatibility with previous versions of Subversion,\n"
      "  copies performed using two working copy paths (WC -> WC) will not\n"
      "  contact the repository.  As such, they may not, by default, be able\n"
@@ -631,8 +644,8 @@ svn_cl__cmd_table_main[] =
 
   { "delete", svn_cl__delete, {"del", "remove", "rm"}, {N_(
      "Remove files and directories from version control.\n"
-     "usage: 1. delete PATH...\n"
-     "       2. delete URL...\n"
+     "usage: 1. delete PATH[@]...\n"
+     "       2. delete URL[@]...\n"
      "\n"), N_(
      "  1. Each item specified by a PATH is scheduled for deletion upon\n"
      "    the next commit.  Files, and directories that have not been\n"
@@ -642,7 +655,10 @@ svn_cl__cmd_table_main[] =
      "    not be removed unless the --force or --keep-local option is given.\n"
      "\n"), N_(
      "  2. Each item specified by a URL is deleted from the repository\n"
-     "    via an immediate commit.\n"
+     "    via an immediate commit.\n"), N_(
+     "  If PATH or URL contains an @ character, an additional @ must be 
specified\n"
+     "  at the end of PATH to avoid interpreting the first @ as a peg 
revision\n"
+     "  indicator.\n"
     )},
     {opt_force, 'q', opt_targets, SVN_CL__LOG_MSG_OPTIONS, opt_keep_local} },
 
@@ -692,23 +708,26 @@ svn_cl__cmd_table_main[] =
 
   { "export", svn_cl__export, {0}, {N_(
      "Create an unversioned copy of a tree.\n"
-     "usage: 1. export [-r REV] URL[@PEGREV] [PATH]\n"
-     "       2. export [-r REV] PATH1[@PEGREV] [PATH2]\n"
+     "usage: 1. export [-r REV] URL[@PEGREV] [UNVERSIONED_PATH[@]]\n"
+     "       2. export [-r REV] WCPATH[@PEGREV] [UNVERSIONED_PATH[@]]\n"
      "\n"), N_(
      "  1. Exports a clean directory tree from the repository specified by\n"
      "     URL, at revision REV if it is given, otherwise at HEAD, into\n"
-     "     PATH. If PATH is omitted, the last component of the URL is used\n"
-     "     for the local directory name.\n"
+     "     UNVERSIONED_PATH. If UNVERSIONED_PATH is omitted, the last\n"
+     "     component of the URL is used for the local directory name.\n"
      "\n"), N_(
      "  2. Exports a clean directory tree from the working copy specified by\n"
-     "     PATH1, at revision REV if it is given, otherwise at WORKING, into\n"
-     "     PATH2.  If PATH2 is omitted, the last component of the PATH1 is 
used\n"
-     "     for the local directory name. If REV is not specified, all local\n"
-     "     changes will be preserved.  Files not under version control will\n"
-     "     not be copied.\n"
+     "     WCPATH, at revision REV if it is given, otherwise at WORKING, 
into\n"
+     "     UNVERSIONED_PATH. If UNVERSIONED_PATH is omitted, the last\n"
+     "     component of the WCPATH is used for the local directory name. If\n"
+     "     REV is not specified, all local changes will be preserved. Files\n"
+     "     not under version control will not be copied.\n"
      "\n"), N_(
      "  If specified, PEGREV determines in which revision the target is 
first\n"
-     "  looked up.\n"
+     "  looked up.\n"), N_(
+     "  If UNVERSIONED_PATH contains an @ character, an additional @ must be\n"
+     "  specified at the end of UNVERSIONED_PATH to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     {'r', 'q', 'N', opt_depth, opt_force, opt_native_eol, opt_ignore_externals,
      opt_ignore_keywords},
@@ -1356,8 +1375,8 @@ svn_cl__cmd_table_main[] =
 
   { "mkdir", svn_cl__mkdir, {0}, {N_(
      "Create a new directory under version control.\n"
-     "usage: 1. mkdir PATH...\n"
-     "       2. mkdir URL...\n"
+     "usage: 1. mkdir PATH[@]...\n"
+     "       2. mkdir URL[@]...\n"
      "\n"), N_(
      "  Create version controlled directories.\n"
      "\n"), N_(
@@ -1369,12 +1388,16 @@ svn_cl__cmd_table_main[] =
      "\n"), N_(
      "  In both cases, all the intermediate directories must already exist,\n"
      "  unless the --parents option is given.\n"
+    ), N_(
+     "  If PATH or URL contains an @ character, an additional @ must be\n"
+     "  specified at the end of PATH/URL to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     {'q', opt_parents, SVN_CL__LOG_MSG_OPTIONS} },
 
   { "move", svn_cl__move, {"mv", "rename", "ren"}, {N_(
      "Move (rename) an item in a working copy or repository.\n"
-     "usage: move SRC... DST\n"
+     "usage: move SRC[@]... DST\n"
      "\n"), N_(
      "  SRC and DST can both be working copy (WC) paths or URLs:\n"
      "    WC  -> WC:  move an item in a working copy, as a local change to\n"
@@ -1390,6 +1413,10 @@ svn_cl__cmd_table_main[] =
      "  To avoid unnecessary conflicts, it is recommended to run 'svn 
update'\n"
      "  to update the subtree to a single revision before moving it.\n"
      "  The --allow-mixed-revisions option is provided for backward 
compatibility.\n"
+    ), N_(
+     "  If any SRC contains an @ character, an additional @ must be\n"
+     "  specified at the end of that SRC to avoid interpreting the\n"
+     "  first @ as a peg revision indicator. This does not apply to DST.\n"
     )},
     {'q', opt_force, opt_parents, opt_allow_mixed_revisions,
      SVN_CL__LOG_MSG_OPTIONS, 'r'},
@@ -1397,7 +1424,7 @@ svn_cl__cmd_table_main[] =
 
   { "patch", svn_cl__patch, {0}, {N_(
      "Apply a patch to a working copy.\n"
-     "usage: patch PATCHFILE [WCPATH]\n"
+     "usage: patch PATCHFILE [WCPATH[@]]\n"
      "\n"), N_(
      "  Apply a unidiff patch in PATCHFILE to the working copy WCPATH.\n"
      "  If WCPATH is omitted, '.' is assumed.\n"
@@ -1439,40 +1466,52 @@ svn_cl__cmd_table_main[] =
      "        To avoid rejects, first update to the revision N using\n"
      "        'svn update -r N', apply the patch, and then update back to 
the\n"
      "        HEAD revision. This way, conflicts can be resolved 
interactively.\n"
+    ), N_(
+     "  If WCPATH contains an @ character, an additional @ must be\n"
+     "  specified at the end of WCPATH to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     {'q', opt_dry_run, opt_strip, opt_reverse_diff,
      opt_ignore_whitespace} },
 
   { "propdel", svn_cl__propdel, {"pdel", "pd"}, {N_(
      "Remove a property from files, dirs, or revisions.\n"
-     "usage: 1. propdel PROPNAME [PATH...]\n"
-     "       2. propdel PROPNAME --revprop -r REV [TARGET]\n"
+     "usage: 1. propdel PROPNAME [PATH[@]...]\n"
+     "       2. propdel PROPNAME --revprop -r REV [TARGET[@]]\n"
      "\n"), N_(
      "  1. Removes versioned props in working copy.\n"
      "  2. Removes unversioned remote prop on repos revision.\n"
      "     TARGET only determines which repository to access.\n"
      "\n"), N_(
      "  See 'svn help propset' for descriptions of the svn:* special 
properties.\n"
+    ), N_(
+     "  If PATH or TARGET contains an @ character, an additional @ must be\n"
+     "  specified at the end of PATH or TARGET to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     {'q', 'R', opt_depth, 'r', opt_revprop, opt_changelist} },
 
   { "propedit", svn_cl__propedit, {"pedit", "pe"}, {N_(
      "Edit a property with an external editor.\n"
-     "usage: 1. propedit PROPNAME TARGET...\n"
-     "       2. propedit PROPNAME --revprop -r REV [TARGET]\n"
+     "usage: 1. propedit PROPNAME TARGET[@]...\n"
+     "       2. propedit PROPNAME --revprop -r REV [TARGET[@]]\n"
      "\n"), N_(
      "  1. Edits versioned prop in working copy or repository.\n"
      "  2. Edits unversioned remote prop on repos revision.\n"
      "     TARGET only determines which repository to access.\n"
      "\n"), N_(
      "  See 'svn help propset' for descriptions of the svn:* special 
properties.\n"
+    ), N_(
+     "  If TARGET contains an @ character, an additional @ must be\n"
+     "  specified at the end of TARGET to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     {'r', opt_revprop, SVN_CL__LOG_MSG_OPTIONS, opt_force} },
 
   { "propget", svn_cl__propget, {"pget", "pg"}, {N_(
      "Print the value of a property on files, dirs, or revisions.\n"
      "usage: 1. propget PROPNAME [TARGET[@REV]...]\n"
-     "       2. propget PROPNAME --revprop -r REV [TARGET]\n"
+     "       2. propget PROPNAME --revprop -r REV [TARGET[@]]\n"
      "\n"), N_(
      "  1. Prints versioned props. If specified, REV determines in which\n"
      "     revision the target is first looked up.\n"
@@ -1490,6 +1529,10 @@ svn_cl__cmd_table_main[] =
      "  (useful when redirecting a binary property value to a file, for 
example).\n"
      "\n"), N_(
      "  See 'svn help propset' for descriptions of the svn:* special 
properties.\n"
+    ), N_(
+     "  If TARGET contains an @ character, an additional @ must be\n"
+     "  specified at the end of TARGET to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     {'v', 'R', opt_depth, 'r', opt_revprop, opt_strict, opt_no_newline, 
opt_xml,
      opt_changelist, opt_show_inherited_props },
@@ -1499,7 +1542,7 @@ svn_cl__cmd_table_main[] =
   { "proplist", svn_cl__proplist, {"plist", "pl"}, {N_(
      "List all properties on files, dirs, or revisions.\n"
      "usage: 1. proplist [TARGET[@REV]...]\n"
-     "       2. proplist --revprop -r REV [TARGET]\n"
+     "       2. proplist --revprop -r REV [TARGET[@]]\n"
      "\n"), N_(
      "  1. Lists versioned props. If specified, REV determines in which\n"
      "     revision the target is first looked up.\n"
@@ -1510,6 +1553,10 @@ svn_cl__cmd_table_main[] =
      "  --verbose'.  With --quiet, the paths are not printed.\n"
      "\n"), N_(
      "  See 'svn help propset' for descriptions of the svn:* special 
properties.\n"
+    ), N_(
+     "  If TARGET contains an @ character, an additional @ must be\n"
+     "  specified at the end of TARGET to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     {'v', 'R', opt_depth, 'r', 'q', opt_revprop, opt_xml, opt_changelist,
      opt_show_inherited_props },
@@ -1518,8 +1565,8 @@ svn_cl__cmd_table_main[] =
 
   { "propset", svn_cl__propset, {"pset", "ps"}, {N_(
      "Set the value of a property on files, dirs, or revisions.\n"
-     "usage: 1. propset PROPNAME PROPVAL PATH...\n"
-     "       2. propset PROPNAME --revprop -r REV PROPVAL [TARGET]\n"
+     "usage: 1. propset PROPNAME PROPVAL PATH[@]...\n"
+     "       2. propset PROPNAME --revprop -r REV PROPVAL [TARGET[@]]\n"
      "\n"), N_(
      "  1. Changes a versioned file or directory property in a working copy.\n"
      "  2. Changes an unversioned property on a repository revision.\n"
@@ -1602,6 +1649,10 @@ svn_cl__cmd_table_main[] =
      "      The ambiguous format 'relative_path relative_path' is taken as\n"
      "      'relative_url relative_path' with peg revision support.\n"
      "      Lines starting with a '#' character are ignored.\n"
+    ), N_(
+     "  If PATH or TARGET contains an @ character, an additional @ must be\n"
+     "  specified at the end of PATH or TARGET to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     {'F', opt_encoding, 'q', 'r', opt_targets, 'R', opt_depth, opt_revprop,
      opt_force, opt_changelist },
@@ -1633,7 +1684,7 @@ svn_cl__cmd_table_main[] =
 
   { "resolve", svn_cl__resolve, {0}, {N_(
      "Resolve conflicts on working copy files or directories.\n"
-     "usage: resolve [PATH...]\n"
+     "usage: resolve [PATH[@]...]\n"
      "\n"), N_(
      "  By default, perform interactive conflict resolution on PATH.\n"
      "  In this mode, the command is recursive by default (depth 
'infinity').\n"
@@ -1682,6 +1733,10 @@ svn_cl__cmd_table_main[] =
      "  files manually or with 'svn merge'. It may be necessary to discard 
some\n"
      "  local changes with 'svn revert'. Files or directories might have to 
be\n"
      "  copied, deleted, or moved.\n"
+    ), N_(
+     "  If PATH contains an @ character, an additional @ must be\n"
+     "  specified at the end of PATH to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     {opt_targets, 'R', opt_depth, 'q', opt_accept},
     {{opt_accept, N_("specify automatic conflict resolution source\n"
@@ -1692,18 +1747,22 @@ svn_cl__cmd_table_main[] =
 
   { "resolved", svn_cl__resolved, {0}, {N_(
      "Remove 'conflicted' state on working copy files or directories.\n"
-     "usage: resolved PATH...\n"
+     "usage: resolved PATH[@]...\n"
      "\n"), N_(
      "  Note:  this subcommand does not semantically resolve conflicts or\n"
      "  remove conflict markers; it merely removes the conflict-related\n"
      "  artifact files and allows PATH to be committed again.  It has been\n"
      "  deprecated in favor of running 'svn resolve --accept working'.\n"
+    ), N_(
+     "  If PATH contains an @ character, an additional @ must be\n"
+     "  specified at the end of PATH to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     {opt_targets, 'R', opt_depth, 'q'} },
 
   { "revert", svn_cl__revert, {0}, {N_(
      "Restore pristine working copy state (undo local changes).\n"
-     "usage: revert PATH...\n"
+     "usage: revert PATH[@]...\n"
      "\n"), N_(
      "  Revert changes in the working copy at or within PATH, and remove\n"
      "  conflict markers as well, if any.\n"
@@ -1711,13 +1770,17 @@ svn_cl__cmd_table_main[] =
      "  This subcommand does not revert already committed changes.\n"
      "  For information about undoing already committed changes, search\n"
      "  the output of 'svn help merge' for 'undo'.\n"
+    ), N_(
+     "  If PATH contains an @ character, an additional @ must be\n"
+     "  specified at the end of PATH to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     {opt_targets, 'R', opt_depth, 'q', opt_changelist,
      opt_remove_added} },
 
   { "status", svn_cl__status, {"stat", "st"}, {N_(
      "Print the status of working copy files and directories.\n"
-     "usage: status [PATH...]\n"
+     "usage: status [PATH[@]...]\n"
      "\n"), N_(
      "  With no args, print only locally modified items (no network access).\n"
      "  With -q, print only summary information about locally modified 
items.\n"
@@ -1807,6 +1870,10 @@ svn_cl__cmd_table_main[] =
      "    !     C wc/qaz.c\n"
      "          >   local missing, incoming edit upon update\n"
      "    D       wc/qax.c\n"
+    ), N_(
+     "  If PATH contains an @ character, an additional @ must be\n"
+     "  specified at the end of PATH to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     { 'u', 'v', 'N', opt_depth, 'r', 'q', opt_no_ignore, opt_incremental,
       opt_xml, opt_ignore_externals, opt_changelist},
@@ -1865,16 +1932,20 @@ svn_cl__cmd_table_main[] =
 
   { "unlock", svn_cl__unlock, {0}, {N_(
      "Unlock working copy paths or URLs.\n"
-     "usage: unlock TARGET...\n"
+     "usage: unlock TARGET[@]...\n"
      "\n"), N_(
      "  Use --force to break a lock held by another user or working copy.\n"
+    ), N_(
+     "  If TARGET contains an @ character, an additional @ must be\n"
+     "  specified at the end of TARGET to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     { opt_targets, opt_force, 'q' },
     {{opt_force, N_("break locks")}} },
 
   { "update", svn_cl__update, {"up"},  {N_(
      "Bring changes from the repository into the working copy.\n"
-     "usage: update [PATH...]\n"
+     "usage: update [PATH[@]...]\n"
      "\n"), N_(
      "  If no revision is given, bring working copy up-to-date with HEAD 
rev.\n"
      "  Else synchronize working copy to revision given by -r.\n"
@@ -1918,6 +1989,10 @@ svn_cl__cmd_table_main[] =
      "\n"), N_(
      "  Use the --set-depth option to set a new working copy depth on the\n"
      "  targets of this operation.\n"
+    ), N_(
+     "  If PATH contains an @ character, an additional @ must be\n"
+     "  specified at the end of PATH to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     {'r', 'N', opt_depth, opt_set_depth, 'q', opt_merge_cmd, opt_force,
      opt_ignore_externals, opt_changelist, opt_editor_cmd, opt_accept,
@@ -1928,7 +2003,7 @@ svn_cl__cmd_table_main[] =
 
   { "upgrade", svn_cl__upgrade, {0}, {N_(
      "Upgrade the metadata storage format for a working copy.\n"
-     "usage: upgrade [WCPATH...]\n"
+     "usage: upgrade [WCPATH[@]...]\n"
      "\n"), N_(
      "  The upgraded working copy will be compatible with Subversion 1.8 and\n"
      "  newer (this default may change in the future). To upgrade to a 
different\n"
@@ -1939,6 +2014,10 @@ svn_cl__cmd_table_main[] =
      "  Only upgrades are supported, not downgrades.\n"
      "\n"), N_(
      "  Local modifications are preserved.\n"
+    ), N_(
+     "  If WCPATH contains an @ character, an additional @ must be\n"
+     "  specified at the end of WCPATH to avoid interpreting the\n"
+     "  first @ as a peg revision indicator.\n"
     )},
     { 'q', opt_compatible_version } },
 

Modified: 
subversion/branches/pristine-checksum-salt/subversion/svnbench/notify.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/svnbench/notify.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/svnbench/notify.c 
(original)
+++ subversion/branches/pristine-checksum-salt/subversion/svnbench/notify.c Thu 
Feb  1 20:04:07 2024
@@ -241,6 +241,12 @@ notify(void *baton, const svn_wc_notify_
         goto print_error;
       break;
 
+    case svn_wc_notify_revert_noaccess:
+      if ((err = svn_cmdline_printf(pool, _("User doesn't have WRITE 
permissions to file '%s' and the file isn't svn:needslock. But the file is 
already writeable. Probably owned by another user."),
+                                    path_local)))
+        goto print_error;
+      break;
+
     case svn_wc_notify_failed_revert:
       if (( err = svn_cmdline_printf(pool, _("Failed to revert '%s' -- "
                                              "try updating instead.\n"),

Modified: 
subversion/branches/pristine-checksum-salt/subversion/svnmucc/svnmucc.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/svnmucc/svnmucc.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/svnmucc/svnmucc.c 
(original)
+++ subversion/branches/pristine-checksum-salt/subversion/svnmucc/svnmucc.c Thu 
Feb  1 20:04:07 2024
@@ -286,7 +286,9 @@ help(FILE *stream, apr_pool_t *pool)
       "  mv SRC-URL DST-URL     : move SRC-URL to DST-URL\n"
       "  rm URL                 : delete URL\n"
       "  put SRC-FILE URL       : add or modify file URL with contents copied 
from\n"
-      "                           SRC-FILE (use \"-\" to read from standard 
input)\n"
+      "                           SRC-FILE (to read from standard input, use 
\"--\"\n"
+      "                           to stop option processing followed by \"-\" 
to\n"
+      "                           indicate standard input)\n"
       "  propset NAME VALUE URL : set property NAME on URL to VALUE\n"
       "  propsetf NAME FILE URL : set property NAME on URL to value read from 
FILE\n"
       "  propdel NAME URL       : delete property NAME from URL\n"

Modified: 
subversion/branches/pristine-checksum-salt/subversion/svnserve/svnserve.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/svnserve/svnserve.c?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- subversion/branches/pristine-checksum-salt/subversion/svnserve/svnserve.c 
(original)
+++ subversion/branches/pristine-checksum-salt/subversion/svnserve/svnserve.c 
Thu Feb  1 20:04:07 2024
@@ -574,9 +574,14 @@ accept_connection(connection_t **connect
     || APR_STATUS_IS_ECONNABORTED(status)
     || APR_STATUS_IS_ECONNRESET(status));
 
-  return status
-       ? svn_error_wrap_apr(status, _("Can't accept client connection"))
-       : SVN_NO_ERROR;
+  if (!status)
+    return SVN_NO_ERROR;
+#if APR_HAVE_SIGACTION
+  else if (sigtermint_seen)
+    return SVN_NO_ERROR;
+#endif
+  else
+    return svn_error_wrap_apr(status, _("Can't accept client connection"));
 }
 
 /* Add a reference to CONNECTION, i.e. keep it and it's pool valid unless

Modified: 
subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/basic_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/basic_tests.py?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/basic_tests.py
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/basic_tests.py
 Thu Feb  1 20:04:07 2024
@@ -705,8 +705,8 @@ def basic_conflict(sbox):
 
   # "Extra" files that we expect to result from the conflicts.
   # These are expressed as list of regexps.  What a cool system!  :-)
-  extra_files = ['mu.*\.r1', 'mu.*\.r2', 'mu.*\.mine',
-                 'rho.*\.r1', 'rho.*\.r2', 'rho.*\.mine',]
+  extra_files = [r'mu.*\.r1', r'mu.*\.r2', r'mu.*\.mine',
+                 r'rho.*\.r1', r'rho.*\.r2', r'rho.*\.mine',]
 
   # Do the update and check the results in three ways.
   # All "extra" files are passed to detect_conflict_files().
@@ -2267,11 +2267,11 @@ def automatic_conflict_resolution(sbox):
 
   # "Extra" files that we expect to result from the conflicts.
   # These are expressed as list of regexps.  What a cool system!  :-)
-  extra_files = ['mu.*\.r1', 'mu.*\.r2', 'mu.*\.mine',
-                 'lambda.*\.r1', 'lambda.*\.r2', 'lambda.*\.mine',
-                 'omega.*\.r1', 'omega.*\.r2', 'omega.*\.mine',
-                 'rho.*\.r1', 'rho.*\.r2', 'rho.*\.mine',
-                 'tau.*\.r1', 'tau.*\.r2', 'tau.*\.mine',
+  extra_files = [r'mu.*\.r1', r'mu.*\.r2', r'mu.*\.mine',
+                 r'lambda.*\.r1', r'lambda.*\.r2', r'lambda.*\.mine',
+                 r'omega.*\.r1', r'omega.*\.r2', r'omega.*\.mine',
+                 r'rho.*\.r1', r'rho.*\.r2', r'rho.*\.mine',
+                 r'tau.*\.r1', r'tau.*\.r2', r'tau.*\.mine',
                  ]
 
   # Do the update and check the results in three ways.
@@ -2347,7 +2347,7 @@ def automatic_conflict_resolution(sbox):
                                           ""]))
 
   # Set the expected extra files for the test
-  extra_files = ['omega.*\.r1', 'omega.*\.r2', 'omega.*\.mine',]
+  extra_files = [r'omega.*\.r1', r'omega.*\.r2', r'omega.*\.mine',]
 
   # Set the expected status for the test
   expected_status = svntest.actions.get_virginal_state(wc_backup, 2)

Modified: 
subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/changelist_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/changelist_tests.py?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/changelist_tests.py
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/changelist_tests.py
 Thu Feb  1 20:04:07 2024
@@ -130,9 +130,9 @@ def clname_from_lastchar_cb(full_path):
 
 
 # Regular expressions for 'svn changelist' output.
-_re_cl_rem_pattern = "^D \[(.*)\] (.*)"
-_re_cl_skip = re.compile("Skipped '(.*)'")
-_re_cl_add  = re.compile("^A \[(.*)\] (.*)")
+_re_cl_rem_pattern = r"^D \[(.*)\] (.*)"
+_re_cl_skip = re.compile(r"Skipped '(.*)'")
+_re_cl_add  = re.compile(r"^A \[(.*)\] (.*)")
 _re_cl_rem  = re.compile(_re_cl_rem_pattern)
 
 def verify_changelist_output(output, expected_adds=None,

Modified: 
subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/checkout_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/checkout_tests.py?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/checkout_tests.py
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/checkout_tests.py
 Thu Feb  1 20:04:07 2024
@@ -882,8 +882,8 @@ def co_with_obstructing_local_adds(sbox)
     })
 
   # "Extra" files that we expect to result from the conflicts.
-  extra_files = ['eta\.r0', 'eta\.r2', 'eta\.mine',
-                 'kappa\.r0', 'kappa\.r2', 'kappa\.mine']
+  extra_files = [r'eta\.r0', r'eta\.r2', r'eta\.mine',
+                 r'kappa\.r0', r'kappa\.r2', r'kappa\.mine']
 
   # Perform the checkout and check the results in three ways.
   # We use --force here because run_and_verify_checkout() will delete

Modified: 
subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/copy_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/copy_tests.py?rev=1915519&r1=1915518&r2=1915519&view=diff
==============================================================================
--- 
subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/copy_tests.py
 (original)
+++ 
subversion/branches/pristine-checksum-salt/subversion/tests/cmdline/copy_tests.py
 Thu Feb  1 20:04:07 2024
@@ -1252,6 +1252,55 @@ def wc_copy_parent_into_child(sbox):
                                         expected_status)
 
 #----------------------------------------------------------------------
+@Issue(4913)
+def url_move_parent_into_child(sbox):
+  "move URL URL/subdir"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  B_url = sbox.repo_url + "/A/B"
+  F_url = sbox.repo_url + "/A/B/F"
+
+  expected_error = "svn: E200007: Cannot move path '.*%s' into its own " \
+                   "child '.*%s'" % (re.escape(B_url),
+                                     re.escape(F_url))
+  svntest.actions.run_and_verify_svn(None, expected_error,
+                                     'mv',
+                                     '-m', 'a can of worms',
+                                     B_url, F_url)
+
+#----------------------------------------------------------------------
+@Issue(4913)
+def wc_move_parent_into_child(sbox):
+  "move WC WC/subdir"
+
+  sbox.build(create_wc = False)
+  wc_dir = sbox.wc_dir
+
+  B_url = sbox.repo_url + "/A/B"
+  F_B_url = sbox.repo_url + "/A/B/F/B"
+
+  # Want a smaller WC
+  svntest.main.safe_rmtree(wc_dir)
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'checkout',
+                                     B_url, wc_dir)
+
+  was_cwd = os.getcwd()
+  from_path = os.path.abspath(sbox.ospath(''))
+  to_path = os.path.abspath(sbox.ospath('F/B'))
+  os.chdir(wc_dir)
+  
+  expected_error = "svn: E200007: Cannot move path '%s' into its own " \
+                   "child '%s'" % (re.escape(from_path), re.escape(to_path))
+  svntest.actions.run_and_verify_svn(None, expected_error,
+                                     'mv',
+                                     from_path, to_path)
+
+  os.chdir(was_cwd)
+
+#----------------------------------------------------------------------
 # Issue 1419: at one point ra_neon->get_uuid() was failing on a
 # non-existent public URL, which prevented us from resurrecting files
 # (svn cp -rOLD URL wc).
@@ -1370,7 +1419,7 @@ def repos_to_wc_copy_eol_keywords(sbox):
   if re.match(b'[^\\r]\\n', raw_contents):
     raise svntest.Failure
 
-  if not re.match(b'.*\$LastChangedRevision:\s*\d+\s*\$', line_contents[3]):
+  if not re.match(b'.*\\$LastChangedRevision:\\s*\\d+\\s*\\$', 
line_contents[3]):
     raise svntest.Failure
 
 #-------------------------------------------------------------
@@ -5991,6 +6040,8 @@ test_list = [ None,
               copy_to_root,
               url_copy_parent_into_child,
               wc_copy_parent_into_child,
+              url_move_parent_into_child,
+              wc_move_parent_into_child,
               resurrect_deleted_file,
               diff_repos_to_wc_copy,
               repos_to_wc_copy_eol_keywords,


Reply via email to