Author: julianfoad
Date: Thu Feb 10 20:04:43 2022
New Revision: 1897946

URL: http://svn.apache.org/viewvc?rev=1897946&view=rev
Log:
On the 'pristines-on-demand-on-mwf' branch: merge 'pristines-on-demand' here.

Added:
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/textbase.c
      - copied unchanged from r1897945, 
subversion/branches/pristines-on-demand/subversion/libsvn_client/textbase.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/textbase.c
      - copied unchanged from r1897945, 
subversion/branches/pristines-on-demand/subversion/libsvn_wc/textbase.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/textbase.h
      - copied unchanged from r1897945, 
subversion/branches/pristines-on-demand/subversion/libsvn_wc/textbase.h
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_textbase.c
      - copied unchanged from r1897945, 
subversion/branches/pristines-on-demand/subversion/libsvn_wc/wc_db_textbase.c
Modified:
    subversion/branches/pristines-on-demand-on-mwf/   (props changed)
    subversion/branches/pristines-on-demand-on-mwf/BRANCH-README
    subversion/branches/pristines-on-demand-on-mwf/build/run_tests.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/bindings/swig/python/tests/fs.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/include/private/svn_wc_private.h
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/cat.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/client.h
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/commit.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/conflicts.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/diff.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/resolved.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/revert.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/switch.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/update.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/upgrade.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_crawler.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_files.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_files.h
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_ops.c
    subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/copy.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/diff_editor.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/externals.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/questions.c
    subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/revert.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/update_editor.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/upgrade.c
    subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/util.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc-metadata.sql
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db.h
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_pristine.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_update_move.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/authz_tests.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/basic_tests.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/diff_tests.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/externals_tests.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/log_tests.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/pegrev_parse_tests.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/revert_tests.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/actions.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/main.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/trans_tests.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/update_tests.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/upgrade_tests.py
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/db-test.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/entries-compat.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/pristine-store-test.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/utils.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-queries-test.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-test-queries.sql

Propchange: subversion/branches/pristines-on-demand-on-mwf/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1897030-1897694
  Merged /subversion/branches/pristines-on-demand:r1892643-1897945

Modified: subversion/branches/pristines-on-demand-on-mwf/BRANCH-README
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/BRANCH-README?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/BRANCH-README (original)
+++ subversion/branches/pristines-on-demand-on-mwf/BRANCH-README Thu Feb 10 
20:04:43 2022
@@ -48,3 +48,56 @@ OPTIONAL: The "svn upgrade" command may
    Bad Thing, and b) defeat the purpose of this feature, which is
    support for multiple versions of the client in the same working
    copy.
+
+   
+============================================================================
+
+Pristines-on-Demand
+-------------------
+
+The purpose of this branch is to try to make the text-bases in the working
+copy optional [1][2].
+
+
+Description of the approach:
+----------------------------
+
+The core idea is that we start to maintain the following invariant: only the
+modified files have their pristine text-base files available on the disk.
+
+- To avoid having to access the text-base, the "is the file modified?" check
+  is performed by calculating the checksum of a file and comparing that to
+  what's recorded in the working copy.
+
+- A text-base of the unmodified file is the file itself, appropriately
+  detranslated.
+
+- To get into the appropriate state at the beginning of the operation, we walk
+  through the current text-base info in the db and check if the corresponding
+  working files are modified.  The missing text-bases are fetched using the
+  svn_ra layer.  The operations also include a final step during which the
+  no longer required text-bases are removed from disk.
+
+- The operations that don't need to access the text-bases (such as "svn ls"
+  or the updated "svn st") do not perform this walk and do not synchronize
+  the text-base state.
+
+
+For the production-ready state, it would probably make sense to also:
+---------------------------------------------------------------------
+
+ 1. Complete the work on ^/subversion/branches/multi-wc-format so that the
+    client would work with both the new and old working copy formats, for
+    a seamless user experience and better compatibility.
+
+ 2. For the new working copy format, incorporate a switch to a different
+    checksum type without known collisions instead of SHA-1.
+
+3. Fix the minor issues written down as TODOs in the code.
+
+
+References:
+-----------
+
+[1] https://issues.apache.org/jira/browse/SVN-525
+[2] 
https://lists.apache.org/thread.html/r40aa795b9e0c1aabb392c43b64e540432a31e22d8b0d9de7202b4950%40%3Cdev.subversion.apache.org%3E

Modified: subversion/branches/pristines-on-demand-on-mwf/build/run_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/build/run_tests.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/build/run_tests.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/build/run_tests.py Thu Feb 
10 20:04:43 2022
@@ -803,10 +803,12 @@ class TestHarness:
     # ### Even if failure==1 it could be that the test didn't run at all.
     if test_failed and test_failed != 1:
       if self.log:
-        log.write('FAIL:  %s: Unknown test failure; see tests.log.\n' % 
progbase)
+        log.write('FAIL:  %s: Unknown test failure (%s); see tests.log.\n'
+                  % (progbase, test_failed))
         log.flush()
       else:
-        log.write('FAIL:  %s: Unknown test failure.\n' % progbase)
+        log.write('FAIL:  %s: Unknown test failure (%s).\n'
+                  % (progbase, test_failed))
 
   def _run_c_test(self, progabs, progdir, progbase, test_nums, dot_count):
     'Run a c test, escaping parameters as required.'

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/bindings/swig/python/tests/fs.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/bindings/swig/python/tests/fs.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/bindings/swig/python/tests/fs.py
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/bindings/swig/python/tests/fs.py
 Thu Feb 10 20:04:43 2022
