You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2010/03/07 15:12:22 UTC

svn commit: r919999 [2/5] - in /subversion/branches/svn-patch-improvements: ./ build/generator/templates/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/javahl/src/org/apache/subversi...

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_client/switch.c?rev=919999&r1=919998&r2=919999&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_client/switch.c Sun Mar  7 14:12:20 2010
@@ -56,20 +56,21 @@
 
 
 svn_error_t *
-svn_client__switch_internal(svn_revnum_t *result_rev,
-                            const char *path,
-                            const char *switch_url,
-                            const svn_opt_revision_t *peg_revision,
-                            const svn_opt_revision_t *revision,
-                            svn_wc_adm_access_t *adm_access,
-                            svn_depth_t depth,
-                            svn_boolean_t depth_is_sticky,
-                            svn_boolean_t *timestamp_sleep,
-                            svn_boolean_t ignore_externals,
-                            svn_boolean_t allow_unver_obstructions,
-                            svn_boolean_t innerswitch,
-                            svn_client_ctx_t *ctx,
-                            apr_pool_t *pool)
+switch_internal(svn_revnum_t *result_rev,
+                const char *path,
+                const char *local_abspath,
+                const char *anchor_abspath,
+                const char *switch_url,
+                const svn_opt_revision_t *peg_revision,
+                const svn_opt_revision_t *revision,
+                svn_depth_t depth,
+                svn_boolean_t depth_is_sticky,
+                svn_boolean_t *timestamp_sleep,
+                svn_boolean_t ignore_externals,
+                svn_boolean_t allow_unver_obstructions,
+                svn_boolean_t innerswitch,
+                svn_client_ctx_t *ctx,
+                apr_pool_t *pool)
 {
   const svn_ra_reporter3_t *reporter;
   void *report_baton;
@@ -77,8 +78,6 @@
   svn_ra_session_t *ra_session;
   svn_revnum_t revnum;
   svn_error_t *err = SVN_NO_ERROR;
-  svn_wc_adm_access_t *dir_access;
-  const svn_boolean_t close_adm_access = ! adm_access;
   const char *diff3_cmd;
   svn_boolean_t use_commit_times;
   svn_boolean_t sleep_here = FALSE;
@@ -86,18 +85,14 @@
   const svn_delta_editor_t *switch_editor;
   void *switch_edit_baton;
   const char *preserved_exts_str;
-  const char *anchor_abspath;
   apr_array_header_t *preserved_exts;
   svn_boolean_t server_supports_depth;
-  const char *local_abspath;
   svn_client__external_func_baton_t efb;
   svn_config_t *cfg = ctx->config ? apr_hash_get(ctx->config,
                                                  SVN_CONFIG_CATEGORY_CONFIG,
                                                  APR_HASH_KEY_STRING)
                                   : NULL;
 
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-
   /* An unknown depth can't be sticky. */
   if (depth == svn_depth_unknown)
     depth_is_sticky = FALSE;
@@ -125,49 +120,16 @@
     : NULL;
 
   /* Sanity check.  Without these, the switch is meaningless. */
-  SVN_ERR_ASSERT(path);
   SVN_ERR_ASSERT(switch_url && (switch_url[0] != '\0'));
 
-  /* ### Need to lock the whole target tree to invalidate wcprops. Does
-     non-recursive switch really need to invalidate the whole tree? */
-  if (innerswitch)
-    {
-      SVN_ERR(svn_wc__adm_open_in_context(&adm_access, ctx->wc_ctx,
-                                          path, TRUE, -1, ctx->cancel_func,
-                                          ctx->cancel_baton, pool));
-      dir_access = adm_access;
-      target = "";
-      anchor = svn_wc_adm_access_path(adm_access);
-    }
-  else if (adm_access)
-    {
-      svn_wc_adm_access_t *a = adm_access;
-      const char *dir_access_path;
-
-      /* This is a little hacky, but open two new read-only access
-         baton's to get the anchor and target access batons that would
-         be used if a locked access baton was not available. */
-      SVN_ERR(svn_wc_adm_open_anchor(&adm_access, &dir_access, &target, path,
-                                     FALSE, -1, ctx->cancel_func,
-                                     ctx->cancel_baton, pool));
-      anchor = svn_wc_adm_access_path(adm_access);
-      dir_access_path = svn_wc_adm_access_path(dir_access);
-      SVN_ERR(svn_wc_adm_close2(adm_access, pool));
-
-      SVN_ERR(svn_wc_adm_retrieve(&adm_access, a, anchor, pool));
-      SVN_ERR(svn_wc_adm_retrieve(&dir_access, a, dir_access_path, pool));
-    }
+  if (strcmp(local_abspath, anchor_abspath))
+    svn_dirent_split(path, &anchor, &target, pool);
   else
     {
-      SVN_ERR(svn_wc__adm_open_anchor_in_context(&adm_access, &dir_access,
-                                                 &target, ctx->wc_ctx, path,
-                                                 TRUE, -1, ctx->cancel_func,
-                                                 ctx->cancel_baton, pool));
-
-      anchor = svn_wc_adm_access_path(adm_access);
+      target = "";
+      anchor = path;
     }
 
-  SVN_ERR(svn_dirent_get_absolute(&anchor_abspath, anchor, pool));
   SVN_ERR(svn_wc__node_get_url(&url, ctx->wc_ctx, anchor_abspath, pool, pool));
   if (! url)
     return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
@@ -188,10 +150,6 @@
                                  pool));
 
           /* Target excluded, we are done now */
-
-          if (close_adm_access)
-            SVN_ERR(svn_wc_adm_close2(adm_access, pool));
-
           return SVN_NO_ERROR;
         }
 
@@ -280,7 +238,7 @@
      handling external items (and any errors therefrom) doesn't delay
      the primary operation. */
   if (SVN_DEPTH_IS_RECURSIVE(depth) && (! ignore_externals))
-    err = svn_client__handle_externals(adm_access, efb.externals_old,
+    err = svn_client__handle_externals(efb.externals_old,
                                        efb.externals_new, efb.ambient_depths,
                                        switch_url, path, source_root, depth,
                                        use_sleep, ctx, pool);
@@ -294,9 +252,6 @@
   if (err)
     return svn_error_return(err);
 
-  if (close_adm_access)
-    SVN_ERR(svn_wc_adm_close2(adm_access, pool));
-
   /* Let everyone know we're finished here. */
   if (ctx->notify_func2)
     {
@@ -318,6 +273,57 @@
 }
 
 svn_error_t *
+svn_client__switch_internal(svn_revnum_t *result_rev,
+                            const char *path,
+                            const char *switch_url,
+                            const svn_opt_revision_t *peg_revision,
+                            const svn_opt_revision_t *revision,
+                            svn_depth_t depth,
+                            svn_boolean_t depth_is_sticky,
+                            svn_boolean_t *timestamp_sleep,
+                            svn_boolean_t ignore_externals,
+                            svn_boolean_t allow_unver_obstructions,
+                            svn_boolean_t innerswitch,
+                            svn_client_ctx_t *ctx,
+                            apr_pool_t *pool)
+{
+  const char *local_abspath, *anchor_abspath;
+  svn_boolean_t acquired_lock;
+  svn_error_t *err, *err1, *err2;
+
+  SVN_ERR_ASSERT(path);
+
+  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
+
+  /* Rely on svn_wc__acquire_write_lock setting ANCHOR_ABSPATH even
+     when it returns SVN_ERR_WC_LOCKED */
+  err = svn_wc__acquire_write_lock(&anchor_abspath, ctx->wc_ctx,
+                                   local_abspath, pool, pool);
+  if (err && err->apr_err != SVN_ERR_WC_LOCKED)
+    return svn_error_return(err);
+  else if (err)
+    {
+      svn_error_clear(err);
+      acquired_lock = FALSE;
+    }
+  else
+    acquired_lock = TRUE;
+
+  err1 = switch_internal(result_rev, path, local_abspath, anchor_abspath,
+                         switch_url, peg_revision, revision,
+                         depth, depth_is_sticky,
+                         timestamp_sleep, ignore_externals,
+                         allow_unver_obstructions, innerswitch, ctx, pool);
+
+  if (acquired_lock)
+    err2 = svn_wc__release_write_lock(ctx->wc_ctx, anchor_abspath, pool);
+  else
+    err2 = SVN_NO_ERROR;
+
+  return svn_error_compose_create(err1, err2);
+}
+
+svn_error_t *
 svn_client_switch2(svn_revnum_t *result_rev,
                    const char *path,
                    const char *switch_url,
@@ -331,7 +337,7 @@
                    apr_pool_t *pool)
 {
   return svn_client__switch_internal(result_rev, path, switch_url,
-                                     peg_revision, revision, NULL, depth,
+                                     peg_revision, revision, depth,
                                      depth_is_sticky, NULL, ignore_externals,
                                      allow_unver_obstructions, FALSE, ctx,
                                      pool);

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_client/update.c?rev=919999&r1=919998&r2=919999&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_client/update.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_client/update.c Sun Mar  7 14:12:20 2010
@@ -79,19 +79,21 @@
 }
 
 
-svn_error_t *
-svn_client__update_internal(svn_revnum_t *result_rev,
-                            const char *path,
-                            const svn_opt_revision_t *revision,
-                            svn_depth_t depth,
-                            svn_boolean_t depth_is_sticky,
-                            svn_boolean_t ignore_externals,
-                            svn_boolean_t allow_unver_obstructions,
-                            svn_boolean_t *timestamp_sleep,
-                            svn_boolean_t send_copyfrom_args,
-                            svn_boolean_t innerupdate,
-                            svn_client_ctx_t *ctx,
-                            apr_pool_t *pool)
+static svn_error_t *
+update_internal(svn_revnum_t *result_rev,
+                const char *path,
+                const char *local_abspath,
+                const char *anchor_abspath,
+                const svn_opt_revision_t *revision,
+                svn_depth_t depth,
+                svn_boolean_t depth_is_sticky,
+                svn_boolean_t ignore_externals,
+                svn_boolean_t allow_unver_obstructions,
+                svn_boolean_t *timestamp_sleep,
+                svn_boolean_t send_copyfrom_args,
+                svn_boolean_t innerupdate,
+                svn_client_ctx_t *ctx,
+                apr_pool_t *pool)
 {
   const svn_delta_editor_t *update_editor;
   void *update_edit_baton;
@@ -102,18 +104,14 @@
   const char *repos_root;
   svn_error_t *err;
   svn_revnum_t revnum;
-  svn_wc_adm_access_t *adm_access;
   svn_boolean_t use_commit_times;
   svn_boolean_t sleep_here = FALSE;
   svn_boolean_t *use_sleep = timestamp_sleep ? timestamp_sleep : &sleep_here;
   const char *diff3_cmd;
   svn_ra_session_t *ra_session;
-  svn_wc_adm_access_t *dir_access;
   const char *preserved_exts_str;
   apr_array_header_t *preserved_exts;
   struct ff_baton *ffb;
-  const char *local_abspath;
-  const char *anchor_abspath;
   svn_client__external_func_baton_t efb;
   svn_boolean_t server_supports_depth;
   svn_config_t *cfg = ctx->config ? apr_hash_get(ctx->config,
@@ -124,44 +122,18 @@
   if (depth == svn_depth_unknown)
     depth_is_sticky = FALSE;
 
-  /* Sanity check.  Without this, the update is meaningless. */
-  SVN_ERR_ASSERT(path);
-
-  if (svn_path_is_url(path))
-    return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
-                             _("Path '%s' is not a directory"),
-                             path);
-
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-
-  if (!innerupdate)
+  if (strcmp(local_abspath, anchor_abspath))
     {
-      /* Use PATH to get the update's anchor and targets and get a write lock.
-       */
-      SVN_ERR(svn_wc__adm_open_anchor_in_context(&adm_access, &dir_access,
-                                                 &target, ctx->wc_ctx, path,
-                                                 TRUE,
-                                                 -1, /* recursive lock */
-                                                 ctx->cancel_func,
-                                                 ctx->cancel_baton, pool));
+      target = svn_dirent_basename(local_abspath, pool);
+      anchor = svn_dirent_basename(path, pool);
     }
   else
     {
-      /* Assume the exact root is specified (required for externals to work,
-         as these would otherwise try to open the parent working copy again) */
-      SVN_ERR(svn_wc__adm_open_in_context(&adm_access, ctx->wc_ctx, path, TRUE,
-                                          -1, /* recursive lock */
-                                          ctx->cancel_func, ctx->cancel_baton,
-                                          pool));
-      dir_access = adm_access;
       target = "";
+      anchor = path;
     }
 
-  anchor = svn_wc_adm_access_path(adm_access);
-  SVN_ERR(svn_dirent_get_absolute(&anchor_abspath, anchor, pool));
-
   /* Get full URL from the ANCHOR. */
-
   SVN_ERR(svn_wc__node_get_url(&anchor_url, ctx->wc_ctx, anchor_abspath,
                                pool, pool));
   if (! anchor_url)
@@ -183,7 +155,8 @@
                                  pool));
 
           /* Target excluded, we are done now */
