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/01/14 14:01:51 UTC

svn commit: r1897034 [25/37] - in /subversion/branches/multi-wc-format: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/ contrib/client-side/svn_load_dirs/ contrib/hook-scripts/ contrib/s...

Modified: subversion/branches/multi-wc-format/subversion/libsvn_subr/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_subr/version.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_subr/version.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_subr/version.c Fri Jan 14 14:01:45 2022
@@ -41,7 +41,7 @@ svn_boolean_t svn_ver_compatible(const s
                                  const svn_version_t *lib_version)
 {
   /* With normal development builds the matching rules are stricter
-     that for release builds, to avoid inadvertantly using the wrong
+     than for release builds, to avoid inadvertently using the wrong
      libraries.  For backward compatibility testing of development
      builds one can use --disable-full-version-match to cause a
      development build to use the release build rules.  This allows
@@ -143,7 +143,7 @@ svn_version_extended(svn_boolean_t verbo
   info->build_time = __TIME__;
   info->build_host = SVN_BUILD_HOST;
   info->copyright = apr_pstrdup
-    (pool, _("Copyright (C) 2018 The Apache Software Foundation.\n"
+    (pool, _("Copyright (C) 2022 The Apache Software Foundation.\n"
              "This software consists of contributions made by many people;\n"
              "see the NOTICE file for more information.\n"
              "Subversion is open source software, see "

Modified: subversion/branches/multi-wc-format/subversion/libsvn_subr/win32_crashrpt.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_subr/win32_crashrpt.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_subr/win32_crashrpt.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_subr/win32_crashrpt.c Fri Jan 14 14:01:45 2022
@@ -45,9 +45,6 @@ typedef int win32_crashrpt__dummy;
 /*** Global variables ***/
 static HANDLE dbghelp_dll = INVALID_HANDLE_VALUE;
 
-/* Email address where the crash reports should be sent too. */
-#define CRASHREPORT_EMAIL "users@subversion.apache.org"
-
 #define DBGHELP_DLL "dbghelp.dll"
 
 #define LOGFILE_PREFIX "svn-crash-log"
@@ -56,6 +53,8 @@ static HANDLE dbghelp_dll = INVALID_HAND
 #define FORMAT_PTR "0x%08Ix"
 #elif defined(_M_X64)
 #define FORMAT_PTR "0x%016Ix"
+#elif defined(_M_ARM64)
+#define FORMAT_PTR "0x%016Ix"
 #endif
 
 /*** Code. ***/
@@ -256,6 +255,35 @@ write_process_info(EXCEPTION_RECORD *exc
                 "cs=%04x  ss=%04x  ds=%04x  es=%04x  fs=%04x  gs=%04x\n",
                 context->SegCs, context->SegSs, context->SegDs,
                 context->SegEs, context->SegFs, context->SegGs);
+#elif defined(_M_ARM64)
+  fprintf(log_file,
+          "X0 = %016I64x  X1 = %016I64x  X2 = %016I64x  X3 = %016I64x\n",
+          context->X0, context->X1, context->X2, context->X3);
+  fprintf(log_file,
+          "X4 = %016I64x  X5 = %016I64x  X6 = %016I64x  X7 = %016I64x\n",
+          context->X4, context->X5, context->X6, context->X7);
+  fprintf(log_file,
+          "X8 = %016I64x  X9 = %016I64x  X10= %016I64x  X11= %016I64x\n",
+          context->X8, context->X9, context->X10, context->X11);
+  fprintf(log_file,
+          "X12= %016I64x  X13= %016I64x  X14= %016I64x  X15= %016I64x\n",
+          context->X12, context->X13, context->X14, context->X15);
+  fprintf(log_file,
+          "X16= %016I64x  X17= %016I64x  X18= %016I64x  X19= %016I64x\n",
+          context->X16, context->X17, context->X18, context->X19);
+  fprintf(log_file,
+          "X20= %016I64x  X21= %016I64x  X22= %016I64x  X23= %016I64x\n",
+          context->X20, context->X21, context->X22, context->X23);
+  fprintf(log_file,
+          "X24= %016I64x  X25= %016I64x  X26= %016I64x  X27= %016I64x\n",
+          context->X24, context->X25, context->X26, context->X27);
+  fprintf(log_file,
+          "X28= %016I64x\n",
+          context->X28);
+  fprintf(log_file,
+          "Fp = %016I64x  Lr = %016I64x  Sp = %016I64x  Pc = %016I64x\n",
+          context->Fp, context->Lr, context->Sp, context->Pc);
+  /* Ignoring debug and floating point registers here */
 #else
 #error Unknown processortype, please disable SVN_USE_WIN32_CRASHHANDLER
 #endif
@@ -518,7 +546,7 @@ write_function_detail(STACKFRAME64 stack
 static void
 write_stacktrace(CONTEXT *context, FILE *log_file)
 {
-#if defined (_M_IX86) || defined(_M_X64) || defined(_M_IA64)
+#if defined (_M_IX86) || defined(_M_X64) || defined(_M_IA64) || defined(_M_ARM64)
   HANDLE proc = GetCurrentProcess();
   STACKFRAME64 stack_frame;
   DWORD machine;
@@ -565,6 +593,11 @@ write_stacktrace(CONTEXT *context, FILE
   stack_frame.AddrStack.Offset  = context->SP;
   stack_frame.AddrBStore.Mode   = AddrModeFlat;
   stack_frame.AddrBStore.Offset = context->RsBSP;
+#elif defined(_M_ARM64)
+  machine = IMAGE_FILE_MACHINE_ARM64;
+  stack_frame.AddrPC.Offset = context->Pc;
+  stack_frame.AddrStack.Offset = context->Sp;
+  stack_frame.AddrFrame.Offset = context->Fp;
 #else
 #error Unknown processortype, please disable SVN_USE_WIN32_CRASHHANDLER
 #endif
@@ -774,7 +807,7 @@ svn__unhandled_exception_filter(PEXCEPTI
                   "usernames and passwords etc.)\n",
                   log_filename,
                   dmp_filename,
-                  CRASHREPORT_EMAIL);
+                  SVN_WIN32_CRASHREPORT_EMAIL);
 
   if (getenv("SVN_DBG_STACKTRACES_TO_STDERR") != NULL)
     {

Modified: subversion/branches/multi-wc-format/subversion/libsvn_subr/win32_crypto.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_subr/win32_crypto.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_subr/win32_crypto.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_subr/win32_crypto.c Fri Jan 14 14:01:45 2022
@@ -395,16 +395,29 @@ windows_validate_certificate(svn_boolean
       memset(&chain_para, 0, sizeof(chain_para));
       chain_para.cbSize = sizeof(chain_para);
 
+      /* Don't hit the wire for URL based objects and revocation checks, as
+         that may cause stalls, network timeouts or spurious errors in cases
+         such as with the remote OCSP and CRL endpoints being inaccessible or
+         unreliable.
+
+         For this particular case of the SVN_AUTH_SSL_UNKNOWNCA cert failure
+         override we should be okay with just the data that we have immediately
+         available on the local machine.
+       */
       if (CertGetCertificateChain(NULL, cert_context, NULL, NULL, &chain_para,
                                   CERT_CHAIN_CACHE_END_CERT |
-                                  CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT,
+                                  CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL |
+                                  CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT |
+                                  CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY,
                                   NULL, &chain_context))
         {
           CERT_CHAIN_POLICY_PARA policy_para;
           CERT_CHAIN_POLICY_STATUS policy_status;
 
           policy_para.cbSize = sizeof(policy_para);
-          policy_para.dwFlags = 0;
+          /* We only use the local data for revocation checks, so they may
+             fail with errors like CRYPT_E_REVOCATION_OFFLINE; ignore those. */
+          policy_para.dwFlags = CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS;
           policy_para.pvExtraPolicyPara = NULL;
 
           policy_status.cbSize = sizeof(policy_status);

Modified: subversion/branches/multi-wc-format/subversion/libsvn_subr/win32_xlate.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_subr/win32_xlate.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_subr/win32_xlate.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_subr/win32_xlate.c Fri Jan 14 14:01:45 2022
@@ -65,8 +65,8 @@ initialize_com(void *baton, apr_pool_t*
 
   if (hr == RPC_E_CHANGED_MODE)
     {
-      /* COM already initalized for multi-threaded object concurrency. We are
-         neutral to object concurrency so try to initalize it in the same way
+      /* COM already initialized for multi-threaded object concurrency. We are
+         neutral to object concurrency so try to initialize it in the same way
          for us, to keep an handle open. */
       hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
     }

Modified: subversion/branches/multi-wc-format/subversion/libsvn_subr/x509parse.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_subr/x509parse.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_subr/x509parse.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_subr/x509parse.c Fri Jan 14 14:01:45 2022
@@ -262,7 +262,7 @@ x509_get_alg(const unsigned char **p, co
 
   if (*p == end)
     return SVN_NO_ERROR;
-  
+
   /* The OID encoding of 1.2.840.113549.1.1.10 (id-RSASSA-PSS) */
 #define OID_RSASSA_PSS "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0a"
 
@@ -882,7 +882,7 @@ x509name_to_utf8_string(const x509_name
 
       /* Both BMP and UNIVERSAL should always be in Big Endian (aka
        * network byte order).  But rumor has it that there are certs
-       * out there with other endianess and even Byte Order Marks.
+       * out there with other endianness and even Byte Order Marks.
        * If we actually run into these, we might need to do something
        * about it. */
 
@@ -916,7 +916,7 @@ x509name_to_utf8_string(const x509_name
 
       /* This leaves two types out there in the wild.  PrintableString,
        * which is just a subset of ASCII and IA5 which is ASCII (though
-       * 0x24 '$' and 0x23 '#' may be defined with differnet symbols
+       * 0x24 '$' and 0x23 '#' may be defined with different symbols
        * depending on the location, in practice it seems everyone just
        * treats it as ASCII).  Since these are just ASCII run through
        * the fuzzy_escape code to deal with anything that isn't actually
@@ -979,7 +979,7 @@ is_hostname(const char *str)
           if (i + 1 != len)
             {
               if (str[i + 1] == '.')
-                return FALSE; /* '-' preceeds a '.' */
+                return FALSE; /* '-' precedes a '.' */
             }
           else
             return FALSE; /* '-' is at end of string */

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/conflicts.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/conflicts.c Fri Jan 14 14:01:45 2022
@@ -660,7 +660,7 @@ svn_wc__conflict_skel_resolve(svn_boolea
           /* If no conflicted property names left */
           if (!c->next->next->children)
             {
-              /* Remove the propery conflict skel from the linked list */
+              /* Remove the property conflict skel from the linked list */
              *pconflict = (*pconflict)->next;
              continue;
             }
@@ -1386,7 +1386,7 @@ generate_propconflict(svn_boolean_t *con
         }
       case svn_wc_conflict_choose_merged:
         {
-          if (!cdesc->merged_file 
+          if (!cdesc->merged_file
               && (!result->merged_file && !result->merged_value))
             return svn_error_create
                 (SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
@@ -2381,7 +2381,7 @@ svn_wc__read_conflict_descriptions2_t(co
                                       apr_pool_t *result_pool,
                                       apr_pool_t *scratch_pool)
 {
-  return svn_wc__read_conflicts(conflicts, NULL, wc_ctx->db, local_abspath, 
+  return svn_wc__read_conflicts(conflicts, NULL, wc_ctx->db, local_abspath,
                                 FALSE, FALSE, result_pool, scratch_pool);
 }
 
@@ -2637,7 +2637,7 @@ resolve_prop_conflict_on_node(svn_boolea
   return SVN_NO_ERROR;
 }
 
-/* 
+/*
  * Record a tree conflict resolution failure due to error condition ERR
  * in the RESOLVE_LATER hash table. If the hash table is not available
  * (meaning the caller does not wish to retry resolution later), or if
@@ -3899,7 +3899,7 @@ svn_wc__guess_incoming_move_target_nodes
    * cannot be modified (e.g. replaced or deleted nodes) don't count.
    * Nodes which are of a different node kind don't count either.
    * Ignore switched nodes as well, since that is an unlikely case during
-   * update/swtich/merge conflict resolution. And externals shouldn't even
+   * update/switch/merge conflict resolution. And externals shouldn't even
    * be on our candidate list in the first place.
    * If multiple candidates match these criteria, choose the one which
    * shares the longest common ancestor with the victim. */
@@ -3938,7 +3938,7 @@ svn_wc__guess_incoming_move_target_nodes
           status != svn_wc__db_status_added)
         continue;
 
-      if (node_kind != victim_node_kind)
+      if (victim_node_kind != svn_node_none && node_kind != victim_node_kind)
         continue;
 
       SVN_ERR(svn_wc__db_is_switched(&is_wcroot, &is_switched, NULL,
@@ -3965,8 +3965,8 @@ svn_wc__guess_incoming_move_target_nodes
         {
           insert_index = (*possible_targets)->nelts; /* append */
         }
-      svn_sort__array_insert(*possible_targets, &moved_to_abspath,
-                             insert_index);
+      SVN_ERR(svn_sort__array_insert2(*possible_targets, &moved_to_abspath,
+                                      insert_index));
     }
 
   svn_pool_destroy(iterpool);

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/conflicts.h
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/conflicts.h?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/conflicts.h (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/conflicts.h Fri Jan 14 14:01:45 2022
@@ -220,7 +220,7 @@ svn_wc__conflict_skel_add_prop_conflict(
    with (1), MOVE_SRC_OP_ROOT_ABSPATH should be A/B for a conflict
    associated with (2).
    MOVE_DST_OP_ROOT_ABSPATH is the op-root of the move target (i.e. the
-   op-root of the corresponding copy). This needs to be stored because 
+   op-root of the corresponding copy). This needs to be stored because
    moves in the NODE table do not always persist after an update, while
    the conflict resolver may need information about the pre-update state
    of the move.
@@ -259,7 +259,7 @@ svn_wc__conflict_skel_add_tree_conflict(
    resolve/remove the tree conflict in CONFLICT_SKEL.
 
    If COMPLETELY_RESOLVED is not NULL, then set *COMPLETELY_RESOLVED to TRUE,
-   when no conflict registration is left in CONFLICT_SKEL after editting,
+   when no conflict registration is left in CONFLICT_SKEL after editing,
    otherwise to FALSE.
 
    Allocate data stored in the skel in RESULT_POOL.

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/copy.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/copy.c Fri Jan 14 14:01:45 2022
@@ -148,7 +148,7 @@ copy_to_tmpdir(svn_skel_t **work_item,
     }
   else if (*kind == svn_node_dir && !file_copy)
     {
-      /* Just build a new direcory from the workqueue */
+      /* Just build a new directory from the workqueue */
       SVN_ERR(svn_wc__wq_build_dir_install(work_item,
                                            db, dst_abspath,
                                            result_pool, scratch_pool));

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/diff_local.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/diff_local.c Fri Jan 14 14:01:45 2022
@@ -490,7 +490,7 @@ svn_wc__diff7(svn_boolean_t anchor_at_gi
       SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelist_filter,
                                          result_pool));
       diff_processor = svn_wc__changelist_filter_tree_processor_create(
-                         diff_processor, wc_ctx, local_abspath,
+                         diff_processor, wc_ctx, eb.anchor_abspath,
                          changelist_hash, result_pool);
     }
 

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/entries.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/entries.c Fri Jan 14 14:01:45 2022
@@ -781,7 +781,7 @@ read_one_entry(const svn_wc_entry_t **ne
               if (parent_root_url != NULL
                        && strcmp(original_root_url, parent_root_url) == 0)
                 {
-                  
+
                   const char *relpath_to_entry = svn_dirent_is_child(
                     op_root_abspath, entry_abspath, NULL);
                   const char *entry_repos_relpath = svn_relpath_join(
@@ -1049,7 +1049,7 @@ read_entries_new(apr_hash_t **result_ent
       svn_pool_clear(iterpool);
 
       SVN_ERR(read_one_entry(&entry,
-                             db, dir_abspath, 
+                             db, dir_abspath,
                              wcroot, dir_relpath,
                              name, parent_entry,
                              result_pool, iterpool));

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/lock.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/lock.c Fri Jan 14 14:01:45 2022
@@ -594,7 +594,7 @@ open_single(svn_wc_adm_access_t **adm_ac
    KIND can be NULL.
 
    ### note: this function should go away when we move to a single
-   ### adminstrative area.  */
+   ### administrative area.  */
 static svn_error_t *
 adm_available(svn_boolean_t *available,
               svn_node_kind_t *kind,

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/node.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/node.c Fri Jan 14 14:01:45 2022
@@ -1140,3 +1140,17 @@ svn_wc__find_working_nodes_with_basename
                            abspaths, wc_ctx->db, wri_abspath, basename, kind,
                            result_pool, scratch_pool));
 }
+
+svn_error_t *
+svn_wc__find_copies_of_repos_path(apr_array_header_t **abspaths,
+                                  const char *wri_abspath,
+                                  const char *repos_relpath,
+                                  svn_node_kind_t kind,
+                                  svn_wc_context_t *wc_ctx,
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(svn_wc__db_find_copies_of_repos_path(
+                           abspaths, wc_ctx->db, wri_abspath, repos_relpath,
+                           kind, result_pool, scratch_pool));
+}

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/revert.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/revert.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/revert.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/revert.c Fri Jan 14 14:01:45 2022
@@ -62,6 +62,18 @@
       the addition of all the directory's children.  Again,
       svn_wc_remove_from_revision_control() should do the trick.
 
+    - For a copy, we remove the item from disk as well. The thinking here
+      is that Subversion is responsible for the existence of the item: it
+      must have been created by something like 'svn copy' or 'svn merge'.
+
+    - For a plain add, removing the file or directory from disk is optional.
+      The user's idea of Subversion's involvement could be either that
+      Subversion was just responsible for adding an existing item to version
+      control, as with 'svn add', and so should not be responsible for
+      deleting it from disk; or that Subversion is responsible for the
+      existence of the item, e.g. if created by 'svn patch' or svn mkdir'.
+      It depends on the use case.
+
     Deletes
 
     - Restore properties to their unmodified state.

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/update_editor.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/update_editor.c Fri Jan 14 14:01:45 2022
@@ -765,6 +765,12 @@ struct file_baton
 
   /* The tree conflict to install once the node is really edited */
   svn_skel_t *edit_conflict;
+
+  /* Cached copy of the base properties for this file. */
+  apr_hash_t *base_props;
+
+  /* Writer with the provisioned content of the working file.  May be NULL. */
+  svn_wc__working_file_writer_t *file_writer;
 };
 
 
@@ -1014,6 +1020,12 @@ window_handler(svn_txdelta_window_t *win
           svn_error_clear(svn_wc__db_pristine_install_abort(hb->install_data,
                                                             hb->pool));
         }
+
+      if (fb->file_writer)
+        {
+          svn_error_clear(svn_wc__working_file_writer_close(fb->file_writer));
+          fb->file_writer = NULL;
+        }
     }
   else
     {
@@ -1040,7 +1052,7 @@ window_handler(svn_txdelta_window_t *win
 
 /* Find the last-change info within ENTRY_PROPS, and return then in the
    CHANGED_* parameters. Each parameter will be initialized to its "none"
-   value, and will contain the relavent info if found.
+   value, and will contain the relevant info if found.
 
    CHANGED_AUTHOR will be allocated in RESULT_POOL. SCRATCH_POOL will be
    used for some temporary allocations.
@@ -1458,7 +1470,7 @@ check_tree_conflict(svn_skel_t **pconfli
          * Therefore, we need to start a separate crawl here. */
 
         SVN_ERR(svn_wc__node_has_local_mods(&modified, NULL,
-                                            eb->db, local_abspath, FALSE,
+                                            eb->db, local_abspath, TRUE,
                                             eb->cancel_func, eb->cancel_baton,
                                             scratch_pool));
 
@@ -3560,6 +3572,151 @@ open_file(const char *path,
   return SVN_NO_ERROR;
 }
 
+/* Return the, possibly cached, base properties for file associated
+   with the delta editor baton FB. */
+static svn_error_t *
+get_file_base_props(apr_hash_t **props_p,
+                    struct file_baton *fb,
+                    apr_pool_t *scratch_pool)
+{
+  if (!fb->base_props)
+    {
+      apr_hash_t *props;
+
+      if (fb->add_existed)
+        {
+          /* This node already exists. Grab the current pristine properties. */
+          SVN_ERR(svn_wc__db_read_pristine_props(&props,
+                                                 fb->edit_baton->db,
+                                                 fb->local_abspath,
+                                                 fb->pool, scratch_pool));
+        }
+      else if (!fb->adding_file)
+        {
+          /* Get the BASE properties for proper merging. */
+          SVN_ERR(svn_wc__db_base_get_props(&props,
+                                            fb->edit_baton->db,
+                                            fb->local_abspath,
+                                            fb->pool, scratch_pool));
+        }
+      else
+        props = apr_hash_make(fb->pool);
+
+      fb->base_props = props;
+    }
+
+  *props_p = fb->base_props;
+  return SVN_NO_ERROR;
+}
+
+/* Create the writer of the working file based on the state of
+   the file associated with the delta editor baton FB. */
+static svn_error_t *
+open_working_file_writer(svn_wc__working_file_writer_t **writer_p,
+                         struct file_baton *fb,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
+{
+  apr_hash_t *base_props;
+  apr_hash_t *props;
+  svn_boolean_t is_special;
+  svn_boolean_t is_executable;
+  svn_boolean_t needs_lock;
+  const char *eol_propval;
+  svn_subst_eol_style_t eol_style;
+  const char *eol;
+  const char *keywords_propval;
+  apr_hash_t *keywords;
+  const char *temp_dir_abspath;
+  const char *cmt_rev_str;
+  const char *cmt_date_str;
+  apr_time_t cmt_date;
+  const char *cmt_author;
+  apr_time_t final_mtime;
+  svn_boolean_t is_readonly;
+
+  SVN_ERR(get_file_base_props(&base_props, fb, scratch_pool));
+  props = svn_prop__patch(base_props, fb->propchanges, scratch_pool);
+
+  is_special = svn_prop_get_value(props, SVN_PROP_SPECIAL) != NULL;
+  is_executable = svn_prop_get_value(props, SVN_PROP_EXECUTABLE) != NULL;
+  needs_lock = svn_prop_get_value(props, SVN_PROP_NEEDS_LOCK) != NULL;
+
+  eol_propval = svn_prop_get_value(props, SVN_PROP_EOL_STYLE);
+  svn_subst_eol_style_from_value(&eol_style, &eol, eol_propval);
+
+  cmt_rev_str = svn_prop_get_value(props, SVN_PROP_ENTRY_COMMITTED_REV);
+
+  cmt_date_str = svn_prop_get_value(props, SVN_PROP_ENTRY_COMMITTED_DATE);
+  if (cmt_date_str)
+    SVN_ERR(svn_time_from_cstring(&cmt_date, cmt_date_str, scratch_pool));
+  else
+    cmt_date = 0;
+
+  cmt_author = svn_prop_get_value(props, SVN_PROP_ENTRY_LAST_AUTHOR);
+
+  keywords_propval = svn_prop_get_value(props, SVN_PROP_KEYWORDS);
+  if (keywords_propval)
+    {
+      const char *url =
+        svn_path_url_add_component2(fb->edit_baton->repos_root,
+                                    fb->new_repos_relpath,
+                                    scratch_pool);
+
+      SVN_ERR(svn_subst_build_keywords3(&keywords, keywords_propval,
+                                        cmt_rev_str, url,
+                                        fb->edit_baton->repos_root,
+                                        cmt_date, cmt_author,
+                                        scratch_pool));
+    }
+  else
+    {
+      keywords = NULL;
+    }
+
+  SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath,
+                                         fb->edit_baton->db,
+                                         fb->edit_baton->wcroot_abspath,
+                                         scratch_pool, scratch_pool));
+
+  if (fb->edit_baton->use_commit_times && cmt_date)
+    final_mtime = cmt_date;
+  else
+    final_mtime = -1;
+
+  if (needs_lock)
+    {
+      svn_wc__db_lock_t *lock;
+
+      SVN_ERR(svn_wc__db_lock_get(&lock,
+                                  fb->edit_baton->db,
+                                  fb->edit_baton->wcroot_abspath,
+                                  fb->new_repos_relpath,
+                                  scratch_pool,
+                                  scratch_pool));
+      is_readonly = (lock == NULL);
+    }
+  else
+    {
+      is_readonly = FALSE;
+    }
+
+  SVN_ERR(svn_wc__working_file_writer_open(writer_p,
+                                           temp_dir_abspath,
+                                           final_mtime,
+                                           eol_style,
+                                           eol,
+                                           TRUE /* repair_eol */,
+                                           keywords,
+                                           is_special,
+                                           is_executable,
+                                           is_readonly,
+                                           result_pool,
+                                           scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* Implements svn_stream_lazyopen_func_t. */
 static svn_error_t *
 lazy_open_source(svn_stream_t **stream,
@@ -3580,29 +3737,61 @@ lazy_open_source(svn_stream_t **stream,
 
 /* Implements svn_stream_lazyopen_func_t. */
 static svn_error_t *
-lazy_open_target(svn_stream_t **stream,
+lazy_open_target(svn_stream_t **stream_p,
                  void *baton,
                  apr_pool_t *result_pool,
                  apr_pool_t *scratch_pool)
 {
   struct handler_baton *hb = baton;
-  svn_wc__db_install_data_t *install_data;
+  struct file_baton *fb = hb->fb;
+  svn_wc__db_install_data_t *pristine_install_data;
+  svn_stream_t *pristine_install_stream;
+  svn_wc__working_file_writer_t *file_writer;
+  svn_stream_t *stream;
 
   /* By convention return value is undefined on error, but we rely
      on HB->INSTALL_DATA value in window_handler() and abort
      INSTALL_STREAM if is not NULL on error.
      So we store INSTALL_DATA to local variable first, to leave
      HB->INSTALL_DATA unchanged on error. */
-  SVN_ERR(svn_wc__db_pristine_prepare_install(stream,
-                                              &install_data,
+  SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_install_stream,
+                                              &pristine_install_data,
                                               &hb->new_text_base_sha1_checksum,
                                               NULL,
-                                              hb->fb->edit_baton->db,
-                                              hb->fb->dir_baton->local_abspath,
+                                              fb->edit_baton->db,
+                                              fb->dir_baton->local_abspath,
                                               result_pool, scratch_pool));
 
-  hb->install_data = install_data;
+  if (fb->shadowed || fb->obstruction_found || fb->edit_obstructed)
+    {
+      /* No need to provision the working file. */
+      file_writer = NULL;
+    }
+  else
+    {
+      SVN_ERR(open_working_file_writer(&file_writer, fb, fb->pool,
+                                       scratch_pool));
+    }
 
+  hb->install_data = pristine_install_data;
+  fb->file_writer = file_writer;
+
+  /* Configure the incoming data to be written to both the pristine and the
+     provisioned working file.  This allows us to properly stream data and
+     avoid having to re-read and copy the contents of the pristine file as
+     some post-op.  Streaming is essential if we want the underlying transport
+     such as HTTP to work without timeouts and without any limits on the
+     sizes of the directories that can be checked out. */
+  stream = pristine_install_stream;
+  if (file_writer)
+    {
+      stream = svn_stream_tee(
+                 pristine_install_stream,
+                 svn_wc__working_file_writer_get_stream(file_writer),
+                 result_pool);
+    }
+
+  *stream_p = stream;
   return SVN_NO_ERROR;
 }
 
@@ -4214,6 +4403,9 @@ close_file(void *file_baton,
   svn_boolean_t keep_recorded_info = FALSE;
   const svn_checksum_t *new_checksum;
   apr_array_header_t *iprops = NULL;
+  svn_boolean_t install_pristine;
+  const char *install_from = NULL;
+  svn_boolean_t record_fileinfo;
 
   if (fb->skip_this)
     {
@@ -4318,22 +4510,8 @@ close_file(void *file_baton,
   if (local_actual_props == NULL)
     local_actual_props = apr_hash_make(scratch_pool);
 
-  if (fb->add_existed)
-    {
-      /* This node already exists. Grab the current pristine properties. */
-      SVN_ERR(svn_wc__db_read_pristine_props(&current_base_props,
-                                             eb->db, fb->local_abspath,
-                                             scratch_pool, scratch_pool));
-      current_actual_props = local_actual_props;
-    }
-  else if (!fb->adding_file)
-    {
-      /* Get the BASE properties for proper merging. */
-      SVN_ERR(svn_wc__db_base_get_props(&current_base_props,
-                                        eb->db, fb->local_abspath,
-                                        scratch_pool, scratch_pool));
-      current_actual_props = local_actual_props;
-    }
+  SVN_ERR(get_file_base_props(&current_base_props, fb, scratch_pool));
+  current_actual_props = local_actual_props;
 
   /* Note: even if the node existed before, it may not have
      pristine props (e.g a local-add)  */
@@ -4348,9 +4526,6 @@ close_file(void *file_baton,
 
   if (! fb->shadowed)
     {
-      svn_boolean_t install_pristine;
-      const char *install_from = NULL;
-
       /* Merge the 'regular' props into the existing working proplist. */
       /* This will merge the old and new props into a new prop db, and
          write <cp> commands to the logfile to install the merged
@@ -4419,29 +4594,8 @@ close_file(void *file_baton,
             content_state = svn_wc_notify_state_unchanged;
         }
 
-      if (install_pristine)
-        {
-          svn_boolean_t record_fileinfo;
-
-          /* If we are installing from the pristine contents, then go ahead and
-             record the fileinfo. That will be the "proper" values. Installing
-             from some random file means the fileinfo does NOT correspond to
-             the pristine (in which case, the fileinfo will be cleared for
-             safety's sake).  */
-          record_fileinfo = (install_from == NULL);
-
-          SVN_ERR(svn_wc__wq_build_file_install(&work_item,
-                                                eb->db,
-                                                fb->local_abspath,
-                                                install_from,
-                                                eb->use_commit_times,
-                                                record_fileinfo,
-                                                scratch_pool, scratch_pool));
-          all_work_items = svn_wc__wq_merge(all_work_items, work_item,
-                                            scratch_pool);
-        }
-      else if (lock_state == svn_wc_notify_lock_state_unlocked
-               && !fb->obstruction_found)
+      if (lock_state == svn_wc_notify_lock_state_unlocked
+          && !fb->obstruction_found)
         {
           /* If a lock was removed and we didn't update the text contents, we
              might need to set the file read-only.
@@ -4460,20 +4614,6 @@ close_file(void *file_baton,
           /* It is safe to keep the current recorded timestamp and size */
           keep_recorded_info = TRUE;
         }
-
-      /* Clean up any temporary files.  */
-
-      /* Remove the INSTALL_FROM file, as long as it doesn't refer to the
-         working file.  */
-      if (install_from != NULL
-          && strcmp(install_from, fb->local_abspath) != 0)
-        {
-          SVN_ERR(svn_wc__wq_build_file_remove(&work_item, eb->db,
-                                               fb->local_abspath, install_from,
-                                               scratch_pool, scratch_pool));
-          all_work_items = svn_wc__wq_merge(all_work_items, work_item,
-                                            scratch_pool);
-        }
     }
   else
     {
@@ -4505,6 +4645,8 @@ close_file(void *file_baton,
         content_state = svn_wc_notify_state_changed;
       else
         content_state = svn_wc_notify_state_unchanged;
+
+      install_pristine = FALSE;
     }
 
   /* Insert/replace the BASE node with all of the new metadata.  */
@@ -4558,6 +4700,54 @@ close_file(void *file_baton,
         svn_hash_sets(eb->wcroot_iprops, fb->local_abspath, NULL);
     }
 
+  /* We have to install the working file from the pristine, but we did not
+     receive it as the part of this edit.  Or we did receive it, but have to
+     install from a different file.  Either way, reset the writer and copy
+     appropriate contents to it.  */
+  if (install_pristine && (fb->file_writer == NULL || install_from))
+    {
+      svn_stream_t *src_stream;
+      svn_stream_t *dst_stream;
+
+      if (!fb->file_writer)
+        {
+          SVN_ERR(open_working_file_writer(&fb->file_writer, fb, fb->pool,
+                                           scratch_pool));
+        }
+
+      dst_stream = svn_wc__working_file_writer_get_stream(fb->file_writer);
+      SVN_ERR(svn_stream_reset(dst_stream));
+
+      if (install_from)
+        {
+          apr_file_t *file;
+          /* Open an unbuffered file, as svn_wc__db_pristine_read() does. */
+          SVN_ERR(svn_io_file_open(&file, install_from, APR_READ,
+                                   APR_OS_DEFAULT, scratch_pool));
+          src_stream = svn_stream_from_aprfile2(file, FALSE, scratch_pool);
+        }
+      else
+        {
+          SVN_ERR(svn_wc__db_pristine_read(&src_stream, NULL, eb->db,
+                                           eb->wcroot_abspath, new_checksum,
+                                           scratch_pool, scratch_pool));
+        }
+
+      SVN_ERR(svn_stream_copy3(src_stream, dst_stream, NULL, NULL, scratch_pool));
+
+      /* Remove the INSTALL_FROM file, as long as it doesn't refer to the
+         working file.  */
+      if (install_from && strcmp(install_from, fb->local_abspath) != 0)
+        SVN_ERR(svn_io_remove_file2(install_from, TRUE, scratch_pool));
+    }
+
+  /* If we are installing from the pristine contents, then go ahead and
+     record the fileinfo. That will be the "proper" values. Installing
+     from some random file means the fileinfo does NOT correspond to
+     the pristine (in which case, the fileinfo will be cleared for
+     safety's sake).  */
+  record_fileinfo = (install_from == NULL);
+
   SVN_ERR(svn_wc__db_base_add_file(eb->db, fb->local_abspath,
                                    eb->wcroot_abspath,
                                    fb->new_repos_relpath,
@@ -4580,9 +4770,17 @@ close_file(void *file_baton,
                                    keep_recorded_info,
                                    (fb->shadowed && fb->obstruction_found),
                                    conflict_skel,
+                                   install_pristine ? fb->file_writer : NULL,
+                                   record_fileinfo,
                                    all_work_items,
                                    scratch_pool));
 
+  if (fb->file_writer)
+    {
+      SVN_ERR(svn_wc__working_file_writer_close(fb->file_writer));
+      fb->file_writer = NULL;
+    }
+
   if (conflict_skel && eb->conflict_func)
     SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, fb->local_abspath,
                                              svn_node_file,

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/upgrade.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/upgrade.c Fri Jan 14 14:01:45 2022
@@ -1639,7 +1639,7 @@ svn_wc__version_string_from_format(int w
       case 29: return "1.7";
       case 31: return "1.8";
 #ifdef SVN_TEST_MULTI_WC_FORMAT
-      case 32: return "1.12";
+      case 32: return "1.15";
 #endif
     }
   return _("(unreleased development version)");
@@ -1670,11 +1670,14 @@ svn_wc__format_from_version(int *format,
       case 5:  *format = 9; break;
       case 6:  *format = 10; break;
       case 7:  *format = 29; break;
-      case 8:  /* Same as 1.11.x. */
-      case 9:  /* Same as 1.11.x. */
-      case 10: /* Same as 1.11.x. */
-      case 11: *format = 31; break;
-      case 12: /* Same as the current version. */
+      case 8:  /* Same as 1.14.x. */
+      case 9:  /* Same as 1.14.x. */
+      case 10: /* Same as 1.14.x. */
+      case 11: /* Same as 1.14.x. */
+      case 12: /* Same as 1.14.x. */
+      case 13: /* Same as 1.14.x. */
+      case 14: *format = 31; break;
+      case 15: /* Same as the current version. */
       default: *format = SVN_WC__VERSION; break;
     }
 

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/wc-metadata.sql?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/wc-metadata.sql Fri Jan 14 14:01:45 2022
@@ -638,7 +638,7 @@ ON NODES (wc_id, moved_to, op_depth);
 
 CREATE INDEX IF NOT EXISTS I_PRISTINE_MD5 ON PRISTINE (md5_checksum);
 
-UPDATE nodes SET presence = "server-excluded" WHERE presence = "absent";
+UPDATE nodes SET presence = 'server-excluded' WHERE presence = 'absent';
 
 /* Just to be sure clear out file external skels from pre 1.7.0 development
    working copies that were never updated by 1.7.0+ style clients */

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/wc-queries.sql?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/wc-queries.sql Fri Jan 14 14:01:45 2022
@@ -260,7 +260,7 @@ WHERE wc_id = ?1 AND IS_STRICT_DESCENDAN
 
 -- STMT_DELETE_BASE_RECURSIVE
 DELETE FROM nodes
-WHERE wc_id = ?1 AND (local_relpath = ?2 
+WHERE wc_id = ?1 AND (local_relpath = ?2
                       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth = 0
 
@@ -1796,6 +1796,23 @@ WHERE wc_id = ?1
 SELECT 1 FROM sqlite_master WHERE name='sqlite_stat1' AND type='table'
 LIMIT 1
 
+-- STMT_SELECT_COPIES_OF_REPOS_RELPATH
+SELECT local_relpath
+FROM nodes n
+WHERE wc_id = ?1 AND repos_path = ?2 AND kind = ?3
+  AND presence = MAP_NORMAL
+  AND op_depth = (SELECT MAX(op_depth)
+                  FROM NODES w
+                  WHERE w.wc_id = ?1
+                    AND w.local_relpath = n.local_relpath)
+ORDER BY local_relpath ASC
+
+-- STMT_GET_LOCK
+SELECT lock_token, lock_owner, lock_comment, lock_date
+FROM lock
+WHERE repos_id = ?1 AND (repos_relpath = ?2)
+
+
 /* ------------------------------------------------------------------------- */
 
 /* Grab all the statements related to the schema.  */

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db.c Fri Jan 14 14:01:45 2022
@@ -514,7 +514,7 @@ create_repos_id(apr_int64_t *repos_id,
      above query and the insertion below. We're simply going to ignore
      that, as it means two processes are *modifying* the working copy
      at the same time, *and* new repositores are becoming visible.
-     This is rare enough, let alone the miniscule chance of hitting
+     This is rare enough, let alone the minuscule chance of hitting
      this race condition. Further, simply failing out will leave the
      database in a consistent state, and the user can just re-run the
      failed operation. */
@@ -1782,6 +1782,64 @@ svn_wc__db_base_add_incomplete_directory
 }
 
 
+/* Record RECORDED_SIZE and RECORDED_TIME into top layer in NODES */
+static svn_error_t *
+db_record_fileinfo(svn_wc__db_wcroot_t *wcroot,
+                   const char *local_relpath,
+                   apr_int64_t recorded_size,
+                   apr_int64_t recorded_time,
+                   apr_pool_t *scratch_pool)
+{
+  svn_sqlite__stmt_t *stmt;
+  int affected_rows;
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_UPDATE_NODE_FILEINFO));
+  SVN_ERR(svn_sqlite__bindf(stmt, "isii", wcroot->wc_id, local_relpath,
+                            recorded_size, recorded_time));
+  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+
+  SVN_ERR_ASSERT(affected_rows == 1);
+
+  return SVN_NO_ERROR;
+}
+
+
+/* Install the working file provided by FILE_WRITER, optionally
+   recording its fileinfo. */
+static svn_error_t *
+install_working_file(svn_wc__db_wcroot_t *wcroot,
+                     const char *local_relpath,
+                     svn_wc__working_file_writer_t *file_writer,
+                     svn_boolean_t record_fileinfo,
+                     apr_pool_t *scratch_pool)
+{
+  const char *local_abspath;
+
+  if (record_fileinfo)
+    {
+      apr_time_t mtime;
+      apr_off_t size;
+
+      SVN_ERR(svn_wc__working_file_writer_finalize(&mtime, &size, file_writer,
+                                                   scratch_pool));
+      SVN_ERR(db_record_fileinfo(wcroot, local_relpath, size, mtime,
+                                 scratch_pool));
+    }
+  else
+    {
+      SVN_ERR(svn_wc__working_file_writer_finalize(NULL, NULL, file_writer,
+                                                   scratch_pool));
+    }
+
+  local_abspath = svn_dirent_join(wcroot->abspath, local_relpath, scratch_pool);
+  SVN_ERR(svn_wc__working_file_writer_install(file_writer, local_abspath,
+                                              scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+
 svn_error_t *
 svn_wc__db_base_add_file(svn_wc__db_t *db,
                          const char *local_abspath,
@@ -1803,6 +1861,8 @@ svn_wc__db_base_add_file(svn_wc__db_t *d
                          svn_boolean_t keep_recorded_info,
                          svn_boolean_t insert_base_deleted,
                          const svn_skel_t *conflict,
+                         svn_wc__working_file_writer_t *file_writer,
+                         svn_boolean_t record_fileinfo,
                          const svn_skel_t *work_items,
                          apr_pool_t *scratch_pool)
 {
@@ -1858,9 +1918,22 @@ svn_wc__db_base_add_file(svn_wc__db_t *d
   ibb.conflict = conflict;
   ibb.work_items = work_items;
 
-  SVN_WC__DB_WITH_TXN(
-            insert_base_node(&ibb, wcroot, local_relpath, scratch_pool),
-            wcroot);
+  if (file_writer)
+    {
+      /* Atomically update the db and install the file (installation
+       * of the file is atomic, because it happens as a rename). */
+      SVN_WC__DB_WITH_TXN2(
+        insert_base_node(&ibb, wcroot, local_relpath, scratch_pool),
+        install_working_file(wcroot, local_relpath, file_writer,
+                             record_fileinfo, scratch_pool),
+        wcroot);
+    }
+  else
+    {
+      SVN_WC__DB_WITH_TXN(
+        insert_base_node(&ibb, wcroot, local_relpath, scratch_pool),
+        wcroot);
+    }
 
   /* If this used to be a directory we should remove children so pass
    * depth infinity. */
@@ -2404,7 +2477,7 @@ db_base_remove(svn_wc__db_wcroot_t *wcro
 
           /* For file externals we only want to place a not present marker
              if there is a BASE parent */
-          
+
           svn_relpath_split(&parent_local_relpath, &name, local_relpath,
                             scratch_pool);
 
@@ -6076,28 +6149,6 @@ svn_wc__db_op_add_symlink(svn_wc__db_t *
   return SVN_NO_ERROR;
 }
 
-/* Record RECORDED_SIZE and RECORDED_TIME into top layer in NODES */
-static svn_error_t *
-db_record_fileinfo(svn_wc__db_wcroot_t *wcroot,
-                   const char *local_relpath,
-                   apr_int64_t recorded_size,
-                   apr_int64_t recorded_time,
-                   apr_pool_t *scratch_pool)
-{
-  svn_sqlite__stmt_t *stmt;
-  int affected_rows;
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_UPDATE_NODE_FILEINFO));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isii", wcroot->wc_id, local_relpath,
-                            recorded_size, recorded_time));
-  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
-
-  SVN_ERR_ASSERT(affected_rows == 1);
-
-  return SVN_NO_ERROR;
-}
-
 
 svn_error_t *
 svn_wc__db_global_record_fileinfo(svn_wc__db_t *db,
@@ -6732,7 +6783,7 @@ svn_wc__db_op_mark_resolved_internal(svn
     return SVN_NO_ERROR;
 
   conflicts = svn_skel__parse(conflict_data, conflict_len, scratch_pool);
-  
+
 
   SVN_ERR(svn_wc__conflict_skel_resolve(&resolved_all, conflicts,
                                         db, wcroot->abspath,
@@ -8021,7 +8072,7 @@ struct op_delete_baton_t {
  * Note that the following sequence results in the same DB state:
  *   mv A B; mv B/F B/G
  * We do not care about the order the moves were performed in.
- * For details, see http://wiki.apache.org/subversion/MultiLayerMoves
+ * For details, see https://cwiki.apache.org/confluence/display/SVN/MultiLayerMoves
  */
 struct moved_node_t {
   /* The source of the move. */
@@ -8426,7 +8477,7 @@ delete_node(void *baton,
                                          scratch_pool, iterpool));
 
               if (!mn->local_relpath)
-                svn_sort__array_delete(moved_nodes, i--, 1);
+                SVN_ERR(svn_sort__array_delete2(moved_nodes, i--, 1));
             }
         }
 
@@ -10834,7 +10885,7 @@ db_read_inherited_props(apr_array_header
 
                   iprop_elt->prop_hash = node_props;
                   /* Build the output array in depth-first order. */
-                  svn_sort__array_insert(iprops, &iprop_elt, 0);
+                  SVN_ERR(svn_sort__array_insert2(iprops, &iprop_elt, 0));
                 }
             }
         }
@@ -10870,7 +10921,7 @@ db_read_inherited_props(apr_array_header
 
           /* If we didn't filter everything then keep this iprop. */
           if (apr_hash_count(cached_iprop->prop_hash))
-            svn_sort__array_insert(iprops, &cached_iprop, 0);
+            SVN_ERR(svn_sort__array_insert2(iprops, &cached_iprop, 0));
         }
     }
 
@@ -12539,6 +12590,43 @@ svn_wc__db_lock_remove(svn_wc__db_t *db,
   return SVN_NO_ERROR;
 }
 
+
+svn_error_t *
+svn_wc__db_lock_get(svn_wc__db_lock_t **lock_p,
+                    svn_wc__db_t *db,
+                    const char *wri_abspath,
+                    const char *repos_relpath,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *wri_relpath;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+  svn_wc__db_lock_t *lock;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &wri_relpath, db,
+                              wri_abspath, scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_GET_LOCK));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, repos_relpath));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+  if (have_row)
+    lock = lock_from_columns(stmt, 0, 1, 2, 3, result_pool);
+  else
+    lock = NULL;
+
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  *lock_p = lock;
+  return SVN_NO_ERROR;
+}
+
+
 /* A helper for scan_addition().
  * Compute moved-from information for the node at LOCAL_RELPATH which
  * has been determined as having been moved-here.
@@ -13564,7 +13652,7 @@ svn_wc__db_wq_fetch_next(apr_uint64_t *i
   return SVN_NO_ERROR;
 }
 
-/* Records timestamp and date for one or more files in wcroot */
+/* Records timestamp and size for one or more files in wcroot */
 static svn_error_t *
 wq_record(svn_wc__db_wcroot_t *wcroot,
           apr_hash_t *record_map,
@@ -13577,7 +13665,7 @@ wq_record(svn_wc__db_wcroot_t *wcroot,
        hi = apr_hash_next(hi))
     {
       const char *local_abspath = apr_hash_this_key(hi);
-      const svn_io_dirent2_t *dirent = apr_hash_this_val(hi);
+      const svn_wc__db_fileinfo_t *info = apr_hash_this_val(hi);
       const char *local_relpath = svn_dirent_skip_ancestor(wcroot->abspath,
                                                            local_abspath);
 
@@ -13587,7 +13675,7 @@ wq_record(svn_wc__db_wcroot_t *wcroot,
         continue;
 
       SVN_ERR(db_record_fileinfo(wcroot, local_relpath,
-                                 dirent->filesize, dirent->mtime,
+                                 info->size, info->mtime,
                                  iterpool));
     }
 
@@ -16648,7 +16736,7 @@ svn_wc__db_find_repos_node_in_wc(apr_arr
 
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
     }
-    
+
   return svn_error_trace(svn_sqlite__reset(stmt));
 }
 
@@ -16676,7 +16764,7 @@ svn_wc__db_find_working_nodes_with_basen
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
             STMT_SELECT_PRESENT_HIGHEST_WORKING_NODES_BY_BASENAME_AND_KIND));
   SVN_ERR(svn_sqlite__bindf(stmt, "ist", wcroot->wc_id, basename,
-                            kind_map, kind));
+                            kind_map_none, kind));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
 
   *local_abspaths = apr_array_make(result_pool, 1, sizeof(const char *));
@@ -16690,6 +16778,50 @@ svn_wc__db_find_working_nodes_with_basen
       local_abspath = svn_dirent_join(wcroot->abspath, local_relpath,
                                       result_pool);
       APR_ARRAY_PUSH(*local_abspaths, const char *) = local_abspath;
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+    }
+
+  return svn_error_trace(svn_sqlite__reset(stmt));
+}
+
+svn_error_t *
+svn_wc__db_find_copies_of_repos_path(apr_array_header_t **local_abspaths,
+                                     svn_wc__db_t *db,
+                                     const char *wri_abspath,
+                                     const char *repos_relpath,
+                                     svn_node_kind_t kind,
+                                     apr_pool_t *result_pool,
+                                     apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *wri_relpath;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &wri_relpath, db,
+                                                wri_abspath, scratch_pool,
+                                                scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+            STMT_SELECT_COPIES_OF_REPOS_RELPATH));
+  SVN_ERR(svn_sqlite__bindf(stmt, "ist", wcroot->wc_id, repos_relpath,
+                            kind_map_none, kind));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+  *local_abspaths = apr_array_make(result_pool, 1, sizeof(const char *));
+
+  while (have_row)
+    {
+      const char *local_relpath;
+      const char *local_abspath;
+
+      local_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+      local_abspath = svn_dirent_join(wcroot->abspath, local_relpath,
+                                      result_pool);
+      APR_ARRAY_PUSH(*local_abspaths, const char *) = local_abspath;
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
     }
 

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db.h?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db.h Fri Jan 14 14:01:45 2022
@@ -202,6 +202,15 @@ typedef struct svn_wc__db_lock_t {
   apr_time_t date;
 } svn_wc__db_lock_t;
 
+/* Structure holding the size and timestamp values for a file.  */
+typedef struct svn_wc__db_fileinfo_t {
+  /* The time the file was last modified. */
+  apr_time_t mtime;
+
+  /* The size of this file. */
+  svn_filesize_t size;
+} svn_wc__db_fileinfo_t;
+
 
 /* ### NOTE: I have not provided docstrings for most of this file at this
    ### point in time. The shape and extent of this API is still in massive
@@ -516,6 +525,10 @@ svn_wc__db_base_add_incomplete_directory
    Unless KEEP_RECORDED_INFO is set to TRUE, recorded size and timestamp values
    will be cleared.
 
+   If FILE_WRITER is not NULL, atomically complete installation of the file to
+   LOCAL_ABSPATH together with updating the DB.  If RECORD_FILEINFO is non-zero,
+   also record the size and timestamp values of the installed file.
+
    All temporary allocations will be made in SCRATCH_POOL.
 */
 svn_error_t *
@@ -539,6 +552,8 @@ svn_wc__db_base_add_file(svn_wc__db_t *d
                          svn_boolean_t keep_recorded_info,
                          svn_boolean_t insert_base_deleted,
                          const svn_skel_t *conflict,
+                         svn_wc__working_file_writer_t *file_writer,
+                         svn_boolean_t record_fileinfo,
                          const svn_skel_t *work_items,
                          apr_pool_t *scratch_pool);
 
@@ -965,7 +980,7 @@ typedef struct svn_wc__db_install_data_t
 /* Open a writable stream to a temporary text base, ready for installing
    into the pristine store.  Set *STREAM to the opened stream.  The temporary
    file will have an arbitrary unique name. Return as *INSTALL_DATA a baton
-   for eiter installing or removing the file
+   for either installing or removing the file
 
    Arrange that, on stream closure, *MD5_CHECKSUM and *SHA1_CHECKSUM will be
    set to the MD-5 and SHA-1 checksums respectively of that file.
@@ -2709,6 +2724,18 @@ svn_wc__db_lock_remove(svn_wc__db_t *db,
                        apr_pool_t *scratch_pool);
 
 
+/* Fetch the information about the lock which corresponds to REPOS_RELPATH
+   within the working copy indicated by WRI_ABSPATH. Set *LOCK_P to NULL
+   if there is no such lock.  */
+svn_error_t *
+svn_wc__db_lock_get(svn_wc__db_lock_t **lock_p,
+                    svn_wc__db_t *db,
+                    const char *wri_abspath,
+                    const char *repos_relpath,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool);
+
+
 /* @} */
 
 
@@ -3535,6 +3562,24 @@ svn_wc__db_find_working_nodes_with_basen
                                             svn_node_kind_t kind,
                                             apr_pool_t *result_pool,
                                             apr_pool_t *scratch_pool);
+
+/* Return an array of const char * elements, which represent local absolute
+ * paths for nodes, within the working copy indicated by WRI_ABSPATH, which
+ * are copies of REPOS_RELPATH and have node kind KIND.
+ * If no such nodes exist, return an empty array.
+ *
+ * This function returns only paths to nodes which are present in the highest
+ * layer of the WC. In other words, paths to deleted and/or excluded nodes are
+ * never returned.
+ */
+svn_error_t *
+svn_wc__db_find_copies_of_repos_path(apr_array_header_t **local_abspaths,
+                                     svn_wc__db_t *db,
+                                     const char *wri_abspath,
+                                     const char *repos_relpath,
+                                     svn_node_kind_t kind,
+                                     apr_pool_t *result_pool,
+                                     apr_pool_t *scratch_pool);
 /* @} */
 
 typedef svn_error_t * (*svn_wc__db_verify_cb_t)(void *baton,

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db_pristine.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db_pristine.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db_pristine.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db_pristine.c Fri Jan 14 14:01:45 2022
@@ -305,21 +305,22 @@ pristine_install_txn(svn_sqlite__db_t *s
       /* Consistency checks.  Verify both files exist and match.
        * ### We could check much more. */
       {
-        apr_finfo_t finfo1, finfo2;
+        apr_finfo_t finfo;
+        apr_off_t size;
 
-        SVN_ERR(svn_stream__install_get_info(&finfo1, install_stream, APR_FINFO_SIZE,
+        SVN_ERR(svn_stream__install_finalize(NULL, &size, install_stream,
                                              scratch_pool));
 
-        SVN_ERR(svn_io_stat(&finfo2, pristine_abspath, APR_FINFO_SIZE,
+        SVN_ERR(svn_io_stat(&finfo, pristine_abspath, APR_FINFO_SIZE,
                             scratch_pool));
-        if (finfo1.size != finfo2.size)
+        if (size != finfo.size)
           {
             return svn_error_createf(
               SVN_ERR_WC_CORRUPT_TEXT_BASE, NULL,
               _("New pristine text '%s' has different size: %s versus %s"),
               svn_checksum_to_cstring_display(sha1_checksum, scratch_pool),
-              apr_off_t_toa(scratch_pool, finfo1.size),
-              apr_off_t_toa(scratch_pool, finfo2.size));
+              apr_off_t_toa(scratch_pool, size),
+              apr_off_t_toa(scratch_pool, finfo.size));
           }
       }
 #endif
@@ -332,19 +333,20 @@ pristine_install_txn(svn_sqlite__db_t *s
   /* Move the file to its target location.  (If it is already there, it is
    * an orphan file and it doesn't matter if we overwrite it.) */
   {
-    apr_finfo_t finfo;
-    SVN_ERR(svn_stream__install_get_info(&finfo, install_stream,
-                                         APR_FINFO_SIZE, scratch_pool));
+    apr_off_t size;
+
+    svn_stream__install_set_read_only(install_stream, TRUE);
+
+    SVN_ERR(svn_stream__install_finalize(NULL, &size, install_stream,
+                                         scratch_pool));
     SVN_ERR(svn_stream__install_stream(install_stream, pristine_abspath,
                                        TRUE, scratch_pool));
 
     SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_PRISTINE));
     SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
     SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool));
-    SVN_ERR(svn_sqlite__bind_int64(stmt, 3, finfo.size));
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 3, size));
     SVN_ERR(svn_sqlite__insert(NULL, stmt));
-
-    SVN_ERR(svn_io_set_file_read_only(pristine_abspath, FALSE, scratch_pool));
   }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db_private.h?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db_private.h Fri Jan 14 14:01:45 2022
@@ -383,6 +383,27 @@ svn_wc__db_mark_conflict_internal(svn_wc
 #define SVN_WC__DB_WITH_TXN(expr, wcroot) \
   SVN_SQLITE__WITH_LOCK(expr, (wcroot)->sdb)
 
+/* Evaluate the expressions EXPR1..EXPR2 within a transaction, returning the
+ * first error if an error occurs.
+ *
+ * Begin a transaction in WCROOT's DB; evaluate the expressions, which would
+ * typically be function calls that do some work in DB; finally commit
+ * the transaction if EXPR evaluated to SVN_NO_ERROR, otherwise roll back
+ * the transaction.
+ */
+#define SVN_WC__DB_WITH_TXN2(expr1, expr2, wcroot) \
+  SVN_SQLITE__WITH_LOCK2(expr1, expr2, (wcroot)->sdb)
+
+/* Evaluate the expressions EXPR1..EXPR3 within a transaction, returning the
+ * first error if an error occurs.
+ *
+ * Begin a transaction in WCROOT's DB; evaluate the expressions, which would
+ * typically be function calls that do some work in DB; finally commit
+ * the transaction if EXPR evaluated to SVN_NO_ERROR, otherwise roll back
+ * the transaction.
+ */
+#define SVN_WC__DB_WITH_TXN3(expr1, expr2, expr3, wcroot) \
+  SVN_SQLITE__WITH_LOCK3(expr1, expr2, expr3, (wcroot)->sdb)
 
 /* Evaluate the expressions EXPR1..EXPR4 within a transaction, returning the
  * first error if an error occurs.
@@ -435,7 +456,7 @@ svn_wc__db_op_make_copy_internal(svn_wc_
      MOVE_DST_RELPATH is X
      DELETE_RELPATH is A
 
-     X/C can be calculated if necessesary, like with the other
+     X/C can be calculated if necessary, like with the other
      scan functions.
 
    This function returns SVN_ERR_WC_PATH_NOT_FOUND if LOCAL_RELPATH didn't

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db_update_move.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/wc_db_update_move.c Fri Jan 14 14:01:45 2022
@@ -95,7 +95,7 @@
  * to avoid tree conflicts where the "incoming" and "local" change both
  * originated in the working copy, because the resolver code cannot handle
  * such tree conflicts at present.
- * 
+ *
  * The whole drive occurs as one single wc.db transaction.  At the end
  * of the transaction the destination NODES table should have a WORKING
  * layer that is equivalent to the WORKING layer found in the copied victim
@@ -1056,7 +1056,7 @@ tc_editor_incoming_add_file(node_move_ba
       SVN_ERR(svn_wc__wq_build_file_remove(&work_item, b->db,
                                            b->wcroot->abspath, src_abspath,
                                            scratch_pool, scratch_pool));
-    
+
       work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
     }
 
@@ -2175,11 +2175,12 @@ suitable_for_move(svn_wc__db_wcroot_t *w
   while (have_row)
     {
       svn_revnum_t node_revision = svn_sqlite__column_revnum(stmt, 2);
-      const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+      const char *child_relpath;
       const char *relpath;
 
       svn_pool_clear(iterpool);
 
+      child_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
       relpath = svn_relpath_skip_ancestor(local_relpath, child_relpath);
       relpath = svn_relpath_join(repos_relpath, relpath, iterpool);
 
@@ -2526,7 +2527,7 @@ update_incoming_moved_node(node_move_bat
           SVN_ERR(svn_stream_open_unique(&temp_stream, &temp_abspath,
                                          wctemp_abspath, svn_io_file_del_none,
                                          scratch_pool, scratch_pool));
-          err = svn_stream_copy3(working_stream, temp_stream, 
+          err = svn_stream_copy3(working_stream, temp_stream,
                                  b->cancel_func, b->cancel_baton,
                                  scratch_pool);
           if (err && err->apr_err == SVN_ERR_CANCELLED)
@@ -2691,7 +2692,7 @@ update_incoming_move(svn_revnum_t *old_r
    * recorded for any tree conflicts created during the editor drive.
    * We assume this path contains no local changes, and create local changes
    * in DST_RELPATH corresponding to changes contained in the conflict victim.
-   * 
+   *
    * DST_OP_DEPTH is used to infer the "op-root" of the incoming move. This
    * "op-root" is virtual because all nodes belonging to the incoming move
    * live in the BASE tree. It is used for constructing repository paths
@@ -2987,7 +2988,7 @@ tc_editor_update_add_new_file(added_node
       nb->skip = TRUE;
       return SVN_NO_ERROR;
     }
-  
+
   /* Check for obstructions. */
   local_abspath = svn_dirent_join(nb->b->wcroot->abspath, nb->local_relpath,
                                   scratch_pool);
@@ -3588,7 +3589,7 @@ svn_wc__db_update_local_add(svn_wc__db_t
   VERIFY_USABLE_WCROOT(wcroot);
 
   SVN_WC__DB_WITH_TXN(update_local_add(&new_rev, db, wcroot,
-                                       local_relpath, 
+                                       local_relpath,
                                        cancel_func, cancel_baton,
                                        scratch_pool),
                       wcroot);
@@ -4257,7 +4258,7 @@ svn_wc__db_op_raise_moved_away(svn_wc__d
                                             scratch_pool),
     wcroot);
 
-  /* These version numbers are valid for update/switch notifications 
+  /* These version numbers are valid for update/switch notifications
      only! */
   SVN_ERR(svn_wc__db_update_move_list_notify(wcroot,
                                              (left_version

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/wcroot_anchor.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/wcroot_anchor.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/wcroot_anchor.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/wcroot_anchor.c Fri Jan 14 14:01:45 2022
@@ -183,21 +183,20 @@ svn_wc__get_wcroot(const char **wcroot_a
 
 
 svn_error_t *
-svn_wc__get_shelves_dir(char **dir,
-                        svn_wc_context_t *wc_ctx,
-                        const char *local_abspath,
-                        apr_pool_t *result_pool,
-                        apr_pool_t *scratch_pool)
+svn_wc__get_experimental_dir(char **dir,
+                             svn_wc_context_t *wc_ctx,
+                             const char *local_abspath,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool)
 {
   const char *wcroot_abspath;
 
   SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, wc_ctx, local_abspath,
                              scratch_pool, scratch_pool));
   *dir = svn_dirent_join(wcroot_abspath,
-                         SVN_WC_ADM_DIR_NAME "/" SVN_WC__ADM_EXPERIMENTAL "/"
-                           "shelves/v2",
+                         SVN_WC_ADM_DIR_NAME "/" SVN_WC__ADM_EXPERIMENTAL,
                          result_pool);
-  
+
   /* Ensure the directory exists. (Other versions of svn don't create it.) */
   SVN_ERR(svn_io_make_dir_recursively(*dir, scratch_pool));
 

Modified: subversion/branches/multi-wc-format/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_wc/workqueue.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/multi-wc-format/subversion/libsvn_wc/workqueue.c Fri Jan 14 14:01:45 2022
@@ -30,6 +30,7 @@
 #include "svn_subst.h"
 #include "svn_hash.h"
 #include "svn_io.h"
+#include "svn_path.h"
 
 #include "wc.h"
 #include "wc_db.h"
@@ -39,6 +40,7 @@
 #include "translate.h"
 
 #include "private/svn_io_private.h"
+#include "private/svn_wc_private.h"
 #include "private/svn_skel.h"
 
 
@@ -64,7 +66,14 @@
 /* For work queue debugging. Generates output about its operation.  */
 /* #define SVN_DEBUG_WORK_QUEUE */
 
-typedef struct work_item_baton_t work_item_baton_t;
+typedef struct work_item_baton_t
+{
+  apr_pool_t *result_pool; /* Pool to allocate result in */
+
+  svn_boolean_t used; /* needs reset */
+
+  apr_hash_t *record_map; /* const char * -> svn_wc__db_fileinfo_t map */
+} work_item_baton_t;
 
 struct work_item_dispatch {
   const char *name;
@@ -77,12 +86,26 @@ struct work_item_dispatch {
                        apr_pool_t *scratch_pool);
 };
 
-/* Forward definition */
-static svn_error_t *
-get_and_record_fileinfo(work_item_baton_t *wqb,
-                        const char *local_abspath,
-                        svn_boolean_t ignore_enoent,
-                        apr_pool_t *scratch_pool);
+static void
+wq_record_fileinfo(work_item_baton_t *wqb,
+                   const char *local_abspath,
+                   apr_time_t mtime,
+                   svn_filesize_t size)
+{
+  svn_wc__db_fileinfo_t *info;
+
+  wqb->used = TRUE;
+
+  if (! wqb->record_map)
+    wqb->record_map = apr_hash_make(wqb->result_pool);
+
+  info = apr_pcalloc(wqb->result_pool, sizeof(*info));
+  info->mtime = mtime;
+  info->size = size;
+
+  svn_hash_sets(wqb->record_map, apr_pstrdup(wqb->result_pool, local_abspath),
+                info);
+}
 
 /* ------------------------------------------------------------------------ */
 /* OP_REMOVE_BASE  */
@@ -463,19 +486,33 @@ run_file_install(work_item_baton_t *wqb,
   const char *local_abspath;
   svn_boolean_t use_commit_times;
   svn_boolean_t record_fileinfo;
-  svn_boolean_t special;
   svn_stream_t *src_stream;
-  svn_subst_eol_style_t style;
-  const char *eol;
-  apr_hash_t *keywords;
   const char *temp_dir_abspath;
-  svn_stream_t *dst_stream;
   apr_int64_t val;
   const char *wcroot_abspath;
   const char *source_abspath;
   const svn_checksum_t *checksum;
   apr_hash_t *props;
+  svn_boolean_t is_special;
+  svn_boolean_t is_executable;
+  svn_boolean_t needs_lock;
+  const char *eol_propval;
+  svn_subst_eol_style_t eol_style;
+  const char *eol;
+  const char *keywords_propval;
+  apr_hash_t *keywords;
   apr_time_t changed_date;
+  svn_revnum_t changed_rev;
+  const char *changed_author;
+  apr_time_t final_mtime;
+  svn_wc__db_status_t status;
+  svn_wc__db_lock_t *lock;
+  const char *repos_relpath;
+  const char *repos_root_url;
+  svn_wc__working_file_writer_t *file_writer;
+  apr_time_t record_mtime;
+  apr_off_t record_size;
+  svn_boolean_t is_readonly;
 
   local_relpath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
   SVN_ERR(svn_wc__db_from_relpath(&local_abspath, db, wri_abspath,
@@ -524,108 +561,99 @@ run_file_install(work_item_baton_t *wqb,
                                                   scratch_pool, scratch_pool));
     }
 
-  SVN_ERR(svn_stream_open_readonly(&src_stream, source_abspath,
-                                   scratch_pool, scratch_pool));
-
-  /* Fetch all the translation bits.  */
-  SVN_ERR(svn_wc__get_translate_info(&style, &eol,
-                                     &keywords,
-                                     &special, db, local_abspath,
-                                     props, FALSE,
-                                     scratch_pool, scratch_pool));
-  if (special)
-    {
-      /* When this stream is closed, the resulting special file will
-         atomically be created/moved into place at LOCAL_ABSPATH.  */
-      SVN_ERR(svn_subst_create_specialfile(&dst_stream, local_abspath,
-                                           scratch_pool, scratch_pool));
-
-      /* Copy the "repository normal" form of the special file into the
-         special stream.  */
-      SVN_ERR(svn_stream_copy3(src_stream, dst_stream,
-                               cancel_func, cancel_baton,
-                               scratch_pool));
-
-      /* No need to set exec or read-only flags on special files.  */
-
-      /* ### Shouldn't this record a timestamp and size, etc.? */
-      return SVN_NO_ERROR;
-    }
-
-  if (svn_subst_translation_required(style, eol, keywords,
-                                     FALSE /* special */,
-                                     TRUE /* force_eol_check */))
-    {
-      /* Wrap it in a translating (expanding) stream.  */
-      src_stream = svn_subst_stream_translated(src_stream, eol,
-                                               TRUE /* repair */,
-                                               keywords,
-                                               TRUE /* expand */,
-                                               scratch_pool);
-    }
-
   /* Where is the Right Place to put a temp file in this working copy?  */
   SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath,
                                          db, wcroot_abspath,
                                          scratch_pool, scratch_pool));
 
-  /* Translate to a temporary file. We don't want the user seeing a partial
-     file, nor let them muck with it while we translate. We may also need to
-     get its TRANSLATED_SIZE before the user can monkey it.  */
-  SVN_ERR(svn_stream__create_for_install(&dst_stream, temp_dir_abspath,
-                                         scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, &repos_relpath,
+                               &repos_root_url, NULL, &changed_rev, NULL,
+                               &changed_author, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, &lock, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               db, local_abspath,
+                               scratch_pool, scratch_pool));
+  /* Handle special statuses (e.g. added) */
+  if (!repos_relpath)
+     SVN_ERR(svn_wc__db_read_repos_info(NULL, &repos_relpath,
+                                        &repos_root_url, NULL,
+                                        db, local_abspath,
+                                        scratch_pool, scratch_pool));
+
+  is_special = svn_prop_get_value(props, SVN_PROP_SPECIAL) != NULL;
+  is_executable = svn_prop_get_value(props, SVN_PROP_EXECUTABLE) != NULL;
+  needs_lock = svn_prop_get_value(props, SVN_PROP_NEEDS_LOCK) != NULL;
+
+  eol_propval = svn_prop_get_value(props, SVN_PROP_EOL_STYLE);
+  svn_subst_eol_style_from_value(&eol_style, &eol, eol_propval);
+
+  keywords_propval = svn_prop_get_value(props, SVN_PROP_KEYWORDS);
+  if (keywords_propval)
+    {
+      const char *url =
+        svn_path_url_add_component2(repos_root_url, repos_relpath, scratch_pool);
+
+      SVN_ERR(svn_subst_build_keywords3(&keywords, keywords_propval,
+                                        apr_psprintf(scratch_pool, "%ld",
+                                                     changed_rev),
+                                        url, repos_root_url, changed_date,
+                                        changed_author, scratch_pool));
+    }
+  else
+    {
+      keywords = NULL;
+    }
 
-  /* Copy from the source to the dest, translating as we go. This will also
-     close both streams.  */
-  SVN_ERR(svn_stream_copy3(src_stream, dst_stream,
-                           cancel_func, cancel_baton,
-                           scratch_pool));
+  if (use_commit_times && changed_date)
+    final_mtime = changed_date;
+  else
+    final_mtime = -1;
 
-  /* All done. Move the file into place.  */
-  /* With a single db we might want to install files in a missing directory.
-     Simply trying this scenario on error won't do any harm and at least
-     one user reported this problem on IRC. */
-  SVN_ERR(svn_stream__install_stream(dst_stream, local_abspath,
-                                     TRUE /* make_parents*/, scratch_pool));
-
-  /* Tweak the on-disk file according to its properties.  */
-#ifndef WIN32
-  if (props && svn_hash_gets(props, SVN_PROP_EXECUTABLE))
-    SVN_ERR(svn_io_set_file_executable(local_abspath, TRUE, FALSE,
-                                       scratch_pool));
-#endif
+  if (needs_lock && !lock && status != svn_wc__db_status_added)
+    is_readonly = TRUE;
+  else
+    is_readonly = FALSE;
 
-  /* Note that this explicitly checks the pristine properties, to make sure
-     that when the lock is locally set (=modification) it is not read only */
-  if (props && svn_hash_gets(props, SVN_PROP_NEEDS_LOCK))
-    {
-      svn_wc__db_status_t status;
-      svn_wc__db_lock_t *lock;
-      SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, &lock, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL,
-                                   db, local_abspath,
+  SVN_ERR(svn_wc__working_file_writer_open(&file_writer,
+                                           temp_dir_abspath,
+                                           final_mtime,
+                                           eol_style,
+                                           eol,
+                                           TRUE /* repair_eol */,
+                                           keywords,
+                                           is_special,
+                                           is_executable,
+                                           is_readonly,
+                                           scratch_pool,
+                                           scratch_pool));
+
+  SVN_ERR(svn_stream_open_readonly(&src_stream, source_abspath,
                                    scratch_pool, scratch_pool));
 
-      if (!lock && status != svn_wc__db_status_added)
-        SVN_ERR(svn_io_set_file_read_only(local_abspath, FALSE, scratch_pool));
-    }
+  SVN_ERR(svn_stream_copy3(src_stream,
+                           svn_wc__working_file_writer_get_stream(file_writer),
+                           cancel_func, cancel_baton,
+                           scratch_pool));
 
-  if (use_commit_times)
+  if (record_fileinfo)
     {
-      if (changed_date)
-        SVN_ERR(svn_io_set_file_affected_time(changed_date,
-                                              local_abspath,
-                                              scratch_pool));
+      SVN_ERR(svn_wc__working_file_writer_finalize(&record_mtime, &record_size,
+                                                   file_writer, scratch_pool));
+    }
+  else
+    {
+      SVN_ERR(svn_wc__working_file_writer_finalize(NULL, NULL, file_writer,
+                                                   scratch_pool));
+      record_mtime = -1;
+      record_size = -1;
     }
 
-  /* ### this should happen before we rename the file into place.  */
+  SVN_ERR(svn_wc__working_file_writer_install(file_writer, local_abspath,
+                                              scratch_pool));
+
   if (record_fileinfo)
     {
-      SVN_ERR(get_and_record_fileinfo(wqb, local_abspath,
-                                      FALSE /* ignore_enoent */,
-                                      scratch_pool));
+      wq_record_fileinfo(wqb, local_abspath, record_mtime, record_size);
     }
 
   return SVN_NO_ERROR;
@@ -1180,6 +1208,7 @@ run_record_fileinfo(work_item_baton_t *w
   const char *local_relpath;
   const char *local_abspath;
   apr_time_t set_time = 0;
+  const svn_io_dirent2_t *dirent;
 
   local_relpath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
 
@@ -1213,10 +1242,17 @@ run_record_fileinfo(work_item_baton_t *w
          filesystem might have a different timestamp granularity */
     }
 
+  SVN_ERR(svn_io_stat_dirent2(&dirent, local_abspath,
+                              FALSE /* verify_truename */,
+                              TRUE /* ignore_enoent */,
+                              scratch_pool, scratch_pool));
+
+  if (dirent->kind == svn_node_file)
+    {
+      wq_record_fileinfo(wqb, local_abspath, dirent->mtime, dirent->filesize);
+    }
 
-  return svn_error_trace(get_and_record_fileinfo(wqb, local_abspath,
-                                                 TRUE /* ignore_enoent */,
-                                                 scratch_pool));
+  return SVN_NO_ERROR;
 }
 
 /* ------------------------------------------------------------------------ */
@@ -1408,16 +1444,6 @@ static const struct work_item_dispatch d
   { NULL }
 };
 
-struct work_item_baton_t
-{
-  apr_pool_t *result_pool; /* Pool to allocate result in */
-
-  svn_boolean_t used; /* needs reset */
-
-  apr_hash_t *record_map; /* const char * -> svn_io_dirent2_t map */
-};
-
-
 static svn_error_t *
 dispatch_work_item(work_item_baton_t *wqb,
                    svn_wc__db_t *db,
@@ -1613,29 +1639,3 @@ svn_wc__wq_merge(svn_skel_t *work_item1,
   svn_skel__append(work_item1, work_item2->children);
   return work_item1;
 }
-
-
-static svn_error_t *
-get_and_record_fileinfo(work_item_baton_t *wqb,
-                        const char *local_abspath,
-                        svn_boolean_t ignore_enoent,
-                        apr_pool_t *scratch_pool)
-{
-  const svn_io_dirent2_t *dirent;
-
-  SVN_ERR(svn_io_stat_dirent2(&dirent, local_abspath, FALSE, ignore_enoent,
-                              wqb->result_pool, scratch_pool));
-
-  if (dirent->kind != svn_node_file)
-    return SVN_NO_ERROR;
-
-  wqb->used = TRUE;
-
-  if (! wqb->record_map)
-    wqb->record_map = apr_hash_make(wqb->result_pool);
-
-  svn_hash_sets(wqb->record_map, apr_pstrdup(wqb->result_pool, local_abspath),
-                dirent);
-
-  return SVN_NO_ERROR;
-}