You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2022/02/10 20:04:43 UTC

svn commit: r1897946 [3/3] - in /subversion/branches/pristines-on-demand-on-mwf: ./ build/ subversion/bindings/swig/python/tests/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_wc/ subversion/tests/cmdline/ subversion/tests/cmd...

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_update_move.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_update_move.c Thu Feb 10 20:04:43 2022
@@ -154,6 +154,7 @@
 #include "conflicts.h"
 #include "workqueue.h"
 #include "token-map.h"
+#include "textbase.h"
 
 /* Helper functions */
 /* Return the absolute path, in local path style, of LOCAL_RELPATH
@@ -970,15 +971,28 @@ tc_editor_add_file(node_move_baton_t *nm
     }
   else
     {
+      const char *src_abspath;
+      const char *install_from;
+      svn_skel_t *cleanup_work_item;
+
+      src_abspath = svn_dirent_join(b->wcroot->abspath, nmb->src_relpath,
+                                    scratch_pool);
+
       /* Update working file. */
+      SVN_ERR(svn_wc__textbase_setaside_wq(&install_from,
+                                           &cleanup_work_item,
+                                           b->db, src_abspath, NULL,
+                                           b->cancel_func, b->cancel_baton,
+                                           scratch_pool, scratch_pool));
       SVN_ERR(svn_wc__wq_build_file_install(&work_item, b->db,
                                             svn_dirent_join(b->wcroot->abspath,
                                                             relpath,
                                                             scratch_pool),
-                                            NULL,
+                                            install_from,
                                             FALSE /*FIXME: use_commit_times?*/,
                                             TRUE  /* record_file_info */,
                                             scratch_pool, scratch_pool));