-          SVN_ERR(svn_wc_adm_close2(adm_access, pool));
+          SVN_ERR(svn_wc__release_write_lock(ctx->wc_ctx, anchor_abspath,
+                                             pool));
 
           return SVN_NO_ERROR;
         }
@@ -297,17 +270,18 @@
      the primary operation.  */
   if (SVN_DEPTH_IS_RECURSIVE(depth) && (! ignore_externals))
     {
-      SVN_ERR(svn_client__handle_externals(adm_access, efb.externals_old,
+      SVN_ERR(svn_client__handle_externals(efb.externals_old,
                                            efb.externals_new, 
                                            efb.ambient_depths,
-                                           anchor_url, anchor, repos_root,
+                                           anchor_url, anchor,
+                                           repos_root,
                                            depth, use_sleep, ctx, pool));
     }
 
   if (sleep_here)
     svn_io_sleep_for_timestamps(path, pool);
 
-  SVN_ERR(svn_wc_adm_close2(adm_access, pool));
+  SVN_ERR(svn_wc__release_write_lock(ctx->wc_ctx, anchor_abspath, pool));
 
   /* Let everyone know we're finished here. */
   if (ctx->notify_func2)
@@ -330,6 +304,56 @@
 }
 
 svn_error_t *
+svn_client__update_internal(svn_revnum_t *result_rev,
+                            const char *path,
+                            const svn_opt_revision_t *revision,
+                            svn_depth_t depth,
+                            svn_boolean_t depth_is_sticky,
+                            svn_boolean_t ignore_externals,
+                            svn_boolean_t allow_unver_obstructions,
+                            svn_boolean_t *timestamp_sleep,
+                            svn_boolean_t send_copyfrom_args,
+                            svn_boolean_t innerupdate,
+                            svn_client_ctx_t *ctx,
+                            apr_pool_t *pool)
+{
+  const char *local_abspath, *anchor_abspath;
+  svn_error_t *err1, *err2;
+
+  SVN_ERR_ASSERT(path);
+
+  if (svn_path_is_url(path))
+    return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
+                             _("Path '%s' is not a directory"),
+                             path);
+
+  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
+
+  if (!innerupdate)
+    {
+      SVN_ERR(svn_wc__acquire_write_lock(&anchor_abspath, ctx->wc_ctx,
+                                         local_abspath, pool, pool));
+    }
+  else
+    {
+      SVN_ERR(svn_wc__acquire_write_lock(NULL, ctx->wc_ctx,
+                                         local_abspath, pool, pool));
+      anchor_abspath = local_abspath;
+    }
+
+  err1 = update_internal(result_rev, path, local_abspath, anchor_abspath,
+                         revision, depth, depth_is_sticky,
+                         ignore_externals, allow_unver_obstructions,
+                         timestamp_sleep, send_copyfrom_args,
+                         innerupdate, ctx, pool);
+
+  err2 = svn_wc__release_write_lock(ctx->wc_ctx, anchor_abspath, pool);
+
+  return svn_error_compose_create(err1, err2);
+}
+
+
+svn_error_t *
 svn_client_update3(apr_array_header_t **result_revs,
                    const apr_array_header_t *paths,
                    const svn_opt_revision_t *revision,

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.c?rev=919999&r1=919998&r2=919999&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.c Sun Mar  7 14:12:20 2010
@@ -373,10 +373,18 @@
 
 /*** Opening and closing files in the adm area. ***/
 
+/* Create and open a writable file in the admin temporary area of the WC
+   directory DIR_ABSPATH, in a subdirectory named SUBDIR (such as "text-base"),
+   with the name FNAME and extra EXTENSION (such as ".svn-base").  If the
+   file already exists, first delete it.  Set *STREAM to a writable stream
+   to this file, and (if SELECTED_ABSPATH is not NULL) set *SELECTED_PATH to
+   the path to this file, both allocated in RESULT_POOL.
+
+   Closing the stream will close (but not delete) the file. */
 static svn_error_t *
 open_adm_file(svn_stream_t **stream,
-              const char **selected_path,
-              const char *path,
+              const char **selected_abspath,
+              const char *dir_abspath,
               const char *subdir,
               const char *fname,
               const char *extension,
@@ -386,20 +394,18 @@
   svn_error_t *err;
 
   /* Extend with tmp name. */
-  path = extend_with_adm_name(path, extension, TRUE, result_pool,
-                              subdir, fname, NULL);
-
-  err = svn_stream_open_writable(stream, path, result_pool, scratch_pool);
-
-  if (selected_path)
-    *selected_path = path;  /* note: built in result_pool */
+  dir_abspath = extend_with_adm_name(dir_abspath, extension, TRUE, result_pool,
+                                     subdir, fname, NULL);
+  if (selected_abspath)
+    *selected_abspath = dir_abspath;  /* note: built in result_pool */
 
+  err = svn_stream_open_writable(stream, dir_abspath, result_pool, scratch_pool);
   if (err && APR_STATUS_IS_EEXIST(err->apr_err))
     {
       /* Exclusive open failed, delete and retry */
       svn_error_clear(err);
-      SVN_ERR(svn_io_remove_file2(path, FALSE, scratch_pool));
-      err = svn_stream_open_writable(stream, path, result_pool, scratch_pool);
+      SVN_ERR(svn_io_remove_file2(dir_abspath, FALSE, scratch_pool));
+      err = svn_stream_open_writable(stream, dir_abspath, result_pool, scratch_pool);
     }
 
   /* Examine the error from the first and/or second attempt at opening. */
@@ -436,19 +442,19 @@
 
 svn_error_t *
 svn_wc__open_writable_base(svn_stream_t **stream,
-                           const char **temp_base_path,
-                           const char *path,
+                           const char **temp_base_abspath,
+                           const char *local_abspath,
                            svn_boolean_t need_revert_base,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
 {
-  const char *parent_path;
+  const char *parent_abspath;
   const char *base_name;
 
-  svn_dirent_split(path, &parent_path, &base_name, scratch_pool);
+  svn_dirent_split(local_abspath, &parent_abspath, &base_name, scratch_pool);
 
-  return open_adm_file(stream, temp_base_path,
-                       parent_path,
+  return open_adm_file(stream, temp_base_abspath,
+                       parent_abspath,
                        SVN_WC__ADM_TEXT_BASE,
                        base_name,
                        need_revert_base

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.h?rev=919999&r1=919998&r2=919999&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.h (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/adm_files.h Sun Mar  7 14:12:20 2010
@@ -59,8 +59,8 @@
 svn_wc__sync_text_base(const char *path, apr_pool_t *pool);
 
 
-/* Return an absolute path to LOCAL_ABSPATH's text-base file.
-   If TMP is set, return a path to the tmp text-base file. */
+/* Set *RESULT_PATH to the absolute path to LOCAL_ABSPATH's text-base file,
+   or, if TMP is set, to its temporary text-base file. */
 svn_error_t *
 svn_wc__text_base_path(const char **result_path,
                        svn_wc__db_t *db,
@@ -68,7 +68,7 @@
                        svn_boolean_t tmp,
                        apr_pool_t *pool);
 
-/* Return a readonly stream on the LOCAL_ABSPATH's base file. */
+/* Set *CONTENTS to a readonly stream on the LOCAL_ABSPATH's base file. */
 svn_error_t *
 svn_wc__get_pristine_contents(svn_stream_t **contents,
                               svn_wc__db_t *db,
@@ -78,7 +78,7 @@
 
 
 
-/* Return a readonly stream on the LOCAL_ABSPATH's revert file. */
+/* Set *CONTENTS to a readonly stream on the LOCAL_ABSPATH's revert file. */
 svn_error_t *
 svn_wc__get_revert_contents(svn_stream_t **contents,
                             svn_wc__db_t *db,
@@ -87,8 +87,7 @@
                             apr_pool_t *scratch_pool);
 
 
-/* Retrieve an absolute path to LOCAL_ABSPATH's revert file.
-   If TMP is set, return a path to the tmp revert file. */
+/* Set *RESULT_ABSPATH to the absolute path to LOCAL_ABSPATH's revert file. */
 svn_error_t *
 svn_wc__text_revert_path(const char **result_abspath,
                          svn_wc__db_t *db,
@@ -117,15 +116,16 @@
                                      apr_pool_t *scratch_pool);
 
 
-/* Open the normal or revert text base, associated with PATH, for writing.
+/* Open the normal or revert text base, associated with LOCAL_ABSPATH, for
+   writing.
    The selection is based on NEED_REVERT_BASE. The opened stream will be
    returned in STREAM and the selected path will be returned in,
-   TEMP_BASE_PATH, and both will be allocated in RESULT_POOL. Any temporary
+   TEMP_BASE_ABSPATH, and both will be allocated in RESULT_POOL. Any temporary
    allocations will be performed in SCRATCH_POOL. */
 svn_error_t *
 svn_wc__open_writable_base(svn_stream_t **stream,
-                           const char **temp_base_path,
-                           const char *path,
+                           const char **temp_base_abspath,
+                           const char *local_abspath,
                            svn_boolean_t need_revert_base,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool);

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.c?rev=919999&r1=919998&r2=919999&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.c Sun Mar  7 14:12:20 2010
@@ -2587,17 +2587,7 @@
       ? apr_pstrdup(pool, entry->prejfile)
                           : NULL;
 
-  /* Last-commit stuff */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_CMT_REV)
-    cur_entry->cmt_rev = entry->cmt_rev;
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_CMT_DATE)
-    cur_entry->cmt_date = entry->cmt_date;
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_CMT_AUTHOR)
-    cur_entry->cmt_author = entry->cmt_author
-      ? apr_pstrdup(pool, entry->cmt_author)
-                            : NULL;
+  /* Last-commit flags are no longer passed to entry_modify() */
 
   /* LOCK flags are no longer passed to entry_modify().  */
 

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.h?rev=919999&r1=919998&r2=919999&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.h (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.h Sun Mar  7 14:12:20 2010
@@ -108,9 +108,6 @@
 #define SVN_WC__ENTRY_MODIFY_CONFLICT_NEW       APR_INT64_C(0x0000000000002000)
 #define SVN_WC__ENTRY_MODIFY_CONFLICT_WRK       APR_INT64_C(0x0000000000004000)
 #define SVN_WC__ENTRY_MODIFY_PREJFILE           APR_INT64_C(0x0000000000008000)
-#define SVN_WC__ENTRY_MODIFY_CMT_REV            APR_INT64_C(0x0000000000010000)
-#define SVN_WC__ENTRY_MODIFY_CMT_DATE           APR_INT64_C(0x0000000000020000)
-#define SVN_WC__ENTRY_MODIFY_CMT_AUTHOR         APR_INT64_C(0x0000000000040000)
 /* OPEN */
 #define SVN_WC__ENTRY_MODIFY_INCOMPLETE         APR_INT64_C(0x0000000000100000)
 #define SVN_WC__ENTRY_MODIFY_ABSENT             APR_INT64_C(0x0000000000200000)

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/lock.c?rev=919999&r1=919998&r2=919999&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/lock.c Sun Mar  7 14:12:20 2010
@@ -1733,41 +1733,51 @@
   svn_wc__db_kind_t kind;
   apr_pool_t *iterpool;
   const apr_array_header_t *children;
-  svn_boolean_t parent_is_anchor = FALSE;
   int format, i;
   svn_error_t *err;
 
+  SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath, TRUE,
+                               scratch_pool));
+
   if (anchor_abspath)
     {
-      const char *parent_abspath, *base;
+      const char *parent_abspath;
+      svn_wc__db_kind_t parent_kind;
 
-      svn_dirent_split(local_abspath, &parent_abspath, &base, scratch_pool);
-      err = svn_wc__db_read_children(&children, wc_ctx->db, parent_abspath,
-                                     scratch_pool, scratch_pool);
-      if (err)
-        svn_error_clear(err);
+      parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+      err = svn_wc__db_read_kind(&parent_kind, wc_ctx->db, parent_abspath, TRUE,
+                                 scratch_pool);
+      if (err && err->apr_err == SVN_ERR_WC_NOT_DIRECTORY)
+        {
+          svn_error_clear(err);
+          parent_kind = svn_wc__db_kind_unknown;
+        }
       else
+        SVN_ERR(err);
+
+      if (kind == svn_wc__db_kind_dir && parent_kind == svn_wc__db_kind_dir)
         {
-          for (i = 0; i < children->nelts; ++i)
-            if (! strcmp(APR_ARRAY_IDX(children, i, const char *), base))
-              break;
-          if (i < children->nelts)
-            parent_is_anchor = TRUE;
+          svn_boolean_t disjoint;
+          SVN_ERR(child_is_disjoint(&disjoint, wc_ctx->db, local_abspath,
+                                    scratch_pool));
+          if (!disjoint)
+            local_abspath = parent_abspath;
         }
-      local_abspath = parent_is_anchor ? parent_abspath : local_abspath;
+      else if (parent_kind == svn_wc__db_kind_dir)
+        local_abspath = parent_abspath;
+      else if (kind != svn_wc__db_kind_dir)
+        return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
+                                 _("'%s' is not a working copy"),
+                                 svn_dirent_local_style(local_abspath,
+                                                        scratch_pool));
+
       *anchor_abspath = apr_pstrdup(result_pool, local_abspath);
     }
+  else if (kind != svn_wc__db_kind_dir)
+    local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
 
-  if (! parent_is_anchor)
-    {
-      SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath, TRUE,
-                                   scratch_pool));
-      if (kind != svn_wc__db_kind_dir)
-        local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-
-      SVN_ERR(svn_wc__db_read_children(&children, wc_ctx->db, local_abspath,
-                                       scratch_pool, scratch_pool));
-    }
+  SVN_ERR(svn_wc__db_read_children(&children, wc_ctx->db, local_abspath,
+                                   scratch_pool, scratch_pool));
 
   /* The current lock paradigm is that each directory holds a lock for itself,
      and there are no inherited locks.  In the eventual wc-ng paradigm, a
@@ -1815,6 +1825,8 @@
   svn_wc__db_kind_t kind;
   apr_pool_t *iterpool;
   const apr_array_header_t *children;
+  apr_uint64_t id;
+  svn_skel_t *work_item;
   int i;
 
   SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath, TRUE,
@@ -1822,6 +1834,11 @@
   if (kind != svn_wc__db_kind_dir)
     local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
 
+  SVN_ERR(svn_wc__db_wq_fetch(&id, &work_item, wc_ctx->db, local_abspath,
+                              scratch_pool, scratch_pool));
+  if (work_item)
+    return SVN_NO_ERROR;
+
   /* We need to recursively remove locks (see comment in
      svn_wc__acquire_write_lock(). */
 

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/log.c?rev=919999&r1=919998&r2=919999&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/log.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/log.c Sun Mar  7 14:12:20 2010
@@ -475,40 +475,6 @@
   if (valuestr && strcmp(valuestr, "true") == 0)
     modify_flags |= SVN_WC__ENTRY_MODIFY_FORCE;
 
-  /* It is possible that we will find a log that has a misordered sequence
-     of entry modifications and wcprop modifications. The entry must be
-     "not hidden" before wcprops can be installed. The sequence of actions
-     will look like:
-
-       1. modify_entry
-       2. modify_wcprops
-       3. modify_entry(DELETED=FALSE)
-
-     Step 2 will fail if the current node is marked DELETED. r36697 fixes
-     the ordering, moving step 3 to the beginning of the sequence. However,
-     old logs may still contain the above sequence. To compensate, we will
-     attempt to detect the pattern used by step 1, and preemptively clear
-     the DELETED flag.
-
-     The misordered entry is written by accumulate_entry_props() in
-     update_editor.c. That may modify the CMT_* values and/or the UUID.
-     If we see any of those, then we've detected a modify_entry constructed
-     by that function. And that means we *just* ran a step 3 (new code)
-     or we *will* run a step 3 (too late; old code). In both situations,
-     we can safely clear the DELETED flag.
-
-     The UUID modification is *only* performed by that function. The CMT_*
-     changes are also performed by process_committed_leaf() in adm_ops.c.
-     A just-committed node setting these values will NEVER be DELETED,
-     so it is safe to clear the value.  */
-  if (modify_flags & (SVN_WC__ENTRY_MODIFY_CMT_REV
-                      | SVN_WC__ENTRY_MODIFY_CMT_DATE
-                      | SVN_WC__ENTRY_MODIFY_CMT_AUTHOR))
-    {
-      entry->deleted = FALSE;
-      modify_flags |= SVN_WC__ENTRY_MODIFY_DELETED;
-    }
-
   /* Now write the new entry out. Note that we want to always operate
      on the stub if name is not THIS_DIR. This loggy function is intended
      to operate on the data in ADM_ABSPATH, so we do NOT want to reach
@@ -612,14 +578,6 @@
               return SVN_NO_ERROR;
             }
         }
-      else
-        {
-          /* Deleting full_path requires that any children it has are
-             also locked (issue #3039). */
-            SVN_ERR(svn_wc__adm_extend_lock_to_tree(loggy->db,
-                                                    local_abspath,
-                                                    loggy->pool));
-        }
     }
 
   err = svn_wc__internal_remove_from_revision_control(loggy->db,
@@ -1086,17 +1044,7 @@
                  SVN_WC__ENTRY_ATTR_CHECKSUM,
                  entry->checksum);
 