@@ -346,13 +346,12 @@ class SubversionFSTestCase(unittest.Test
     if (isinstance(expected_conflict, bytes)
         and not isinstance(expected_conflict, str)):
       expected_conflict = expected_conflict.decode('utf-8')
-    err = None
+
     new_rev = None
     conflict = None
     try:
       conflict, new_rev = fs.commit_txn(txn, pool)
     except core.SubversionException as e:
-      err = e
       self.assertTrue(hasattr(e, 'conflict_p'))
       conflict = e.conflict_p
       if isinstance(conflict, bytes) and not isinstance(conflict, str):
@@ -360,41 +359,42 @@ class SubversionFSTestCase(unittest.Test
       self.assertTrue(hasattr(e, 'new_rev'))
       new_rev = e.new_rev
 
-    if err and err.apr_err == core.SVN_ERR_FS_CONFLICT:
-      self.assertIsNotNone(expected_conflict,
-          "commit conflicted at '%s', but no conflict expected"
-          % conflict if conflict else '(missing conflict info!)')
-      self.assertIsNotNone(conflict,
-          "commit conflicted as expected, "
-          "but no conflict path was returned ('%s' expected)"
-          % expected_conflict)
-      if expected_conflict:
-        self.assertEqual(conflict, expected_conflict,
-            "commit conflicted at '%s', but expected conflict at '%s'"
-            % (conflict, expected_conflict))
-
-      # The svn_fs_commit_txn() API promises to set *NEW_REV to an
-      # invalid revision number in the case of a conflict.
-      self.assertEqual(new_rev, core.SVN_INVALID_REVNUM,
-                       "conflicting commit returned valid new revision")
-
-    elif err:
-      # commit may have succeeded, but always report an error
-      if new_rev != core.SVN_INVALID_REVNUM:
-        raise core.SubversionException(
-                    "commit succeeded but something else failed",
-                    err.apr_err, err)
+      if e.apr_err == core.SVN_ERR_FS_CONFLICT:
+        self.assertIsNotNone(expected_conflict,
+            "commit conflicted at '%s', but no conflict expected"
+            % conflict if conflict else '(missing conflict info!)')
+        self.assertIsNotNone(conflict,
+            "commit conflicted as expected, "
+            "but no conflict path was returned ('%s' expected)"
+            % expected_conflict)
+        if expected_conflict:
+          self.assertEqual(conflict, expected_conflict,
+              "commit conflicted at '%s', but expected conflict at '%s'"
+              % (conflict, expected_conflict))
+
+        # The svn_fs_commit_txn() API promises to set *NEW_REV to an
+        # invalid revision number in the case of a conflict.
+        self.assertEqual(new_rev, core.SVN_INVALID_REVNUM,
+                         "conflicting commit returned valid new revision")
+
       else:
-        raise core.SubversionException(
-                    "commit failed due to something other than conflict",
-                    err.apr_err, err)
+        # commit may have succeeded, but always report an error
+        if new_rev != core.SVN_INVALID_REVNUM:
+          raise core.SubversionException(
+                      "commit succeeded but something else failed",
+                      e.apr_err, e)
+        else:
+          raise core.SubversionException(
+                      "commit failed due to something other than conflict",
+                      e.apr_err, e)
     else:
-      # err == None, commit should have succeeded
+      # commit should have succeeded
       self.assertNotEqual(new_rev, core.SVN_INVALID_REVNUM,
                           "commit failed but no error was returned")
       self.assertIsNone(expected_conflict,
                         "commit succeeded that was expected to fail at '%s'"
                         % expected_conflict)
+
     return new_rev
 
 

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/include/private/svn_wc_private.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/include/private/svn_wc_private.h?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/include/private/svn_wc_private.h
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/include/private/svn_wc_private.h
 Thu Feb 10 20:04:43 2022
@@ -2312,6 +2312,33 @@ svn_wc__upgrade(svn_wc_context_t *wc_ctx
                 void *notify_baton,
                 apr_pool_t *scratch_pool);
 
+/* The callback invoked by svn_wc__textbase_sync() to fetch the text-base
+   contents identified by REPOS_ROOT_URL, REPOS_RELPATH and REVISION. */
+typedef svn_error_t *(*svn_wc__textbase_hydrate_cb_t)(
+  void *baton,
+  const char *repos_root_url,
+  const char *repos_relpath,
+  svn_revnum_t revision,
+  svn_stream_t *contents,
+  svn_cancel_func_t cancel_func,
+  void *cancel_baton,
+  apr_pool_t *scratch_pool);
+
+/* Synchronize the state of the text-base contents for the LOCAL_ABSPATH tree.
+   If ALLOW_HYDRATE is true, fetch the required but missing text-base contents
+   using the provided HYDRATE_CALLBACK and HYDRATE_BATON.  If ALLOW_DEHYDRATE
+   is true, remove the on disk text-base contents that is not required. */
+svn_error_t *
+svn_wc__textbase_sync(svn_wc_context_t *wc_ctx,
+                      const char *local_abspath,
+                      svn_boolean_t allow_hydrate,
+                      svn_boolean_t allow_dehydrate,
+                      svn_wc__textbase_hydrate_cb_t hydrate_callback,
+                      void *hydrate_baton,
+                      svn_cancel_func_t cancel_func,
+                      void *cancel_baton,
+                      apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/cat.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/cat.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/cat.c 
(original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/cat.c 
Thu Feb 10 20:04:43 2022
@@ -216,6 +216,10 @@ svn_client_cat3(apr_hash_t **returned_pr
 
       SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url,
                                       scratch_pool));
+
+      SVN_ERR(svn_client__textbase_sync(local_abspath, TRUE, TRUE,
+                                        ctx, scratch_pool));
+
       SVN_ERR(svn_client__get_normalized_stream(&normal_stream, ctx->wc_ctx,
                                             local_abspath, revision,
                                             expand_keywords, FALSE,
@@ -229,9 +233,14 @@ svn_client_cat3(apr_hash_t **returned_pr
         SVN_ERR(svn_wc_prop_list2(returned_props, ctx->wc_ctx, local_abspath,
                                   result_pool, scratch_pool));
 
-      return svn_error_trace(svn_stream_copy3(normal_stream, output,
-                                              ctx->cancel_func,
-                                              ctx->cancel_baton, 
scratch_pool));
+      SVN_ERR(svn_stream_copy3(normal_stream, output,
+                               ctx->cancel_func,
+                               ctx->cancel_baton, scratch_pool));
+
+      SVN_ERR(svn_client__textbase_sync(local_abspath, FALSE, TRUE,
+                                        ctx, scratch_pool));
+
+      return SVN_NO_ERROR;
     }
 
   /* Get an RA plugin for this filesystem object. */

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/client.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/client.h?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/client.h
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/client.h
 Thu Feb 10 20:04:43 2022
@@ -1243,6 +1243,15 @@ svn_client__merge_locked(svn_client__con
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool);
 
+/* Synchronize the state of the text-base contents for the LOCAL_ABSPATH tree.
+ * Internally this calls svn_wc__textbase_sync(), which see for details. */
+svn_error_t *
+svn_client__textbase_sync(const char *local_abspath,
+                          svn_boolean_t allow_hydrate,
+                          svn_boolean_t allow_dehydrate,
+                          svn_client_ctx_t *ctx,
+                          apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/commit.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/commit.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/commit.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/commit.c
 Thu Feb 10 20:04:43 2022
@@ -728,6 +728,12 @@ svn_client_commit6(const apr_array_heade
       if (cmt_err)
         goto cleanup;
 
+      cmt_err = svn_error_trace(
+                    svn_client__textbase_sync(lock_root, FALSE, TRUE,
+                                              ctx, iterpool));
+      if (cmt_err)
+        goto cleanup;
+
       APR_ARRAY_PUSH(locks_obtained, const char *) = lock_root;
     }
 
@@ -1075,6 +1081,11 @@ svn_client_commit6(const apr_array_heade
           svn_pool_clear(iterpool);
 
           unlock_err = svn_error_compose_create(
+                           svn_client__textbase_sync(lock_root, FALSE, TRUE,
+                                                     ctx, iterpool),
+                           unlock_err);
+
+          unlock_err = svn_error_compose_create(
                            svn_wc__release_write_lock(ctx->wc_ctx, lock_root,
                                                       iterpool),
                            unlock_err);

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/conflicts.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/conflicts.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/conflicts.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/conflicts.c
 Thu Feb 10 20:04:43 2022
@@ -6411,6 +6411,52 @@ resolve_postpone(svn_client_conflict_opt
   return SVN_NO_ERROR; /* Nothing to do. */
 }
 
+static svn_error_t *
+begin_resolve(const char **root_abspath_p,
+              const char *local_abspath,
+              svn_client_ctx_t *ctx,
+              apr_pool_t *result_pool,
+              apr_pool_t *scratch_pool)
+{
+  const char *lock_abspath;
+  svn_error_t *err;
+
+  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
+                                                 local_abspath,
+                                                 result_pool, scratch_pool));
+
+  err = svn_client__textbase_sync(lock_abspath, TRUE, TRUE, ctx, scratch_pool);
+  if (err)
+    {
+      return svn_error_compose_create(
+               err,
+               svn_wc__release_write_lock(ctx->wc_ctx, lock_abspath,
+                                          scratch_pool));
+    }
+
+  *root_abspath_p = lock_abspath;
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+finish_resolve(const char *root_abspath,
+               svn_client_ctx_t *ctx,
+               svn_error_t *resolve_err,
+               apr_pool_t *scratch_pool)
+{
+  svn_error_t *err = resolve_err;
+
+  err = svn_error_compose_create(
+          err,
+          svn_client__textbase_sync(root_abspath, FALSE, TRUE, ctx, 
scratch_pool));
+
+  err = svn_error_compose_create(
+          err,
+          svn_wc__release_write_lock(ctx->wc_ctx, root_abspath, scratch_pool));
+
+  return err;
+}
+
 /* Implements conflict_option_resolve_func_t. */
 static svn_error_t *
 resolve_text_conflict(svn_client_conflict_option_t *option,
@@ -6428,9 +6474,8 @@ resolve_text_conflict(svn_client_conflic
   conflict_choice = conflict_option_id_to_wc_conflict_choice(option_id);
   local_abspath = svn_client_conflict_get_local_abspath(conflict);
 
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 local_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                        scratch_pool, scratch_pool));
   err = svn_wc__conflict_text_mark_resolved(ctx->wc_ctx,
                                             local_abspath,
                                             conflict_choice,
@@ -6439,9 +6484,7 @@ resolve_text_conflict(svn_client_conflic
                                             ctx->notify_func2,
                                             ctx->notify_baton2,
                                             scratch_pool);
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
+  err = finish_resolve(lock_abspath, ctx, err, scratch_pool);
   svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
   SVN_ERR(err);
 
@@ -6474,18 +6517,15 @@ resolve_prop_conflict(svn_client_conflic
   else
     merged_value = NULL;
 
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 local_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                        scratch_pool, scratch_pool));
   err = svn_wc__conflict_prop_mark_resolved(ctx->wc_ctx, local_abspath,
                                             propname, conflict_choice,
                                             merged_value,
                                             ctx->notify_func2,
                                             ctx->notify_baton2,
                                             scratch_pool);
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
+  err = finish_resolve(lock_abspath, ctx, err, scratch_pool);
   svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
   SVN_ERR(err);
 
@@ -6550,9 +6590,8 @@ resolve_accept_current_wc_state(svn_clie
                              svn_dirent_local_style(local_abspath,
                                                     scratch_pool));
 
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 local_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                        scratch_pool, scratch_pool));
 
   /* Resolve to current working copy state. */
   err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath, scratch_pool);
@@ -6565,10 +6604,7 @@ resolve_accept_current_wc_state(svn_clie
                                            scratch_pool),
                       scratch_pool);
 
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   conflict->resolution_tree = option_id;
 
@@ -6588,9 +6624,8 @@ resolve_update_break_moved_away(svn_clie
 
   local_abspath = svn_client_conflict_get_local_abspath(conflict);
 
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 local_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                        scratch_pool, scratch_pool));
   err = svn_wc__conflict_tree_update_break_moved_away(ctx->wc_ctx,
                                                       local_abspath,
                                                       ctx->cancel_func,
@@ -6598,10 +6633,7 @@ resolve_update_break_moved_away(svn_clie
                                                       ctx->notify_func2,
                                                       ctx->notify_baton2,
                                                       scratch_pool);
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   conflict->resolution_tree = svn_client_conflict_option_get_id(option);
 
@@ -6621,9 +6653,8 @@ resolve_update_raise_moved_away(svn_clie
 
   local_abspath = svn_client_conflict_get_local_abspath(conflict);
 
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 local_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                        scratch_pool, scratch_pool));
   err = svn_wc__conflict_tree_update_raise_moved_away(ctx->wc_ctx,
                                                       local_abspath,
                                                       ctx->cancel_func,
@@ -6631,10 +6662,7 @@ resolve_update_raise_moved_away(svn_clie
                                                       ctx->notify_func2,
                                                       ctx->notify_baton2,
                                                       scratch_pool);
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   conflict->resolution_tree = svn_client_conflict_option_get_id(option);
 
@@ -6654,9 +6682,8 @@ resolve_update_moved_away_node(svn_clien
 
   local_abspath = svn_client_conflict_get_local_abspath(conflict);
 
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 local_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                        scratch_pool, scratch_pool));
   err = svn_wc__conflict_tree_update_moved_away_node(ctx->wc_ctx,
                                                      local_abspath,
                                                      ctx->cancel_func,
@@ -6664,9 +6691,7 @@ resolve_update_moved_away_node(svn_clien
                                                      ctx->notify_func2,
                                                      ctx->notify_baton2,
                                                      scratch_pool);
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
+  err = finish_resolve(lock_abspath, ctx, err, scratch_pool);
   svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
   SVN_ERR(err);
 
@@ -6838,9 +6863,8 @@ resolve_incoming_add_ignore(svn_client_c
   local_abspath = svn_client_conflict_get_local_abspath(conflict);
   operation = svn_client_conflict_get_operation(conflict);
 
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 local_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                        scratch_pool, scratch_pool));
 
   if (operation == svn_wc_operation_update)
     {
@@ -6865,10 +6889,7 @@ resolve_incoming_add_ignore(svn_client_c
                       scratch_pool);
 
 unlock_wc:
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   conflict->resolution_tree = svn_client_conflict_option_get_id(option);
 
@@ -6962,9 +6983,8 @@ resolve_merge_incoming_added_file_text_u
                          apr_hash_make(scratch_pool), scratch_pool));
 
   /* ### The following WC modifications should be atomic. */
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 local_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                        scratch_pool, scratch_pool));
 
   /* Revert the path in order to restore the repository's line of
    * history, which is part of the BASE tree. This revert operation
@@ -6997,10 +7017,7 @@ unlock_wc:
               err, _("If needed, a backup copy of '%s' can be found at '%s'"),
               svn_dirent_local_style(local_abspath, scratch_pool),
               svn_dirent_local_style(working_file_tmp_abspath, scratch_pool));
-  err = svn_error_compose_create(err,
-                                 svn_wc__release_write_lock(ctx->wc_ctx,
-                                                            lock_abspath,
-                                                            scratch_pool));
+  err = finish_resolve(lock_abspath, ctx, err, scratch_pool);
   svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
   SVN_ERR(err);
 
@@ -7108,16 +7125,12 @@ resolve_merge_incoming_added_file_text_m
                          apr_hash_make(scratch_pool), scratch_pool));
 
   /* ### The following WC modifications should be atomic. */
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 local_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                        scratch_pool, scratch_pool));
   /* Resolve to current working copy state. svn_wc_merge5() requires this. */
   err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath, scratch_pool);
   if (err)
