You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ko...@apache.org on 2022/12/13 09:49:30 UTC

svn commit: r1905955 [3/6] - in /subversion/trunk: ./ build/ build/generator/ notes/i525/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_fs_x/ subversion/libsvn_ra/ subversion/libsvn_ra_local/ subversion/lib...

Modified: subversion/trunk/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_crawler.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_crawler.c Tue Dec 13 09:49:29 2022
@@ -46,6 +46,7 @@
 #include "translate.h"
 #include "workqueue.h"
 #include "conflicts.h"
+#include "textbase.h"
 
 #include "svn_private_config.h"
 
@@ -74,13 +75,22 @@ restore_file(svn_wc__db_t *db,
              apr_pool_t *scratch_pool)
 {
   svn_skel_t *work_item;
+  const char *install_from;
+  svn_skel_t *cleanup_work_item;
 
+  SVN_ERR(svn_wc__textbase_setaside_wq(&install_from,
+                                       &cleanup_work_item,
+                                       db, local_abspath, NULL,
+                                       cancel_func, cancel_baton,
+                                       scratch_pool, scratch_pool));
   SVN_ERR(svn_wc__wq_build_file_install(&work_item,
                                         db, local_abspath,
-                                        NULL /* source_abspath */,
+                                        install_from,
                                         use_commit_times,
                                         TRUE /* record_fileinfo */,
                                         scratch_pool, scratch_pool));
+  work_item = svn_wc__wq_merge(work_item, cleanup_work_item, scratch_pool);
+
   /* ### we need an existing path for wq_add. not entirely WRI_ABSPATH yet  */
   SVN_ERR(svn_wc__db_wq_add(db,
                             svn_dirent_dirname(local_abspath, scratch_pool),
@@ -211,10 +221,10 @@ maybe_restore_node(svn_wc__db_t *db,
 }
 
 svn_error_t *
-svn_wc_restore(svn_wc_context_t *wc_ctx,
-               const char *local_abspath,
-               svn_boolean_t use_commit_times,
-               apr_pool_t *scratch_pool)
+svn_wc_restore2(svn_wc_context_t *wc_ctx,
+                const char *local_abspath,
+                svn_boolean_t use_commit_times,
+                apr_pool_t *scratch_pool)
 {
   /* ### If ever revved: Add cancel func. */
   svn_wc__db_status_t status;
@@ -297,7 +307,7 @@ svn_wc_restore(svn_wc_context_t *wc_ctx,
    passed here to avoid another database query.
 
    DEPTH_COMPATIBILITY_TRICK means the same thing here as it does
-   in svn_wc_crawl_revisions5().
+   in svn_wc_crawl_revisions6().
 
    If RESTORE_FILES is set, then unexpectedly missing working files
    will be restored from text-base and NOTIFY_FUNC/NOTIFY_BATON
@@ -665,7 +675,7 @@ report_revisions_and_depths(svn_wc__db_t
 
 
 svn_error_t *
-svn_wc_crawl_revisions5(svn_wc_context_t *wc_ctx,
+svn_wc_crawl_revisions6(svn_wc_context_t *wc_ctx,
                         const char *local_abspath,
                         const svn_ra_reporter3_t *reporter,
                         void *report_baton,
@@ -979,8 +989,8 @@ read_and_checksum_pristine_text(svn_stre
 {
   svn_stream_t *base_stream;
 
-  SVN_ERR(svn_wc__get_pristine_contents(&base_stream, NULL, db, local_abspath,
-                                        result_pool, scratch_pool));
+  SVN_ERR(svn_wc__textbase_get_contents(&base_stream, db, local_abspath, NULL,
+                                        TRUE, result_pool, scratch_pool));
   if (base_stream == NULL)
     {
       base_stream = svn_stream_empty(result_pool);
@@ -1096,11 +1106,11 @@ svn_wc__internal_transmit_text_deltas(sv
     {
       svn_stream_t *new_pristine_stream;
 
-      SVN_ERR(svn_wc__db_pristine_prepare_install(&new_pristine_stream,
-                                                  &install_data,
-                                                  &local_sha1_checksum, NULL,
-                                                  db, local_abspath,
-                                                  scratch_pool, scratch_pool));
+      SVN_ERR(svn_wc__textbase_prepare_install(&new_pristine_stream,
+                                               &install_data,
+                                               &local_sha1_checksum, NULL,
+                                               db, local_abspath, FALSE,
+                                               scratch_pool, scratch_pool));
       local_stream = copying_stream(local_stream, new_pristine_stream,
                                     scratch_pool);
     }
@@ -1117,11 +1127,23 @@ svn_wc__internal_transmit_text_deltas(sv
       /* We will be computing a delta against the pristine contents */
       /* We need the expected checksum to be an MD-5 checksum rather than a
        * SHA-1 because we want to pass it to apply_textdelta(). */
-      SVN_ERR(read_and_checksum_pristine_text(&base_stream,
-                                              &expected_md5_checksum,
-                                              &verify_checksum,
-                                              db, local_abspath,
-                                              scratch_pool, scratch_pool));
+      err = read_and_checksum_pristine_text(&base_stream,
+                                            &expected_md5_checksum,
+                                            &verify_checksum,
+                                            db, local_abspath,
+                                            scratch_pool, scratch_pool);
+      if (err && err->apr_err == SVN_ERR_WC_PRISTINE_DEHYDRATED)
+        {
+          /* No local pristine contents to delta against, send a fulltext. */
+          svn_error_clear(err);
+          base_stream = svn_stream_empty(scratch_pool);
+          expected_md5_checksum = NULL;
+          verify_checksum = NULL;
+        }
+      else if (err)
+        {
+          return svn_error_trace(err);
+        }
     }
   else
     {
@@ -1227,7 +1249,7 @@ svn_wc__internal_transmit_text_deltas(sv
 }
 
 svn_error_t *
-svn_wc_transmit_text_deltas3(const svn_checksum_t **new_text_base_md5_checksum,
+svn_wc_transmit_text_deltas4(const svn_checksum_t **new_text_base_md5_checksum,
                              const svn_checksum_t **new_text_base_sha1_checksum,
                              svn_wc_context_t *wc_ctx,
                              const char *local_abspath,

Modified: subversion/trunk/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_files.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_files.c Tue Dec 13 09:49:29 2022
@@ -161,122 +161,6 @@ make_adm_subdir(const char *path,
 
 
 
-/*** Syncing files in the adm area. ***/
-
-
-svn_error_t *
-svn_wc__text_base_path_to_read(const char **result_abspath,
-                               svn_wc__db_t *db,
-                               const char *local_abspath,
-                               apr_pool_t *result_pool,
-                               apr_pool_t *scratch_pool)
-{
-  svn_wc__db_status_t status;
-  svn_node_kind_t kind;
-  const svn_checksum_t *checksum;
-
-  SVN_ERR(svn_wc__db_read_pristine_info(&status, &kind, NULL, NULL, NULL, NULL,
-                                        &checksum, NULL, NULL, NULL,
-                                        db, local_abspath,
-                                        scratch_pool, scratch_pool));
-
-  /* Sanity */
-  if (kind != svn_node_file)
-    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
-                             _("Can only get the pristine contents of files; "
-                               "'%s' is not a file"),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-
-  if (status == svn_wc__db_status_not_present)
-    /* We know that the delete of this node has been committed.
-       This should be the same as if called on an unknown path. */
-    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
-                             _("Cannot get the pristine contents of '%s' "
-                               "because its delete is already committed"),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-  else if (status == svn_wc__db_status_server_excluded
-      || status == svn_wc__db_status_excluded
-      || status == svn_wc__db_status_incomplete)
-    return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
-                             _("Cannot get the pristine contents of '%s' "
-                               "because it has an unexpected status"),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-
-  if (checksum == NULL)
-    return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
-                             _("Node '%s' has no pristine text"),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-  SVN_ERR(svn_wc__db_pristine_get_path(result_abspath, db, local_abspath,
-                                       checksum,
-                                       result_pool, scratch_pool));
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_wc__get_pristine_contents(svn_stream_t **contents,
-                              svn_filesize_t *size,
-                              svn_wc__db_t *db,
-                              const char *local_abspath,
-                              apr_pool_t *result_pool,
-                              apr_pool_t *scratch_pool)
-{
-  svn_wc__db_status_t status;
-  svn_node_kind_t kind;
-  const svn_checksum_t *sha1_checksum;
-
-  if (size)
-    *size = SVN_INVALID_FILESIZE;
-
-  SVN_ERR(svn_wc__db_read_pristine_info(&status, &kind, NULL, NULL, NULL, NULL,
-                                        &sha1_checksum, NULL, NULL, NULL,
-                                        db, local_abspath,
-                                        scratch_pool, scratch_pool));
-
-  /* Sanity */
-  if (kind != svn_node_file)
-    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
-                             _("Can only get the pristine contents of files; "
-                               "'%s' is not a file"),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-
-  if (status == svn_wc__db_status_added && !sha1_checksum)
-    {
-      /* Simply added. The pristine base does not exist. */
-      *contents = NULL;
-      return SVN_NO_ERROR;
-    }
-  else if (status == svn_wc__db_status_not_present)
-    /* We know that the delete of this node has been committed.
-       This should be the same as if called on an unknown path. */
-    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
-                             _("Cannot get the pristine contents of '%s' "
-                               "because its delete is already committed"),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-  else if (status == svn_wc__db_status_server_excluded
-      || status == svn_wc__db_status_excluded
-      || status == svn_wc__db_status_incomplete)
-    return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
-                             _("Cannot get the pristine contents of '%s' "
-                               "because it has an unexpected status"),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-  if (sha1_checksum)
-    SVN_ERR(svn_wc__db_pristine_read(contents, size, db, local_abspath,
-                                     sha1_checksum,
-                                     result_pool, scratch_pool));
-  else
-    *contents = NULL;
-
-  return SVN_NO_ERROR;
-}
-
-
 /*** Opening and closing files in the adm area. ***/
 
 svn_error_t *
@@ -323,6 +207,7 @@ init_adm(svn_wc__db_t *db,
          const char *repos_uuid,
          svn_revnum_t initial_rev,
          svn_depth_t depth,
+         svn_boolean_t store_pristine,
          apr_pool_t *pool)
 {
   /* First, make an empty administrative area. */
@@ -344,7 +229,7 @@ init_adm(svn_wc__db_t *db,
   /* Create the SDB. */
   SVN_ERR(svn_wc__db_init(db, target_format, local_abspath,
                           repos_relpath, repos_root_url, repos_uuid,
-                          initial_rev, depth, pool));
+                          initial_rev, depth, store_pristine, pool));
 
   /* Stamp ENTRIES and FORMAT files for old clients.  */
   SVN_ERR(svn_io_file_create(svn_wc__adm_child(local_abspath,
@@ -370,6 +255,7 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
                             const char *repos_uuid,
                             svn_revnum_t revision,
                             svn_depth_t depth,
+                            svn_boolean_t store_pristine,
                             apr_pool_t *scratch_pool)
 {
   int present_format;
@@ -381,6 +267,7 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
   svn_wc__db_status_t status;
   const char *db_repos_relpath, *db_repos_root_url, *db_repos_uuid;
   svn_revnum_t db_revision;
+  svn_boolean_t wc_store_pristine;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(url != NULL);
@@ -388,6 +275,24 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
   SVN_ERR_ASSERT(repos_uuid != NULL);
   SVN_ERR_ASSERT(repos_relpath != NULL);
 
+  if (target_format < SVN_WC__SUPPORTED_VERSION)
+    return svn_error_createf(
+        SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
+        _("Working copy format %d is not supported by client version %s."),
+        target_format, SVN_VER_NUM);
+
+  if (target_format > SVN_WC__VERSION)
+    return svn_error_createf(
+        SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
+        _("Working copy format %d can't be created by client version %s."),
+        target_format, SVN_VER_NUM);
+
+  if (target_format < SVN_WC__HAS_OPTIONAL_PRISTINE && !store_pristine)
+    return svn_error_createf(
+        SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
+        _("Working copy format %d does not support the requested capabilities"),
+        target_format);
+
   SVN_ERR(svn_wc__internal_check_wc(&present_format, db, local_abspath, TRUE,
                                     scratch_pool));
 
@@ -395,22 +300,31 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
      just create one. */
   if (present_format == 0)
     {
-
-      if (target_format < SVN_WC__SUPPORTED_VERSION)
-        return svn_error_createf(
-            SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
-            _("Working copy format %d is not supported by client version %s."),
-            target_format, SVN_VER_NUM);
-
-      if (target_format > SVN_WC__VERSION)
-        return svn_error_createf(
-            SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
-            _("Working copy format %d can't be created by client version %s."),
-            target_format, SVN_VER_NUM);
-
       return svn_error_trace(init_adm(db, target_format, local_abspath,
                                       repos_relpath, repos_root_url, repos_uuid,
-                                      revision, depth, scratch_pool));
+                                      revision, depth, store_pristine,
+                                      scratch_pool));
+    }
+  else if (present_format != target_format)
+    {
+      return svn_error_createf(
+          SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
+          _("Format %d doesn't match existing format %d in '%s'"),
+          target_format, present_format,
+          svn_dirent_local_style(local_abspath, scratch_pool));
+    }
+
+  SVN_ERR(svn_wc__db_get_settings(NULL, &wc_store_pristine, db,
+                                  local_abspath, scratch_pool));
+
+  if ((store_pristine && !wc_store_pristine) ||
+      (!store_pristine && wc_store_pristine))
+    {
+      return svn_error_createf(
+          SVN_ERR_WC_INCOMPATIBLE_SETTINGS, NULL,
+          _("'%s' is an existing working copy with different '%s' setting"),
+          svn_dirent_local_style(local_abspath, scratch_pool),
+          "store-pristine");
     }
 
   SVN_ERR(svn_wc__db_read_info(&status, NULL,
@@ -430,14 +344,6 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
   if (status != svn_wc__db_status_deleted
       && status != svn_wc__db_status_not_present)
     {
-      /* Check that the existing format matches the requested format. */
-      if (present_format != target_format)
-        return svn_error_createf(
-            SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
-            _("Format %d doesn't match existing format %d in '%s'"),
-            target_format, present_format,
-            svn_dirent_local_style(local_abspath, scratch_pool));
-
       /* ### Should we match copyfrom_revision? */
       if (db_revision != revision)
         return
@@ -509,12 +415,13 @@ svn_wc__ensure_adm(svn_wc_context_t *wc_
                    const char *repos_uuid,
                    svn_revnum_t revision,
                    svn_depth_t depth,
+                   svn_boolean_t store_pristine,
                    apr_pool_t *scratch_pool)
 {
   return svn_error_trace(
     svn_wc__internal_ensure_adm(wc_ctx->db, target_format, local_abspath,
                                 url, repos_root_url, repos_uuid, revision,
-                                depth, scratch_pool));
+                                depth, store_pristine, scratch_pool));
 }
 
 svn_error_t *

Modified: subversion/trunk/subversion/libsvn_wc/adm_files.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_files.h?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_files.h (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_files.h Tue Dec 13 09:49:29 2022
@@ -52,55 +52,6 @@ svn_boolean_t svn_wc__adm_area_exists(co
                                       apr_pool_t *pool);
 
 
-/* Set *CONTENTS to a readonly stream on the pristine text of the working
- * version of the file LOCAL_ABSPATH in DB.  If the file is locally copied
- * or moved to this path, this means the pristine text of the copy source,
- * even if the file replaces a previously existing base node at this path.
- *
- * Set *CONTENTS to NULL if there is no pristine text because the file is
- * locally added (even if it replaces an existing base node).  Return an
- * error if there is no pristine text for any other reason.
- *
- * If SIZE is not NULL, set *SIZE to the length of the pristine stream in
- * BYTES or to SVN_INVALID_FILESIZE if no pristine is available for this
- * file.
- *
- * For more detail, see the description of svn_wc_get_pristine_contents2().
- */
-svn_error_t *
-svn_wc__get_pristine_contents(svn_stream_t **contents,
-                              svn_filesize_t *size,
-                              svn_wc__db_t *db,
-                              const char *local_abspath,
-                              apr_pool_t *result_pool,
-                              apr_pool_t *scratch_pool);
-
-/* Set *RESULT_ABSPATH to the absolute path to a readable file containing
-   the WC-1 "normal text-base" of LOCAL_ABSPATH in DB.
-
-   "Normal text-base" means the same as in svn_wc__text_base_path().
-   ### May want to check the callers' exact requirements and replace this
-       definition with something easier to comprehend.
-
-   What the callers want:
-     A path to a file that will remain available and unchanged as long as
-     the caller wants it - such as for the lifetime of RESULT_POOL.
-
-   What the current implementation provides:
-     A path to the file in the pristine store.  This file will be removed or
-     replaced the next time this or another Subversion client updates the WC.
-
-   If the node LOCAL_ABSPATH has no such pristine text, return an error of
-   type SVN_ERR_WC_PATH_UNEXPECTED_STATUS.
-
-   Allocate *RESULT_PATH in RESULT_POOL.  */
-svn_error_t *
-svn_wc__text_base_path_to_read(const char **result_abspath,
-                               svn_wc__db_t *db,
-                               const char *local_abspath,
-                               apr_pool_t *result_pool,
-                               apr_pool_t *scratch_pool);
-
 
 /*** Opening all kinds of adm files ***/
 

Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Tue Dec 13 09:49:29 2022
@@ -53,6 +53,7 @@
 #include "adm_files.h"
 #include "conflicts.h"
 #include "workqueue.h"
+#include "textbase.h"
 
 #include "private/svn_dep_compat.h"
 #include "private/svn_sorts_private.h"
@@ -753,13 +754,86 @@ svn_wc_add_from_disk3(svn_wc_context_t *
   return SVN_NO_ERROR;
 }
 
-/* Return a path where nothing exists on disk, within the admin directory
-   belonging to the WCROOT_ABSPATH directory.  */
-static const char *
-nonexistent_path(const char *wcroot_abspath, apr_pool_t *scratch_pool)
+
+static svn_error_t *
+get_pristine_copy_path(const char **pristine_path_p,
+                       const char *local_abspath,
+                       svn_wc__db_t *db,
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
-  return svn_wc__adm_child(wcroot_abspath, SVN_WC__ADM_NONEXISTENT_PATH,
-                           scratch_pool);
+  svn_boolean_t store_pristine;
+  svn_wc__db_status_t status;
+  svn_node_kind_t kind;
+  const svn_checksum_t *checksum;
+  const char *wcroot_abspath;
+
+  SVN_ERR(svn_wc__db_get_settings(NULL, &store_pristine, db,
+                                  local_abspath, scratch_pool));
+  if (!store_pristine)
+    return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE,
+                            NULL, NULL);
+
+  SVN_ERR(svn_wc__db_read_pristine_info(&status, &kind, NULL, NULL, NULL, NULL,
+                                        &checksum, NULL, NULL, NULL,
+                                        db, local_abspath,
+                                        scratch_pool, scratch_pool));
+
+  /* Sanity */
+  if (kind != svn_node_file)
+    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
+                             _("Can only get the pristine contents of files; "
+                               "'%s' is not a file"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+  if (status == svn_wc__db_status_not_present)
+    /* We know that the delete of this node has been committed.
+       This should be the same as if called on an unknown path. */
+    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                             _("Cannot get the pristine contents of '%s' "
+                               "because its delete is already committed"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+  else if (status == svn_wc__db_status_server_excluded
+      || status == svn_wc__db_status_excluded
+      || status == svn_wc__db_status_incomplete)
+    return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
+                             _("Cannot get the pristine contents of '%s' "
+                               "because it has an unexpected status"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+  SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath, db, local_abspath,
+                                scratch_pool, scratch_pool));
+
+  if (checksum == NULL)
+    {
+      /* Return a path where nothing exists on disk, within the admin directory
+         belonging to the WCROOT_ABSPATH directory.  */
+      *pristine_path_p = svn_wc__adm_child(wcroot_abspath,
+                                           SVN_WC__ADM_NONEXISTENT_PATH,
+                                           result_pool);
+    }
+  else
+    {
+      svn_boolean_t present;
+
+      SVN_ERR(svn_wc__db_pristine_check(&present, NULL, db, local_abspath,
+                                        checksum, scratch_pool));
+      if (!present)
+        return svn_error_createf(SVN_ERR_WC_DB_ERROR, NULL,
+                                 _("The pristine text with checksum '%s' was "
+                                   "not found"),
+                                 svn_checksum_to_cstring_display(checksum,
+                                                                 scratch_pool));
+
+      SVN_ERR(svn_wc__db_pristine_get_future_path(pristine_path_p,
+                                                  wcroot_abspath, checksum,
+                                                  result_pool, scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
 }
 
 
@@ -778,37 +852,23 @@ svn_wc_get_pristine_copy_path(const char
   /* DB is now open. This is seemingly a "light" function that a caller
      may use repeatedly despite error return values. The rest of this
      function should aggressively close DB, even in the error case.  */
+  err = get_pristine_copy_path(pristine_path, local_abspath, db, pool, pool);
 
-  err = svn_wc__text_base_path_to_read(pristine_path, db, local_abspath,
-                                       pool, pool);
-  if (err && err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
-    {
-      /* The node doesn't exist, so return a non-existent path located
-         in WCROOT/.svn/  */
-      const char *wcroot_abspath;
-
-      svn_error_clear(err);
-
-      err = svn_wc__db_get_wcroot(&wcroot_abspath, db, local_abspath,
-                                  pool, pool);
-      if (err == NULL)
-        *pristine_path = nonexistent_path(wcroot_abspath, pool);
-    }
-
-   return svn_error_compose_create(err, svn_wc__db_close(db));
+  return svn_error_compose_create(err, svn_wc__db_close(db));
 }
 
 
 svn_error_t *
-svn_wc_get_pristine_contents2(svn_stream_t **contents,
+svn_wc_get_pristine_contents3(svn_stream_t **contents,
                               svn_wc_context_t *wc_ctx,
                               const char *local_abspath,
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
 {
-  return svn_error_trace(svn_wc__get_pristine_contents(contents, NULL,
+  return svn_error_trace(svn_wc__textbase_get_contents(contents,
                                                        wc_ctx->db,
                                                        local_abspath,
+                                                       NULL, TRUE,
                                                        result_pool,
                                                        scratch_pool));
 }
@@ -825,13 +885,14 @@ typedef struct get_pristine_lazyopen_bat
 
 /* Implements svn_stream_lazyopen_func_t */
 static svn_error_t *
-get_pristine_lazyopen_func(svn_stream_t **stream,
+get_pristine_lazyopen_func(svn_stream_t **stream_p,
                            void *baton,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
 {
   get_pristine_lazyopen_baton_t *b = baton;
   const svn_checksum_t *sha1_checksum;
+  svn_stream_t *stream;
 
   /* svn_wc__db_pristine_read() wants a SHA1, so if we have an MD5,
      we'll use it to lookup the SHA1. */
@@ -842,9 +903,13 @@ get_pristine_lazyopen_func(svn_stream_t
                                          b->wri_abspath, b->checksum,
                                          scratch_pool, scratch_pool));
 
-  SVN_ERR(svn_wc__db_pristine_read(stream, NULL, b->wc_ctx->db,
+  SVN_ERR(svn_wc__db_pristine_read(&stream, NULL, b->wc_ctx->db,
                                    b->wri_abspath, sha1_checksum,
                                    result_pool, scratch_pool));
+  if (!stream)
+    return svn_error_create(SVN_ERR_WC_PRISTINE_DEHYDRATED, NULL, NULL);
+
+  *stream_p = stream;
   return SVN_NO_ERROR;
 }
 
@@ -857,13 +922,14 @@ svn_wc__get_pristine_contents_by_checksu
                                           apr_pool_t *scratch_pool)
 {
   svn_boolean_t present;
+  svn_boolean_t hydrated;
 
   *contents = NULL;
 
-  SVN_ERR(svn_wc__db_pristine_check(&present, wc_ctx->db, wri_abspath,
-                                    checksum, scratch_pool));
+  SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, wc_ctx->db,
+                                    wri_abspath, checksum, scratch_pool));
 
-  if (present)
+  if (present && hydrated)
     {
       get_pristine_lazyopen_baton_t *gpl_baton;
 

Modified: subversion/trunk/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/conflicts.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_wc/conflicts.c Tue Dec 13 09:49:29 2022
@@ -3365,6 +3365,13 @@ svn_wc_resolved_conflict5(svn_wc_context
                           void *notify_baton,
                           apr_pool_t *scratch_pool)
 {
+  svn_boolean_t store_pristine;
+
+  SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath,
+                               scratch_pool));
+  if (!store_pristine)
+    return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL);
+
   return svn_error_trace(svn_wc__resolve_conflicts(wc_ctx, local_abspath,
                                                    depth, resolve_text,
                                                    resolve_prop, resolve_tree,

Modified: subversion/trunk/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/copy.c (original)
+++ subversion/trunk/subversion/libsvn_wc/copy.c Tue Dec 13 09:49:29 2022
@@ -38,6 +38,7 @@
 #include "workqueue.h"
 #include "props.h"
 #include "conflicts.h"
+#include "textbase.h"
 
 #include "svn_private_config.h"
 #include "private/svn_wc_private.h"
@@ -138,11 +139,20 @@ copy_to_tmpdir(svn_skel_t **work_item,
 
       if (!modified)
         {
-          /* Why create a temp copy if we can just reinstall from pristine? */
-          SVN_ERR(svn_wc__wq_build_file_install(work_item,
-                                                db, dst_abspath, NULL, FALSE,
-                                                TRUE,
+          const char *install_from;
+          svn_skel_t *cleanup_work_item;
+
+          SVN_ERR(svn_wc__textbase_setaside_wq(&install_from,
+                                               &cleanup_work_item,
+                                               db, src_abspath, NULL,
+                                               cancel_func, cancel_baton,
+                                               result_pool, scratch_pool));
+          SVN_ERR(svn_wc__wq_build_file_install(work_item, db, dst_abspath,
+                                                install_from, FALSE, TRUE,
                                                 result_pool, scratch_pool));
+          *work_item = svn_wc__wq_merge(*work_item, cleanup_work_item,
+                                        result_pool);
+
           return SVN_NO_ERROR;
         }
     }

Modified: subversion/trunk/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/deprecated.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_wc/deprecated.c Tue Dec 13 09:49:29 2022
@@ -155,6 +155,51 @@ gather_traversal_info(svn_wc_context_t *
 /*** From adm_crawler.c ***/
 
 svn_error_t *
+svn_wc_crawl_revisions5(svn_wc_context_t *wc_ctx,
+                        const char *local_abspath,
+                        const svn_ra_reporter3_t *reporter,
+                        void *report_baton,
+                        svn_boolean_t restore_files,
+                        svn_depth_t depth,
+                        svn_boolean_t honor_depth_exclude,
+                        svn_boolean_t depth_compatibility_trick,
+                        svn_boolean_t use_commit_times,
+                        svn_cancel_func_t cancel_func,
+                        void *cancel_baton,
+                        svn_wc_notify_func2_t notify_func,
+                        void *notify_baton,
+                        apr_pool_t *scratch_pool)
+{
+  if (restore_files)
+    {
+      svn_boolean_t store_pristine;
+
+      SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath,
+                                   scratch_pool));
+      if (!store_pristine)
+        return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE,
+                                NULL, NULL);
+    }
+
+  SVN_ERR(svn_wc_crawl_revisions6(wc_ctx,
+                                  local_abspath,
+                                  reporter,
+                                  report_baton,
+                                  restore_files,
+                                  depth,
+                                  honor_depth_exclude,
+                                  depth_compatibility_trick,
+                                  use_commit_times,
+                                  cancel_func,
+                                  cancel_baton,
+                                  notify_func,
+                                  notify_baton,
+                                  scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_wc_crawl_revisions4(const char *path,
                         svn_wc_adm_access_t *adm_access,
                         const svn_ra_reporter3_t *reporter,
@@ -467,6 +512,37 @@ svn_wc_crawl_revisions(const char *path,
 }
 
 svn_error_t *
+svn_wc_transmit_text_deltas3(const svn_checksum_t **new_text_base_md5_checksum,
+                             const svn_checksum_t **new_text_base_sha1_checksum,
+                             svn_wc_context_t *wc_ctx,
+                             const char *local_abspath,
+                             svn_boolean_t fulltext,
+                             const svn_delta_editor_t *editor,
+                             void *file_baton,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool)
+{
+  svn_boolean_t store_pristine;
+
+  SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath,
+                               scratch_pool));
+  if (!store_pristine)
+    return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL);
+
+  SVN_ERR(svn_wc_transmit_text_deltas4(new_text_base_md5_checksum,
+                                       new_text_base_sha1_checksum,
+                                       wc_ctx,
+                                       local_abspath,
+                                       fulltext,
+                                       editor,
+                                       file_baton,
+                                       result_pool,
+                                       scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_wc_transmit_text_deltas2(const char **tempfile,
                              unsigned char digest[],
                              const char *path,
@@ -568,6 +644,27 @@ svn_wc_transmit_prop_deltas(const char *
   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
 }
 
+svn_error_t *
+svn_wc_restore(svn_wc_context_t *wc_ctx,
+               const char *local_abspath,
+               svn_boolean_t use_commit_times,
+               apr_pool_t *scratch_pool)
+{
+  svn_boolean_t store_pristine;
+
+  SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath,
+                               scratch_pool));
+  if (!store_pristine)
+    return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL);
+
+  SVN_ERR(svn_wc_restore2(wc_ctx,
+                          local_abspath,
+                          use_commit_times,
+                          scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 /*** From adm_files.c ***/
 svn_error_t *
 svn_wc_ensure_adm4(svn_wc_context_t *wc_ctx,
@@ -582,7 +679,7 @@ svn_wc_ensure_adm4(svn_wc_context_t *wc_
   return svn_error_trace(
       svn_wc__ensure_adm(wc_ctx, SVN_WC__DEFAULT_VERSION, local_abspath,
                          url, repos_root_url, repos_uuid, revision, depth,
-                         scratch_pool));
+                         TRUE, scratch_pool));
 }
 
 svn_error_t *
@@ -678,6 +775,29 @@ svn_wc_create_tmp_file2(apr_file_t **fp,
 
 /*** From adm_ops.c ***/
 svn_error_t *
+svn_wc_get_pristine_contents2(svn_stream_t **contents,
+                              svn_wc_context_t *wc_ctx,
+                              const char *local_abspath,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool)
+{
+  svn_boolean_t store_pristine;
+
+  SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath,
+                               scratch_pool));
+  if (!store_pristine)
+    return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL);
+
+  SVN_ERR(svn_wc_get_pristine_contents3(contents,
+                                        wc_ctx,
+                                        local_abspath,
+                                        result_pool,
+                                        scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_wc_get_pristine_contents(svn_stream_t **contents,
                              const char *path,
                              apr_pool_t *result_pool,
@@ -1107,6 +1227,45 @@ svn_wc_add(const char *path,
 
 /*** From revert.c ***/
 svn_error_t *
+svn_wc_revert6(svn_wc_context_t *wc_ctx,
+               const char *local_abspath,
+               svn_depth_t depth,
+               svn_boolean_t use_commit_times,
+               const apr_array_header_t *changelist_filter,
+               svn_boolean_t clear_changelists,
+               svn_boolean_t metadata_only,
+               svn_boolean_t added_keep_local,
+               svn_cancel_func_t cancel_func,
+               void *cancel_baton,
+               svn_wc_notify_func2_t notify_func,
+               void *notify_baton,
+               apr_pool_t *scratch_pool)
+{
+  svn_boolean_t store_pristine;
+
+  SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath,
+                               scratch_pool));
+  if (!store_pristine)
+    return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL);
+
+  SVN_ERR(svn_wc_revert7(wc_ctx,
+                         local_abspath,
+                         depth,
+                         use_commit_times,
+                         changelist_filter,
+                         clear_changelists,
+                         metadata_only,
+                         added_keep_local,
+                         cancel_func,
+                         cancel_baton,
+                         notify_func,
+                         notify_baton,
+                         scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_wc_revert5(svn_wc_context_t *wc_ctx,
                const char *local_abspath,
                svn_depth_t depth,
@@ -2098,6 +2257,12 @@ svn_wc_get_diff_editor6(const svn_delta_
                         apr_pool_t *scratch_pool)
 {
   const svn_diff_tree_processor_t *diff_processor;
+  svn_boolean_t store_pristine;
+
+  SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, anchor_abspath,
+                               scratch_pool));
+  if (!store_pristine)
+    return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL);
 
   /* --git implies --show-copies-as-adds */
   if (use_git_diff_format)
@@ -2297,6 +2462,43 @@ svn_wc_get_diff_editor(svn_wc_adm_access
 }
 
 svn_error_t *
+svn_wc_diff6(svn_wc_context_t *wc_ctx,
+             const char *local_abspath,
+             const svn_wc_diff_callbacks4_t *callbacks,
+             void *callback_baton,
+             svn_depth_t depth,
+             svn_boolean_t ignore_ancestry,
+             svn_boolean_t show_copies_as_adds,
+             svn_boolean_t use_git_diff_format,
+             const apr_array_header_t *changelist_filter,
+             svn_cancel_func_t cancel_func,
+             void *cancel_baton,
+             apr_pool_t *scratch_pool)
+{
+  svn_boolean_t store_pristine;
+
+  SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, local_abspath,
+                               scratch_pool));
+  if (!store_pristine)
+    return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL);
+
+  SVN_ERR(svn_wc_diff7(wc_ctx,
+                       local_abspath,
+                       callbacks,
+                       callback_baton,
+                       depth,
+                       ignore_ancestry,
+                       show_copies_as_adds,
+                       use_git_diff_format,
+                       changelist_filter,
+                       cancel_func,
+                       cancel_baton,
+                       scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_wc_diff5(svn_wc_adm_access_t *anchor,
              const char *target,
              const svn_wc_diff_callbacks3_t *callbacks,
@@ -2983,6 +3185,13 @@ svn_wc_get_status_editor5(const svn_delt
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
 {
+  svn_boolean_t store_pristine;
+
+  SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, anchor_abspath,
+                               scratch_pool));
+  if (!store_pristine)
+    return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL);
+
   return svn_error_trace(
     svn_wc__get_status_editor(editor, edit_baton,
                               set_locks_baton,
@@ -3630,6 +3839,13 @@ svn_wc_get_update_editor4(const svn_delt
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
 {
+  svn_boolean_t store_pristine;
+
+  SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, anchor_abspath,
+                               scratch_pool));
+  if (!store_pristine)
+    return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL);
+
   return svn_error_trace(
     svn_wc__get_update_editor(editor, edit_baton,
                               target_revision,
@@ -3816,6 +4032,13 @@ svn_wc_get_switch_editor4(const svn_delt
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
 {
+  svn_boolean_t store_pristine;
+
+  SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, anchor_abspath,
+                               scratch_pool));
+  if (!store_pristine)
+    return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL);
+
   return svn_error_trace(
     svn_wc__get_switch_editor(editor, edit_baton,
                               target_revision,
@@ -4572,6 +4795,61 @@ svn_wc_copy(const char *src_path,
 /*** From merge.c ***/
 
 svn_error_t *
+svn_wc_merge5(enum svn_wc_merge_outcome_t *merge_content_outcome,
+              enum svn_wc_notify_state_t *merge_props_outcome,
+              svn_wc_context_t *wc_ctx,
+              const char *left_abspath,
+              const char *right_abspath,
+              const char *target_abspath,
+              const char *left_label,
+              const char *right_label,
+              const char *target_label,
+              const svn_wc_conflict_version_t *left_version,
+              const svn_wc_conflict_version_t *right_version,
+              svn_boolean_t dry_run,
+              const char *diff3_cmd,
+              const apr_array_header_t *merge_options,
+              apr_hash_t *original_props,
+              const apr_array_header_t *prop_diff,
+              svn_wc_conflict_resolver_func2_t conflict_func,
+              void *conflict_baton,
+              svn_cancel_func_t cancel_func,
+              void *cancel_baton,
+              apr_pool_t *scratch_pool)
+{
+  svn_boolean_t store_pristine;
+
+  SVN_ERR(svn_wc__get_settings(NULL, &store_pristine, wc_ctx, target_abspath,
+                               scratch_pool));
+  if (!store_pristine)
+    return svn_error_create(SVN_ERR_WC_DEPRECATED_API_STORE_PRISTINE, NULL, NULL);
+
+  SVN_ERR(svn_wc_merge6(merge_content_outcome,
+                        merge_props_outcome,
+                        wc_ctx,
+                        left_abspath,
+                        right_abspath,
+                        target_abspath,
+                        left_label,
+                        right_label,
+                        target_label,
+                        left_version,
+                        right_version,
+                        dry_run,
+                        diff3_cmd,
+                        merge_options,
+                        original_props,
+                        prop_diff,
+                        conflict_func,
+                        conflict_baton,
+                        cancel_func,
+                        cancel_baton,
+                        scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome,
               svn_wc_context_t *wc_ctx,
               const char *left_abspath,
@@ -4901,7 +5179,7 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
                void *notify_baton,
                apr_pool_t *scratch_pool)
 {
-  return svn_wc__upgrade(wc_ctx, local_abspath, SVN_WC__DEFAULT_VERSION,
+  return svn_wc__upgrade(wc_ctx, local_abspath, SVN_WC__DEFAULT_VERSION, TRUE,
                          repos_info_func, repos_info_baton,
                          cancel_func, cancel_baton,
                          notify_func, notify_baton,

Modified: subversion/trunk/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff_editor.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/diff_editor.c Tue Dec 13 09:49:29 2022
@@ -75,6 +75,7 @@
 #include "adm_files.h"
 #include "translate.h"
 #include "diff.h"
+#include "textbase.h"
 
 #include "svn_private_config.h"
 
@@ -476,15 +477,17 @@ svn_wc__diff_base_working_diff(svn_wc__d
   if (skip)
     return SVN_NO_ERROR;
 
-  SVN_ERR(svn_wc__db_pristine_get_path(&pristine_file,
-                                       db, local_abspath, checksum,
-                                       scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__textbase_setaside(&pristine_file,
+                                    db, local_abspath, checksum,
+                                    cancel_func, cancel_baton,
+                                    scratch_pool, scratch_pool));
 
   if (diff_pristine)
-    SVN_ERR(svn_wc__db_pristine_get_path(&local_file,
-                                         db, local_abspath,
-                                         working_checksum,
-                                         scratch_pool, scratch_pool));
+    SVN_ERR(svn_wc__textbase_setaside(&local_file,
+                                      db, local_abspath,
+                                      working_checksum,
+                                      cancel_func, cancel_baton,
+                                      scratch_pool, scratch_pool));
   else if (! (had_props || props_mod))
     local_file = local_abspath;
   else if (files_same)
@@ -1019,8 +1022,9 @@ svn_wc__diff_local_only_file(svn_wc__db_
     right_props = svn_prop_hash_dup(pristine_props, scratch_pool);
 
   if (checksum)
-    SVN_ERR(svn_wc__db_pristine_get_path(&pristine_file, db, local_abspath,
-                                         checksum, scratch_pool, scratch_pool));
+    SVN_ERR(svn_wc__textbase_setaside(&pristine_file, db, local_abspath,
+                                      checksum, cancel_func, cancel_baton,
+                                      scratch_pool, scratch_pool));
   else
     pristine_file = NULL;
 
@@ -1415,9 +1419,10 @@ svn_wc__diff_base_only_file(svn_wc__db_t
   if (skip)
     return SVN_NO_ERROR;
 
-  SVN_ERR(svn_wc__db_pristine_get_path(&pristine_file,
-                                       db, local_abspath, checksum,
-                                       scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__textbase_setaside(&pristine_file,
+                                    db, local_abspath, checksum,
+                                    NULL, NULL,
+                                    scratch_pool, scratch_pool));
 
   SVN_ERR(processor->file_deleted(relpath,
                                   left_src,
@@ -2111,17 +2116,17 @@ apply_textdelta(void *file_baton,
                                                pool));
         }
 
-      SVN_ERR(svn_wc__db_pristine_read(&source, NULL,
-                                       eb->db, fb->local_abspath,
-                                       fb->base_checksum,
-                                       pool, pool));
+      SVN_ERR(svn_wc__textbase_get_contents(&source,
+                                            eb->db, fb->local_abspath,
+                                            fb->base_checksum, FALSE,
+                                            pool, pool));
     }
   else if (fb->base_checksum)
     {
-      SVN_ERR(svn_wc__db_pristine_read(&source, NULL,
-                                       eb->db, fb->local_abspath,
-                                       fb->base_checksum,
-                                       pool, pool));
+      SVN_ERR(svn_wc__textbase_get_contents(&source,
+                                            eb->db, fb->local_abspath,
+                                            fb->base_checksum, FALSE,
+                                            pool, pool));
     }
   else
     source = svn_stream_empty(pool);
@@ -2217,10 +2222,11 @@ close_file(void *file_baton,
     if (! repos_file)
       {
         assert(fb->base_checksum);
-        SVN_ERR(svn_wc__db_pristine_get_path(&repos_file,
-                                             eb->db, eb->anchor_abspath,
-                                             fb->base_checksum,
-                                             scratch_pool, scratch_pool));
+        SVN_ERR(svn_wc__textbase_setaside(&repos_file,
+                                          eb->db, fb->local_abspath,
+                                          fb->base_checksum,
+                                          eb->cancel_func, eb->cancel_baton,
+                                          scratch_pool, scratch_pool));
       }
   }
 
@@ -2253,10 +2259,11 @@ close_file(void *file_baton,
                                                 eb->db, fb->local_abspath,
                                                 scratch_pool, scratch_pool));
           assert(checksum);
-          SVN_ERR(svn_wc__db_pristine_get_path(&localfile,
-                                               eb->db, eb->anchor_abspath,
-                                               checksum,
-                                               scratch_pool, scratch_pool));
+          SVN_ERR(svn_wc__textbase_setaside(&localfile,
+                                            eb->db, fb->local_abspath,
+                                            checksum,
+                                            eb->cancel_func, eb->cancel_baton,
+                                            scratch_pool, scratch_pool));
         }
       else
         {

Modified: subversion/trunk/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff_local.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/trunk/subversion/libsvn_wc/diff_local.c Tue Dec 13 09:49:29 2022
@@ -547,7 +547,7 @@ svn_wc__diff7(svn_boolean_t anchor_at_gi
 }
 
 svn_error_t *
-svn_wc_diff6(svn_wc_context_t *wc_ctx,
+svn_wc_diff7(svn_wc_context_t *wc_ctx,
              const char *local_abspath,
              const svn_wc_diff_callbacks4_t *callbacks,
              void *callback_baton,

Modified: subversion/trunk/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/externals.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/externals.c (original)
+++ subversion/trunk/subversion/libsvn_wc/externals.c Tue Dec 13 09:49:29 2022
@@ -53,6 +53,7 @@
 #include "translate.h"
 #include "workqueue.h"
 #include "conflicts.h"
+#include "textbase.h"
 
 #include "svn_private_config.h"
 
@@ -631,19 +632,21 @@ apply_textdelta(void *file_baton,
                                                            pool)));
         }
 
-      SVN_ERR(svn_wc__db_pristine_read(&src_stream, NULL, eb->db,
-                                       eb->wri_abspath, eb->original_checksum,
-                                       pool, pool));
+      SVN_ERR(svn_wc__textbase_get_contents(&src_stream, eb->db,
+                                            eb->local_abspath,
+                                            eb->original_checksum,
+                                            FALSE, pool, pool));
     }
   else
     src_stream = svn_stream_empty(pool);
 
-  SVN_ERR(svn_wc__db_pristine_prepare_install(&dest_stream,
-                                              &eb->install_data,
-                                              &eb->new_sha1_checksum,
-                                              &eb->new_md5_checksum,
-                                              eb->db, eb->wri_abspath,
-                                              eb->pool, pool));
+  SVN_ERR(svn_wc__textbase_prepare_install(&dest_stream,
+                                           &eb->install_data,
+                                           &eb->new_sha1_checksum,
+                                           &eb->new_md5_checksum,
+                                           eb->db, eb->local_abspath,
+                                           TRUE,
+                                           eb->pool, pool));
 
   svn_txdelta_apply2(src_stream, dest_stream, NULL, eb->local_abspath, pool,
                      handler, handler_baton);
@@ -887,13 +890,43 @@ close_file(void *file_baton,
           }
         if (install_pristine)
           {
+            svn_stream_t *contents;
+            const char *tmpdir_abspath;
+            svn_stream_t *tmpstream;
+            const char *tmpfile_abspath;
+
+            SVN_ERR(svn_wc__db_pristine_read(&contents, NULL, eb->db,
+                                             eb->wri_abspath,
+                                             eb->new_sha1_checksum,
+                                             pool, pool));
+            if (!contents)
+              return svn_error_create(SVN_ERR_WC_PRISTINE_DEHYDRATED,
+                                      NULL, NULL);
+
+            SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath,
+                                                   eb->db, eb->wri_abspath,
+                                                   pool, pool));
+            SVN_ERR(svn_stream_open_unique(&tmpstream, &tmpfile_abspath,
+                                           tmpdir_abspath,
+                                           svn_io_file_del_none,
+                                           pool, pool));
+            SVN_ERR(svn_stream_copy3(contents, tmpstream, eb->cancel_func,
+                                     eb->cancel_baton, pool));
+
             SVN_ERR(svn_wc__wq_build_file_install(&work_item, eb->db,
                                             eb->local_abspath,
-                                            NULL,
+                                            tmpfile_abspath,
                                             eb->use_commit_times, TRUE,
                                             pool, pool));
 
             all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
+
+            SVN_ERR(svn_wc__wq_build_file_remove(&work_item, eb->db,
+                                                 eb->wri_abspath,
+                                                 tmpfile_abspath,
+                                                 pool, pool));
+
+            all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
           }
       }
     else
@@ -1207,8 +1240,8 @@ svn_wc__crawl_file_external(svn_wc_conte
 
           if (disk_kind == svn_node_none)
             {
-              err = svn_wc_restore(wc_ctx, local_abspath, use_commit_times,
-                                   scratch_pool);
+              err = svn_wc_restore2(wc_ctx, local_abspath, use_commit_times,
+                                    scratch_pool);
 
               if (err)
                 {

Modified: subversion/trunk/subversion/libsvn_wc/info.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/info.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/info.c (original)
+++ subversion/trunk/subversion/libsvn_wc/info.c Tue Dec 13 09:49:29 2022
@@ -106,8 +106,9 @@ build_info_for_node(svn_wc__info2_t **in
 
   wc_info->copyfrom_rev = SVN_INVALID_REVNUM;
 
-  SVN_ERR(svn_wc__db_get_format(&wc_info->wc_format,
-                                db, local_abspath, scratch_pool));
+  SVN_ERR(svn_wc__db_get_settings(&wc_info->wc_format,
+                                  &wc_info->store_pristine,
+                                  db, local_abspath, scratch_pool));
 
   SVN_ERR(svn_wc__db_read_info(&status, &db_kind, &tmpinfo->rev,
                                &repos_relpath,
@@ -556,3 +557,16 @@ svn_wc__get_info(svn_wc_context_t *wc_ct
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_wc__get_settings(int *format_p,
+                     svn_boolean_t *store_pristine_p,
+                     svn_wc_context_t *wc_ctx,
+                     const char *local_abspath,
+                     apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_wc__db_get_settings(format_p, store_pristine_p, wc_ctx->db,
+                                  local_abspath, scratch_pool));
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/trunk/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/merge.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/merge.c (original)
+++ subversion/trunk/subversion/libsvn_wc/merge.c Tue Dec 13 09:49:29 2022
@@ -1202,7 +1202,7 @@ svn_wc__internal_merge(svn_skel_t **work
 
 
 svn_error_t *
-svn_wc_merge5(enum svn_wc_merge_outcome_t *merge_content_outcome,
+svn_wc_merge6(enum svn_wc_merge_outcome_t *merge_content_outcome,
               enum svn_wc_notify_state_t *merge_props_outcome,
               svn_wc_context_t *wc_ctx,
               const char *left_abspath,

Modified: subversion/trunk/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/questions.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/questions.c (original)
+++ subversion/trunk/subversion/libsvn_wc/questions.c Tue Dec 13 09:49:29 2022
@@ -79,15 +79,14 @@
 
 
 /* Set *MODIFIED_P to TRUE if (after translation) VERSIONED_FILE_ABSPATH
- * (of VERSIONED_FILE_SIZE bytes) differs from PRISTINE_STREAM (of
- * PRISTINE_SIZE bytes), else to FALSE if not.
+ * (of VERSIONED_FILE_SIZE bytes) differs from pristine file with checksum
+ * PRISTINE_CHECKSUM, else to FALSE if not.
  *
  * If EXACT_COMPARISON is FALSE, translate VERSIONED_FILE_ABSPATH's EOL
  * style and keywords to repository-normal form according to its properties,
- * and compare the result with PRISTINE_STREAM.  If EXACT_COMPARISON is
- * TRUE, translate PRISTINE_STREAM's EOL style and keywords to working-copy
- * form according to VERSIONED_FILE_ABSPATH's properties, and compare the
- * result with VERSIONED_FILE_ABSPATH.
+ * calculate checksum and compare the result with PRISTINE_CHECKSUM.
+ * If EXACT_COMPARISON is TRUE, also check that VERSIONED_FILE_ABSPATH
+ * contents remains the same when retranslated according to its properties.
  *
  * HAS_PROPS should be TRUE if the file had properties when it was not
  * modified, otherwise FALSE.
@@ -95,8 +94,6 @@
  * PROPS_MOD should be TRUE if the file's properties have been changed,
  * otherwise FALSE.
  *
- * PRISTINE_STREAM will be closed before a successful return.
- *
  * DB is a wc_db; use SCRATCH_POOL for temporary allocation.
  */
 static svn_error_t *
@@ -104,20 +101,20 @@ compare_and_verify(svn_boolean_t *modifi
                    svn_wc__db_t *db,
                    const char *versioned_file_abspath,
                    svn_filesize_t versioned_file_size,
-                   svn_stream_t *pristine_stream,
-                   svn_filesize_t pristine_size,
+                   const svn_checksum_t *pristine_checksum,
                    svn_boolean_t has_props,
                    svn_boolean_t props_mod,
                    svn_boolean_t exact_comparison,
                    apr_pool_t *scratch_pool)
 {
-  svn_boolean_t same;
   svn_subst_eol_style_t eol_style;
   const char *eol_str;
   apr_hash_t *keywords;
   svn_boolean_t special = FALSE;
   svn_boolean_t need_translation;
   svn_stream_t *v_stream; /* versioned_file */
+  svn_checksum_t *v_checksum;
+  svn_error_t *err;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(versioned_file_abspath));
 
@@ -133,6 +130,9 @@ compare_and_verify(svn_boolean_t *modifi
                                          !exact_comparison,
                                          scratch_pool, scratch_pool));
 
+      if (eol_style == svn_subst_eol_style_unknown)
+        return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL, NULL, NULL);
+
       need_translation = svn_subst_translation_required(eol_style, eol_str,
                                                         keywords, special,
                                                         TRUE);
@@ -140,13 +140,20 @@ compare_and_verify(svn_boolean_t *modifi
   else
     need_translation = FALSE;
 
-  if (! need_translation
-      && (versioned_file_size != pristine_size))
+  if (! need_translation)
     {
-      *modified_p = TRUE;
+      svn_filesize_t pristine_size;
+
+      SVN_ERR(svn_wc__db_pristine_read(NULL, &pristine_size, db,
+                                       versioned_file_abspath, pristine_checksum,
+                                       scratch_pool, scratch_pool));
+
+      if (versioned_file_size != pristine_size)
+        {
+          *modified_p = TRUE;
 
-      /* ### Why did we open the pristine? */
-      return svn_error_trace(svn_stream_close(pristine_stream));
+          return SVN_NO_ERROR;
+        }
     }
 
   /* ### Other checks possible? */
@@ -162,46 +169,97 @@ compare_and_verify(svn_boolean_t *modifi
       /* We don't use APR-level buffering because the comparison function
        * will do its own buffering. */
       apr_file_t *file;
-      SVN_ERR(svn_io_file_open(&file, versioned_file_abspath, APR_READ,
-                               APR_OS_DEFAULT, scratch_pool));
+      err = svn_io_file_open(&file, versioned_file_abspath, APR_READ,
+                             APR_OS_DEFAULT, scratch_pool);
+      /* Convert EACCESS on working copy path to WC specific error code. */
+      if (err && APR_STATUS_IS_EACCES(err->apr_err))
+        return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL);
+      else
+        SVN_ERR(err);
       v_stream = svn_stream_from_aprfile2(file, FALSE, scratch_pool);
 
       if (need_translation)
         {
-          if (!exact_comparison)
+          const char *pristine_eol_str;
+
+          if (eol_style == svn_subst_eol_style_native)
+            pristine_eol_str = SVN_SUBST_NATIVE_EOL_STR;
+          else
+            pristine_eol_str = eol_str;
+
+          if (exact_comparison)
             {
-              if (eol_style == svn_subst_eol_style_native)
-                eol_str = SVN_SUBST_NATIVE_EOL_STR;
-              else if (eol_style != svn_subst_eol_style_fixed
-                       && eol_style != svn_subst_eol_style_none)
-                return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL,
-                                        svn_stream_close(v_stream), NULL);
+              svn_checksum_t *working_checksum;
+              svn_checksum_t *detranslated_checksum;
+              svn_checksum_t *retranslated_checksum;
+
+              v_stream = svn_stream_checksummed2(v_stream,
+                                                 &working_checksum, NULL,
+                                                 pristine_checksum->kind, TRUE,
+                                                 scratch_pool);
+
+              v_stream = svn_subst_stream_translated(v_stream,
+                                                     pristine_eol_str, TRUE,
+                                                     keywords, FALSE,
+                                                     scratch_pool);
+              v_stream = svn_stream_checksummed2(v_stream,
+                                                 &detranslated_checksum, NULL,
+                                                 pristine_checksum->kind, TRUE,
+                                                 scratch_pool);
+
+              v_stream = svn_subst_stream_translated(v_stream, eol_str, FALSE,
+                                                     keywords, TRUE,
+                                                     scratch_pool);
+              v_stream = svn_stream_checksummed2(v_stream,
+                                                 &retranslated_checksum, NULL,
+                                                 pristine_checksum->kind, TRUE,
+                                                 scratch_pool);
+
+              err = svn_stream_copy3(v_stream, svn_stream_empty(scratch_pool),
+                                     NULL, NULL, scratch_pool);
+              /* Convert EACCESS on working copy path to WC specific error code. */
+              if (err && APR_STATUS_IS_EACCES(err->apr_err))
+                return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL);
+              else
+                SVN_ERR(err);
+
+              if (svn_checksum_match(detranslated_checksum, pristine_checksum) &&
+                  svn_checksum_match(working_checksum, retranslated_checksum))
+                {
+                  *modified_p = FALSE;
+                }
+              else
+                {
+                  *modified_p = TRUE;
+                }
 
+              return SVN_NO_ERROR;
+            }
+          else
+            {
               /* Wrap file stream to detranslate into normal form,
                * "repairing" the EOL style if it is inconsistent. */
               v_stream = svn_subst_stream_translated(v_stream,
-                                                     eol_str,
+                                                     pristine_eol_str,
                                                      TRUE /* repair */,
                                                      keywords,
                                                      FALSE /* expand */,
                                                      scratch_pool);
             }
-          else
-            {
-              /* Wrap base stream to translate into working copy form, and
-               * arrange to throw an error if its EOL style is inconsistent. */
-              pristine_stream = svn_subst_stream_translated(pristine_stream,
-                                                            eol_str, FALSE,
-                                                            keywords, TRUE,
-                                                            scratch_pool);
-            }
         }
     }
 
-  SVN_ERR(svn_stream_contents_same2(&same, pristine_stream, v_stream,
-                                    scratch_pool));
+  /* Get checksum of detranslated (normalized) content. */
+  err = svn_stream_contents_checksum(&v_checksum, v_stream,
+                                     pristine_checksum->kind,
+                                     scratch_pool, scratch_pool);
+  /* Convert EACCESS on working copy path to WC specific error code. */
+  if (err && APR_STATUS_IS_EACCES(err->apr_err))
+    return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL);
+  else
+    SVN_ERR(err);
 
-  *modified_p = (! same);
+  *modified_p = (! svn_checksum_match(v_checksum, pristine_checksum));
 
   return SVN_NO_ERROR;
 }
@@ -213,8 +271,6 @@ svn_wc__internal_file_modified_p(svn_boo
                                  svn_boolean_t exact_comparison,
                                  apr_pool_t *scratch_pool)
 {
-  svn_stream_t *pristine_stream;
-  svn_filesize_t pristine_size;
   svn_wc__db_status_t status;
   svn_node_kind_t kind;
   const svn_checksum_t *checksum;
@@ -302,27 +358,12 @@ svn_wc__internal_file_modified_p(svn_boo
     }
 
  compare_them:
-  SVN_ERR(svn_wc__db_pristine_read(&pristine_stream, &pristine_size,
-                                   db, local_abspath, checksum,
-                                   scratch_pool, scratch_pool));
-
   /* Check all bytes, and verify checksum if requested. */
-  {
-    svn_error_t *err;
-    err = compare_and_verify(modified_p, db,
+  SVN_ERR(compare_and_verify(modified_p, db,
                              local_abspath, dirent->filesize,
-                             pristine_stream, pristine_size,
-                             has_props, props_mod,
+                             checksum, has_props, props_mod,
                              exact_comparison,
-                             scratch_pool);
-
-    /* At this point we already opened the pristine file, so we know that
-       the access denied applies to the working copy path */
-    if (err && APR_STATUS_IS_EACCES(err->apr_err))
-      return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL);
-    else
-      SVN_ERR(err);
-  }
+                             scratch_pool));
 
   if (!*modified_p)
     {

Modified: subversion/trunk/subversion/libsvn_wc/revert.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/revert.c?rev=1905955&r1=1905954&r2=1905955&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/revert.c (original)
+++ subversion/trunk/subversion/libsvn_wc/revert.c Tue Dec 13 09:49:29 2022
@@ -42,6 +42,7 @@
 #include "wc.h"
 #include "adm_files.h"
 #include "workqueue.h"
+#include "textbase.h"
 
 #include "svn_private_config.h"
 #include "private/svn_io_private.h"
@@ -714,10 +715,21 @@ revert_wc_data(svn_boolean_t *run_wq,
       if (kind == svn_node_file)
         {
           svn_skel_t *work_item;
+          const char *install_from;
+          svn_skel_t *cleanup_work_item;
 
+          SVN_ERR(svn_wc__textbase_setaside_wq(&install_from,
+                                               &cleanup_work_item,
+                                               db, local_abspath, NULL,
+                                               cancel_func, cancel_baton,
+                                               scratch_pool, scratch_pool));
           SVN_ERR(svn_wc__wq_build_file_install(&work_item, db, local_abspath,
-                                                NULL, use_commit_times, TRUE,
+                                                install_from,
+                                                use_commit_times, TRUE,
                                                 scratch_pool, scratch_pool));
+          work_item = svn_wc__wq_merge(work_item, cleanup_work_item,
+                                       scratch_pool);
+
           SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item,
                                     scratch_pool));
           *run_wq = TRUE;
@@ -969,7 +981,7 @@ revert_partial(svn_wc__db_t *db,
 
 
 svn_error_t *
-svn_wc_revert6(svn_wc_context_t *wc_ctx,
+svn_wc_revert7(svn_wc_context_t *wc_ctx,
                const char *local_abspath,
                svn_depth_t depth,
                svn_boolean_t use_commit_times,