-  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_CMT_REV,
-                 SVN_WC__ENTRY_ATTR_CMT_REV,
-                 apr_psprintf(scratch_pool, "%ld", entry->cmt_rev));
-
-  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_CMT_DATE,
-                 SVN_WC__ENTRY_ATTR_CMT_DATE,
-                 svn_time_to_cstring(entry->cmt_date, scratch_pool));
-
-  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_CMT_AUTHOR,
-                 SVN_WC__ENTRY_ATTR_CMT_AUTHOR,
-                 entry->cmt_author);
+  /* Note: Last-commit flags are no longer passed to this function. */
 
   /* Note: LOCK flags are no longer passed to this function.  */
 

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/old-and-busted.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/old-and-busted.c?rev=919999&r1=919998&r2=919999&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/old-and-busted.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/old-and-busted.c Sun Mar  7 14:12:20 2010
@@ -946,7 +946,6 @@
     if (cmt_datestr)
       {
         SVN_ERR(svn_time_from_cstring(&entry->cmt_date, cmt_datestr, pool));
-        *modify_flags |= SVN_WC__ENTRY_MODIFY_CMT_DATE;
       }
     else
       entry->cmt_date = 0;
@@ -956,15 +955,13 @@
     if (cmt_revstr)
       {
         entry->cmt_rev = SVN_STR_TO_REV(cmt_revstr);
-        *modify_flags |= SVN_WC__ENTRY_MODIFY_CMT_REV;
       }
     else
       entry->cmt_rev = SVN_INVALID_REVNUM;
 
     entry->cmt_author = extract_string(modify_flags, atts,
                                        SVN_WC__ENTRY_ATTR_CMT_AUTHOR,
-                                       SVN_WC__ENTRY_MODIFY_CMT_AUTHOR,
-                                       FALSE, pool);
+                                       0, FALSE, pool);
   }
 
   /* NOTE: we do not set modify_flags values since the lock attributes only

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/update_editor.c?rev=919999&r1=919998&r2=919999&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/update_editor.c Sun Mar  7 14:12:20 2010
@@ -168,9 +168,6 @@
   svn_wc__db_t *db;
   svn_wc_context_t *wc_ctx;
 
-  /* ADM_ACCESS is an access baton that includes the ANCHOR directory */
-  svn_wc_adm_access_t *adm_access;
-
   /* Array of file extension patterns to preserve as extensions in
      generated conflict files. */
   apr_array_header_t *ext_patterns;