-    return svn_error_compose_create(err,
-                                    svn_wc__release_write_lock(ctx->wc_ctx,
-                                                               lock_abspath,
-                                                               scratch_pool));
+    return finish_resolve(lock_abspath, ctx, err, scratch_pool);
   /* Perform the file merge. ### Merge into tempfile and then rename on top? */
   err = svn_wc_merge5(&merge_content_outcome, &merge_props_outcome,
                       ctx->wc_ctx, empty_file_abspath,
@@ -7130,9 +7143,7 @@ resolve_merge_incoming_added_file_text_m
                       NULL, NULL, /* conflict func/baton */
                       NULL, NULL, /* don't allow user to cancel here */
                       scratch_pool);
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
+  err = finish_resolve(lock_abspath, ctx, err, scratch_pool);
   svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
   SVN_ERR(err);
 
@@ -7247,9 +7258,8 @@ resolve_merge_incoming_added_file_replac
   /* Reset the stream in preparation for adding its content to WC. */
   SVN_ERR(svn_stream_reset(incoming_new_stream));
 
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 local_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                        scratch_pool, scratch_pool));
 
   /* ### The following WC modifications should be atomic. */
 
@@ -7334,9 +7344,7 @@ resolve_merge_incoming_added_file_replac
     }
 
 unlock_wc:
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
+  err = finish_resolve(lock_abspath, ctx, err, scratch_pool);
   svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
   SVN_ERR(err);
 