+      work_item = svn_wc__wq_merge(work_item, cleanup_work_item, scratch_pool);
     }
 
   SVN_ERR(update_move_list_add(b->wcroot, relpath, b->db,
@@ -1369,33 +1383,56 @@ tc_editor_alter_file(node_move_baton_t *
                                                scratch_pool));
       if (!is_locally_modified)
         {
+          const char *src_abspath;
+          const char *install_from;
+          svn_skel_t *cleanup_work_item;
+
+          src_abspath = svn_dirent_join(b->wcroot->abspath, nmb->src_relpath,
+                                        scratch_pool);
+
+          SVN_ERR(svn_wc__textbase_setaside_wq(&install_from,
+                                               &cleanup_work_item,
+                                               b->db, src_abspath, NULL,
+                                               b->cancel_func, b->cancel_baton,
+                                               scratch_pool, scratch_pool));
           SVN_ERR(svn_wc__wq_build_file_install(&work_item, b->db,
                                                 local_abspath,
-                                                NULL,
+                                                install_from,
                                                 FALSE /* FIXME: use_commit_times? */,
                                                 TRUE  /* record_file_info */,
                                                 scratch_pool, scratch_pool));
 
           work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+          work_items = svn_wc__wq_merge(work_items, cleanup_work_item, scratch_pool);
 
           content_state = svn_wc_notify_state_changed;
         }
       else
         {
+          svn_skel_t *cleanup_queue = NULL;
+
           /*
            * Run a 3-way merge to update the file, using the pre-update
            * pristine text as the merge base, the post-update pristine
            * text as the merge-left version, and the current content of the
            * moved-here working file as the merge-right version.
            */
-          SVN_ERR(svn_wc__db_pristine_get_path(&old_pristine_abspath,
-                                               b->db, b->wcroot->abspath,
+          SVN_ERR(svn_wc__textbase_setaside_wq(&old_pristine_abspath,
+                                               &work_item, b->db,
+                                               local_abspath,
                                                old_version.checksum,
+                                               b->cancel_func, b->cancel_baton,
                                                scratch_pool, scratch_pool));
-          SVN_ERR(svn_wc__db_pristine_get_path(&new_pristine_abspath,
-                                               b->db, b->wcroot->abspath,
+          cleanup_queue = svn_wc__wq_merge(cleanup_queue, work_item, scratch_pool);
+
+          SVN_ERR(svn_wc__textbase_setaside_wq(&new_pristine_abspath,
+                                               &work_item, b->db,
+                                               local_abspath,
                                                new_version.checksum,
+                                               b->cancel_func, b->cancel_baton,
                                                scratch_pool, scratch_pool));
+          cleanup_queue = svn_wc__wq_merge(cleanup_queue, work_item, scratch_pool);
+
           SVN_ERR(svn_wc__internal_merge(&work_item, &conflict_skel,
                                          &merge_outcome, b->db,
                                          old_pristine_abspath,
@@ -1412,6 +1449,7 @@ tc_editor_alter_file(node_move_baton_t *
                                          scratch_pool, scratch_pool));
 
           work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+          work_items = svn_wc__wq_merge(work_items, cleanup_queue, scratch_pool);
 
           if (merge_outcome == svn_wc_merge_conflict)
             content_state = svn_wc_notify_state_conflicted;
@@ -1599,6 +1637,7 @@ tc_editor_update_incoming_moved_file(nod
           const char *src_abspath;
           const char *label_left;
           const char *label_target;
+          svn_skel_t *cleanup_queue = NULL;
 
           /*
            * Run a 3-way merge to update the file at its post-move location,
@@ -1607,12 +1646,17 @@ tc_editor_update_incoming_moved_file(nod
            * content of the working file at the pre-move location as the
            * merge-left version.
            */
-          SVN_ERR(svn_wc__db_pristine_get_path(&old_pristine_abspath,
-                                               b->db, b->wcroot->abspath,
-                                               src_checksum,
-                                               scratch_pool, scratch_pool));
           src_abspath = svn_dirent_join(b->wcroot->abspath, src_relpath,
                                         scratch_pool);
+
+          SVN_ERR(svn_wc__textbase_setaside_wq(&old_pristine_abspath,
+                                               &work_item, b->db,
+                                               src_abspath,
+                                               src_checksum,
+                                               b->cancel_func, b->cancel_baton,
+                                               scratch_pool, scratch_pool));
+          cleanup_queue = svn_wc__wq_merge(cleanup_queue, work_item, scratch_pool);
+
           label_left = apr_psprintf(scratch_pool, ".r%ld",
                                     b->old_version->peg_rev);
           label_target = apr_psprintf(scratch_pool, ".r%ld",
@@ -1635,6 +1679,7 @@ tc_editor_update_incoming_moved_file(nod
                                          scratch_pool, scratch_pool));
 
           work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+          work_items = svn_wc__wq_merge(work_items, cleanup_queue, scratch_pool);
 
           if (merge_outcome == svn_wc_merge_conflict)
             content_state = svn_wc_notify_state_conflicted;
@@ -3147,14 +3192,22 @@ tc_editor_update_add_merge_files(added_n
   if (!is_modified)
     {
       svn_skel_t *work_item = NULL;
+      const char *install_from;
+      svn_skel_t *cleanup_work_item;
 
+      SVN_ERR(svn_wc__textbase_setaside_wq(&install_from,
+                                           &cleanup_work_item,
+                                           b->db, local_abspath, NULL,
+                                           b->cancel_func, b->cancel_baton,
+                                           scratch_pool, scratch_pool));
       SVN_ERR(svn_wc__wq_build_file_install(&work_item, b->db,
-                                            local_abspath, NULL,
+                                            local_abspath, install_from,
                                             /* FIXME: use_commit_times? */
                                             FALSE,
                                             TRUE,  /* record_file_info */
                                             scratch_pool, scratch_pool));
       work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+      work_items = svn_wc__wq_merge(work_items, cleanup_work_item, scratch_pool);
       content_state = svn_wc_notify_state_changed;
     }
   else
@@ -3162,6 +3215,7 @@ tc_editor_update_add_merge_files(added_n
       const char *empty_file_abspath;
       const char *pristine_abspath;
       svn_skel_t *work_item = NULL;
+      svn_skel_t *cleanup_queue = NULL;
 
       /*
        * Run a 3-way merge to update the file, using the empty file
@@ -3172,9 +3226,13 @@ tc_editor_update_add_merge_files(added_n
       SVN_ERR(svn_io_open_unique_file3(NULL, &empty_file_abspath, NULL,
                                        svn_io_file_del_on_pool_cleanup,
                                        scratch_pool, scratch_pool));
-      SVN_ERR(svn_wc__db_pristine_get_path(&pristine_abspath, b->db,
-                                           b->wcroot->abspath, base_checksum,
+      SVN_ERR(svn_wc__textbase_setaside_wq(&pristine_abspath,
+                                           &work_item, b->db,
+                                           local_abspath,
+                                           base_checksum,
+                                           b->cancel_func, b->cancel_baton,
                                            scratch_pool, scratch_pool));
+      cleanup_queue = svn_wc__wq_merge(cleanup_queue, work_item, scratch_pool);
 
       /* Create a property diff which shows all props as added. */
       SVN_ERR(svn_prop_diffs(&propchanges, working_props,
@@ -3196,6 +3254,7 @@ tc_editor_update_add_merge_files(added_n
                                      scratch_pool, scratch_pool));
 
       work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+      work_items = svn_wc__wq_merge(work_items, cleanup_queue, scratch_pool);
 
       if (merge_outcome == svn_wc_merge_conflict)
         content_state = svn_wc_notify_state_conflicted;
@@ -3373,12 +3432,23 @@ update_locally_added_node(added_node_bat
        * is currently not installed because the base tree is shadowed.
        * Queue an installation of this node into the working copy. */
       if (base_kind == svn_node_file || base_kind == svn_node_symlink)
-        SVN_ERR(svn_wc__wq_build_file_install(&work_item, db, local_abspath,
-                                              NULL,
-                                              /* FIXME: use_commit_times? */
-                                              FALSE,
-                                              TRUE,  /* record_file_info */
-                                              scratch_pool, scratch_pool));
+        {
+          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,
+                                               b->cancel_func, b->cancel_baton,
+                                               scratch_pool, scratch_pool));
+          SVN_ERR(svn_wc__wq_build_file_install(&work_item, db, local_abspath,
+                                                install_from,
+                                                /* FIXME: use_commit_times? */
+                                                FALSE,
+                                                TRUE,  /* record_file_info */
+                                                scratch_pool, scratch_pool));
+          work_item = svn_wc__wq_merge(work_item, cleanup_work_item, scratch_pool);
+        }
       else if (base_kind == svn_node_dir)
         SVN_ERR(svn_wc__wq_build_dir_install(&work_item, db, local_abspath,
                                              scratch_pool, scratch_pool));

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/authz_tests.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/authz_tests.py Thu Feb 10 20:04:43 2022
@@ -1613,6 +1613,7 @@ def authz_log_censor_revprops(sbox):
           '-r1', sbox.repo_url])
 
 @Skip(svntest.main.is_ra_type_file)
+@Wimp("Applying delta to a local mod needs access to the text base")
 def remove_access_after_commit(sbox):
   "remove a subdir with authz file"
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/basic_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/basic_tests.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/basic_tests.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/basic_tests.py Thu Feb 10 20:04:43 2022
@@ -355,6 +355,7 @@ def basic_mkdir_wc_with_parents(sbox):
 
 
 #----------------------------------------------------------------------
+@Wimp("Relies on wc.text_base_path()")
 def basic_commit_corruption(sbox):
   "basic corruption detection on commit"
 
@@ -420,6 +421,7 @@ def basic_commit_corruption(sbox):
                                         expected_status)
 
 #----------------------------------------------------------------------
+@Wimp("Relies on wc.text_base_path()")
 def basic_update_corruption(sbox):
   "basic corruption detection on update"
 
@@ -3244,6 +3246,42 @@ def filtered_ls_top_level_path(sbox):
     exit_code, output, error = svntest.actions.run_and_verify_svn(
       [], [], 'ls', f_path, '--search=*/*', *extra_opts)
 
+def keep_local_reverted_properly(sbox):
+  "rm --keep-local, /bin/rm, revert"
+
+  sbox.build(read_only=True)
+  wc_dir = sbox.wc_dir
+
+  lambda_path = sbox.ospath('A/B/lambda')
+  E_path =  sbox.ospath('A/B/E')
+  targets = [ lambda_path, E_path ]
+
+  # Modify
+  sbox.simple_append('A/B/lambda', "added text\n")
+  svntest.main.run_svn(None, 'ps', 'k', 'v', E_path)
+
+  # Schedule for removal
+  svntest.main.run_svn(None, 'rm', '--keep-local', *targets)
+
+  # Remove from disk
+  os.unlink(lambda_path)
+  shutil.rmtree(E_path)
+
+  # Revert
+  svntest.main.run_svn(None, 'revert', *targets)
+
+  # Check that the modifications are absent
+  # 
+  # alpha and beta are still scheduled for deletion because 'revert' doesn't
+  # recurse by default.
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.remove('A/B/E/alpha', 'A/B/E/beta')
+  expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_output.tweak('A/B/E/alpha', 'A/B/E/beta', status='D ')
+  #
+  svntest.actions.verify_disk(sbox.wc_dir, expected_disk, check_props=True)
+  svntest.actions.run_and_verify_status(wc_dir, expected_output)
+
 
 ########################################################################
 # Run the tests
@@ -3320,6 +3358,7 @@ test_list = [ None,
               null_update_last_changed_revision,
               null_prop_update_last_changed_revision,
               filtered_ls_top_level_path,
+              keep_local_reverted_properly,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/diff_tests.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/diff_tests.py Thu Feb 10 20:04:43 2022
@@ -3063,6 +3063,7 @@ def diff_wrong_extension_type(sbox):
                                      'diff', '-x', sbox.wc_dir, '-r', '1')
 
 # Check the order of the arguments for an external diff tool
+@Wimp("Relies on wc.text_base_path()")
 def diff_external_diffcmd(sbox):
   "svn diff --diff-cmd provides the correct arguments"
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/externals_tests.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/externals_tests.py Thu Feb 10 20:04:43 2022
@@ -67,14 +67,21 @@ def externals_test_setup(sbox):
 
   The arrangement of the externals in the first repository is:
 
-    /A/B/ ==>  ^/A/D/gamma                      gamma
-    /A/C/ ==>  exdir_G                          <scheme>:///<other_repos>/A/D/G
-               ../../../<other_repos_basename>/A/D/H@1 exdir_H
-
-    /A/D/ ==>  ^/../<other_repos_basename>/A    exdir_A
-               //<other_repos>/A/D/G/           exdir_A/G/
-               exdir_A/H -r 1                   <scheme>:///<other_repos>/A/D/H
-               /<some_paths>/A/B                x/y/z/blah
+    Properties on 'A/B':
+      svn:externals
+        ^/A/D/gamma gamma
+    
+    Properties on 'A/C':
+      svn:externals
+        exdir_G       <scheme>://<...>/<other_repos_basename>/A/D/G
+        ../../../<other_repos_basename>/A/D/H@1 exdir_H
+    
+    Properties on 'A/D':
+      svn:externals
+        ^/../<other_repos_basename>/A exdir_A
+        //<scheme-relative URI to other_repos>/A/D/G/ exdir_A/G/
+        exdir_A/H -r 1 <scheme>://<...>/<other_repos_basename>/A/D/H
+        /<root-relative URI to other_repos>/A/B x/y/z/blah
 
   A dictionary is returned keyed by the directory created by the
   external whose value is the URL of the external.
@@ -1625,6 +1632,8 @@ def merge_target_with_externals(sbox):
      "    /A-branch:8\n"],
     [], 'pg', svntest.main.SVN_PROP_MERGEINFO, '-vR', wc_dir)
 
+# Existing issue: `src_stream` not closed in externals.c:apply_textdelta()
+@XFail(svntest.main.is_os_windows)
 def update_modify_file_external(sbox):
   "update that modifies a file external"
 
@@ -2790,6 +2799,8 @@ def shadowing(sbox):
 # Test for issue #4093 'remapping a file external can segfault due to
 # "deleted" props'.
 @Issue(4093)
+# Existing issue: `src_stream` not closed in externals.c:apply_textdelta()
+@XFail(svntest.main.is_os_windows)
 def remap_file_external_with_prop_del(sbox):
   "file external remap segfaults due to deleted props"
 
@@ -4167,6 +4178,8 @@ def file_external_to_normal_file(sbox):
                                         expected_status)
 
 @Issue(4580)
+# Existing issue: `src_stream` not closed in externals.c:apply_textdelta()
+@XFail(svntest.main.is_os_windows)
 def file_external_recorded_info(sbox):
   "check file external recorded info"
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/log_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/log_tests.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/log_tests.py Thu Feb 10 20:04:43 2022
@@ -2816,6 +2816,59 @@ def log_with_merge_history_and_search(sb
   if count(output, "<logentry") != count(output, "</logentry"):
     raise svntest.Failure("Apparently invalid XML in " + repr(output))
 
+@XFail(svntest.main.is_ra_type_file)
+@Issue(4856)
+def log_xml_with_merge_history(sbox):
+  "log --use-merge-history --xml"
+  
+  sbox.build()
+
+  # r2-r4: create branches
+  sbox.simple_repo_copy('A', 'A2')
+  sbox.simple_repo_copy('A', 'A3')
+  sbox.simple_repo_copy('A', 'A4')
+
+  # r5: mod in trunk
+  sbox.simple_append('A/mu', 'line 2')
+  sbox.simple_commit(message='r5: mod')
+  sbox.simple_update()
+
+  # r6-r7: merge A=>A2, A2=>A3
+  svntest.main.run_svn(None, 'merge', '-c', '5', sbox.repo_url + '/A', sbox.ospath('A2'))
+  sbox.simple_commit(message='r6: merge A=>A2')
+  sbox.simple_update()
+  svntest.main.run_svn(None, 'merge', '-c', '6', sbox.repo_url + '/A2', sbox.ospath('A3'))
+  sbox.simple_commit(message='r7: merge A2=>A3')
+  sbox.simple_update()
+
+  # r8: add file in A3
+  xi_path = os.path.join(sbox.wc_dir, 'A3/xi')
+  svntest.main.file_write(xi_path, "This is the file 'A3/xi'.\n")
+  svntest.main.run_svn(None, 'add', xi_path)
+  sbox.simple_commit(message='r8: add A3/xi')
+  sbox.simple_update()
+
+  # r9: merge A3=>A4
+  svntest.main.run_svn(None, 'merge', '-r', '6:8', sbox.repo_url + '/A3', sbox.ospath('A4'))
+  sbox.simple_commit(message='r9: merge A3=>A4')
+  sbox.simple_update()
+
+  # Helper function
+  def count(haystack, needle):
+    """Return the number of times the string NEEDLE occurs in the string
+    HAYSTACK."""
+    return len(haystack.split(needle)) - 1
+
+  # Check the output is valid
+  # ### Since the test is currently XFail, we only smoke test the output.
+  # ### When fixing this test to PASS, extend this validation.
+  _, output, _ = svntest.main.run_svn(None, 'log', '--xml', '-g', '-r', '8:9',
+                                      sbox.ospath('A4'))
+
+  output = '\n'.join(output)
+  if count(output, "<logentry") != count(output, "</logentry"):
+    raise svntest.Failure("Apparently invalid XML in " + repr(output))
+
 ########################################################################
 # Run the tests
 
@@ -2867,6 +2920,7 @@ test_list = [ None,
               log_revision_move_copy,
               log_on_deleted_deep,
               log_with_merge_history_and_search,
+              log_xml_with_merge_history,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/pegrev_parse_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/pegrev_parse_tests.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/pegrev_parse_tests.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/pegrev_parse_tests.py Thu Feb 10 20:04:43 2022
@@ -52,7 +52,7 @@ Item = wc.StateItem
 # commands, because the parser may have (and as of this writing does have)
 # edge-case bugs that we can only expose in this way. Therefore, these helpers
 # ensure that we run 'svn' with the CWD at the root of the working copy.
-def run_svn(sbox, expected_status, expected_stderr, *varargs):
+def run_svn_at_wcdir(sbox, expected_status, expected_stderr, *varargs):
   if expected_stderr is None:
     expected_stderr = []
 
@@ -96,8 +96,8 @@ def do_add_file(sbox, dst, dst_cmdline,
     expected_status.add({dst: Item(status='A ', wc_rev='-')})
 
   main.file_write(sbox.ospath(dst), "This is file '"  + dst + "'.")
-  run_svn(sbox, expected_status, expected_stderr,
-          'add', dst_cmdline)
+  run_svn_at_wcdir(sbox, expected_status, expected_stderr,
+                   'add', dst_cmdline)
 
 def do_add_file_e(sbox, dst, dst_cmdline, expected_stderr=None):
   "like do_add_file() but with an empty sandbox"
@@ -109,8 +109,8 @@ def do_make_dir(sbox, dst, dst_cmdline,
   if expected_status is not None:
     expected_status.add({dst: Item(status='A ', wc_rev='-')})
 
-  run_svn(sbox, expected_status, expected_stderr,
-          'mkdir', dst_cmdline)
+  run_svn_at_wcdir(sbox, expected_status, expected_stderr,
+                   'mkdir', dst_cmdline)
 
 def do_make_dir_e(sbox, dst, dst_cmdline, expected_stderr=None):
   "like do_make_dir() but with an empty sandbox"
@@ -121,8 +121,8 @@ def do_remove(sbox, dst, dst_cmdline, ex
   if expected_status is not None and dst in expected_status.desc:
     expected_status.tweak(dst, status='D ')
 
-  run_svn(sbox, expected_status, expected_stderr,
-          'remove', dst_cmdline)
+  run_svn_at_wcdir(sbox, expected_status, expected_stderr,
+                   'remove', dst_cmdline)
 
 def do_rename(sbox, src, src_cmdline, dst, dst_cmdline,
               expected_stderr=None):
@@ -132,8 +132,8 @@ def do_rename(sbox, src, src_cmdline, ds
     expected_status.add({dst: Item(status='A ', copied='+',
                                    moved_from=src, wc_rev='-')})
 
-  run_svn(sbox, expected_status, expected_stderr,
-          'rename', src_cmdline, dst_cmdline)
+  run_svn_at_wcdir(sbox, expected_status, expected_stderr,
+                   'rename', src_cmdline, dst_cmdline)
 
 
 ######################################################################

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/revert_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/revert_tests.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/revert_tests.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/revert_tests.py Thu Feb 10 20:04:43 2022
@@ -243,6 +243,15 @@ def revert_from_wc_root(sbox):
   svntest.actions.run_and_verify_status('', expected_output)
 
 @Issue(1663)
+# Walking the text-bases automatically repairs timestamps, so now the
+# first and the second reverts in this test behave identically, as if
+# 'svn cleanup' or any other command that repairs the timestamps had been
+# called beforehand.  Judging by the second part of the test, we're fine
+# with revert doing nothing in that case, but that essentially contradicts
+# the expectation in its first part.
+#
+# I temporarily mark the test XFail.  See r1101730 and r1101817 for details.
+@XFail()
 def revert_reexpand_keyword(sbox):
   "revert reexpands manually contracted keyword"
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/actions.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/actions.py Thu Feb 10 20:04:43 2022
@@ -2134,9 +2134,10 @@ def disable_revprop_changes(repo_dir):
   main.create_python_hook_script(hook_path,
                                  'import sys\n'
                                  'sys.stderr.write("pre-revprop-change %s" %'
-                                                  ' " ".join(sys.argv[1:]))\n'
+                                                  ' " ".join(sys.argv[2:]))\n'
                                  'sys.exit(1)\n',
                                  cmd_alternative=
+                                       '@shift\n'
                                        '@echo pre-revprop-change %* 1>&2\n'
                                        '@exit 1\n')
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/main.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/svntest/main.py Thu Feb 10 20:04:43 2022
@@ -627,6 +627,13 @@ def run_command_stdin(command, error_exp
 
   start = time.time()
 
+  if sys.version_info >= (3, 0):
+    # Don't include 'bytes' since spawn_process() would raise.
+    assert all(isinstance(arg, (str, int)) for arg in varargs)
+  else:
+    # Include 'unicode' since svnrdump_tests pass b''.decode().
+    assert all(isinstance(arg, (str, unicode, int)) for arg in varargs)
+
   exit_code, stdout_lines, stderr_lines = spawn_process(command,
                                                         bufsize,
                                                         binary_mode,
@@ -648,8 +655,7 @@ def run_command_stdin(command, error_exp
       break
     # Does the server leak the repository on-disk path?
     # (prop_tests-12 installs a hook script that does that intentionally)
-    if any(map(_line_contains_repos_diskpath, lines)) \
-       and not any(map(lambda arg: 'prop_tests-12' in arg, varargs)):
+    if any(map(_line_contains_repos_diskpath, lines)):
       raise Failure("Repository diskpath in %s: %r" % (name, lines))
 
   valgrind_diagnostic = False

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/trans_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/trans_tests.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/trans_tests.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/trans_tests.py Thu Feb 10 20:04:43 2022
@@ -213,6 +213,7 @@ def keywords_off(path):
 ### This test is know to fail when Subversion is built in very deep
 ### directory structures, caused by SVN_KEYWORD_MAX_LEN being defined
 ### as 255.
+@Wimp("Relies on wc.text_base_path()")
 def keywords_from_birth(sbox):
   "commit new files with keywords active from birth"
 
@@ -551,6 +552,7 @@ def update_modified_with_translation(sbo
 # after the commit, the file and its text-base have been changed to
 # have the new line-ending style.
 @Issue(1085)
+@Wimp("Relies on wc.text_base_path()")
 def eol_change_is_text_mod(sbox):
   "committing eol-style change forces text send"
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/update_tests.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/update_tests.py Thu Feb 10 20:04:43 2022
@@ -5138,6 +5138,9 @@ def revive_children_of_copy(sbox):
     raise svntest.Failure('psi unexpectedly non-existent')
 
 @SkipUnless(svntest.main.is_os_windows)
+# Needs work: the access denied error now happens when we use the
+# working file as the base in update_editor.c:apply_textdelta().
+@Wimp("Need to update the access denied handling in update_editor.c")
 def skip_access_denied(sbox):
   """access denied paths should be skipped"""
 
@@ -6779,6 +6782,7 @@ def update_add_conflicted_deep(sbox):
   # This final update used to segfault using 1.9.0 and 1.9.1
   sbox.simple_update('A/z/z', 3)
 
+@Wimp("The error message has changed")
 def missing_tmp_update(sbox):
   "missing tmp update caused segfault"
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/upgrade_tests.py?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/cmdline/upgrade_tests.py Thu Feb 10 20:04:43 2022
@@ -118,9 +118,10 @@ def check_pristine(sbox, files):
   for file in files:
     file_path = sbox.ospath(file)
     file_text = open(file_path, 'r').read()
-    file_pristine = open(svntest.wc.text_base_path(file_path), 'r').read()
-    if (file_text != file_pristine):
-      raise svntest.Failure("pristine mismatch for '%s'" % (file))
+    # The file at wc.text_base_path() may not exist:
+    # file_pristine = open(svntest.wc.text_base_path(file_path), 'r').read()
+    # if (file_text != file_pristine):
+    #  raise svntest.Failure("pristine mismatch for '%s'" % (file))
 
 def check_dav_cache(dir_path, wc_id, expected_dav_caches):
   dot_svn = svntest.main.get_admin_name()
@@ -137,9 +138,8 @@ def check_dav_cache(dir_path, wc_id, exp
   minor = sqlite_ver[1]
   patch = sqlite_ver[2]
 
-  if major < 3 or (major == 3 and minor < 6) \
-     or (major == 3 and minor == 6 and patch < 18):
-       return # We need a newer SQLite
+  if major < 3 or (major == 3 and minor < 9):
+    return # We need a newer SQLite
 
   for local_relpath, expected_dav_cache in expected_dav_caches.items():
     # NODES conversion is complete enough that we can use it if it exists
@@ -796,6 +796,7 @@ def delete_in_copy_upgrade(sbox):
                            'b347d1da69df9a6a70433ceeaa0d46c8483e8c03']])
 
 
+@Wimp("Can't fetch pristines: the working copy points to file:///tmp/repo")
 def replaced_files(sbox):
   "upgrade with base and working replaced files"
 
@@ -1370,6 +1371,7 @@ def upgrade_1_7_dir_external(sbox):
   svntest.actions.run_and_verify_svn(None, [], 'upgrade', sbox.wc_dir)
 
 @SkipUnless(svntest.wc.python_sqlite_can_read_wc)
+@Wimp("Test calls status on a non-upgraded wc")
 def auto_analyze(sbox):
   """automatic SQLite ANALYZE"""
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/db-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/db-test.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/db-test.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/db-test.c Thu Feb 10 20:04:43 2022
@@ -87,7 +87,7 @@ static const char * const TESTING_DATA =
    "insert into repository values (2, '" ROOT_TWO "', '" UUID_TWO "'); "
    "insert into wcroot values (1, null); "
 
-   "insert into pristine values ('$sha1$" SHA1_1 "', NULL, 15, 1, '$md5 $" MD5_1 "'); "
+   "insert into pristine values ('$sha1$" SHA1_1 "', NULL, 15, 1, '$md5 $" MD5_1 "', 1); "
 );
 
 #define NOT_MOVED FALSE, NULL

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/entries-compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/entries-compat.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/entries-compat.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/entries-compat.c Thu Feb 10 20:04:43 2022
@@ -86,7 +86,7 @@ static const char * const TESTING_DATA =
    "insert into repository values (2, '" ROOT_TWO "', '" UUID_TWO "'); "
    "insert into wcroot values (1, null); "
 
-   "insert into pristine values ('$sha1$" SHA1_1 "', NULL, 15, 1, '$md5 $" MD5_1 "'); "
+   "insert into pristine values ('$sha1$" SHA1_1 "', NULL, 15, 1, '$md5 $" MD5_1 "', 1); "
    );
 
 #define NOT_MOVED FALSE, NULL

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/pristine-store-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/pristine-store-test.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/pristine-store-test.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/pristine-store-test.c Thu Feb 10 20:04:43 2022
@@ -94,7 +94,7 @@ pristine_write_read(const svn_test_opts_
   SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
                                               &install_data,
                                               &data_sha1, &data_md5,
-                                              db, wc_abspath,
+                                              db, wc_abspath, TRUE,
                                               pool, pool));
 
   sz = strlen(data);
@@ -104,10 +104,12 @@ pristine_write_read(const svn_test_opts_
   /* Ensure it's not already in the store. */
   {
     svn_boolean_t present;
+    svn_boolean_t hydrated;
 
-    SVN_ERR(svn_wc__db_pristine_check(&present, db, wc_abspath, data_sha1,
-                                      pool));
+    SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, db, wc_abspath,
+                                      data_sha1, pool));
     SVN_TEST_ASSERT(! present);
+    SVN_TEST_ASSERT(! hydrated);
   }
 
   /* Install the new pristine file, referenced by its checksum. */
@@ -117,10 +119,12 @@ pristine_write_read(const svn_test_opts_
   /* Ensure it is now found in the store. */
   {
     svn_boolean_t present;
+    svn_boolean_t hydrated;
 
-    SVN_ERR(svn_wc__db_pristine_check(&present, db, wc_abspath, data_sha1,
-                                      pool));
+    SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, db, wc_abspath,
+                                      data_sha1, pool));
     SVN_TEST_ASSERT(present);
+    SVN_TEST_ASSERT(hydrated);
   }
 
   /* Look up its MD-5 from its SHA-1, and check it's the same MD-5. */
@@ -161,10 +165,12 @@ pristine_write_read(const svn_test_opts_
   /* Ensure it's no longer found in the store. */
   {
     svn_boolean_t present;
+    svn_boolean_t hydrated;
 
-    SVN_ERR(svn_wc__db_pristine_check(&present, db, wc_abspath, data_sha1,
-                                      pool));
+    SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, db, wc_abspath,
+                                      data_sha1, pool));
     SVN_TEST_ASSERT(! present);
+    SVN_TEST_ASSERT(! hydrated);
   }
 
   return SVN_NO_ERROR;
@@ -191,7 +197,7 @@ pristine_delete_while_open(const svn_tes
   SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
                                               &install_data,
                                               &data_sha1, &data_md5,
-                                              db, wc_abspath,
+                                              db, wc_abspath, TRUE,
                                               pool, pool));
 
   sz = strlen(data);
@@ -221,10 +227,12 @@ pristine_delete_while_open(const svn_tes
    * an orphan, depending on the implementation.) */
   {
     svn_boolean_t present;
+    svn_boolean_t hydrated;
 
-    SVN_ERR(svn_wc__db_pristine_check(&present, db, wc_abspath, data_sha1,
-                                      pool));
+    SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, db, wc_abspath,
+                                      data_sha1, pool));
     SVN_TEST_ASSERT(! present);
+    SVN_TEST_ASSERT(! hydrated);
   }
 
   /* Close the read stream */
@@ -264,7 +272,7 @@ reject_mismatching_text(const svn_test_o
     SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
                                                 &install_data,
                                                 &data_sha1, &data_md5,
-                                                db, wc_abspath,
+                                                db, wc_abspath, TRUE,
                                                 pool, pool));
 
     sz = strlen(data);
@@ -286,7 +294,7 @@ reject_mismatching_text(const svn_test_o
     SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
                                                 &install_data,
                                                 &data_sha1, &data_md5,
-                                                db, wc_abspath,
+                                                db, wc_abspath, TRUE,
                                                 pool, pool));
 
     sz = strlen(data2);
@@ -306,6 +314,219 @@ reject_mismatching_text(const svn_test_o
 #endif
 }
 
+static svn_error_t *
+pristine_install_dehydrated(const svn_test_opts_t *opts,
+                            apr_pool_t *pool)
+{
+  svn_wc__db_t *db;
+  const char *wc_abspath;
+
+  svn_wc__db_install_data_t *install_data;
+  svn_stream_t *pristine_stream;
+  apr_size_t sz;
+
+  const char data[] = "Blah";
+  svn_checksum_t *data_sha1, *data_md5;
+
+  SVN_ERR(create_repos_and_wc(&wc_abspath, &db,
+                              "pristine_install_dehydrated", opts, pool));
+
+  /* Write DATA into a new temporary pristine file, set PRISTINE_TMP_ABSPATH
+   * to its path and set DATA_SHA1 and DATA_MD5 to its checksums. */
+  SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
+                                              &install_data,
+                                              &data_sha1, &data_md5,
+                                              db, wc_abspath, FALSE,
+                                              pool, pool));
+
+  sz = strlen(data);
+  SVN_ERR(svn_stream_write(pristine_stream, data, &sz));
+  SVN_ERR(svn_stream_close(pristine_stream));
+
+  /* Ensure it's not already in the store. */
+  {
+    svn_boolean_t present;
+    svn_boolean_t hydrated;
+
+    SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, db, wc_abspath,
+                                      data_sha1, pool));
+    SVN_TEST_ASSERT(! present);
+    SVN_TEST_ASSERT(! hydrated);
+  }
+
+  /* Install the new pristine file, referenced by its checksum. */
+  SVN_ERR(svn_wc__db_pristine_install(install_data,
+                                      data_sha1, data_md5, pool));
+
+  /* Ensure it is now found in the store. */
+  {
+    svn_boolean_t present;
+    svn_boolean_t hydrated;
+
+    SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, db, wc_abspath,
+                                      data_sha1, pool));
+    SVN_TEST_ASSERT(present);
+    SVN_TEST_ASSERT(! hydrated);
+  }
+
+  /* Look up its MD-5 from its SHA-1, and check it's the same MD-5. */
+  {
+    const svn_checksum_t *looked_up_md5;
+
+    SVN_ERR(svn_wc__db_pristine_get_md5(&looked_up_md5, db, wc_abspath,
+                                        data_sha1, pool, pool));
+    SVN_TEST_ASSERT(looked_up_md5->kind == svn_checksum_md5);
+    SVN_TEST_ASSERT(svn_checksum_match(data_md5, looked_up_md5));
+  }
+
+  /* Check the saved pristine size and try to read the pristine text back. */
+  {
+    svn_stream_t *actual_contents;
+    svn_filesize_t actual_size;
+
+    SVN_ERR(svn_wc__db_pristine_read(&actual_contents, &actual_size,
+                                     db, wc_abspath, data_sha1, pool, pool));
+    SVN_TEST_ASSERT(actual_contents == NULL);
+    SVN_TEST_INT_ASSERT(actual_size, sz);
+  }
+
+  /* Trivially test the "remove if unreferenced" API: it's not referenced
+     so we should be able to remove it. */
+  {
+    svn_error_t *err;
+    svn_stream_t *data_read_back;
+
+    SVN_ERR(svn_wc__db_pristine_remove(db, wc_abspath, data_sha1, pool));
+    err = svn_wc__db_pristine_read(&data_read_back, NULL, db, wc_abspath,
+                                   data_sha1, pool, pool);
+    SVN_TEST_ASSERT_ERROR(err, SVN_ERR_WC_PATH_NOT_FOUND);
+  }
+
+  /* Ensure it's no longer found in the store. */
+  {
+    svn_boolean_t present;
+    svn_boolean_t hydrated;
+
+    SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, db, wc_abspath,
+                                      data_sha1, pool));
+    SVN_TEST_ASSERT(! present);
+    SVN_TEST_ASSERT(! hydrated);
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+pristine_dehydrate(const svn_test_opts_t *opts,
+                   apr_pool_t *pool)
+{
+  svn_wc__db_t *db;
+  const char *wc_abspath;
+
+  svn_wc__db_install_data_t *install_data;
+  svn_stream_t *pristine_stream;
+  apr_size_t sz;
+
+  const char data[] = "Blah";
+  svn_string_t *data_string = svn_string_create(data, pool);
+  svn_checksum_t *data_sha1, *data_md5;
+
+  SVN_ERR(create_repos_and_wc(&wc_abspath, &db,
+                              "pristine_dehydrate", opts, pool));
+
+  /* Write DATA into a new temporary pristine file, set PRISTINE_TMP_ABSPATH
+   * to its path and set DATA_SHA1 and DATA_MD5 to its checksums. */
+  SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
+                                              &install_data,
+                                              &data_sha1, &data_md5,
+                                              db, wc_abspath, TRUE,
+                                              pool, pool));
+
+  sz = strlen(data);
+  SVN_ERR(svn_stream_write(pristine_stream, data, &sz));
+  SVN_ERR(svn_stream_close(pristine_stream));
+
+  /* Install the new pristine file, referenced by its checksum. */
+  SVN_ERR(svn_wc__db_pristine_install(install_data,
+                                      data_sha1, data_md5, pool));
+
+  /* Check the state of the pristine. */
+  {
+    svn_boolean_t present;
+    svn_boolean_t hydrated;
+
+    SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, db, wc_abspath,
+                                      data_sha1, pool));
+    SVN_TEST_ASSERT(present);
+    SVN_TEST_ASSERT(hydrated);
+  }
+
+  /* Dehydrate the pristine. */
+  SVN_ERR(svn_wc__db_pristine_dehydrate(db, wc_abspath, data_sha1, pool));
+
+  /* Check the state of the pristine. */
+  {
+    svn_boolean_t present;
+    svn_boolean_t hydrated;
+
+    SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, db, wc_abspath,
+                                      data_sha1, pool));
+    SVN_TEST_ASSERT(present);
+    SVN_TEST_ASSERT(! hydrated);
+  }
+
+  /* Check the saved pristine size and try to read the pristine text back. */
+  {
+    svn_stream_t *actual_contents;
+    svn_filesize_t actual_size;
+
+    SVN_ERR(svn_wc__db_pristine_read(&actual_contents, &actual_size,
+                                     db, wc_abspath, data_sha1, pool, pool));
+    SVN_TEST_ASSERT(actual_contents == NULL);
+    SVN_TEST_INT_ASSERT(actual_size, sz);
+  }
+
+  /* Rehydrate it by installing the pristine again. */
+  SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
+                                              &install_data,
+                                              &data_sha1, &data_md5,
+                                              db, wc_abspath, TRUE,
+                                              pool, pool));
+
+  sz = strlen(data);
+  SVN_ERR(svn_stream_write(pristine_stream, data, &sz));
+  SVN_ERR(svn_stream_close(pristine_stream));
+
+  SVN_ERR(svn_wc__db_pristine_install(install_data,
+                                      data_sha1, data_md5, pool));
+
+  /* Check the state of the pristine. */
+  {
+    svn_boolean_t present;
+    svn_boolean_t hydrated;
+
+    SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, db, wc_abspath,
+                                      data_sha1, pool));
+    SVN_TEST_ASSERT(present);
+    SVN_TEST_ASSERT(hydrated);
+  }
+
+  /* Read the pristine text back and verify it's the same content. */
+  {
+    svn_stream_t *data_stream = svn_stream_from_string(data_string, pool);
+    svn_stream_t *data_read_back;
+    svn_boolean_t same;
+
+    SVN_ERR(svn_wc__db_pristine_read(&data_read_back, NULL, db, wc_abspath,
+                                     data_sha1, pool, pool));
+    SVN_ERR(svn_stream_contents_same2(&same, data_read_back, data_stream,
+                                      pool));
+    SVN_TEST_ASSERT(same);
+  }
+
+  return SVN_NO_ERROR;
+}
+
 
 static int max_threads = -1;
 