@@ -201,6 +198,11 @@
   /* Allow unversioned obstructions when adding a path. */
   svn_boolean_t allow_unver_obstructions;
 
+  /* The close_edit method destroys the edit pool and so runs the
+     cleanup_dir_baton cleanup handlers.  This flag is set to indicate
+     that the edit was completed successfully. */
+  svn_boolean_t close_edit_complete;
+
   /* If this is a 'switch' operation, the target URL (### corresponding to
      the ANCHOR plus TARGET path?), else NULL. */
   const char *switch_url;
@@ -377,7 +379,11 @@
   struct file_baton *fb;
 
   /* Where we are assembling the new file. */
-  const char *work_path;
+  const char *work_abspath;
+#ifdef SVN_EXPERIMENTAL
+  /* Where the pristine is before we can copy it into the correct location. */
+  const char *temp_pristine_abspath;
+#endif
 
     /* The expected checksum of the text source or NULL if no base
      checksum is available */
@@ -401,11 +407,6 @@
   /* The stream used to calculate the source checksums */
   svn_stream_t *source_checksum_stream;
 
-#ifdef SVN_EXPERIMENTAL
-  /* Where the pristine is before we can copy it into the correct location. */
-  const char *temp_pristine_abspath;
-#endif
-
   /* This is initialized to all zeroes when the baton is created, then
      populated with the MD5 digest of the resultant fulltext after the
      last window is handled by the handler returned from
@@ -425,14 +426,14 @@
                    apr_pool_t *scratch_pool)
 {
   const char *temp_dir_path;
-  svn_stream_t *empty_stream;
+  apr_file_t *file;
 
   SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_path, db, wri_abspath,
                                          scratch_pool, scratch_pool));
-  SVN_ERR(svn_stream_open_unique(&empty_stream, tmp_filename, temp_dir_path,
-                                 svn_io_file_del_none, scratch_pool,
-                                 scratch_pool));
-  SVN_ERR(svn_stream_close(empty_stream));
+  SVN_ERR(svn_io_open_unique_file3(&file, tmp_filename, temp_dir_path,
+                                   svn_io_file_del_none,
+                                   scratch_pool, scratch_pool));
+  SVN_ERR(svn_io_file_close(file, scratch_pool));
 
   return svn_error_return(svn_dirent_get_absolute(tmp_filename, *tmp_filename,
                                                   result_pool));
@@ -495,6 +496,21 @@
   if (!err)
     err = svn_wc__run_log2(eb->db, db->local_abspath, pool);
 
+  /* If the editor aborts for some sort of error, the command line
+     client relies on pool cleanup to run outstanding work queues and
+     remove locks.  This avoids leaving the working copy locked in
+     many cases, but plays havoc with operations that do multiple
+     updates (think externals). So we flag updates that complete
+     successfully and avoid removing locks.  In 1.6 locks were
+     associated with a pool distinct from the edit pool and so were
+     removed separately. */
+  if (!err && !eb->close_edit_complete)
+    {
+      svn_wc_context_t fake_ctx;
+      fake_ctx.db = eb->db;
+      err = svn_wc__release_write_lock(&fake_ctx, db->local_abspath, pool);
+    }
+
   if (err)
     {
       apr_status_t apr_err = err->apr_err;
@@ -929,7 +945,11 @@
   /* The path to the incoming text base (that is, to a text-base-file-
      in-progress in the tmp area).  This gets set if there are file
      content changes. */
-  const char *new_text_base_path;
+  const char *new_text_base_abspath;
+#ifdef SVN_EXPERIMENTAL
+  /* Where the pristine is before we can copy it into the correct location. */
+  const char *temp_pristine_abspath;
+#endif
 
   /* The checksum for the file located at NEW_TEXT_BASE_PATH. */
   svn_checksum_t *md5_actual_checksum;
@@ -978,11 +998,6 @@
   /* Bump information for the directory this file lives in */
   struct bump_dir_info *bump_info;
 
-#ifdef SVN_EXPERIMENTAL
-  /* Where the pristine is before we can copy it into the correct location. */
-  const char *temp_pristine_abspath;
-#endif
-
   /* log accumulator; will be flushed and run in close_file(). */
   svn_stringbuf_t *log_accum;
 };
@@ -1101,7 +1116,7 @@
   if (err)
     {
       /* We failed to apply the delta; clean up the temporary file.  */
-      svn_error_clear(svn_io_remove_file2(hb->work_path, TRUE, hb->pool));
+      svn_error_clear(svn_io_remove_file2(hb->work_abspath, TRUE, hb->pool));
 #ifdef SVN_EXPERIMENTAL
       svn_error_clear(svn_io_remove_file2(hb->temp_pristine_abspath, TRUE,
                                           hb->pool));
@@ -1110,16 +1125,15 @@
   else
     {
       /* Tell the file baton about the new text base. */
-      fb->new_text_base_path = apr_pstrdup(fb->pool, hb->work_path);
-
-      /* ... and its checksum. */
-      fb->md5_actual_checksum =
-        svn_checksum__from_digest(hb->digest, svn_checksum_md5, fb->pool);
-
+      fb->new_text_base_abspath = apr_pstrdup(fb->pool, hb->work_abspath);
 #ifdef SVN_EXPERIMENTAL
       fb->temp_pristine_abspath = apr_pstrdup(fb->pool,
                                               hb->temp_pristine_abspath);
 #endif
+
+      /* ... and its checksums. */
+      fb->md5_actual_checksum =
+        svn_checksum__from_digest(hb->digest, svn_checksum_md5, fb->pool);
       fb->sha1_actual_checksum =
         svn_checksum_dup(hb->sha1_actual_checksum, fb->pool);
     }
@@ -1144,6 +1158,7 @@
 {
   const char *repos;
   const char *dir_abspath;
+  svn_boolean_t locked_here;
 
   dir_abspath = db->local_abspath;
 
@@ -1165,48 +1180,46 @@
                                       db->edit_baton->uuid, ancestor_revision,
                                       db->ambient_depth, pool));
 