@@ -7908,9 +7916,8 @@ resolve_merge_incoming_added_dir_merge(s
     }
 
   /* ### The following WC modifications should be atomic. */
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 local_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                        scratch_pool, scratch_pool));
 
   /* ### wrap in a transaction */
   err = merge_newly_added_dir(added_repos_relpath,
@@ -7921,9 +7928,7 @@ resolve_merge_incoming_added_dir_merge(s
   if (!err)
     err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath, scratch_pool);
 
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
+  err = finish_resolve(lock_abspath, ctx, err, scratch_pool);
   svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
   SVN_ERR(err);
 
@@ -7957,9 +7962,8 @@ resolve_update_incoming_added_dir_merge(
   if (local_change == svn_wc_conflict_reason_unversioned)
     {
       char *parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-      SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
-                &lock_abspath, ctx->wc_ctx, parent_abspath,
-                scratch_pool, scratch_pool));
+      SVN_ERR(begin_resolve(&lock_abspath, parent_abspath, ctx,
+                            scratch_pool, scratch_pool));
 
       /* The update/switch operation has added the incoming versioned
        * directory as a deleted op-depth layer. We can revert this layer
@@ -7979,9 +7983,8 @@ resolve_update_incoming_added_dir_merge(
     }
   else
     {
-      SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
-                &lock_abspath, ctx->wc_ctx, local_abspath,
-                scratch_pool, scratch_pool));
+      SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                            scratch_pool, scratch_pool));
       err = svn_wc__conflict_tree_update_local_add(ctx->wc_ctx,
                                                    local_abspath,
                                                    ctx->cancel_func,
@@ -7991,10 +7994,7 @@ resolve_update_incoming_added_dir_merge(
                                                    scratch_pool);
     }
 
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -8041,11 +8041,10 @@ merge_incoming_added_dir_replace(svn_cli
 
   /* ### The following WC modifications should be atomic. */
 
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 svn_dirent_dirname(
-                                                   local_abspath,
-                                                   scratch_pool),
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath,
+                        svn_dirent_dirname(local_abspath,
+                                           scratch_pool),
+                        ctx, scratch_pool, scratch_pool));
 
   /* Remove the working directory. */
   err = svn_wc_delete4(ctx->wc_ctx, local_abspath, FALSE, FALSE,
@@ -8136,9 +8135,7 @@ merge_incoming_added_dir_replace(svn_cli
     }
 
 unlock_wc:
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
+  err = finish_resolve(lock_abspath, ctx, err, scratch_pool);
   svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
   SVN_ERR(err);
 
@@ -8388,9 +8385,8 @@ resolve_incoming_delete_ignore(svn_clien
   option_id = svn_client_conflict_option_get_id(option);
   local_abspath = svn_client_conflict_get_local_abspath(conflict);
 
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 local_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, local_abspath, ctx,
+                        scratch_pool, scratch_pool));
 
   err = verify_local_state_for_incoming_delete(conflict, option, ctx,
                                                scratch_pool);
