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, - ¬ify_required, + ¬ify_required, ¬ify_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,