-  if (NULL == svn_wc__adm_retrieve_internal2(db->edit_baton->db, dir_abspath,
-                                             pool))
-    {
-      svn_wc_adm_access_t *adm_access;
-      apr_pool_t *adm_access_pool;
-      const char *rel_path;
-
-      SVN_ERR(svn_wc__temp_get_relpath(&rel_path, db->edit_baton->db,
+  SVN_ERR(svn_wc_locked2(&locked_here, NULL, db->edit_baton->wc_ctx,
+                         dir_abspath, pool));
+  if (!locked_here)
+    /* Recursive lock release on parent will release this lock. */
+    SVN_ERR(svn_wc__acquire_write_lock(NULL, db->edit_baton->wc_ctx,
                                        dir_abspath, pool, pool));
 
-      adm_access_pool = svn_wc_adm_access_pool(db->edit_baton->adm_access);
-
-      SVN_ERR(svn_wc__adm_open_in_context(&adm_access, db->edit_baton->wc_ctx,
-                                          rel_path, TRUE, -1,
-                                          db->edit_baton->cancel_func,
-                                          db->edit_baton->cancel_baton,
-                                          adm_access_pool));
-    }
-
   return SVN_NO_ERROR;
 }
 
 
-/* Accumulate tags in LOG_ACCUM (associated with ADM_ABSPATH) to set
-   ENTRY_PROPS for PATH.
+/* Container for the common "Entry props" */
+struct last_change_info
+{
+  /** last revision this was changed */
+  svn_revnum_t cmt_rev;
+
+  /** last date this was changed */
+  apr_time_t cmt_date;
+
+  /** last commit author of this item */
+  const char *cmt_author;
+};
+
+/* Accumulate last change info in LAST_CHANGE to set on LOCAL_ABSPATH.
    ENTRY_PROPS is an array of svn_prop_t* entry props.
-   If ENTRY_PROPS contains the removal of a lock token, all entryprops
-   related to a lock will be removed and LOCK_STATE, if non-NULL, will be
-   set to svn_wc_notify_lock_state_unlocked.  Else, LOCK_STATE, if non-NULL
+   If ENTRY_PROPS contains the removal of a lock token, the lock info is
+   directly removed from LOCAL_ABSPATH in DB and LOCK_STATE, if non-NULL, will
+   be set to svn_wc_notify_lock_state_unlocked.  Else, LOCK_STATE, if non-NULL
    will be set to svn_wc_lock_state_unchanged. */
 static svn_error_t *
-accumulate_entry_props(svn_stringbuf_t *log_accum,
-                       svn_wc__db_t *db,
-                       const char *adm_abspath,
+accumulate_last_change(struct last_change_info **last_change,
                        svn_wc_notify_lock_state_t *lock_state,
-                       const char *path,
+                       svn_wc__db_t *db,
+                       const char *local_abspath,
                        apr_array_header_t *entry_props,
-                       apr_pool_t *pool)
+                       apr_pool_t *scratch_pool,
+                       apr_pool_t *result_pool)
 {
   int i;
-  svn_wc_entry_t tmp_entry;
-  apr_uint64_t flags = 0;
 
   if (lock_state)
     *lock_state = svn_wc_notify_lock_state_unchanged;
@@ -1217,11 +1230,10 @@
       const char *val;
 
       /* The removal of the lock-token entryprop means that the lock was
-         defunct. */
+         defunct, so remove it directly. */
       if (! strcmp(prop->name, SVN_PROP_ENTRY_LOCK_TOKEN))
         {
-          SVN_WC__FLUSH_LOG_ACCUM(db, adm_abspath, log_accum, pool);
-          SVN_ERR(svn_wc__loggy_delete_lock(db, adm_abspath, path, pool));
+          SVN_ERR(svn_wc__db_lock_remove(db, local_abspath, scratch_pool));
 
           if (lock_state)
             *lock_state = svn_wc_notify_lock_state_unlocked;
@@ -1236,29 +1248,23 @@
 
       val = prop->value->data;
 
-      if (! strcmp(prop->name, SVN_PROP_ENTRY_LAST_AUTHOR))
+      if (*last_change == NULL)
         {
-          flags |= SVN_WC__ENTRY_MODIFY_CMT_AUTHOR;
-          tmp_entry.cmt_author = val;
+          *last_change = apr_pcalloc(result_pool, sizeof(**last_change));
+          (*last_change)->cmt_rev = SVN_INVALID_REVNUM;
         }
+
+      if (! strcmp(prop->name, SVN_PROP_ENTRY_LAST_AUTHOR))
+        (*last_change)->cmt_author = apr_pstrdup(result_pool, val);
       else if (! strcmp(prop->name, SVN_PROP_ENTRY_COMMITTED_REV))
-        {
-          flags |= SVN_WC__ENTRY_MODIFY_CMT_REV;
-          tmp_entry.cmt_rev = SVN_STR_TO_REV(val);
-        }
+        (*last_change)->cmt_rev = SVN_STR_TO_REV(val);
       else if (! strcmp(prop->name, SVN_PROP_ENTRY_COMMITTED_DATE))
-        {
-          flags |= SVN_WC__ENTRY_MODIFY_CMT_DATE;
-          SVN_ERR(svn_time_from_cstring(&tmp_entry.cmt_date, val, pool));
-        }
+        SVN_ERR(svn_time_from_cstring(&((*last_change)->cmt_date), val,
+                                      scratch_pool));
       /* Starting with Subversion 1.7 we ignore the SVN_PROP_ENTRY_UUID
          property here. */
     }
 
-  if (flags)
-    SVN_ERR(svn_wc__loggy_entry_modify(&log_accum, adm_abspath,
-                                       path, &tmp_entry, flags, pool, pool));
-
   return SVN_NO_ERROR;
 }
 
@@ -1739,22 +1745,21 @@
     return SVN_NO_ERROR;
 
 
-  /* Sanity checks.
-   * When the node existed before (it was locally deleted, replaced or
-   * edited), then, to be sane, 'update' can only send
-   * svn_wc_conflict_action_edit, svn_wc_conflict_action_delete or
-   * svn_wc_conflict_action_replace.  Note that if there was no action on
-   * the node, this code would not have been called in the first place. */
+  /* Sanity checks. Note that if there was no action on the node, this function
+   * would not have been called in the first place.*/
   if (reason == svn_wc_conflict_reason_edited
       || reason == svn_wc_conflict_reason_deleted
       || reason == svn_wc_conflict_reason_replaced)
+    /* When the node existed before (it was locally deleted, replaced or
+     * edited), then 'update' cannot add it "again". So it can only send
+     * _action_edit, _delete or _replace. */
     SVN_ERR_ASSERT(action == svn_wc_conflict_action_edit
                    || action == svn_wc_conflict_action_delete
                    || action == svn_wc_conflict_action_replace);
   else
   if (reason == svn_wc_conflict_reason_added)
-    /* When the node did not exist before (it was locally added), then, to
-     * be sane, 'update' can only send svn_wc_conflict_action_add. */
+    /* When the node did not exist before (it was locally added), then 'update'
+     * cannot want to modify it in any way. It can only send _action_add. */
     SVN_ERR_ASSERT(action == svn_wc_conflict_action_add);
 
 
@@ -2192,7 +2197,6 @@
   /* ### Need to change the "base" into a "revert-base" ? */
 
   /* Determine which adm dir holds this node's entry */
-  /* ### But this will fail if eb->adm_access holds only a shallow lock. */
   SVN_ERR(svn_wc__entry_modify2(eb->db,
                                 local_abspath,
                                 entry->kind,
@@ -3173,6 +3177,7 @@
 {
   struct dir_baton *db = dir_baton;
   struct edit_baton *eb = db->edit_baton;
+  struct last_change_info *last_change = NULL;
   svn_wc_notify_state_t prop_state = svn_wc_notify_state_unknown;
   apr_array_header_t *entry_props, *wc_props, *regular_props;
   apr_hash_t *base_props = NULL, *working_props = NULL;
@@ -3303,10 +3308,9 @@
                     _("Couldn't do property merge"));
         }
 
-      SVN_ERR(accumulate_entry_props(dirprop_log, eb->db,
-                                     db->local_abspath,
-                                     NULL, db->local_abspath, entry_props,
-                                     pool));
+      SVN_ERR(accumulate_last_change(&last_change, NULL, eb->db,
+                                     db->local_abspath, entry_props,
+                                     pool, pool));
 
       /* Handle the wcprops. */
       if (wc_props && wc_props->nelts > 0)
@@ -3329,6 +3333,14 @@
 
   /* Flush and run the log. */
   SVN_ERR(flush_log(db, pool));
+
+  if (last_change)
+    SVN_ERR(svn_wc__db_temp_op_set_base_last_change(eb->db, db->local_abspath,
+                                                    last_change->cmt_rev,
+                                                    last_change->cmt_date,
+                                                    last_change->cmt_author,
+                                                    pool));
+
   SVN_ERR(svn_wc__run_log2(eb->db, db->local_abspath, pool));
 
   /* We're done with this directory, so remove one reference from the
@@ -3366,6 +3378,7 @@
   while (bdi && !bdi->ref_count)
     {
       apr_pool_t *destroy_pool = bdi->pool;
+      apr_pool_cleanup_kill(destroy_pool, db, cleanup_dir_baton);
       bdi = bdi->parent;
       svn_pool_destroy(destroy_pool);
     }
@@ -3451,6 +3464,12 @@
 
 
 #ifdef SVN_EXPERIMENTAL
+/* Set *TEE_OUTPUT_STREAM to a writable stream that copies its data to both
+   OUTPUT_STREAM and a new WC-NG pristine temp file corresponding to (DB,
+   LOCAL_ABSPATH). Set *TEMP_PRISTINE_ABSPATH to the path of that file.
+   Arrange that, on stream closure, *ACTUAL_CHECKSUM will be set to the SHA-1
+   checksum of that file.
+ */
 static svn_error_t *
 get_pristine_tee_stream(svn_stream_t **tee_output_stream,
                         const char **temp_pristine_abspath,
@@ -3707,7 +3726,7 @@
   apr_hash_t *base_props, *working_props;
   svn_error_t *err;
   svn_stream_t *copied_stream;
-  const char *temp_dir_path;
+  const char *temp_dir_abspath;
   const char *src_local_abspath;
   svn_wc__db_t *db = eb->db;
   const char *dir_repos_relpath, *dir_repos_root, *dir_repos_uuid;
@@ -3733,13 +3752,20 @@
   else
     SVN_ERR(err);
 
-  SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_path, db, pb->local_abspath,
+  SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath, db, pb->local_abspath,
                                          subpool, subpool));
   SVN_ERR(svn_stream_open_unique(&copied_stream,
                                  &tfb->copied_text_base,
-                                 temp_dir_path,
+                                 temp_dir_abspath,
                                  svn_io_file_del_none,
                                  pool, pool));
+#ifdef SVN_EXPERIMENTAL
+  /* Copy the 'copied_stream' into a WC-NG pristine temp file as well. */
+  SVN_ERR(get_pristine_tee_stream(&copied_stream, &tfb->temp_pristine_abspath,
+                                  &tfb->sha1_copied_base_checksum, db,
+                                  tfb->local_abspath, copied_stream,
+                                  pool, subpool));
+#endif
 
   /* Compute a checksum for the stream as we write stuff into it.
      ### this is temporary. in many cases, we already *know* the checksum
@@ -3748,12 +3774,6 @@
                                 copied_stream,
                                 NULL, &tfb->md5_copied_base_checksum,
                                 svn_checksum_md5, FALSE, pool);
-#ifdef SVN_EXPERIMENTAL
-  SVN_ERR(get_pristine_tee_stream(&copied_stream, &tfb->temp_pristine_abspath,
-                                  &tfb->sha1_copied_base_checksum, db,
-                                  tfb->local_abspath, copied_stream,
-                                  pool, subpool));
-#endif
 
   if (src_local_abspath != NULL) /* Found a file to copy */
     {
@@ -4405,7 +4425,7 @@
     }
 
   /* Open the text base for writing (this will get us a temporary file).  */
-  err = svn_wc__open_writable_base(&target, &hb->work_path,
+  err = svn_wc__open_writable_base(&target, &hb->work_abspath,
                                    fb->local_abspath,
                                    replaced /* need_revert_base */,
                                    handler_pool, pool);
@@ -4416,7 +4436,7 @@
     }
 
 #ifdef SVN_EXPERIMENTAL
-  /* Get a stream for writing our pristine temp.
+  /* Copy the 'target' stream into a WC-NG pristine temp file as well.
      ###: This is currently tee'd for compat. */
   SVN_ERR(get_pristine_tee_stream(&target, &hb->temp_pristine_abspath,
                                   &hb->sha1_actual_checksum,
@@ -4426,7 +4446,7 @@
 
   /* Prepare to apply the delta.  */
   svn_txdelta_apply(source, target,
-                    hb->digest, hb->work_path /* error_info */,
+                    hb->digest, hb->work_abspath /* error_info */,
                     handler_pool,
                     &hb->apply_handler, &hb->apply_baton);
 
@@ -4493,6 +4513,7 @@
             svn_wc_notify_lock_state_t *lock_state,
             apr_hash_t **new_base_props,
             apr_hash_t **new_actual_props,
+            struct last_change_info **last_change,
             svn_wc__db_t *db,
             const char *file_abspath,
             const char *dir_abspath,
@@ -4547,9 +4568,9 @@
      Note that no merging needs to happen; these kinds of props aren't
      versioned, so if the property is present, we overwrite the value. */
   if (entry_props)
-    SVN_ERR(accumulate_entry_props(log_accum, db, dir_abspath,
-                                   lock_state, file_abspath, entry_props,
-                                   pool));
+    SVN_ERR(accumulate_last_change(last_change, lock_state,
+                                   db, file_abspath, entry_props,
+                                   pool, pool));
   else
     *lock_state = svn_wc_notify_lock_state_unchanged;
 
@@ -4562,19 +4583,16 @@
   return SVN_NO_ERROR;
 }
 
-/* TODO ### Update to mention LOCAL_ABSPATH, DIR_ABSPATH; not NAME, ADM_ACCESS.
-
-   Append, to LOG_ACCUM, log commands to update the entry for NAME in
-   ADM_ACCESS with a NEW_REVISION and a NEW_URL (if non-NULL), making sure
+/* Append to LOG_ACCUM, log commands to update the entry for LOCAL_ABSPATH
+   with a NEW_REVISION and a NEW_URL (if non-NULL), making sure
    the entry refers to a file and has no absent or deleted state.
    Use POOL for temporary allocations. */
 static svn_error_t *
-loggy_tweak_entry(svn_stringbuf_t *log_accum,
-                  const char *local_abspath,
-                  const char *dir_abspath,
-                  svn_revnum_t new_revision,
-                  const char *new_URL,
-                  apr_pool_t *pool)
+loggy_tweak_base_node(svn_stringbuf_t *log_accum,
+                      const char *local_abspath,
+                      svn_revnum_t new_revision,
+                      const char *new_URL,
+                      apr_pool_t *pool)
 {
   /* Write log entry which will bump the revision number.  Also, just
      in case we're overwriting an existing phantom 'deleted' or
@@ -4610,12 +4628,41 @@
     }
 
   return svn_error_return(
-    svn_wc__loggy_entry_modify(&log_accum, dir_abspath,
+    svn_wc__loggy_entry_modify(&log_accum,
+                               svn_dirent_dirname(local_abspath, pool),
                                local_abspath, &tmp_entry, modify_flags,
                                pool, pool));
 }
 
 
+/* Write loggy commands to install a text base file from the given temporary
+ * path TEMP_TEXT_BASE_ABSPATH (which must be in the adm temp area) to the
+ * given final text-base path FINAL_TEXT_BASE_ABSPATH (which must be the
+ * standard text-base path or revert-base path for the file).
+ *
+ * Write log instructions to do this into *LOG_ACCUM.  Store all loggy paths
+ * as paths relative to ADM_ABSPATH.
+ *
+ * Allocate *LOG_ACCUM in RESULT_POOL if it is NULL.
+ */
+static svn_error_t *
+install_text_base(svn_stringbuf_t **log_accum,
+                  const char *adm_abspath,
+                  const char *temp_text_base_abspath,
+                  const char *final_text_base_abspath,
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_wc__loggy_move(log_accum, adm_abspath,
+                             temp_text_base_abspath, final_text_base_abspath,
+                             result_pool, scratch_pool));
+  SVN_ERR(svn_wc__loggy_set_readonly(log_accum, adm_abspath,
+                                     final_text_base_abspath,
+                                     result_pool, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+
 /* This is the small planet.  It has the complex responsibility of
  * "integrating" a new revision of a file into a working copy.
  *
@@ -4630,7 +4677,7 @@
  * sensitive to eol translation, keyword substitution, and performing
  * all actions accumulated to FB->DIR_BATON->LOG_ACCUM.
  *
- * If there's a new text base, NEW_TEXT_BASE_PATH must be the full
+ * If there's a new text base, NEW_TEXT_BASE_ABSPATH must be the full
  * pathname of the new text base, somewhere in the administrative area
  * of the working file.  It will be installed as the new text base for
  * this file, and removed after a successful run of the generated log
@@ -4653,8 +4700,9 @@
            svn_wc_notify_lock_state_t *lock_state,
            apr_hash_t **new_base_props,
            apr_hash_t **new_actual_props,
+           struct last_change_info **last_change,
            struct file_baton *fb,
-           const char *new_text_base_path,
+           const char *new_text_base_abspath,
            const svn_checksum_t *actual_checksum,
            apr_pool_t *pool)
 {
@@ -4668,24 +4716,17 @@
   const svn_wc_entry_t *entry;
   svn_wc_conflict_version_t *left_version = NULL; /* ### Fill */
   svn_wc_conflict_version_t *right_version = NULL; /* ### Fill */
-  const char *new_text_base_abspath;
 
   /* Accumulated entry modifications. */
   svn_wc_entry_t tmp_entry;
   apr_uint64_t flags = 0;
 
-  if (new_text_base_path)
-    SVN_ERR(svn_dirent_get_absolute(&new_text_base_abspath,
-                                    new_text_base_path, pool));
-  else
-    new_text_base_abspath = NULL;
-
   /*
      When this function is called on file F, we assume the following
      things are true:
 
          - The new pristine text of F, if any, is present at
-           NEW_TEXT_BASE_PATH
+           NEW_TEXT_BASE_ABSPATH
 
          - The .svn/entries file still reflects the old version of F.
 
@@ -4715,14 +4756,14 @@
   /* Set the new revision and URL in the entry and clean up some other
      fields. This clears DELETED from any prior versioned file with the
      same name (needed before attempting to install props).  */
-  SVN_ERR(loggy_tweak_entry(log_accum, fb->local_abspath, pb->local_abspath,
-                            *eb->target_revision, fb->new_URL, pool));
+  SVN_ERR(loggy_tweak_base_node(log_accum, fb->local_abspath,
+                                *eb->target_revision, fb->new_URL, pool));
 
   /* Install all kinds of properties.  It is important to do this before
      any file content merging, since that process might expand keywords, in
      which case we want the new entryprops to be in place. */
   SVN_ERR(merge_props(log_accum, prop_state, lock_state,
-                      new_base_props, new_actual_props,
+                      new_base_props, new_actual_props, last_change,
                       eb->db, fb->local_abspath, pb->local_abspath,
                       left_version, right_version,
                       fb->propchanges,
@@ -4740,11 +4781,18 @@
      Special case: The working file is referring to a file external? If so
                    then we must mark it as unmodified in order to avoid bogus
                    conflicts, since this file was added as a place holder to
-                   merge externals item from the repository. */
+                   merge externals item from the repository.
+
+     ### Possible entry caching bug?  Before the removal of the access
+     batons a newly added file external caused svn_wc__get_entry to
+     return an entry with entry->schedule=svn_wc_schedule_add (the
+     entry was retrieved from the cache).  Now the svn_wc__get_entry
+     call reads the entries from the database the returned entry is
+     svn_wc_schedule_replace.  2 lines marked ### EBUG below. */
   if (fb->copied_working_text)
     is_locally_modified = TRUE;
   else if (entry && entry->file_external_path
-           && entry->schedule == svn_wc_schedule_add)
+           && entry->schedule == svn_wc_schedule_replace) /* ###EBUG */
     is_locally_modified = FALSE;
   else if (! fb->existed)
     SVN_ERR(svn_wc__internal_text_modified_p(&is_locally_modified, eb->db,
@@ -4761,7 +4809,8 @@
   else
     is_locally_modified = FALSE;
 
-  if (entry && entry->schedule == svn_wc_schedule_replace)
+  if (entry && entry->schedule == svn_wc_schedule_replace
+      && ! entry->file_external_path)  /* ### EBUG */
     is_replaced = TRUE;
 
   if (fb->add_existed)
@@ -4971,12 +5020,9 @@
   /* Deal with installation of the new textbase, if appropriate. */
   if (new_text_base_abspath)
     {
-      SVN_ERR(svn_wc__loggy_move(&log_accum,
-                                 pb->local_abspath,
-                                 new_text_base_abspath,
-                                 fb->text_base_path, pool, pool));
-      SVN_ERR(svn_wc__loggy_set_readonly(&log_accum, pb->local_abspath,
-                                         fb->text_base_path, pool, pool));
+      SVN_ERR(install_text_base(&log_accum, pb->local_abspath,
+                                new_text_base_abspath, fb->text_base_path,
+                                pool, pool));
       tmp_entry.checksum = svn_checksum_to_cstring(actual_checksum, pool);
       flags |= SVN_WC__ENTRY_MODIFY_CHECKSUM;
     }
@@ -5065,12 +5111,13 @@
 {
   struct file_baton *fb = file_baton;
   struct edit_baton *eb = fb->edit_baton;
+  struct last_change_info *last_change = NULL;
   svn_wc_notify_state_t content_state, prop_state;
   svn_wc_notify_lock_state_t lock_state;
   svn_checksum_t *expected_checksum = NULL;
   svn_checksum_t *md5_actual_checksum;
   svn_checksum_t *sha1_actual_checksum;
-  const char *new_base_path;
+  const char *new_base_abspath;
   apr_hash_t *new_base_props = NULL;
   apr_hash_t *new_actual_props = NULL;
 
@@ -5089,7 +5136,7 @@
   /* Was this an add-with-history, with no apply_textdelta? */
   if (fb->added_with_history && ! fb->received_textdelta)
     {
-      SVN_ERR_ASSERT(! fb->text_base_path && ! fb->new_text_base_path
+      SVN_ERR_ASSERT(! fb->text_base_path && ! fb->new_text_base_abspath
                      && fb->copied_text_base);
 
       /* Set up the base paths like apply_textdelta does. */
@@ -5100,7 +5147,10 @@
 
       md5_actual_checksum = fb->md5_copied_base_checksum;
       sha1_actual_checksum = fb->sha1_copied_base_checksum;
-      new_base_path = fb->copied_text_base;
+      new_base_abspath = fb->copied_text_base;
+      if (new_base_abspath)
+        SVN_ERR(svn_dirent_get_absolute(&new_base_abspath, new_base_abspath,
+                                        pool));
     }
   else
     {
@@ -5108,11 +5158,11 @@
          the application of a text delta. */
       md5_actual_checksum = fb->md5_actual_checksum;
       sha1_actual_checksum = fb->sha1_actual_checksum;
-      new_base_path = fb->new_text_base_path;
+      new_base_abspath = fb->new_text_base_abspath;
     }
 
   /* window-handler assembles new pristine text in .svn/tmp/text-base/  */
-  if (new_base_path && expected_checksum
+  if (new_base_abspath && expected_checksum
       && !svn_checksum_match(expected_checksum, md5_actual_checksum))
     return svn_error_createf(SVN_ERR_CHECKSUM_MISMATCH, NULL,
             _("Checksum mismatch for '%s':\n"
@@ -5124,6 +5174,13 @@
 
 #ifdef SVN_EXPERIMENTAL
   /* If we had a text change, drop the pristine into it's proper place. */
+  /* The WC-1 equivalent code is in merge_file(). Shouldn't they be together?
+     Bert said: In 1.0 the install of the .svn-base has to be done in loggy/wq
+     (or it can break your wc), while with the new pristine the file can and
+     should be created directly and then later in a single transaction we can
+     update all the BASE_NODE info to switch the file over and install a wq
+     item to update the in-wc file. So in a few cases it is logical that the
+     file operations are not side by side. */
   if (fb->temp_pristine_abspath)
     SVN_ERR(svn_wc__db_pristine_install(eb->db, fb->temp_pristine_abspath,
                                         sha1_actual_checksum,
@@ -5132,8 +5189,8 @@
 
   /* It's a small world, after all. */
   SVN_ERR(merge_file(&content_state, &prop_state, &lock_state,
-                     &new_base_props, &new_actual_props, fb,
-                     new_base_path, md5_actual_checksum, pool));
+                     &new_base_props, &new_actual_props, &last_change,
+                     fb, new_base_abspath, md5_actual_checksum, pool));
 
 
   if (fb->added || fb->add_existed)
@@ -5144,11 +5201,15 @@
                    be removed soon anyway.
 
          ### HACK: The loggy stuff checked the preconditions for us,
-                   we just make the property code happy here. */
+                   we just make the property code happy here. 
+
+         We can also clear entry.deleted here, as we are adding a new
+         BASE_NODE anyway */
       svn_wc_entry_t tmp_entry;
       svn_stringbuf_t *create_log = NULL;
       apr_uint64_t flags = SVN_WC__ENTRY_MODIFY_KIND
-                           | SVN_WC__ENTRY_MODIFY_REVISION;
+                           | SVN_WC__ENTRY_MODIFY_REVISION
+                           | SVN_WC__ENTRY_MODIFY_DELETED;
 
       if (fb->add_existed)
         {
@@ -5163,6 +5224,7 @@
 
       tmp_entry.kind = svn_node_file;
       tmp_entry.revision = *eb->target_revision;
+      tmp_entry.deleted = FALSE;
 
       SVN_ERR(svn_wc__loggy_entry_modify(&create_log,
                                          fb->dir_baton->local_abspath,
@@ -5175,8 +5237,23 @@
                                    fb->dir_baton->local_abspath,
                                    create_log,
                                    pool));
+
+      SVN_ERR(svn_wc__wq_run(eb->db,
+                             fb->dir_baton->local_abspath,
+                             NULL, NULL, pool));
     }
 
+  /* ### Hack: The following block should be an atomic operation (including the install
+               loggy install portions of some functions called above */
+  SVN_ERR_ASSERT(last_change != NULL); /* Should always be not NULL for files */
+
+  if (last_change)
+    SVN_ERR(svn_wc__db_temp_op_set_base_last_change(eb->db, fb->local_abspath,
+                                                    last_change->cmt_rev,
+                                                    last_change->cmt_date,
+                                                    last_change->cmt_author,
+                                                    pool));
+
   if (new_base_props || new_actual_props)
       SVN_ERR(svn_wc__install_props(eb->db, fb->local_abspath,
                                     new_base_props, new_actual_props,
@@ -5293,6 +5370,7 @@
      should also make eb->pool not be a subpool (see make_editor),
      and change callers of svn_client_{checkout,update,switch} to do
      better pool management. ### */
+  eb->close_edit_complete = TRUE;
   svn_pool_destroy(eb->pool);
 
   return SVN_NO_ERROR;
@@ -5336,12 +5414,10 @@
   svn_delta_editor_t *tree_editor = svn_delta_default_editor(edit_pool);
   const svn_delta_editor_t *inner_editor;
   const char *repos_root, *repos_uuid;
-  svn_wc_adm_access_t *adm_access;
   const char *anchor;
 
-  adm_access = svn_wc__adm_retrieve_internal2(wc_ctx->db, anchor_abspath,
-                                              scratch_pool);
-  anchor = svn_wc_adm_access_path(adm_access);
+  SVN_ERR(svn_wc__temp_get_relpath(&anchor, wc_ctx->db, anchor_abspath,
+                                   result_pool, scratch_pool));
 
   /* An unknown depth can't be sticky. */
   if (depth == svn_depth_unknown)
@@ -5372,7 +5448,6 @@
   eb->uuid                     = repos_uuid;
   eb->db                       = wc_ctx->db;
   eb->wc_ctx                   = wc_ctx;
-  eb->adm_access               = adm_access;
   eb->target_basename          = target_basename;
   eb->anchor_abspath           = anchor_abspath;
 
@@ -5396,6 +5471,7 @@
   eb->fetch_func               = fetch_func;
   eb->fetch_baton              = fetch_baton;
   eb->allow_unver_obstructions = allow_unver_obstructions;
+  eb->close_edit_complete      = FALSE;
   eb->skipped_trees            = apr_hash_make(edit_pool);
   eb->ext_patterns             = preserved_exts;
 
@@ -5866,7 +5942,7 @@
    be an access baton for DST_PATH.
    Use @a POOL for temporary allocations. */
 static svn_error_t *
-install_added_props(svn_stringbuf_t *log_accum,
+install_added_props(struct last_change_info **last_change,
                     svn_wc__db_t *db,
                     const char *dir_abspath,
                     const char *local_abspath,
@@ -5894,14 +5970,57 @@
   }
 
   /* Install the entry props. */
-  SVN_ERR(accumulate_entry_props(log_accum, db, dir_abspath,
-                                 NULL, local_abspath, entry_props, pool));
+  SVN_ERR(accumulate_last_change(last_change, NULL, db, local_abspath,
+                                 entry_props, pool, pool));
 
   return svn_error_return(svn_wc__db_base_set_dav_cache(db, local_abspath,
                                         prop_hash_from_array(wc_props, pool),
                                         pool));
 }
 
+/* Append, to LOG_ACCUM, log commands to update the entry for LOCAL_ABSPATH
+   with a NEW_REVISION and a NEW_URL (if non-NULL), making sure
+   the entry refers to a file and has no absent or deleted state.
+   Use POOL for temporary allocations. */
+static svn_error_t *
+loggy_tweak_working_node(svn_stringbuf_t *log_accum,
+                         const char *local_abspath,
+                         apr_pool_t *pool)
+{
+  /* Write log entry which will bump the revision number.  Also, just
+     in case we're overwriting an existing phantom 'deleted' or
+     'absent' entry, be sure to remove the hiddenness. */
+  svn_wc_entry_t tmp_entry;
+  apr_uint64_t modify_flags = SVN_WC__ENTRY_MODIFY_KIND
+    | SVN_WC__ENTRY_MODIFY_TEXT_TIME
+    | SVN_WC__ENTRY_MODIFY_WORKING_SIZE;
+
+  tmp_entry.kind = svn_node_file;
+  /* Indicate the file was locally modified and we didn't get to
+     calculate the true value, but we can't set it to UNKNOWN (-1),
+     because that would indicate absense of this value.
+     If it isn't locally modified,
+     we'll overwrite with the actual value later. */
+  tmp_entry.working_size = SVN_WC_ENTRY_WORKING_SIZE_UNKNOWN;
+  /* The same is true for the TEXT_TIME field, except that that doesn't
+     have an explicid 'changed' value, so we set the value to 'undefined'. */
+  tmp_entry.text_time = 0;
+
+  return svn_error_return(
+    svn_wc__loggy_entry_modify(&log_accum,
+                               svn_dirent_dirname(local_abspath, pool),
+                               local_abspath,  &tmp_entry, modify_flags,
+                               pool, pool));
+}
+
+/* ### Note that this function is completely different from the rest of the
+       update editor in what it updates. The update editor changes only BASE
+       and ACTUAL and this function just changes WORKING and ACTUAL.
+
+       In the entries world this function shared a lot of code with the
+       update editor but in the wonderful new WC-NG world it will probably
+       do more and more by itself and would be more logically grouped with
+       the add/copy functionality in adm_ops.c and copy.c. */
 svn_error_t *
 svn_wc_add_repos_file4(svn_wc_context_t *wc_ctx,
                        const char *local_abspath,
@@ -5928,6 +6047,7 @@
   const char *temp_dir_abspath;
   svn_stringbuf_t *pre_props_accum;
   svn_stringbuf_t *post_props_accum;
+  struct last_change_info *last_change = NULL;
 
   SVN_ERR(svn_wc__text_base_path(&text_base_path, wc_ctx->db, local_abspath,
                                  FALSE, pool));
@@ -6009,18 +6129,14 @@
                                        modify_flags, pool, pool));
   }
 
-  /* Set the new revision number and URL in the entry and clean up some other
-     fields. This clears DELETED from any prior versioned file with the
-     same name (needed before attempting to install props).  */
-  SVN_ERR(loggy_tweak_entry(pre_props_accum, local_abspath, dir_abspath,
-                            dst_entry ? dst_entry->revision : ent->revision,
-                            new_URL, pool));
+  /* ### Clear working node status in preparation for writing a new node. */
+  SVN_ERR(loggy_tweak_working_node(pre_props_accum, local_abspath, pool));
 
   post_props_accum = svn_stringbuf_create("", pool);
 
   /* Install the props before the loggy translation, so that it has access to
      the properties for this file. */
-  SVN_ERR(install_added_props(post_props_accum, wc_ctx->db, dir_abspath,
+  SVN_ERR(install_added_props(&last_change, wc_ctx->db, dir_abspath,
                               local_abspath, &new_base_props, new_props, pool));
 
   /* Copy the text base contents into a temporary file so our log
@@ -6074,21 +6190,23 @@
 
   /* Install new text base. */
   {
+    const char *tmp_text_base_abspath;
     svn_wc_entry_t tmp_entry;
+    apr_uint64_t flags = 0;
 
-    /* Write out log commands to set up the new text base and its
-       checksum. */
-    SVN_ERR(svn_wc__loggy_move(&post_props_accum, dir_abspath,
-                               tmp_text_base_path, text_base_path,
-                               pool, pool));
-    SVN_ERR(svn_wc__loggy_set_readonly(&post_props_accum, dir_abspath,
-                                       text_base_path, pool, pool));
+    SVN_ERR(svn_dirent_get_absolute(&tmp_text_base_abspath, tmp_text_base_path,
+                                    pool));
 
+    /* Write out log commands to set up the new text base and its checksum. */
+    SVN_ERR(install_text_base(&post_props_accum, dir_abspath,
+                              tmp_text_base_abspath, text_base_path,
+                              pool, pool));
     tmp_entry.checksum = svn_checksum_to_cstring(base_checksum, pool);
+    flags |= SVN_WC__ENTRY_MODIFY_CHECKSUM;
+
     SVN_ERR(svn_wc__loggy_entry_modify(&post_props_accum, dir_abspath,
                                        local_abspath, &tmp_entry,
-                                       SVN_WC__ENTRY_MODIFY_CHECKSUM,
-                                       pool, pool));
+                                       flags, pool, pool));
   }
 
   /* Write our accumulation of log entries into a log file */
@@ -6096,6 +6214,17 @@
   SVN_ERR(svn_wc__install_props(wc_ctx->db, local_abspath, new_base_props,
                                 new_props ? new_props : new_base_props,
                                 TRUE, FALSE, pool));
+
+  SVN_ERR(svn_wc__run_log2(wc_ctx->db, dir_abspath, pool));
+
+  /* ### HACK: The following code should be performed in the same transaction as the install */
+  if (last_change)
+    SVN_ERR(svn_wc__db_temp_op_set_working_last_change(wc_ctx->db, local_abspath,
+                                                       last_change->cmt_rev,
+                                                       last_change->cmt_date,
+                                                       last_change->cmt_author,
+                                                       pool));
+  /* ### /HACK */
   SVN_ERR(svn_wc__wq_add_loggy(wc_ctx->db, dir_abspath, post_props_accum, pool));
 
 

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/upgrade.c?rev=919999&r1=919998&r2=919999&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/upgrade.c Sun Mar  7 14:12:20 2010
@@ -344,6 +344,54 @@
                     TRUE, scratch_pool));
 }
 
+/* Checks ENTRY to see if it misses critical information. Attempts to
+   retrieve this information from REPOS_INFO_FUNC, passing REPOS_INFO_BATON.
+   Returns a user understandable error using LOCAL_ABSPATH if vital
+   information would not be available after this function returns */
+static svn_error_t *
+fetch_missing_entry_data(svn_wc_entry_t *entry,
+                         const char *local_abspath,
+                         svn_wc_upgrade_get_repos_info_t repos_info_func,
+                         void *repos_info_baton,
+                         apr_pool_t *scratch_pool,
+                         apr_pool_t *result_pool)
+{
+  const char *repos_root;
+  const char *repos_uuid;
+  if (entry->repos && entry->uuid)
+    return SVN_NO_ERROR; /* We are done here */
+
+  if (!entry->repos && !repos_info_func)
+    return svn_error_createf(
+        SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
+        _("Working copy '%s' can't be upgraded because the repository root is "
+          "not available and can't be retrieved"),
+        svn_dirent_local_style(local_abspath, scratch_pool));
+
+  if (!entry->uuid && !repos_info_func)
+    return svn_error_createf(
+        SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
+        _("Working copy '%s' can't be upgraded because the repository uuid is "
+          "not available and can't be retrieved"),
+        svn_dirent_local_style(local_abspath, scratch_pool));
+
+   if (!entry->url)
+     return svn_error_createf(
+        SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
+        _("Working copy '%s' can't be upgraded because it doesn't have a url"),
+        svn_dirent_local_style(local_abspath, scratch_pool));
+
+   SVN_ERR(repos_info_func(&repos_root, &repos_uuid, repos_info_baton,
+                          entry->url, scratch_pool, result_pool));
+
+   if (!entry->repos)
+     entry->repos = repos_root;
+   if (!entry->uuid)
+     entry->uuid = repos_uuid;
+
+   return SVN_NO_ERROR;
+}
+
 
 /* Upgrade the working copy directory represented by DB/DIR_ABSPATH
    from OLD_FORMAT to the wc-ng format (SVN_WC__WC_NG_VERSION)'.
@@ -353,13 +401,15 @@
 upgrade_to_wcng(svn_wc__db_t *db,
                 const char *dir_abspath,
                 int old_format,
+                svn_wc_upgrade_get_repos_info_t repos_info_func,
+                void *repos_info_baton,
                 apr_pool_t *scratch_pool)
 {
   const char *logfile_path = svn_wc__adm_child(dir_abspath, SVN_WC__ADM_LOG,
                                                scratch_pool);
   svn_node_kind_t logfile_on_disk;
   apr_hash_t *entries;
-  const svn_wc_entry_t *this_dir;
+  svn_wc_entry_t *this_dir;
   svn_sqlite__db_t *sdb;
   apr_int64_t repos_id;
   apr_int64_t wc_id;
@@ -401,6 +451,10 @@
 
   this_dir = apr_hash_get(entries, SVN_WC_ENTRY_THIS_DIR, APR_HASH_KEY_STRING);
 
+  SVN_ERR(fetch_missing_entry_data(this_dir, dir_abspath,
+                                   repos_info_func, repos_info_baton,
+                                   scratch_pool, apr_hash_pool_get(entries)));
+
   /* Create an empty sqlite database for this directory. */
   SVN_ERR(svn_wc__db_upgrade_begin(&sdb, &repos_id, &wc_id, dir_abspath,
                                    this_dir->repos, this_dir->uuid,
@@ -1060,6 +1114,8 @@
 static svn_error_t *
 upgrade_working_copy(svn_wc__db_t *db,
                      const char *dir_abspath,
+                     svn_wc_upgrade_get_repos_info_t repos_info_func,
+                     void *repos_info_baton,
                      svn_cancel_func_t cancel_func,
                      void *cancel_baton,
                      svn_wc_notify_func2_t notify_func,
@@ -1083,7 +1139,9 @@
 
   /* Upgrade this directory first. */
   if (old_format < SVN_WC__WC_NG_VERSION)
-    SVN_ERR(upgrade_to_wcng(db, dir_abspath, old_format, iterpool));
+    SVN_ERR(upgrade_to_wcng(db, dir_abspath, old_format,
+                            repos_info_func, repos_info_baton,
+                            iterpool));
 
   if (notify_func)
     notify_func(notify_baton,
@@ -1099,6 +1157,7 @@
       svn_pool_clear(iterpool);
 
       SVN_ERR(upgrade_working_copy(db, child_abspath,
+                                   repos_info_func, repos_info_baton,
                                    cancel_func, cancel_baton,
                                    notify_func, notify_baton,
                                    iterpool));
@@ -1113,6 +1172,8 @@
 svn_error_t *
 svn_wc_upgrade(svn_wc_context_t *wc_ctx,
                const char *local_abspath,
+               svn_wc_upgrade_get_repos_info_t repos_info_func,
+               void *repos_info_baton,
                svn_cancel_func_t cancel_func,
                void *cancel_baton,
                svn_wc_notify_func2_t notify_func,
@@ -1142,6 +1203,7 @@
 
   /* Upgrade this directory and/or its subdirectories.  */
   SVN_ERR(upgrade_working_copy(db, local_abspath,
+                               repos_info_func, repos_info_baton,
                                cancel_func, cancel_baton,
                                notify_func, notify_baton,
                                scratch_pool));

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-queries.sql?rev=919999&r1=919998&r2=919999&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-queries.sql Sun Mar  7 14:12:20 2010
@@ -372,6 +372,14 @@
 update base_node set file_external = ?3
 where wc_id = ?1 and local_relpath = ?2;
 
+-- STMT_UPDATE_BASE_LAST_CHANGE
+update base_node set changed_rev = ?3, changed_date = ?4, changed_author = ?5
+where wc_id = ?1 and local_relpath = ?2;
+
+-- STMT_UPDATE_WORKING_LAST_CHANGE
+update working_node set changed_rev = ?3, changed_date = ?4, changed_author = ?5
+where wc_id = ?1 and local_relpath = ?2;
+
 /* ------------------------------------------------------------------------- */
 
 /* these are used in upgrade.c  */