Author: rinrab
Date: Fri Sep 25 17:57:10 2026
New Revision: 1938518
Log:
On the 'reparentless' branch: Implement lock-unlock operations by
repos_relpath.
* subversion/include/svn_ra.h
(svn_ra_lock2, svn_ra_unlock2): Declare.
(svn_ra_lock, svn_ra_unlock): Deprecate.
* subversion/libsvn_ra/deprecated.c
(svn_ra_lock, svn_ra_unlock): Implement compat wrappers.
* subversion/libsvn_ra/ra_loader.c
(svn_ra_lock2, svn_ra_unlock2): Update version.
* subversion/libsvn_ra_local/ra_plugin.c
(svn_ra_local__lock, svn_ra_local__unlock): Assume absolute paths.
* subversion/libsvn_ra_svn/client.c
(reparent_repos_relpath_hash): New function - substitute for
reparent_path_hash.
(reparent_path_hash): Delete.
(ra_svn_lock, ra_svn_unlock): Use new function for reparenting path
collection.
Modified:
subversion/branches/reparentless/subversion/include/svn_ra.h
subversion/branches/reparentless/subversion/libsvn_ra/deprecated.c
subversion/branches/reparentless/subversion/libsvn_ra/ra_loader.c
subversion/branches/reparentless/subversion/libsvn_ra_local/ra_plugin.c
subversion/branches/reparentless/subversion/libsvn_ra_svn/client.c
Modified: subversion/branches/reparentless/subversion/include/svn_ra.h
==============================================================================
--- subversion/branches/reparentless/subversion/include/svn_ra.h Fri Sep
25 16:52:04 2026 (r1938517)
+++ subversion/branches/reparentless/subversion/include/svn_ra.h Fri Sep
25 17:57:10 2026 (r1938518)
@@ -2191,7 +2191,24 @@ svn_ra_get_file_revs(svn_ra_session_t *s
*
* Use @a pool for temporary allocations.
*
+ * @since New in 1.16.
+ */
+svn_error_t *
+svn_ra_lock2(svn_ra_session_t *session,
+ apr_hash_t *path_revs,
+ const char *comment,
+ svn_boolean_t steal_lock,
+ svn_ra_lock_callback_t lock_func,
+ void *lock_baton,
+ apr_pool_t *pool);
+
+
+/**
+ * Similar to @c svn_ra_lock, but @a path_revs specify paths relative to
+ * session URL.
+ *
* @since New in 1.2.
+ * @deprecated Provided for compatibility with the 1.15 API.
*/
svn_error_t *
svn_ra_lock(svn_ra_session_t *session,
@@ -2223,7 +2240,23 @@ svn_ra_lock(svn_ra_session_t *session,
*
* Use @a pool for temporary allocations.
*
+ * @since New in 1.16.
+ */
+svn_error_t *
+svn_ra_unlock2(svn_ra_session_t *session,
+ apr_hash_t *path_tokens,
+ svn_boolean_t break_lock,
+ svn_ra_lock_callback_t lock_func,
+ void *lock_baton,
+ apr_pool_t *pool);
+
+
+/**
+ * Similar to @c svn_ra_unlock, but @a path_tokens specify paths relative to
+ * session URL.
+ *
* @since New in 1.2.
+ * @deprecated Provided for compatibility with the 1.15 API.
*/
svn_error_t *
svn_ra_unlock(svn_ra_session_t *session,
Modified: subversion/branches/reparentless/subversion/libsvn_ra/deprecated.c
==============================================================================
--- subversion/branches/reparentless/subversion/libsvn_ra/deprecated.c Fri Sep
25 16:52:04 2026 (r1938517)
+++ subversion/branches/reparentless/subversion/libsvn_ra/deprecated.c Fri Sep
25 17:57:10 2026 (r1938518)
@@ -494,6 +494,71 @@ svn_ra_get_locks2(svn_ra_session_t *sess
}
svn_error_t *
+svn_ra_lock(svn_ra_session_t *session,
+ apr_hash_t *path_revs,
+ const char *comment,
+ svn_boolean_t steal_lock,
+ svn_ra_lock_callback_t lock_func,
+ void *lock_baton,
+ apr_pool_t *pool)
+{
+ apr_hash_t *abs_path_revs = apr_hash_make(pool);
+ apr_hash_index_t *hi;
+ const char *session_path;
+
+ SVN_ERR(get_session_path(session, &session_path, pool));
+
+ for (hi = apr_hash_first(pool, path_revs);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *path = apr_hash_this_key(hi);
+ const char *value = apr_hash_this_val(hi);
+
+ svn_hash_sets(abs_path_revs,
+ svn_relpath_join(session_path, path, pool),
+ value);
+ }
+
+ SVN_ERR(svn_ra_lock2(session, abs_path_revs, comment, steal_lock, lock_func,
+ lock_baton, pool));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_unlock(svn_ra_session_t *session,
+ apr_hash_t *path_tokens,
+ svn_boolean_t break_lock,
+ svn_ra_lock_callback_t lock_func,
+ void *lock_baton,
+ apr_pool_t *pool)
+{
+ apr_hash_t *abs_path_tokens = apr_hash_make(pool);
+ apr_hash_index_t *hi;
+ const char *session_path;
+
+ SVN_ERR(get_session_path(session, &session_path, pool));
+
+ for (hi = apr_hash_first(pool, path_tokens);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *path = apr_hash_this_key(hi);
+ const char *value = apr_hash_this_val(hi);
+
+ svn_hash_sets(abs_path_tokens,
+ svn_relpath_join(session_path, path, pool),
+ value);
+ }
+
+ SVN_ERR(svn_ra_unlock2(session, abs_path_tokens, break_lock, lock_func,
+ lock_baton, pool));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_ra_do_update3(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
Modified: subversion/branches/reparentless/subversion/libsvn_ra/ra_loader.c
==============================================================================
--- subversion/branches/reparentless/subversion/libsvn_ra/ra_loader.c Fri Sep
25 16:52:04 2026 (r1938517)
+++ subversion/branches/reparentless/subversion/libsvn_ra/ra_loader.c Fri Sep
25 17:57:10 2026 (r1938518)
@@ -1089,13 +1089,13 @@ svn_error_t *svn_ra_get_file_revs3(svn_r
return svn_error_trace(err);
}
-svn_error_t *svn_ra_lock(svn_ra_session_t *session,
- apr_hash_t *path_revs,
- const char *comment,
- svn_boolean_t steal_lock,
- svn_ra_lock_callback_t lock_func,
- void *lock_baton,
- apr_pool_t *pool)
+svn_error_t *svn_ra_lock2(svn_ra_session_t *session,
+ apr_hash_t *path_revs,
+ const char *comment,
+ svn_boolean_t steal_lock,
+ svn_ra_lock_callback_t lock_func,
+ void *lock_baton,
+ apr_pool_t *pool)
{
apr_hash_index_t *hi;
@@ -1115,12 +1115,12 @@ svn_error_t *svn_ra_lock(svn_ra_session_
lock_func, lock_baton, pool);
}
-svn_error_t *svn_ra_unlock(svn_ra_session_t *session,
- apr_hash_t *path_tokens,
- svn_boolean_t break_lock,
- svn_ra_lock_callback_t lock_func,
- void *lock_baton,
- apr_pool_t *pool)
+svn_error_t *svn_ra_unlock2(svn_ra_session_t *session,
+ apr_hash_t *path_tokens,
+ svn_boolean_t break_lock,
+ svn_ra_lock_callback_t lock_func,
+ void *lock_baton,
+ apr_pool_t *pool)
{
apr_hash_index_t *hi;
Modified:
subversion/branches/reparentless/subversion/libsvn_ra_local/ra_plugin.c
==============================================================================
--- subversion/branches/reparentless/subversion/libsvn_ra_local/ra_plugin.c
Fri Sep 25 16:52:04 2026 (r1938517)
+++ subversion/branches/reparentless/subversion/libsvn_ra_local/ra_plugin.c
Fri Sep 25 17:57:10 2026 (r1938518)
@@ -1523,7 +1523,7 @@ svn_ra_local__lock(svn_ra_session_t *ses
for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi))
{
- const char *abs_path = svn_fspath__join(sess->fs_path->data,
+ const char *abs_path = svn_fspath__join("/",
apr_hash_this_key(hi), pool);
svn_revnum_t current_rev = *(svn_revnum_t *)apr_hash_this_val(hi);
svn_fs_lock_target_t *target = svn_fs_lock_target_create(NULL,
@@ -1573,7 +1573,7 @@ svn_ra_local__unlock(svn_ra_session_t *s
for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi))
{
- const char *abs_path = svn_fspath__join(sess->fs_path->data,
+ const char *abs_path = svn_fspath__join("/",
apr_hash_this_key(hi), pool);
const char *token = apr_hash_this_val(hi);
Modified: subversion/branches/reparentless/subversion/libsvn_ra_svn/client.c
==============================================================================
--- subversion/branches/reparentless/subversion/libsvn_ra_svn/client.c Fri Sep
25 16:52:04 2026 (r1938517)
+++ subversion/branches/reparentless/subversion/libsvn_ra_svn/client.c Fri Sep
25 17:57:10 2026 (r1938518)
@@ -1078,6 +1078,57 @@ reparent_repos_relpath_exact(svn_ra_sess
return SVN_NO_ERROR;
}
+
+static svn_error_t *
+reparent_repos_relpath_hash(svn_ra_session_t *ra_session,
+ apr_hash_t *paths,
+ apr_hash_t *result,
+ apr_pool_t *scratch_pool,
+ apr_pool_t *result_pool)
+{
+ svn_ra_svn__session_baton_t *sess = ra_session->priv;
+ const char *common_ancestor = NULL;
+ const char *dummy, *reparented;
+ apr_hash_index_t *hi;
+
+ for (hi = apr_hash_first(scratch_pool, paths);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *path = apr_hash_this_key(hi);
+
+ if (common_ancestor)
+ common_ancestor = svn_relpath_get_longest_ancestor(common_ancestor,
+ path, scratch_pool);
+ else
+ common_ancestor = path;
+ }
+
+
+ SVN_ERR(reparent_repos_relpath(&dummy, ra_session, common_ancestor,
+ scratch_pool, scratch_pool));
+
+ reparented = svn_uri_skip_ancestor(sess->conn->repos_root,
+ sess->parent->server_url->data,
+ result_pool);
+
+ for (hi = apr_hash_first(scratch_pool, paths);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *path, *newpath;
+
+ path = apr_hash_this_key(hi);
+ newpath = svn_relpath_skip_ancestor(reparented, path);
+
+ svn_hash_sets(result,
+ apr_pstrdup(result_pool, newpath),
+ apr_hash_this_val(hi));
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* Return a copy of PATHS, containing the same const char * paths but
adjusted to the RA_SESSION's server parent URL. Returns NULL if
PATHS is NULL. Allocate the result in RESULT_POOL. */
@@ -1102,33 +1153,6 @@ reparent_path_array(svn_ra_session_t *ra
return result;
}
-/* Return a copy of PATHS, containing the same paths for keys but adjusted
- to the RA_SESSION's server parent URL. Keeps the values as-are and
- returns NULL if PATHS is NULL. Allocate the result in RESULT_POOL. */
-static apr_hash_t *
-reparent_path_hash(svn_ra_session_t *ra_session,
- apr_hash_t *paths,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- apr_hash_t *result;
- apr_hash_index_t *hi;
-
- if (!paths)
- return NULL;
-
- result = svn_hash__make(result_pool);
- for (hi = apr_hash_first(scratch_pool, paths); hi; hi = apr_hash_next(hi))
- {
- const char *path = apr_hash_this_key(hi);
- svn_hash_sets(result,
- reparent_path(ra_session, path, result_pool),
- apr_hash_this_val(hi));
- }
-
- return result;
-}
-
static svn_error_t *ra_svn_reparent(svn_ra_session_t *ra_session,
const char *url,
apr_pool_t *pool)
@@ -2683,15 +2707,17 @@ static svn_error_t *ra_svn_lock(svn_ra_s
{
svn_ra_svn__session_baton_t *sess = session->priv;
svn_ra_svn_conn_t *conn = sess->conn;
+ apr_hash_t *reparented = apr_hash_make(pool);
apr_hash_index_t *hi;
svn_error_t *err;
apr_pool_t *iterpool = svn_pool_create(pool);
- path_revs = reparent_path_hash(session, path_revs, pool, pool);
+ SVN_ERR(reparent_repos_relpath_hash(session, path_revs, reparented,
+ pool, pool));
SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((?c)b(!", "lock-many",
comment, steal_lock));
- for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi))
+ for (hi = apr_hash_first(pool, reparented); hi; hi = apr_hash_next(hi))
{
const void *key;
const char *path;
@@ -2715,7 +2741,7 @@ static svn_error_t *ra_svn_lock(svn_ra_s
if (err && err->apr_err == SVN_ERR_RA_SVN_UNKNOWN_CMD)
{
svn_error_clear(err);
- return ra_svn_lock_compat(session, path_revs, comment, steal_lock,
+ return ra_svn_lock_compat(session, reparented, comment, steal_lock,
lock_func, lock_baton, pool);
}
@@ -2723,7 +2749,7 @@ static svn_error_t *ra_svn_lock(svn_ra_s
return err;
/* Loop over responses to get lock information. */
- for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi))
+ for (hi = apr_hash_first(pool, reparented); hi; hi = apr_hash_next(hi))
{
svn_ra_svn__item_t *elt;
const void *key;
@@ -2807,16 +2833,18 @@ static svn_error_t *ra_svn_unlock(svn_ra
{
svn_ra_svn__session_baton_t *sess = session->priv;
svn_ra_svn_conn_t *conn = sess->conn;
+ apr_hash_t *reparented = apr_hash_make(pool);
apr_hash_index_t *hi;
apr_pool_t *iterpool = svn_pool_create(pool);
svn_error_t *err;
const char *path;
- path_tokens = reparent_path_hash(session, path_tokens, pool, pool);
+ SVN_ERR(reparent_repos_relpath_hash(session, path_tokens, reparented,
+ pool, pool));
SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w(b(!", "unlock-many",
break_lock));
- for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi))
+ for (hi = apr_hash_first(pool, reparented); hi; hi = apr_hash_next(hi))
{
void *val;
const void *key;
@@ -2844,7 +2872,7 @@ static svn_error_t *ra_svn_unlock(svn_ra
if (err && err->apr_err == SVN_ERR_RA_SVN_UNKNOWN_CMD)
{
svn_error_clear(err);
- return ra_svn_unlock_compat(session, path_tokens, break_lock, lock_func,
+ return ra_svn_unlock_compat(session, reparented, break_lock, lock_func,
lock_baton, pool);
}
@@ -2852,7 +2880,7 @@ static svn_error_t *ra_svn_unlock(svn_ra
return err;
/* Loop over responses to unlock files. */
- for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi))
+ for (hi = apr_hash_first(pool, reparented); hi; hi = apr_hash_next(hi))
{
svn_ra_svn__item_t *elt;
const void *key;