Author: rinrab
Date: Fri Sep 4 20:20:39 2026
New Revision: 1937886
Log:
On the 'reparentless' branch: Implement update editor commands (do_update,
do_switch, do_status, and do_diff) with repos_relpath as the target, instead of
session URL.
* subversion/include/svn_ra.h
(svn_ra_do_update4,
svn_ra_do_switch4,
svn_ra_do_status3,
svn_ra_do_diff4): Bump functions, add repos_relpath, update description.
(svn_ra_do_update3,
svn_ra_do_switch3,
svn_ra_do_status2,
svn_ra_do_diff3): Deprecate.
* subversion/libsvn_ra/deprecated.c
(svn_ra_do_update3,
svn_ra_do_switch3,
svn_ra_do_status2,
svn_ra_do_diff3): Implement compat wrappers.
(svn_ra_do_update2,
svn_ra_do_switch2,
svn_ra_do_status2): Wrap around v3's instead of calling vtable directly.
* subversion/libsvn_ra/ra_loader.c
(svn_ra_do_update4,
svn_ra_do_switch4,
svn_ra_do_status3,
svn_ra_do_diff4): Bump versions, add repos_relpath that is checked for
validity and passed further into vtables.
* subversion/libsvn_ra/ra_loader.h
(svn_ra__vtable_t::do_update4,
svn_ra__vtable_t::do_switch4,
svn_ra__vtable_t::do_status3,
svn_ra__vtable_t::do_diff4): Add repos_relpath, reference newer version
of svn_ra.h method.
* subversion/libsvn_ra_local/ra_plugin.c
(make_reporter,
svn_ra_local__do_update,
svn_ra_local__do_switch,
svn_ra_local__do_status,
svn_ra_local__do_diff): Add repos_relpath argument.
* subversion/libsvn_ra_serf/ra_serf.h
(svn_ra_serf__do_update,
svn_ra_serf__do_switch,
svn_ra_serf__do_status,
svn_ra_serf__do_diff): Add repos_relpath argument to the declarations.
* subversion/libsvn_ra_serf/update.c
(make_update_reporter): Resolve repos_relpath into path from server origin
via svn_ra_serf__resolve_path().
(svn_ra_serf__do_update,
svn_ra_serf__do_switch,
svn_ra_serf__do_status,
svn_ra_serf__do_diff): Add repos_relpath and pass it by the callstack.
* subversion/libsvn_ra_svn/client.c
(reparent_repos_relpath_exact): New function.
(ra_svn_update,
ra_svn_switch,
ra_svn_status,
ra_svn_diff): Add repos_relpath, use reparent_repos_relpath_exact() instead
of ensure_exact_server_parent() to prepare the session.
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/ra_loader.h
subversion/branches/reparentless/subversion/libsvn_ra_local/ra_plugin.c
subversion/branches/reparentless/subversion/libsvn_ra_serf/ra_serf.h
subversion/branches/reparentless/subversion/libsvn_ra_serf/update.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
4 20:10:03 2026 (r1937885)
+++ subversion/branches/reparentless/subversion/include/svn_ra.h Fri Sep
4 20:20:39 2026 (r1937886)
@@ -1284,7 +1284,7 @@ svn_ra_get_mergeinfo(svn_ra_session_t *s
*
* @a update_target is an optional single path component to restrict
* the scope of the update to just that entry (in the directory
- * represented by the @a session's URL). If @a update_target is the
+ * represented by the @a repos_relpath). If @a update_target is the
* empty string, the entire directory is updated.
*
* Update the target only as deeply as @a depth indicates.
@@ -1324,8 +1324,31 @@ svn_ra_get_mergeinfo(svn_ra_session_t *s
* leaving any switched subtrees still switched, whereas switch changes
* every node in the tree to a child of the same URL.
*
+ * @since New in 1.16.
+ */
+svn_error_t *
+svn_ra_do_update4(svn_ra_session_t *session,
+ const svn_ra_reporter3_t **reporter,
+ void **report_baton,
+ const char *repos_relpath,
+ svn_revnum_t revision_to_update_to,
+ const char *update_target,
+ svn_depth_t depth,
+ svn_boolean_t send_copyfrom_args,
+ svn_boolean_t ignore_ancestry,
+ const svn_delta_editor_t *update_editor,
+ void *update_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/**
+ * Similar to svn_ra_do_switch4() but origins at session URL instead of
+ * repos_relpath.
+ *
* @since New in 1.8.
+ * @deprecated Provided for compatibility with the 1.15 API.
*/
+SVN_DEPRECATED
svn_error_t *
svn_ra_do_update3(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
@@ -1391,8 +1414,32 @@ svn_ra_do_update(svn_ra_session_t *sessi
* @note Pre Subversion 1.8 svnserve based servers always ignore ancestry
* and never send copyfrom data.
*
+ * @since New in 1.16.
+ */
+svn_error_t *
+svn_ra_do_switch4(svn_ra_session_t *session,
+ const svn_ra_reporter3_t **reporter,
+ void **report_baton,
+ const char *repos_relpath,
+ svn_revnum_t revision_to_switch_to,
+ const char *switch_target,
+ svn_depth_t depth,
+ const char *switch_url,
+ svn_boolean_t send_copyfrom_args,
+ svn_boolean_t ignore_ancestry,
+ const svn_delta_editor_t *switch_editor,
+ void *switch_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/**
+ * Similar to svn_ra_do_switch3() but origins at session URL instead of
+ * repos_relpath.
+ *
* @since New in 1.8.
+ * @deprecated Provided for compatibility with the 1.15 API.
*/
+SVN_DEPRECATED
svn_error_t *
svn_ra_do_switch3(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
@@ -1468,7 +1515,7 @@ svn_ra_do_switch(svn_ra_session_t *sessi
* the working copy were the client to call do_update().
* @a status_target is an optional single path component will restrict
* the scope of the status report to an entry in the directory
- * represented by the @a session's URL, or empty if the entire directory
+ * represented by the @a repos_relpath, or empty if the entire directory
* is meant to be examined.
*
* Get status as deeply as @a depth indicates. If @a depth is
@@ -1489,8 +1536,28 @@ svn_ra_do_switch(svn_ra_session_t *sessi
* needed, and sending too much data back, a pre-1.5 'recurse'
* directive may be sent to the server, based on @a depth.
*
+ * @since New in 1.16.
+ */
+svn_error_t *
+svn_ra_do_status3(svn_ra_session_t *session,
+ const svn_ra_reporter3_t **reporter,
+ void **report_baton,
+ const char *repos_relpath,
+ const char *status_target,
+ svn_revnum_t revision,
+ svn_depth_t depth,
+ const svn_delta_editor_t *status_editor,
+ void *status_baton,
+ apr_pool_t *pool);
+
+/**
+ * Similar to svn_ra_do_status3() but origins at session URL instead of
+ * repos_relpath.
+ *
* @since New in 1.5.
+ * @deprecated Provided for compatibility with the 1.15 API.
*/
+SVN_DEPRECATED
svn_error_t *
svn_ra_do_status2(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
@@ -1546,7 +1613,7 @@ svn_ra_do_status(svn_ra_session_t *sessi
*
* @a diff_target is an optional single path component will restrict
* the scope of the diff to an entry in the directory represented by
- * the @a session's URL, or empty if the entire directory is meant to be
+ * the @a repos_relpath, or empty if the entire directory is meant to be
* one of the diff paths.
*
* The working copy will be diffed against @a versus_url as it exists
@@ -1579,8 +1646,31 @@ svn_ra_do_status(svn_ra_session_t *sessi
* needed, and sending too much data back, a pre-1.5 'recurse'
* directive may be sent to the server, based on @a depth.
*
+ * @since New in 1.16.
+ */
+svn_error_t *
+svn_ra_do_diff4(svn_ra_session_t *session,
+ const svn_ra_reporter3_t **reporter,
+ void **report_baton,
+ const char *repos_relpath,
+ svn_revnum_t revision,
+ const char *diff_target,
+ svn_depth_t depth,
+ svn_boolean_t ignore_ancestry,
+ svn_boolean_t text_deltas,
+ const char *versus_url,
+ const svn_delta_editor_t *diff_editor,
+ void *diff_baton,
+ apr_pool_t *pool);
+
+/**
+ * Similar to svn_ra_do_diff4() but origins at session URL instead of
+ * repos_relpath.
+ *
* @since New in 1.5.
+ * @deprecated Provided for compatibility with the 1.15 API.
*/
+SVN_DEPRECATED
svn_error_t *
svn_ra_do_diff3(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
Modified: subversion/branches/reparentless/subversion/libsvn_ra/deprecated.c
==============================================================================
--- subversion/branches/reparentless/subversion/libsvn_ra/deprecated.c Fri Sep
4 20:10:03 2026 (r1937885)
+++ subversion/branches/reparentless/subversion/libsvn_ra/deprecated.c Fri Sep
4 20:20:39 2026 (r1937886)
@@ -281,6 +281,31 @@ svn_error_t *svn_ra_get_commit_editor(sv
keep_locks, pool);
}
+svn_error_t *
+svn_ra_do_diff3(svn_ra_session_t *session,
+ const svn_ra_reporter3_t **reporter,
+ void **report_baton,
+ svn_revnum_t revision,
+ const char *diff_target,
+ svn_depth_t depth,
+ svn_boolean_t ignore_ancestry,
+ svn_boolean_t text_deltas,
+ const char *versus_url,
+ const svn_delta_editor_t *diff_editor,
+ void *diff_baton,
+ apr_pool_t *pool)
+{
+ const char *session_path;
+ SVN_ERR_ASSERT(svn_path_is_empty(diff_target)
+ || svn_path_is_single_path_component(diff_target));
+ SVN_ERR(get_session_path(session, &session_path, pool));
+
+ return session->vtable->do_diff(session, reporter, report_baton,
+ session_path, revision, diff_target,
+ depth, ignore_ancestry, text_deltas,
+ versus_url, diff_editor, diff_baton, pool);
+}
+
svn_error_t *svn_ra_do_diff2(svn_ra_session_t *session,
const svn_ra_reporter2_t **reporter,
void **report_baton,
@@ -299,12 +324,12 @@ svn_error_t *svn_ra_do_diff2(svn_ra_sess
|| svn_path_is_single_path_component(diff_target));
*reporter = &reporter_3in2_wrapper;
*report_baton = b;
- return session->vtable->do_diff(session,
- &(b->reporter3), &(b->reporter3_baton),
- revision, diff_target,
- SVN_DEPTH_INFINITY_OR_FILES(recurse),
- ignore_ancestry, text_deltas, versus_url,
- diff_editor, diff_baton, pool);
+ return svn_ra_do_diff3(session,
+ &(b->reporter3), &(b->reporter3_baton),
+ revision, diff_target,
+ SVN_DEPTH_INFINITY_OR_FILES(recurse),
+ ignore_ancestry, text_deltas, versus_url,
+ diff_editor, diff_baton, pool);
}
svn_error_t *svn_ra_do_diff(svn_ra_session_t *session,
@@ -382,6 +407,34 @@ svn_error_t *svn_ra_get_file_revs(svn_ra
}
svn_error_t *
+svn_ra_do_update3(svn_ra_session_t *session,
+ const svn_ra_reporter3_t **reporter,
+ void **report_baton,
+ svn_revnum_t revision_to_update_to,
+ const char *update_target,
+ svn_depth_t depth,
+ svn_boolean_t send_copyfrom_args,
+ svn_boolean_t ignore_ancestry,
+ const svn_delta_editor_t *update_editor,
+ void *update_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *session_path;
+ SVN_ERR(get_session_path(session, &session_path, scratch_pool));
+
+ return svn_error_trace(
+ svn_ra_do_update4(session, reporter, report_baton,
+ session_path,
+ revision_to_update_to, update_target,
+ depth,
+ send_copyfrom_args,
+ FALSE /* ignore_ancestry */,
+ update_editor, update_baton,
+ result_pool, scratch_pool));
+}
+
+svn_error_t *
svn_ra_do_update2(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
@@ -419,18 +472,48 @@ svn_error_t *svn_ra_do_update(svn_ra_ses
|| svn_path_is_single_path_component(update_target));
*reporter = &reporter_3in2_wrapper;
*report_baton = b;
- return session->vtable->do_update(session,
- &(b->reporter3), &(b->reporter3_baton),
- revision_to_update_to, update_target,
- SVN_DEPTH_INFINITY_OR_FILES(recurse),
- FALSE, /* no copyfrom args */
- FALSE /* ignore_ancestry */,
- update_editor, update_baton,
- pool, pool);
+ return svn_ra_do_update2(session,
+ &(b->reporter3), &(b->reporter3_baton),
+ revision_to_update_to, update_target,
+ SVN_DEPTH_INFINITY_OR_FILES(recurse),
+ FALSE, /* no copyfrom args */
+ update_editor, update_baton,
+ pool);
}
svn_error_t *
+svn_ra_do_switch3(svn_ra_session_t *session,
+ const svn_ra_reporter3_t **reporter,
+ void **report_baton,
+ svn_revnum_t revision_to_switch_to,
+ const char *switch_target,
+ svn_depth_t depth,
+ const char *switch_url,
+ svn_boolean_t send_copyfrom_args,
+ svn_boolean_t ignore_ancestry,
+ const svn_delta_editor_t *switch_editor,
+ void *switch_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *session_path;
+ SVN_ERR(get_session_path(session, &session_path, scratch_pool));
+
+ return svn_error_trace(
+ svn_ra_do_switch4(session,
+ reporter, report_baton,
+ session_path,
+ revision_to_switch_to, switch_target,
+ depth,
+ switch_url,
+ send_copyfrom_args,
+ ignore_ancestry,
+ switch_editor, switch_baton,
+ result_pool, scratch_pool));
+}
+
+svn_error_t *
svn_ra_do_switch2(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
@@ -470,15 +553,32 @@ svn_error_t *svn_ra_do_switch(svn_ra_ses
|| svn_path_is_single_path_component(switch_target));
*reporter = &reporter_3in2_wrapper;
*report_baton = b;
- return session->vtable->do_switch(session,
- &(b->reporter3), &(b->reporter3_baton),
- revision_to_switch_to, switch_target,
- SVN_DEPTH_INFINITY_OR_FILES(recurse),
- switch_url,
- FALSE /* send_copyfrom_args */,
- TRUE /* ignore_ancestry */,
- switch_editor, switch_baton,
- pool, pool);
+ return svn_ra_do_switch2(session,
+ &(b->reporter3), &(b->reporter3_baton),
+ revision_to_switch_to, switch_target,
+ SVN_DEPTH_INFINITY_OR_FILES(recurse),
+ switch_url,
+ switch_editor, switch_baton,
+ pool);
+}
+
+svn_error_t *
+svn_ra_do_status2(svn_ra_session_t *session,
+ const svn_ra_reporter3_t **reporter,
+ void **report_baton,
+ const char *status_target,
+ svn_revnum_t revision,
+ svn_depth_t depth,
+ const svn_delta_editor_t *status_editor,
+ void *status_baton,
+ apr_pool_t *pool)
+{
+ const char *session_path;
+ SVN_ERR(get_session_path(session, &session_path, pool));
+
+ return svn_ra_do_status3(session, reporter, report_baton, session_path,
+ status_target, revision, depth, status_editor,
+ status_baton, pool);
}
svn_error_t *svn_ra_do_status(svn_ra_session_t *session,
@@ -496,11 +596,11 @@ svn_error_t *svn_ra_do_status(svn_ra_ses
|| svn_path_is_single_path_component(status_target));
*reporter = &reporter_3in2_wrapper;
*report_baton = b;
- return session->vtable->do_status(session,
- &(b->reporter3), &(b->reporter3_baton),
- status_target, revision,
- SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
- status_editor, status_baton, pool);
+ return svn_ra_do_status2(session,
+ &(b->reporter3), &(b->reporter3_baton),
+ status_target, revision,
+ SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
+ status_editor, status_baton, pool);
}
svn_error_t *svn_ra_get_dir(svn_ra_session_t *session,
Modified: subversion/branches/reparentless/subversion/libsvn_ra/ra_loader.c
==============================================================================
--- subversion/branches/reparentless/subversion/libsvn_ra/ra_loader.c Fri Sep
4 20:10:03 2026 (r1937885)
+++ subversion/branches/reparentless/subversion/libsvn_ra/ra_loader.c Fri Sep
4 20:20:39 2026 (r1937886)
@@ -704,9 +704,10 @@ svn_error_t *svn_ra_get_mergeinfo(svn_ra
}
svn_error_t *
-svn_ra_do_update3(svn_ra_session_t *session,
+svn_ra_do_update4(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision_to_update_to,
const char *update_target,
svn_depth_t depth,
@@ -719,8 +720,10 @@ svn_ra_do_update3(svn_ra_session_t *sess
{
SVN_ERR_ASSERT(svn_path_is_empty(update_target)
|| svn_path_is_single_path_component(update_target));
+ SVN_ERR_ASSERT(svn_relpath_is_canonical(repos_relpath));
return session->vtable->do_update(session,
reporter, report_baton,
+ repos_relpath,
revision_to_update_to, update_target,
depth, send_copyfrom_args,
ignore_ancestry,
@@ -729,9 +732,10 @@ svn_ra_do_update3(svn_ra_session_t *sess
}
svn_error_t *
-svn_ra_do_switch3(svn_ra_session_t *session,
+svn_ra_do_switch4(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision_to_switch_to,
const char *switch_target,
svn_depth_t depth,
@@ -745,8 +749,10 @@ svn_ra_do_switch3(svn_ra_session_t *sess
{
SVN_ERR_ASSERT(svn_path_is_empty(switch_target)
|| svn_path_is_single_path_component(switch_target));
+ SVN_ERR_ASSERT(svn_relpath_is_canonical(repos_relpath));
return session->vtable->do_switch(session,
reporter, report_baton,
+ repos_relpath,
revision_to_switch_to, switch_target,
depth, switch_url,
send_copyfrom_args,
@@ -756,9 +762,10 @@ svn_ra_do_switch3(svn_ra_session_t *sess
result_pool, scratch_pool);
}
-svn_error_t *svn_ra_do_status2(svn_ra_session_t *session,
+svn_error_t *svn_ra_do_status3(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
const char *status_target,
svn_revnum_t revision,
svn_depth_t depth,
@@ -768,15 +775,16 @@ svn_error_t *svn_ra_do_status2(svn_ra_se
{
SVN_ERR_ASSERT(svn_path_is_empty(status_target)
|| svn_path_is_single_path_component(status_target));
- return session->vtable->do_status(session,
- reporter, report_baton,
- status_target, revision, depth,
- status_editor, status_baton, pool);
+ SVN_ERR_ASSERT(svn_relpath_is_canonical(repos_relpath));
+ return session->vtable->do_status(session, reporter, report_baton,
+ repos_relpath, status_target, revision,
+ depth, status_editor, status_baton, pool);
}
-svn_error_t *svn_ra_do_diff3(svn_ra_session_t *session,
+svn_error_t *svn_ra_do_diff4(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision,
const char *diff_target,
svn_depth_t depth,
@@ -789,9 +797,10 @@ svn_error_t *svn_ra_do_diff3(svn_ra_sess
{
SVN_ERR_ASSERT(svn_path_is_empty(diff_target)
|| svn_path_is_single_path_component(diff_target));
+ SVN_ERR_ASSERT(svn_relpath_is_canonical(repos_relpath));
return session->vtable->do_diff(session,
reporter, report_baton,
- revision, diff_target,
+ repos_relpath, revision, diff_target,
depth, ignore_ancestry,
text_deltas, versus_url, diff_editor,
diff_baton, pool);
Modified: subversion/branches/reparentless/subversion/libsvn_ra/ra_loader.h
==============================================================================
--- subversion/branches/reparentless/subversion/libsvn_ra/ra_loader.h Fri Sep
4 20:10:03 2026 (r1937885)
+++ subversion/branches/reparentless/subversion/libsvn_ra/ra_loader.h Fri Sep
4 20:20:39 2026 (r1937886)
@@ -160,6 +160,7 @@ typedef struct svn_ra__vtable_t {
svn_error_t *(*do_update)(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision_to_update_to,
const char *update_target,
svn_depth_t depth,
@@ -173,6 +174,7 @@ typedef struct svn_ra__vtable_t {
svn_error_t *(*do_switch)(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision_to_switch_to,
const char *switch_target,
svn_depth_t depth,
@@ -187,6 +189,7 @@ typedef struct svn_ra__vtable_t {
svn_error_t *(*do_status)(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
const char *status_target,
svn_revnum_t revision,
svn_depth_t depth,
@@ -197,6 +200,7 @@ typedef struct svn_ra__vtable_t {
svn_error_t *(*do_diff)(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision,
const char *diff_target,
svn_depth_t depth,
Modified:
subversion/branches/reparentless/subversion/libsvn_ra_local/ra_plugin.c
==============================================================================
--- subversion/branches/reparentless/subversion/libsvn_ra_local/ra_plugin.c
Fri Sep 4 20:10:03 2026 (r1937885)
+++ subversion/branches/reparentless/subversion/libsvn_ra_local/ra_plugin.c
Fri Sep 4 20:20:39 2026 (r1937886)
@@ -292,6 +292,7 @@ static svn_error_t *
make_reporter(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision,
const char *target,
const char *other_url,
@@ -350,7 +351,7 @@ make_reporter(svn_ra_session_t *session,
SVN_ERR(svn_repos_begin_report3(&rbaton,
revision,
sess->repos,
- sess->fs_path->data,
+ repos_relpath,
target,
other_fs_path,
text_deltas,
@@ -978,6 +979,7 @@ static svn_error_t *
svn_ra_local__do_update(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t update_revision,
const char *update_target,
svn_depth_t depth,
@@ -991,6 +993,7 @@ svn_ra_local__do_update(svn_ra_session_t
return make_reporter(session,
reporter,
report_baton,
+ repos_relpath,
update_revision,
update_target,
NULL,
@@ -1008,6 +1011,7 @@ static svn_error_t *
svn_ra_local__do_switch(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t update_revision,
const char *update_target,
svn_depth_t depth,
@@ -1022,6 +1026,7 @@ svn_ra_local__do_switch(svn_ra_session_t
return make_reporter(session,
reporter,
report_baton,
+ repos_relpath,
update_revision,
update_target,
switch_url,
@@ -1039,6 +1044,7 @@ static svn_error_t *
svn_ra_local__do_status(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
const char *status_target,
svn_revnum_t revision,
svn_depth_t depth,
@@ -1049,6 +1055,7 @@ svn_ra_local__do_status(svn_ra_session_t
return make_reporter(session,
reporter,
report_baton,
+ repos_relpath,
revision,
status_target,
NULL,
@@ -1066,6 +1073,7 @@ static svn_error_t *
svn_ra_local__do_diff(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t update_revision,
const char *update_target,
svn_depth_t depth,
@@ -1079,6 +1087,7 @@ svn_ra_local__do_diff(svn_ra_session_t *
return make_reporter(session,
reporter,
report_baton,
+ repos_relpath,
update_revision,
update_target,
switch_url,
Modified: subversion/branches/reparentless/subversion/libsvn_ra_serf/ra_serf.h
==============================================================================
--- subversion/branches/reparentless/subversion/libsvn_ra_serf/ra_serf.h
Fri Sep 4 20:10:03 2026 (r1937885)
+++ subversion/branches/reparentless/subversion/libsvn_ra_serf/ra_serf.h
Fri Sep 4 20:20:39 2026 (r1937886)
@@ -1264,6 +1264,7 @@ svn_error_t *
svn_ra_serf__do_diff(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision,
const char *diff_target,
svn_depth_t depth,
@@ -1279,6 +1280,7 @@ svn_error_t *
svn_ra_serf__do_status(svn_ra_session_t *ra_session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
const char *status_target,
svn_revnum_t revision,
svn_depth_t depth,
@@ -1291,6 +1293,7 @@ svn_error_t *
svn_ra_serf__do_update(svn_ra_session_t *ra_session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision_to_update_to,
const char *update_target,
svn_depth_t depth,
@@ -1306,6 +1309,7 @@ svn_error_t *
svn_ra_serf__do_switch(svn_ra_session_t *ra_session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision_to_switch_to,
const char *switch_target,
svn_depth_t depth,
Modified: subversion/branches/reparentless/subversion/libsvn_ra_serf/update.c
==============================================================================
--- subversion/branches/reparentless/subversion/libsvn_ra_serf/update.c Fri Sep
4 20:10:03 2026 (r1937885)
+++ subversion/branches/reparentless/subversion/libsvn_ra_serf/update.c Fri Sep
4 20:20:39 2026 (r1937886)
@@ -2597,7 +2597,8 @@ make_update_reporter(svn_ra_session_t *r
report->text_deltas = text_deltas;
report->switched_paths = apr_hash_make(report->pool);
- report->source = src_path;
+ SVN_ERR(svn_ra_serf__resolve_path(ra_session, &report->source, src_path,
+ result_pool));
report->destination = dest_path;
report->update_target = update_target;
@@ -2753,6 +2754,7 @@ svn_error_t *
svn_ra_serf__do_update(svn_ra_session_t *ra_session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision_to_update_to,
const char *update_target,
svn_depth_t depth,
@@ -2763,11 +2765,9 @@ svn_ra_serf__do_update(svn_ra_session_t
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_ra_serf__session_t *session = ra_session->priv;
-
SVN_ERR(make_update_reporter(ra_session, reporter, report_baton,
revision_to_update_to,
- session->session_url.path, NULL, update_target,
+ repos_relpath, NULL, update_target,
depth, ignore_ancestry, TRUE /* text_deltas */,
send_copyfrom_args,
update_editor, update_baton,
@@ -2779,6 +2779,7 @@ svn_error_t *
svn_ra_serf__do_diff(svn_ra_session_t *ra_session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision,
const char *diff_target,
svn_depth_t depth,
@@ -2789,12 +2790,11 @@ svn_ra_serf__do_diff(svn_ra_session_t *r
void *diff_baton,
apr_pool_t *pool)
{
- svn_ra_serf__session_t *session = ra_session->priv;
apr_pool_t *scratch_pool = svn_pool_create(pool);
SVN_ERR(make_update_reporter(ra_session, reporter, report_baton,
revision,
- session->session_url.path, versus_url,
diff_target,
+ repos_relpath, versus_url, diff_target,
depth, ignore_ancestry, text_deltas,
FALSE /* send_copyfrom */,
diff_editor, diff_baton,
@@ -2807,6 +2807,7 @@ svn_error_t *
svn_ra_serf__do_status(svn_ra_session_t *ra_session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
const char *status_target,
svn_revnum_t revision,
svn_depth_t depth,
@@ -2814,12 +2815,11 @@ svn_ra_serf__do_status(svn_ra_session_t
void *status_baton,
apr_pool_t *pool)
{
- svn_ra_serf__session_t *session = ra_session->priv;
apr_pool_t *scratch_pool = svn_pool_create(pool);
SVN_ERR(make_update_reporter(ra_session, reporter, report_baton,
revision,
- session->session_url.path, NULL, status_target,
+ repos_relpath, NULL, status_target,
depth, FALSE, FALSE, FALSE,
status_editor, status_baton,
pool, scratch_pool));
@@ -2831,6 +2831,7 @@ svn_error_t *
svn_ra_serf__do_switch(svn_ra_session_t *ra_session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t revision_to_switch_to,
const char *switch_target,
svn_depth_t depth,
@@ -2842,11 +2843,9 @@ svn_ra_serf__do_switch(svn_ra_session_t
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_ra_serf__session_t *session = ra_session->priv;
-
return make_update_reporter(ra_session, reporter, report_baton,
revision_to_switch_to,
- session->session_url.path,
+ repos_relpath,
switch_url, switch_target,
depth,
ignore_ancestry,
Modified: subversion/branches/reparentless/subversion/libsvn_ra_svn/client.c
==============================================================================
--- subversion/branches/reparentless/subversion/libsvn_ra_svn/client.c Fri Sep
4 20:10:03 2026 (r1937885)
+++ subversion/branches/reparentless/subversion/libsvn_ra_svn/client.c Fri Sep
4 20:20:39 2026 (r1937886)
@@ -1051,6 +1051,33 @@ reparent_repos_relpath(const char **path
return SVN_NO_ERROR;
}
+/* Reparent server to repos_relpath but don't change client location. */
+static svn_error_t *
+reparent_repos_relpath_exact(svn_ra_session_t *ra_session,
+ const char *repos_relpath,
+ apr_pool_t *scratch_pool)
+{
+ svn_ra_svn__session_baton_t *sess = ra_session->priv;
+ svn_ra_svn_conn_t *conn = sess->conn;
+ svn_ra_svn__parent_t *parent = sess->parent;
+ const char *url;
+
+ if (! conn->repos_root)
+ return svn_error_create(SVN_ERR_RA_SVN_BAD_VERSION, NULL,
+ _("Server did not send repository root"));
+
+ url = svn_path_url_add_component2(conn->repos_root, repos_relpath,
+ scratch_pool);
+
+ /* No need to reparent if session URL is the same as our resolved URL. */
+ if (strcmp(url, parent->server_url->data) == 0)
+ return SVN_NO_ERROR;
+
+ /* Actually reparent the server. */
+ SVN_ERR(reparent_server(ra_session, url, scratch_pool));
+
+ 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. */
@@ -1750,7 +1777,9 @@ static svn_error_t *ra_svn_get_mergeinfo
static svn_error_t *ra_svn_update(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
- void **report_baton, svn_revnum_t rev,
+ void **report_baton,
+ const char *repos_relpath,
+ svn_revnum_t rev,
const char *target, svn_depth_t depth,
svn_boolean_t send_copyfrom_args,
svn_boolean_t ignore_ancestry,
@@ -1764,7 +1793,7 @@ static svn_error_t *ra_svn_update(svn_ra
svn_boolean_t recurse = DEPTH_TO_RECURSE(depth);
/* Callbacks may assume that all data is relative the sessions's URL. */
- SVN_ERR(ensure_exact_server_parent(session, scratch_pool));
+ SVN_ERR(reparent_repos_relpath_exact(session, repos_relpath, scratch_pool));
/* Tell the server we want to start an update. */
SVN_ERR(svn_ra_svn__write_cmd_update(conn, pool, rev, target, recurse,
@@ -1782,7 +1811,9 @@ static svn_error_t *ra_svn_update(svn_ra
static svn_error_t *
ra_svn_switch(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
- void **report_baton, svn_revnum_t rev,
+ void **report_baton,
+ const char *repos_relpath,
+ svn_revnum_t rev,
const char *target, svn_depth_t depth,
const char *switch_url,
svn_boolean_t send_copyfrom_args,
@@ -1798,7 +1829,7 @@ ra_svn_switch(svn_ra_session_t *session,
svn_boolean_t recurse = DEPTH_TO_RECURSE(depth);
/* Callbacks may assume that all data is relative the sessions's URL. */
- SVN_ERR(ensure_exact_server_parent(session, scratch_pool));
+ SVN_ERR(reparent_repos_relpath_exact(session, repos_relpath, scratch_pool));
/* Tell the server we want to start a switch. */
SVN_ERR(svn_ra_svn__write_cmd_switch(conn, pool, rev, target, recurse,
@@ -1816,6 +1847,7 @@ ra_svn_switch(svn_ra_session_t *session,
static svn_error_t *ra_svn_status(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
const char *target, svn_revnum_t rev,
svn_depth_t depth,
const svn_delta_editor_t *status_editor,
@@ -1826,7 +1858,7 @@ static svn_error_t *ra_svn_status(svn_ra
svn_boolean_t recurse = DEPTH_TO_RECURSE(depth);
/* Callbacks may assume that all data is relative the sessions's URL. */
- SVN_ERR(ensure_exact_server_parent(session, pool));
+ SVN_ERR(reparent_repos_relpath_exact(session, repos_relpath, pool));
/* Tell the server we want to start a status operation. */
SVN_ERR(svn_ra_svn__write_cmd_status(conn, pool, target, recurse, rev,
@@ -1843,6 +1875,7 @@ static svn_error_t *ra_svn_status(svn_ra
static svn_error_t *ra_svn_diff(svn_ra_session_t *session,
const svn_ra_reporter3_t **reporter,
void **report_baton,
+ const char *repos_relpath,
svn_revnum_t rev, const char *target,
svn_depth_t depth,
svn_boolean_t ignore_ancestry,
@@ -1856,7 +1889,7 @@ static svn_error_t *ra_svn_diff(svn_ra_s
svn_boolean_t recurse = DEPTH_TO_RECURSE(depth);
/* Callbacks may assume that all data is relative the sessions's URL. */
- SVN_ERR(ensure_exact_server_parent(session, pool));
+ SVN_ERR(reparent_repos_relpath_exact(session, repos_relpath, pool));
/* Tell the server we want to start a diff. */
SVN_ERR(svn_ra_svn__write_cmd_diff(conn, pool, rev, target, recurse,