@@ -318,6 +539,10 @@ static struct svn_test_descriptor_t test
                        "pristine_delete_while_open"),
     SVN_TEST_OPTS_PASS(reject_mismatching_text,
                        "reject_mismatching_text"),
+    SVN_TEST_OPTS_PASS(pristine_install_dehydrated,
+                       "pristine_install_dehydrated"),
+    SVN_TEST_OPTS_PASS(pristine_dehydrate,
+                       "pristine_dehydrate"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/utils.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/utils.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/utils.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/utils.c Thu Feb 10 20:04:43 2022
@@ -414,28 +414,22 @@ sbox_wc_copy_url(svn_test__sandbox_t *b,
 svn_error_t *
 sbox_wc_revert(svn_test__sandbox_t *b, const char *path, svn_depth_t depth)
 {
-  const char *abspath = sbox_wc_path(b, path);
-  const char *dir_abspath;
-  const char *lock_root_abspath;
+  svn_client_ctx_t *ctx;
+  apr_array_header_t *paths;
 
-  if (strcmp(abspath, b->wc_abspath))
-    dir_abspath = svn_dirent_dirname(abspath, b->pool);
-  else
-    dir_abspath = abspath;
+  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+
+  paths = apr_array_make(b->pool, 1, sizeof(const char *));
+  APR_ARRAY_PUSH(paths, const char *) = sbox_wc_path(b, path);
+
+  SVN_ERR(svn_client_revert4(paths, depth,
+                             NULL /* changelists */,
+                             FALSE /* clear_changelists */,
+                             FALSE /* metadata_only */,
+                             TRUE /*added_keep_local*/,
+                             ctx,
+                             b->pool));
 
-  SVN_ERR(svn_wc__acquire_write_lock(&lock_root_abspath, b->wc_ctx,
-                                     dir_abspath, FALSE /* lock_anchor */,
-                                     b->pool, b->pool));
-  SVN_ERR(svn_wc_revert6(b->wc_ctx, abspath, depth,
-                         FALSE /* use_commit_times */,
-                         NULL /* changelist_filter */,
-                         FALSE /* clear_changelists */,
-                         FALSE /* metadata_only */,
-                         TRUE /*added_keep_local*/,
-                         NULL, NULL, /* cancel baton + func */
-                         NULL, NULL, /* notify baton + func */
-                         b->pool));
-  SVN_ERR(svn_wc__release_write_lock(b->wc_ctx, lock_root_abspath, b->pool));
   return SVN_NO_ERROR;
 }
 
@@ -585,27 +579,14 @@ svn_error_t *
 sbox_wc_resolve(svn_test__sandbox_t *b, const char *path, svn_depth_t depth,
                 svn_wc_conflict_choice_t conflict_choice)
 {
-  const char *lock_abspath;
-  svn_error_t *err;
+  svn_client_ctx_t *ctx;
+
+  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
 
-  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, b->wc_ctx,
-                                                 sbox_wc_path(b, path),
-                                                 b->pool, b->pool));
-  err = svn_wc__resolve_conflicts(b->wc_ctx, sbox_wc_path(b, path),
-                                  depth,
-                                  TRUE /* resolve_text */,
-                                  "" /* resolve_prop (ALL props) */,
-                                  TRUE /* resolve_tree */,
-                                  conflict_choice,
-                                  NULL, NULL, /* conflict func */
-                                  NULL, NULL, /* cancellation */
-                                  NULL, NULL, /* notification */
-                                  b->pool);
-
-  err = svn_error_compose_create(err, svn_wc__release_write_lock(b->wc_ctx,
-                                                                 lock_abspath,
-                                                                 b->pool));
-  return err;
+  SVN_ERR(svn_client_resolve(sbox_wc_path(b, path), depth, conflict_choice,
+                             ctx, b->pool));
+
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-queries-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-queries-test.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-queries-test.c Thu Feb 10 20:04:43 2022
@@ -106,14 +106,14 @@ static const int slow_statements[] =
   STMT_SELECT_PRESENT_HIGHEST_WORKING_NODES_BY_BASENAME_AND_KIND,
   STMT_SELECT_COPIES_OF_REPOS_RELPATH,
 
-  /* Designed as slow to avoid penalty on other queries */
-  STMT_SELECT_UNREFERENCED_PRISTINES,
-
   /* Slow, but just if foreign keys are enabled:
    * STMT_DELETE_PRISTINE_IF_UNREFERENCED,
    */
   STMT_HAVE_STAT1_TABLE, /* Queries sqlite_master which has no index */
 
+  /* Currently uses a temporary B-tree for GROUP BY */
+  STMT_TEXTBASE_SYNC,
+
   -1 /* final marker */
 };
 

Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-test-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-test-queries.sql?rev=1897946&r1=1897945&r2=1897946&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-test-queries.sql (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-test-queries.sql Thu Feb 10 20:04:43 2022
@@ -61,10 +61,10 @@ INSERT INTO actual_node (local_relpath,
                 VALUES (?1, ?2, ?3, 1)
 
 -- STMT_ENSURE_EMPTY_PRISTINE
-INSERT OR IGNORE INTO pristine (checksum, md5_checksum, size, refcount)
+INSERT OR IGNORE INTO pristine (checksum, md5_checksum, size, refcount, hydrated)
   VALUES ('$sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709',
           '$md5 $d41d8cd98f00b204e9800998ecf8427e',
-          0, 0)
+          0, 0, 1)
 
 -- STMT_NODES_SET_FILE
 UPDATE nodes