@@ -8409,10 +8405,7 @@ resolve_incoming_delete_ignore(svn_clien
                       scratch_pool);
 
 unlock_wc:
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   conflict->resolution_tree = option_id;
 
@@ -8437,9 +8430,8 @@ resolve_incoming_delete_accept(svn_clien
 
   /* Deleting a node requires a lock on the node's parent. */
   parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
-                                                 parent_abspath,
-                                                 scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath, parent_abspath, ctx,
+                        scratch_pool, scratch_pool));
 
   err = verify_local_state_for_incoming_delete(conflict, option, ctx,
                                                scratch_pool);
@@ -8478,10 +8470,7 @@ resolve_incoming_delete_accept(svn_clien
                       scratch_pool);
 
 unlock_wc:
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   conflict->resolution_tree = option_id;
 
@@ -8616,12 +8605,11 @@ resolve_incoming_move_file_text_merge(sv
     merge_source_abspath = victim_abspath;
 
   /* ### The following WC modifications should be atomic. */
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
-            &lock_abspath, ctx->wc_ctx,
-            svn_dirent_get_longest_ancestor(victim_abspath,
-                                            moved_to_abspath,
-                                            scratch_pool),
-            scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath,
+                        svn_dirent_get_longest_ancestor(victim_abspath,
+                                                        moved_to_abspath,
+                                                        scratch_pool),
+                        ctx, scratch_pool, scratch_pool));
 
   if (local_change != svn_wc_conflict_reason_missing)
     {
@@ -8817,10 +8805,7 @@ unlock_wc:
               err, _("If needed, a backup copy of '%s' can be found at '%s'"),
               svn_dirent_local_style(moved_to_abspath, scratch_pool),
               svn_dirent_local_style(incoming_abspath, scratch_pool));
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -8934,12 +8919,11 @@ resolve_both_moved_file_text_merge(svn_c
     APR_ARRAY_IDX(local_moves, local_details->wc_move_target_idx, const char 
*);
 
   /* ### The following WC modifications should be atomic. */
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
-            &lock_abspath, ctx->wc_ctx,
-            svn_dirent_get_longest_ancestor(victim_abspath,
-                                            local_moved_to_abspath,
-                                            scratch_pool),
-            scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath,
+                        svn_dirent_get_longest_ancestor(victim_abspath,
+                                                        local_moved_to_abspath,
+                                                        scratch_pool),
+                        ctx, scratch_pool, scratch_pool));
 
    /* Get a copy of the incoming moved item's properties. */
   err = svn_wc_prop_list2(&incoming_props, ctx->wc_ctx,
@@ -9022,10 +9006,7 @@ resolve_both_moved_file_text_merge(svn_c
   conflict->resolution_tree = option_id;
 
 unlock_wc:
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -9109,12 +9090,11 @@ resolve_both_moved_dir_merge(svn_client_
     APR_ARRAY_IDX(local_moves, local_details->wc_move_target_idx, const char 
*);
 
   /* ### The following WC modifications should be atomic. */
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
-            &lock_abspath, ctx->wc_ctx,
-            svn_dirent_get_longest_ancestor(victim_abspath,
-                                            local_moved_to_abspath,
-                                            scratch_pool),
-            scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath,
+                        svn_dirent_get_longest_ancestor(victim_abspath,
+                                                        local_moved_to_abspath,
+                                                        scratch_pool),
+                        ctx, scratch_pool, scratch_pool));
 
   /* Perform the merge. */
   incoming_old_url = apr_pstrcat(scratch_pool, repos_root_url, "/",
@@ -9170,10 +9150,7 @@ resolve_both_moved_dir_merge(svn_client_
   conflict->resolution_tree = option_id;
 
 unlock_wc:
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -9258,12 +9235,11 @@ resolve_both_moved_dir_move_merge(svn_cl
     APR_ARRAY_IDX(local_moves, local_details->wc_move_target_idx, const char 
*);
 
   /* ### The following WC modifications should be atomic. */
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
-            &lock_abspath, ctx->wc_ctx,
-            svn_dirent_get_longest_ancestor(victim_abspath,
-                                            local_moved_to_abspath,
-                                            scratch_pool),
-            scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath,
+                        svn_dirent_get_longest_ancestor(victim_abspath,
+                                                        local_moved_to_abspath,
+                                                        scratch_pool),
+                        ctx, scratch_pool, scratch_pool));
 
   /* Revert the incoming move target directory. */
   err = svn_wc_revert6(ctx->wc_ctx, incoming_moved_to_abspath,
@@ -9332,10 +9308,7 @@ resolve_both_moved_dir_move_merge(svn_cl
   conflict->resolution_tree = option_id;
 
 unlock_wc:
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -9420,12 +9393,11 @@ resolve_incoming_move_dir_merge(svn_clie
 
   /* ### The following WC modifications should be atomic. */
 
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
-            &lock_abspath, ctx->wc_ctx,
-            svn_dirent_get_longest_ancestor(local_abspath,
-                                            moved_to_abspath,
-                                            scratch_pool),
-            scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath,
+                        svn_dirent_get_longest_ancestor(local_abspath,
+                                                        moved_to_abspath,
+                                                        scratch_pool),
+                        ctx, scratch_pool, scratch_pool));
 
   err = svn_wc__node_get_origin(&is_copy, &moved_to_peg_rev,
                                 &moved_to_repos_relpath,
@@ -9564,10 +9536,7 @@ resolve_incoming_move_dir_merge(svn_clie
   conflict->resolution_tree = option_id;
 
 unlock_wc:
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -9689,12 +9658,11 @@ resolve_local_move_file_merge(svn_client
                          scratch_pool));
 
   /* ### The following WC modifications should be atomic. */
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
-            &lock_abspath, ctx->wc_ctx,
-            svn_dirent_get_longest_ancestor(conflict->local_abspath,
-                                            merge_target_abspath,
-                                            scratch_pool),
-            scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath,
+                        
svn_dirent_get_longest_ancestor(conflict->local_abspath,
+                                                        merge_target_abspath,
+                                                        scratch_pool),
+                        ctx, scratch_pool, scratch_pool));
 
   /* Perform the file merge. */
   err = svn_wc_merge5(&merge_content_outcome, &merge_props_outcome,
@@ -9712,19 +9680,11 @@ resolve_local_move_file_merge(svn_client
                       scratch_pool);
   svn_io_sleep_for_timestamps(merge_target_abspath, scratch_pool);
   if (err)
-    return svn_error_compose_create(err,
-                                    svn_wc__release_write_lock(ctx->wc_ctx,
-                                                               lock_abspath,
-                                                               scratch_pool));
+    return finish_resolve(lock_abspath, ctx, err, scratch_pool);
 
   err = svn_wc__del_tree_conflict(ctx->wc_ctx, conflict->local_abspath,
                                   scratch_pool);
-  err = svn_error_compose_create(err,
-                                 svn_wc__release_write_lock(ctx->wc_ctx,
-                                                            lock_abspath,
-                                                            scratch_pool));
-  if (err)
-    return svn_error_trace(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   if (ctx->notify_func2)
     {
@@ -9805,12 +9765,11 @@ resolve_local_move_dir_merge(svn_client_
                                          const char *);
 
   /* ### The following WC modifications should be atomic. */
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
-            &lock_abspath, ctx->wc_ctx,
-            svn_dirent_get_longest_ancestor(conflict->local_abspath,
-                                            merge_target_abspath,
-                                            scratch_pool),
-            scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath,
+                        
svn_dirent_get_longest_ancestor(conflict->local_abspath,
+                                                        merge_target_abspath,
+                                                        scratch_pool),
+                        ctx, scratch_pool, scratch_pool));
 
   /* Resolve to current working copy state.
    * svn_client__merge_locked() requires this. */
@@ -9841,12 +9800,7 @@ resolve_local_move_dir_merge(svn_client_
                                  NULL, ctx, scratch_pool, scratch_pool);
 unlock_wc:
   svn_io_sleep_for_timestamps(merge_target_abspath, scratch_pool);
-  err = svn_error_compose_create(err,
-                                 svn_wc__release_write_lock(ctx->wc_ctx,
-                                                            lock_abspath,
-                                                            scratch_pool));
-  if (err)
-    return svn_error_trace(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   if (ctx->notify_func2)
     {
@@ -11232,12 +11186,11 @@ resolve_both_moved_file_update_keep_loca
                   local_details->preferred_move_target_idx, const char *);
 
   /* ### The following WC modifications should be atomic. */
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
-            &lock_abspath, ctx->wc_ctx,
-            svn_dirent_get_longest_ancestor(victim_abspath,
-                                            local_moved_to_abspath,
-                                            scratch_pool),
-            scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath,
+                        svn_dirent_get_longest_ancestor(victim_abspath,
+                                                        local_moved_to_abspath,
+                                                        scratch_pool),
+                        ctx, scratch_pool, scratch_pool));
 
    /* Get a copy of the incoming moved item's properties. */
   err = svn_wc_prop_list2(&incoming_props, ctx->wc_ctx,
@@ -11326,10 +11279,7 @@ resolve_both_moved_file_update_keep_loca
   conflict->resolution_tree = option_id;
 
 unlock_wc:
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -11443,12 +11393,11 @@ resolve_both_moved_file_update_keep_inco
                   local_details->preferred_move_target_idx, const char *);
 
   /* ### The following WC modifications should be atomic. */
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
-            &lock_abspath, ctx->wc_ctx,
-            svn_dirent_get_longest_ancestor(victim_abspath,
-                                            local_moved_to_abspath,
-                                            scratch_pool),
-            scratch_pool, scratch_pool));
+  SVN_ERR(begin_resolve(&lock_abspath,
+                        svn_dirent_get_longest_ancestor(victim_abspath,
+                                                        local_moved_to_abspath,
+                                                        scratch_pool),
+                        ctx, scratch_pool, scratch_pool));
 
    /* Get a copy of the incoming moved item's properties. */
   err = svn_wc_prop_list2(&incoming_props, ctx->wc_ctx,
@@ -11532,10 +11481,7 @@ resolve_both_moved_file_update_keep_inco
   conflict->resolution_tree = option_id;
 
 unlock_wc:
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
-                                                                 lock_abspath,
-                                                                 
scratch_pool));
-  SVN_ERR(err);
+  SVN_ERR(finish_resolve(lock_abspath, ctx, err, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/diff.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/diff.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/diff.c 
(original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/diff.c 
Thu Feb 10 20:04:43 2022
@@ -1866,12 +1866,17 @@ diff_wc_wc(const char *path1,
                           "or between the working versions of two paths"
                           )));
 
+  SVN_ERR(svn_client__textbase_sync(abspath1, TRUE, TRUE, ctx, scratch_pool));
+
   SVN_ERR(svn_wc__diff7(TRUE,
                         ctx->wc_ctx, abspath1, depth,
                         ignore_ancestry, changelists,
                         diff_processor,
                         ctx->cancel_func, ctx->cancel_baton,
                         result_pool, scratch_pool));
+
+  SVN_ERR(svn_client__textbase_sync(abspath1, FALSE, TRUE, ctx, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -2135,6 +2140,8 @@ diff_repos_wc(struct diff_driver_info_t
 
   SVN_ERR(svn_dirent_get_absolute(&abspath2, path2, scratch_pool));
 
+  SVN_ERR(svn_client__textbase_sync(abspath2, TRUE, TRUE, ctx, scratch_pool));
+
   /* Check if our diff target is a copied node. */
   SVN_ERR(svn_wc__node_get_origin(&is_copy,
                                   &cf_revision,
@@ -2340,6 +2347,8 @@ diff_repos_wc(struct diff_driver_info_t
                                       scratch_pool));
     }
 
+  SVN_ERR(svn_client__textbase_sync(abspath2, FALSE, TRUE, ctx, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/resolved.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/resolved.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/resolved.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/resolved.c
 Thu Feb 10 20:04:43 2022
@@ -66,6 +66,10 @@ svn_client__resolve_conflicts(svn_boolea
       const char *local_abspath = APR_ARRAY_IDX(array, i, const char *);
 
       svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_client__textbase_sync(local_abspath, TRUE, TRUE, ctx,
+                                        iterpool));
+
       SVN_ERR(svn_wc__resolve_conflicts(ctx->wc_ctx, local_abspath,
                                         svn_depth_empty,
                                         TRUE /* resolve_text */,
@@ -98,12 +102,44 @@ svn_client__resolve_conflicts(svn_boolea
           if (text_c || prop_c || tree_c)
             *conflicts_remain = TRUE;
         }
+
+      SVN_ERR(svn_client__textbase_sync(local_abspath, FALSE, TRUE, ctx,
+                                        iterpool));
     }
   svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+resolve_locked(const char *local_abspath,
+               const char *root_abspath,
+               svn_depth_t depth,
+               svn_wc_conflict_choice_t conflict_choice,
+               svn_client_ctx_t *ctx,
+               apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_client__textbase_sync(root_abspath, TRUE, TRUE, ctx,
+                                    scratch_pool));
+
+  SVN_ERR(svn_wc__resolve_conflicts(ctx->wc_ctx, local_abspath,
+                                    depth,
+                                    TRUE /* resolve_text */,
+                                    "" /* resolve_prop (ALL props) */,
+                                    TRUE /* resolve_tree */,
+                                    conflict_choice,
+                                    ctx->conflict_func2,
+                                    ctx->conflict_baton2,
+                                    ctx->cancel_func, ctx->cancel_baton,
+                                    ctx->notify_func2, ctx->notify_baton2,
+                                    scratch_pool));
+
+  SVN_ERR(svn_client__textbase_sync(root_abspath, FALSE, TRUE, ctx,
+                                    scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_client_resolve(const char *path,
                    svn_depth_t depth,
@@ -126,17 +162,9 @@ svn_client_resolve(const char *path,
 
   SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                  local_abspath, pool, pool));
-  err = svn_wc__resolve_conflicts(ctx->wc_ctx, local_abspath,
-                                  depth,
-                                  TRUE /* resolve_text */,
-                                  "" /* resolve_prop (ALL props) */,
-                                  TRUE /* resolve_tree */,
-                                  conflict_choice,
-                                  ctx->conflict_func2,
-                                  ctx->conflict_baton2,
-                                  ctx->cancel_func, ctx->cancel_baton,
-                                  ctx->notify_func2, ctx->notify_baton2,
-                                  pool);
+
+  err = resolve_locked(local_abspath, lock_abspath, depth,
+                       conflict_choice, ctx, pool);
 
   err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                  lock_abspath,

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/revert.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/revert.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/revert.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/revert.c
 Thu Feb 10 20:04:43 2022
@@ -69,6 +69,9 @@ revert(void *baton, apr_pool_t *result_p
   struct revert_with_write_lock_baton *b = baton;
   svn_error_t *err;
 
+  SVN_ERR(svn_client__textbase_sync(b->local_abspath, TRUE, TRUE,
+                                    b->ctx, scratch_pool));
+
   err = svn_wc_revert6(b->ctx->wc_ctx,
                        b->local_abspath,
                        b->depth,
@@ -108,6 +111,9 @@ revert(void *baton, apr_pool_t *result_p
         return svn_error_trace(err);
     }
 
+  SVN_ERR(svn_client__textbase_sync(b->local_abspath, FALSE, TRUE,
+                                    b->ctx, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/switch.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/switch.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/switch.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/switch.c
 Thu Feb 10 20:04:43 2022
@@ -202,6 +202,8 @@ switch_internal(svn_revnum_t *result_rev
                                   pool));
     }
 
+  SVN_ERR(svn_client__textbase_sync(local_abspath, TRUE, TRUE, ctx, pool));
+
   /* Open an RA session to 'source' URL */
   SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &switch_loc,
                                             switch_url, anchor_abspath,
@@ -369,6 +371,8 @@ switch_internal(svn_revnum_t *result_rev
                                            ctx, pool));
     }
 
+  SVN_ERR(svn_client__textbase_sync(local_abspath, FALSE, TRUE, ctx, pool));
+
   /* Let everyone know we're finished here. */
   if (ctx->notify_func2)
     {

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/update.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/update.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/update.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/update.c
 Thu Feb 10 20:04:43 2022
@@ -467,6 +467,9 @@ update_internal(svn_revnum_t *result_rev
       ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
     }
 
+  SVN_ERR(svn_client__textbase_sync(local_abspath, TRUE, TRUE,
+                                    ctx, scratch_pool));
+
   SVN_ERR(reuse_ra_session(ra_session_p, &corrected_url, anchor_url,
                            anchor_abspath, ctx, result_pool, scratch_pool));
   ra_session = *ra_session_p;
@@ -576,6 +579,9 @@ update_internal(svn_revnum_t *result_rev
                                repos_root_url, ra_session, ctx, scratch_pool));
     }
 
+  SVN_ERR(svn_client__textbase_sync(local_abspath, FALSE, TRUE,
+                                    ctx, scratch_pool));
+
   /* Let everyone know we're finished here (unless we're asked not to). */
   if (ctx->notify_func2 && notify_summary)
     {

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/upgrade.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/upgrade.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/upgrade.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/upgrade.c
 Thu Feb 10 20:04:43 2022
@@ -181,6 +181,10 @@ upgrade_internal(const char *path,
       SVN_ERR(upgrade_externals_from_properties(ctx, local_abspath, wc_format,
                                                 &info_baton, scratch_pool));
     }
+
+  SVN_ERR(svn_client__textbase_sync(local_abspath, FALSE, TRUE,
+                                    ctx, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_crawler.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_crawler.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_crawler.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_crawler.c
 Thu Feb 10 20:04:43 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),
@@ -980,8 +990,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);
@@ -1097,11 +1107,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);
     }

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_files.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_files.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_files.c 
(original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_files.c 
Thu Feb 10 20:04:43 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 *

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_files.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_files.h?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_files.h 
(original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_files.h 
Thu Feb 10 20:04:43 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/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_ops.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_ops.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_ops.c 
(original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/adm_ops.c 
Thu Feb 10 20:04:43 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"
@@ -779,8 +780,8 @@ svn_wc_get_pristine_copy_path(const char
      may use repeatedly despite error return values. The rest of this
      function should aggressively close DB, even in the error case.  */
 
-  err = svn_wc__text_base_path_to_read(pristine_path, db, local_abspath,
-                                       pool, pool);
+  err = svn_wc__textbase_setaside(pristine_path, db, local_abspath,
+                                  NULL, NULL, NULL, 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
@@ -806,9 +807,10 @@ svn_wc_get_pristine_contents2(svn_stream
                               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 +827,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 +845,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_PATH_UNEXPECTED_STATUS, NULL, NULL);
+
+  *stream_p = stream;
   return SVN_NO_ERROR;
 }
 
@@ -857,13 +864,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/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/copy.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/copy.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/copy.c 
(original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/copy.c 
Thu Feb 10 20:04:43 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;
         }
     }


Reply via email to