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,

Reply via email to