You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/09/15 21:32:38 UTC

svn commit: r997472 [23/41] - in /subversion/branches/py-tests-as-modules: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/server-side/ notes/ notes/tree-conflicts/ notes/wc-ng/ subversion/bindings/javahl/native/ subversi...

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_wc/props.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_wc/props.c Wed Sep 15 19:32:26 2010
@@ -52,12 +52,8 @@
 #include "private/svn_skel.h"
 
 #include "wc.h"
-#include "log.h"
-#include "adm_files.h"
-#include "entries.h"
 #include "props.h"
 #include "translate.h"
-#include "lock.h"  /* for svn_wc__write_check()  */
 #include "workqueue.h"
 #include "conflicts.h"
 
@@ -72,190 +68,6 @@ message_from_skel(const svn_skel_t *skel
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool);
 
-
-#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
-
-/* Get PATH's properies of PROPS_KIND, and put them into *HASH.
-   PATH should be of kind NODE_KIND. */
-static svn_error_t *
-load_props(apr_hash_t **hash,
-           svn_wc__db_t *db,
-           const char *local_abspath,
-           svn_wc__props_kind_t props_kind,
-           apr_pool_t *pool)
-{
-  svn_error_t *err;
-  svn_stream_t *stream;
-  apr_finfo_t finfo;
-  const char *prop_path;
-  svn_wc__db_kind_t kind;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE, pool));
-  SVN_ERR(svn_wc__prop_path(&prop_path, local_abspath, kind, props_kind,
-                            pool));
-
-  /* We shouldn't be calling load_prop_file() with an empty file, but
-     we do.  This check makes sure that we don't call svn_hash_read2()
-     on an empty stream.  Ugly, hacky and crude. */
-  err = svn_io_stat(&finfo, prop_path, APR_FINFO_SIZE, pool);
-  if (err)
-    {
-      if (APR_STATUS_IS_ENOENT(err->apr_err)
-            || APR_STATUS_IS_ENOTDIR(err->apr_err))
-        {
-          svn_error_clear(err);
-
-          /* NOTE: we need to signal that this file is NOT PRESENT, as
-             opposed to merely devoid of properties. */
-          if (props_kind == svn_wc__props_working)
-            *hash = NULL;
-          else
-            *hash = apr_hash_make(pool);
-
-          return SVN_NO_ERROR;
-        }
-      else
-        return err;
-    }
-
-  *hash = apr_hash_make(pool);
-
-  if (finfo.size == 0)
-    return SVN_NO_ERROR;
-
-  SVN_ERR(svn_stream_open_readonly(&stream, prop_path, pool, pool));
-
-  SVN_ERR(svn_hash_read2(*hash, stream, SVN_HASH_TERMINATOR, pool));
-
-  return svn_stream_close(stream);
-}
-
-#endif /* (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB) */
-
-
-static svn_error_t *
-load_pristine_props(apr_hash_t **props,
-                    svn_wc__db_t *db,
-                    const char *local_abspath,
-                    apr_pool_t *result_pool,
-                    apr_pool_t *scratch_pool)
-{
-#if (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB)
-
-  SVN_ERR(svn_wc__db_read_pristine_props(props, db, local_abspath,
-                                         result_pool, scratch_pool));
-
-#ifdef TEST_DB_PROPS
-  {
-    SVN_ERR_MALFUNCTION();  /* ### not yet implemented  */
-  }
-#endif
-
-#else /* (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB) */
-
-  /* NOTE: svn_wc__props_base really means "pristine" props, which may
-     come from BASE or WORKING.  */
-  SVN_ERR(load_props(props, db, local_abspath, svn_wc__props_base,
-                     result_pool));
-
-#ifdef TEST_DB_PROPS
-  {
-    apr_hash_t *db_base_props;
-
-    SVN_ERR(svn_wc__db_read_pristine_props(&db_base_props, db,
-                                           local_abspath,
-                                           scratch_pool, scratch_pool));
-
-    if (*props != NULL && apr_hash_count(*props) > 0)
-      {
-        apr_array_header_t *diffs;
-
-        SVN_ERR_ASSERT(db_base_props != NULL);
-
-        SVN_ERR(svn_prop_diffs(&diffs, *props, db_base_props, scratch_pool));
-        SVN_ERR_ASSERT(diffs->nelts == 0);
-      }
-    else
-      {
-        /* If the propfile is missing, then we should see no/empty props
-           in the database.  */
-        SVN_ERR_ASSERT(db_base_props == NULL
-                       || apr_hash_count(db_base_props) == 0);
-      }
-  }
-#endif /* TEST_DB_PROPS */
-#endif /* (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB) */
-
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-load_actual_props(apr_hash_t **props,
-                  svn_wc__db_t *db,
-                  const char *local_abspath,
-                  apr_pool_t *result_pool,
-                  apr_pool_t *scratch_pool)
-{
-#if (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB)
-
-  SVN_ERR(svn_wc__db_read_props(props, db, local_abspath,
-                                result_pool, scratch_pool));
-
-#ifdef TEST_DB_PROPS
-  {
-    SVN_ERR_MALFUNCTION();  /* ### not yet implemented  */
-  }
-#endif
-
-#else /* (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB) */
-  /* NOTE: svn_wc__props_working really means ACTUAL.  */
-  SVN_ERR(load_props(props, db, local_abspath, svn_wc__props_working,
-                     result_pool));
-
-  /* It is possible that we'll get NULL back, meaning "no props file".
-     For this case, just use the pristine properties. This is very
-     different from an empty file, which means "all props deleted".  */
-  if (*props == NULL)
-    {
-      SVN_ERR(load_pristine_props(props, db, local_abspath,
-                                  result_pool, scratch_pool));
-
-      /* If pristines are not defined for this node, then define this
-         node to have an empty set of properties.  */
-      if (*props == NULL)
-        *props = apr_hash_make(result_pool);
-    }
-
-#ifdef TEST_DB_PROPS
-  {
-    apr_hash_t *db_props;
-    apr_array_header_t *diffs;
-
-    SVN_ERR_ASSERT(*props != NULL);
-
-    SVN_ERR(svn_wc__db_read_props(&db_props, db, local_abspath,
-                                  scratch_pool, scratch_pool));
-
-    if (db_props != NULL)
-      {
-        SVN_ERR(svn_prop_diffs(&diffs, *props, db_props, scratch_pool));
-        SVN_ERR_ASSERT(diffs->nelts == 0);
-      }
-    else
-      {
-        SVN_ERR_ASSERT(apr_hash_count(*props) == 0);
-      }
-  }
-#endif /* TEST_DB_PROPS  */
-#endif /* (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB) */
-
-  return SVN_NO_ERROR;
-}
-
-
 /* Given a *SINGLE* property conflict in PROP_SKEL, generate a message
    for it, and write it to STREAM, along with a trailing EOL sequence.
 
@@ -323,129 +135,6 @@ svn_wc__get_prejfile_abspath(const char 
   return SVN_NO_ERROR;
 }
 
-
-svn_error_t *
-svn_wc__get_revert_props(apr_hash_t **revert_props_p,
-                         svn_wc__db_t *db,
-                         const char *local_abspath,
-                         apr_pool_t *result_pool,
-                         apr_pool_t *scratch_pool)
-{
-  svn_boolean_t replaced;
-
-  SVN_ERR_ASSERT(revert_props_p != NULL);
-
-  SVN_ERR(svn_wc__internal_is_replaced(&replaced, db, local_abspath,
-                                       scratch_pool));
-  if (replaced)
-    {
-#if (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB)
-      SVN_ERR(svn_wc__db_base_get_props(revert_props_p, db, local_abspath,
-                                        result_pool, scratch_pool));
-#else
-      SVN_ERR(load_props(revert_props_p, db, local_abspath,
-                         svn_wc__props_revert, result_pool));
-#endif
-    }
-  else
-    *revert_props_p = apr_hash_make(result_pool);
-
-#ifdef TEST_DB_PROPS
-  {
-    apr_hash_t *other_props;
-    apr_array_header_t *diffs;
-
-#if (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB)
-    SVN_ERR(svn_wc__db_base_get_props(&other_props, db, local_abspath,
-                                      scratch_pool, scratch_pool));
-#else
-    SVN_ERR(load_props(&other_props, db, local_abspath,
-                       svn_wc__props_revert, scratch_pool));
-    if (other_props == NULL)
-      other_props = apr_hash_make(scratch_pool);
-#endif
-    SVN_ERR_ASSERT(other_props != NULL);
-
-    SVN_ERR(svn_prop_diffs(&diffs, *revert_props_p, other_props,
-                           scratch_pool));
-    SVN_ERR_ASSERT(diffs->nelts == 0);
-  }
-#endif /* TEST_DB_PROPS  */
-
-  return SVN_NO_ERROR;
-}
-
-
-/* See props.h  */
-#ifdef SVN__SUPPORT_BASE_MERGE
-
-/* Add a working queue item to install PROPS and, if INSTALL_PRISTINE_PROPS is
-   TRUE, BASE_PROPS for the LOCAL_ABSPATH in DB, updating the node to reflect
-   the changes.  PRISTINE_PROPS must be supplied even if INSTALL_PRISTINE_PROPS
-   is FALSE.
-
-   Use SCRATCH_POOL for temporary allocations. */
-static svn_error_t *
-queue_install_props(svn_wc__db_t *db,
-                    const char *local_abspath,
-                    svn_wc__db_kind_t kind,
-                    apr_hash_t *pristine_props,
-                    apr_hash_t *props,
-                    svn_boolean_t install_pristine_props,
-                    apr_pool_t *scratch_pool)
-{
-  apr_array_header_t *prop_diffs;
-  const char *prop_abspath;
-  svn_skel_t *work_item;
-
-  SVN_ERR_ASSERT(pristine_props != NULL);
-
-  /* Check if the props are modified. */
-  SVN_ERR(svn_prop_diffs(&prop_diffs, props, pristine_props, scratch_pool));
-
-  /* Save the actual properties file if it differs from base. */
-  if (prop_diffs->nelts == 0)
-    props = NULL; /* Remove actual properties*/
-
-  if (install_pristine_props)
-    {
-      /* Write out a new set of pristine properties.  */
-      SVN_ERR(svn_wc__prop_path(&prop_abspath, local_abspath, kind,
-                                svn_wc__props_base, scratch_pool));
-      SVN_ERR(svn_wc__wq_build_write_old_props(&work_item,
-                                               prop_abspath,
-                                               pristine_props,
-                                               scratch_pool));
-      SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool));
-    }
-
-  /* For the old school: write the properties into the "working" (aka ACTUAL)
-     location. Note that PROPS may be NULL, indicating a removal of the
-     props file.  */
-  SVN_ERR(svn_wc__prop_path(&prop_abspath, local_abspath, kind,
-                            svn_wc__props_working, scratch_pool));
-  SVN_ERR(svn_wc__wq_build_write_old_props(&work_item,
-                                           prop_abspath,
-                                           props,
-                                           scratch_pool));
-  SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool));
-
-  /* ### this is disappearing. for now, it is a delayed call to put
-     ### properties into wc_db.  */
-  if (!install_pristine_props)
-    pristine_props = NULL; /* Don't change the pristine properties */
-  SVN_ERR(svn_wc__wq_add_install_properties(db,
-                                            local_abspath,
-                                            pristine_props,
-                                            props,
-                                            scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-#endif /* SVN__SUPPORT_BASE_MERGE  */
-
-
 /* */
 static svn_error_t *
 immediate_install_props(svn_wc__db_t *db,
@@ -455,17 +144,12 @@ immediate_install_props(svn_wc__db_t *db
                         apr_pool_t *scratch_pool)
 {
   apr_hash_t *base_props;
-  const char *propfile_abspath;
-  svn_skel_t *work_item;
 
   /* ### no pristines should be okay.  */
-  SVN_ERR_W(load_pristine_props(&base_props, db, local_abspath,
-                                scratch_pool, scratch_pool),
+  SVN_ERR_W(svn_wc__db_read_pristine_props(&base_props, db, local_abspath,
+                                           scratch_pool, scratch_pool),
             _("Failed to load pristine properties"));
 
-  SVN_ERR(svn_wc__prop_path(&propfile_abspath, local_abspath, kind,
-                            svn_wc__props_working, scratch_pool));
-
   /* Check if the props are modified. If no changes, then wipe out
      the ACTUAL props. No pristines defined means that any ACTUAL
      props are okay, so go ahead and set them.  */
@@ -479,78 +163,13 @@ immediate_install_props(svn_wc__db_t *db
         working_props = NULL;
     }
 
-  /* Save (if there are differences from "base") or remove the
-     ACTUAL (aka "props_working") properties file.  */
-  SVN_ERR(svn_wc__wq_build_write_old_props(&work_item,
-                                           propfile_abspath,
-                                           working_props,
-                                           scratch_pool));
-
   SVN_ERR(svn_wc__db_op_set_props(db, local_abspath,
                                   working_props,
                                   NULL /* conflict */,
-                                  work_item,
+                                  NULL, /* work_items */
                                   scratch_pool));
 
-  /* ### should really leave this to the caller. but for now... */
-  SVN_ERR(svn_wc__wq_run(db, local_abspath,
-                         NULL, NULL,  /* cancel_func/baton  */
-                         scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_wc__working_props_committed(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                apr_pool_t *scratch_pool)
-{
-#if (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB)
   return SVN_NO_ERROR;
-#else
-  svn_wc__db_kind_t kind;
-  const char *working;
-  const char *base;
-
-  SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE,
-                               scratch_pool));
-
-  /* The path is ensured not an excluded path. */
-  /* TODO(#2843) It seems that there is no need to
-     reveal hidden entry here? */
-
-  SVN_ERR(svn_wc__prop_path(&working, local_abspath, kind,
-                            svn_wc__props_working, scratch_pool));
-  SVN_ERR(svn_wc__prop_path(&base, local_abspath, kind,
-                            svn_wc__props_base, scratch_pool));
-
-  /* svn_io_file_rename() retains a read-only bit, so there's no
-     need to explicitly set it. */
-  return svn_error_return(svn_io_file_rename(working, base, scratch_pool));
-#endif
-}
-
-
-svn_error_t *
-svn_wc__props_delete(svn_wc__db_t *db,
-                     const char *local_abspath,
-                     svn_wc__props_kind_t props_kind,
-                     apr_pool_t *pool)
-{
-#if (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB)
-  return SVN_NO_ERROR;
-#else
-  const char *props_file;
-  svn_wc__db_kind_t kind;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE, pool));
-  SVN_ERR(svn_wc__prop_path(&props_file, local_abspath, kind, props_kind,
-                            pool));
-  return svn_error_return(svn_io_remove_file2(props_file, TRUE, pool));
-#endif
 }
 
 
@@ -728,9 +347,35 @@ svn_wc__perform_props_merge(svn_wc_notif
 
 /* See props.h  */
 #ifdef SVN__SUPPORT_BASE_MERGE
-      SVN_ERR(queue_install_props(db, local_abspath, kind,
-                                  new_base_props, new_actual_props,
-                                  base_merge, pool));
+      {
+        svn_wc__db_status_t status;
+        svn_boolean_t have_base;
+        apr_array_header_t *prop_diffs;
+
+        SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL,
+                                     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                     &have_base, NULL, NULL, NULL,
+                                     db, local_abspath, pool, pool));
+
+        if (status == svn_wc__db_status_added)
+          SVN_ERR(svn_wc__db_temp_working_set_props(db, local_abspath,
+                                                    new_base_props, pool));
+        else
+          SVN_ERR(svn_wc__db_temp_base_set_props(db, local_abspath,
+                                                 new_base_props, pool));
+
+        /* Check if the props are modified. */
+        SVN_ERR(svn_prop_diffs(&prop_diffs, actual_props, new_base_props, pool));
+
+        /* Save the actual properties file if it differs from base. */
+        if (prop_diffs->nelts == 0)
+          SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, NULL, NULL, NULL,
+                                          pool));
+        else
+          SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props,
+                                          NULL, NULL, pool));
+      }
 #else
       if (base_merge)
         return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
@@ -738,8 +383,6 @@ svn_wc__perform_props_merge(svn_wc_notif
 
       {
         apr_array_header_t *prop_diffs;
-        const char *props_abspath;
-        svn_skel_t *work_item;
 
         SVN_ERR(svn_prop_diffs(&prop_diffs, new_actual_props, new_base_props,
                                pool));
@@ -751,16 +394,11 @@ svn_wc__perform_props_merge(svn_wc_notif
         /* For the old school: write the properties into the "working"
            (aka ACTUAL) location. Note that PROPS may be NULL, indicating
            a removal of the props file.  */
-        SVN_ERR(svn_wc__prop_path(&props_abspath, local_abspath, kind,
-                                  svn_wc__props_working, pool));
-        SVN_ERR(svn_wc__wq_build_write_old_props(&work_item,
-                                                 props_abspath,
-                                                 new_actual_props,
-                                                 pool));
 
         SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, new_actual_props,
                                         NULL /* conflict */,
-                                        work_item, pool));
+                                        NULL /* work_item */,
+                                        pool));
       }
 #endif
 
@@ -1962,7 +1600,7 @@ svn_wc__merge_props(svn_wc_notify_state_
               reject_filename = SVN_WC__THIS_DIR_PREJ;
             }
           else
-            svn_dirent_split(local_abspath, &reject_dirpath, &reject_filename,
+            svn_dirent_split(&reject_dirpath, &reject_filename, local_abspath,
                              scratch_pool);
 
           SVN_ERR(svn_io_open_uniquely_named(NULL, &reject_path,
@@ -2055,8 +1693,8 @@ svn_wc__get_actual_props(apr_hash_t **pr
   /* ### perform some state checking. for example, locally-deleted nodes
      ### should not have any ACTUAL props.  */
 
-  return svn_error_return(load_actual_props(props, db, local_abspath,
-                                            result_pool, scratch_pool));
+  return svn_error_return(svn_wc__db_read_props(props, db, local_abspath,
+                                                result_pool, scratch_pool));
 }
 
 
@@ -2120,30 +1758,11 @@ svn_wc__get_pristine_props(apr_hash_t **
       return SVN_NO_ERROR;
     }
 
-  /* The node is obstructed:
-
-     - subdir is missing, obstructed by a file, or missing admin area
-     - a file is obstructed by a versioned subdir   (### not reported)
-
-     Thus, properties are not available for this node. Returning NULL
-     would indicate "not defined" for its state. For obstructions, we
-     cannot *determine* whether properties should be here or not.
-
-     ### it would be nice to report an obstruction, rather than simply
-     ### PROPERTY_NOT_FOUND. but this is transitional until single-db.  */
-  if (status == svn_wc__db_status_obstructed_delete
-      || status == svn_wc__db_status_obstructed
-      || status == svn_wc__db_status_obstructed_add)
-    return svn_error_createf(SVN_ERR_PROPERTY_NOT_FOUND, NULL,
-                             U_("Directory '%s' is missing on disk, so the "
-                                "properties are not available."),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-
   /* status: normal, moved_here, copied, deleted  */
 
   /* After the above checks, these pristines should always be present.  */
-  return svn_error_return(load_pristine_props(props, db, local_abspath,
+  return svn_error_return(
+               svn_wc__db_read_pristine_props(props, db, local_abspath,
                                               result_pool, scratch_pool));
 }
 
@@ -2198,22 +1817,12 @@ svn_wc__internal_propget(const svn_strin
 {
   apr_hash_t *prophash = NULL;
   enum svn_prop_kind kind = svn_property_kind(NULL, name);
-  svn_wc__db_kind_t wc_kind;
   svn_boolean_t hidden;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(kind != svn_prop_entry_kind);
 
-  SVN_ERR(svn_wc__db_read_kind(&wc_kind, db, local_abspath, TRUE, scratch_pool));
-
-  if (wc_kind == svn_wc__db_kind_unknown)
-    {
-      /* The node is not present, or not really "here". Therefore, the
-         property is not present.  */
-      *value = NULL;
-      return SVN_NO_ERROR;
-    }
-
+  /* This returns SVN_ERR_WC_PATH_NOT_FOUND for unversioned paths for us */
   SVN_ERR(svn_wc__db_node_hidden(&hidden, db, local_abspath, scratch_pool));
   if (hidden)
     {
@@ -2236,14 +1845,14 @@ svn_wc__internal_propget(const svn_strin
           svn_error_clear(err);
           return SVN_NO_ERROR;
         }
-      SVN_ERR_W(err, _("Failed to load properties from disk"));
+      SVN_ERR_W(err, _("Failed to load properties"));
     }
   else
     {
       /* regular prop */
       SVN_ERR_W(svn_wc__get_actual_props(&prophash, db, local_abspath,
                                          result_pool, scratch_pool),
-                _("Failed to load properties from disk"));
+                _("Failed to load properties"));
     }
 
   if (prophash)
@@ -2404,13 +2013,39 @@ svn_wc__internal_propset(svn_wc__db_t *d
   enum svn_prop_kind prop_kind = svn_property_kind(NULL, name);
   svn_wc_notify_action_t notify_action;
   svn_wc__db_kind_t kind;
+  svn_wc__db_status_t status;
+  const char *dir_abspath;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
+  /* Get the node kind for this path. */
+  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL,
+                               db, local_abspath,
+                               scratch_pool, scratch_pool));
+
+  if (kind == svn_wc__db_kind_dir)
+    dir_abspath = local_abspath;
+  else
+    dir_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+
+  SVN_ERR(svn_wc__write_check(db, dir_abspath, scratch_pool));
+
   if (prop_kind == svn_prop_wc_kind)
     return svn_error_return(wcprop_set(db, local_abspath, name, value,
                                        scratch_pool));
 
+  if (status != svn_wc__db_status_normal
+      && status != svn_wc__db_status_added
+      && status != svn_wc__db_status_incomplete)
+    return svn_error_createf(SVN_ERR_WC_INVALID_SCHEDULE, NULL,
+                             _("Can't set properties on '%s':"
+                               " invalid status for updating properties."),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
   /* we don't do entry properties here */
   if (prop_kind == svn_prop_entry_kind)
     return svn_error_createf(SVN_ERR_BAD_PROP_KIND, NULL,
@@ -2418,13 +2053,6 @@ svn_wc__internal_propset(svn_wc__db_t *d
 
   /* Else, handle a regular property: */
 
-  /* Get the node kind for this path. */
-  SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL,
-                               db, local_abspath,
-                               scratch_pool, scratch_pool));
 
   /* Setting an inappropriate property is not allowed (unless
      overridden by 'skip_checks', in some circumstances).  Deleting an
@@ -2474,8 +2102,8 @@ svn_wc__internal_propset(svn_wc__db_t *d
       /* If not, we'll set the file to read-only at commit time. */
     }
 
-  SVN_ERR_W(load_actual_props(&prophash, db, local_abspath,
-                              scratch_pool, scratch_pool),
+  SVN_ERR_W(svn_wc__db_read_props(&prophash, db, local_abspath,
+                                  scratch_pool, scratch_pool),
             _("Failed to load current properties"));
 
   /* If we're changing this file's list of expanded keywords, then
@@ -2492,12 +2120,19 @@ svn_wc__internal_propset(svn_wc__db_t *d
                                              APR_HASH_KEY_STRING);
       apr_hash_t *old_keywords, *new_keywords;
 
-      SVN_ERR(svn_wc__get_keywords(&old_keywords, db, local_abspath,
-                                   old_value ? old_value->data : "",
-                                   scratch_pool, scratch_pool));
-      SVN_ERR(svn_wc__get_keywords(&new_keywords, db, local_abspath,
-                                   value ? value->data : "",
-                                   scratch_pool, scratch_pool));
+      if (old_value)
+        SVN_ERR(svn_wc__expand_keywords(&old_keywords,
+                                        db, local_abspath, old_value->data,
+                                        scratch_pool, scratch_pool));
+      else
+        old_keywords = apr_hash_make(scratch_pool);
+
+      if (value)
+        SVN_ERR(svn_wc__expand_keywords(&new_keywords,
+                                        db, local_abspath, value->data,
+                                        scratch_pool, scratch_pool));
+      else
+        new_keywords = apr_hash_make(scratch_pool);
 
       if (svn_subst_keywords_differ2(old_keywords, new_keywords, FALSE,
                                      scratch_pool))
@@ -2614,7 +2249,8 @@ svn_wc_canonicalize_svn_prop(const svn_s
       svn_subst_eol_style_from_value(&eol_style, &ignored_eol, new_value->data);
       if (eol_style == svn_subst_eol_style_unknown)
         return svn_error_createf(SVN_ERR_IO_UNKNOWN_EOL, NULL,
-                                 _("Unrecognized line ending style for '%s'"),
+                                 _("Unrecognized line ending style '%s' for '%s'"),
+                                 new_value->data,
                                  svn_dirent_local_style(path, pool));
       SVN_ERR(validate_eol_prop_against_file(path, getter, getter_baton,
                                              pool));
@@ -2632,7 +2268,7 @@ svn_wc_canonicalize_svn_prop(const svn_s
       if (propval->data[propval->len - 1] != '\n')
         {
           new_value = svn_stringbuf_create_from_string(propval, pool);
-          svn_stringbuf_appendbytes(new_value, "\n", 1);
+          svn_stringbuf_appendbyte(new_value, '\n');
         }
 
       /* Make sure this is a valid externals property.  Do not
@@ -2718,77 +2354,28 @@ svn_wc__props_modified(svn_boolean_t *mo
                        const char *local_abspath,
                        apr_pool_t *scratch_pool)
 {
-  apr_array_header_t *local_propchanges;
-  apr_hash_t *localprops;
-  apr_hash_t *baseprops;
-  svn_wc__db_status_t status;
-  svn_error_t *err;
-
-  err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL,
-                             db, local_abspath,
-                             scratch_pool, scratch_pool);
-
-  /* If we have no entry, we can't have any prop mods. */
-  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-    {
-      *modified_p = FALSE;
-      svn_error_clear(err);
-      return SVN_NO_ERROR;
-    }
-  else if (err)
-    return err;
-
-  SVN_ERR(load_actual_props(&localprops, db, local_abspath,
-                            scratch_pool, scratch_pool));
-  SVN_ERR_ASSERT(localprops != NULL);
-
-  /* ### this should not apply nowadays. especially if
-                            (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB)  */
-#if 0
-  {
-    svn_boolean_t replaced;
-
-    /* If something is scheduled for replacement, we do *not* want to
-       pay attention to any base-props;  they might be residual from the
-       old deleted file. */
-    /* ### in modern WC formats, they should be the replaced file's
-       ### base props. hard to know on old WCs tho? (given the above
-       ### comment). just declare propmods if the node has any working
-       ### properties. */
-    SVN_ERR(svn_wc__internal_is_replaced(&replaced, db, local_abspath,
-                                         scratch_pool));
-    if (replaced)
-      {
-        *modified_p = apr_hash_count(localprops) > 0;
-        return SVN_NO_ERROR;
-      }
-  }
-#endif
-
-  /* The WORKING props are present, so let's dig in and see what the
-     differences are. On really old WCs, they might be the same. On
-     newer WCs, the file would have been removed if there was no delta. */
-  SVN_ERR(load_pristine_props(&baseprops, db, local_abspath,
-                              scratch_pool, scratch_pool));
-  if (baseprops == NULL)
-    {
-      /* No pristines are defined. Let's say mods exist if there are any
-         ACTUAL props on this node.  */
-      *modified_p = apr_hash_count(localprops) > 0;
-      return SVN_NO_ERROR;
-    }
-
-  SVN_ERR(svn_prop_diffs(&local_propchanges, localprops, baseprops,
-                         scratch_pool));
-
-  *modified_p = (local_propchanges->nelts > 0);
+  SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, modified_p,
+                               NULL, NULL, NULL, NULL,
+                               db, local_abspath,
+                               scratch_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_wc_props_modified_p2(svn_boolean_t *modified_p,
+                         svn_wc_context_t* wc_ctx,
+                         const char *local_abspath,
+                         apr_pool_t *scratch_pool)
+{
+  return svn_error_return(
+             svn_wc__props_modified(modified_p,
+                                    wc_ctx->db,
+                                    local_abspath,
+                                    scratch_pool));
+}
 
 svn_error_t *
 svn_wc__internal_propdiff(apr_array_header_t **propchanges,
@@ -2804,8 +2391,8 @@ svn_wc__internal_propdiff(apr_array_head
 
   /* ### if pristines are not defined, then should this raise an error,
      ### or use an empty set?  */
-  SVN_ERR(load_pristine_props(&baseprops, db, local_abspath,
-                              result_pool, scratch_pool));
+  SVN_ERR(svn_wc__db_read_pristine_props(&baseprops, db, local_abspath,
+                                         result_pool, scratch_pool));
 
   if (original_props != NULL)
     *original_props = baseprops;
@@ -2819,8 +2406,8 @@ svn_wc__internal_propdiff(apr_array_head
       if (baseprops == NULL)
         baseprops = apr_hash_make(scratch_pool);
 
-      SVN_ERR(load_actual_props(&actual_props, db, local_abspath,
-                                result_pool, scratch_pool));
+      SVN_ERR(svn_wc__db_read_props(&actual_props, db, local_abspath,
+                                    result_pool, scratch_pool));
       /* ### be wary. certain nodes don't have ACTUAL props either. we
          ### may want to raise an error. or maybe that is a deletion of
          ### any potential pristine props?  */

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_wc/props.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_wc/props.h?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_wc/props.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_wc/props.h Wed Sep 15 19:32:26 2010
@@ -49,15 +49,6 @@ extern "C" {
 */
 #undef SVN__SUPPORT_BASE_MERGE
 
-
-typedef enum svn_wc__props_kind_t
-{
-  svn_wc__props_base = 0,
-  svn_wc__props_revert,
-  svn_wc__props_working
-} svn_wc__props_kind_t;
-
-
 /* Internal function for diffing props. See svn_wc_get_prop_diffs2(). */
 svn_error_t *
 svn_wc__internal_propdiff(apr_array_header_t **propchanges,
@@ -148,14 +139,6 @@ svn_wc__merge_props(svn_wc_notify_state_
    changing the working file. */
 svn_boolean_t svn_wc__has_magic_property(const apr_array_header_t *properties);
 
-
-/* Delete PROPS_KIND props for LOCAL_ABSPATH */
-svn_error_t *
-svn_wc__props_delete(svn_wc__db_t *db,
-                     const char *local_abspath,
-                     svn_wc__props_kind_t props_kind,
-                     apr_pool_t *pool);
-
 /* Set *MODIFIED_P TRUE if the props for LOCAL_ABSPATH have been modified. */
 svn_error_t *
 svn_wc__props_modified(svn_boolean_t *modified_p,
@@ -163,13 +146,6 @@ svn_wc__props_modified(svn_boolean_t *mo
                        const char *local_abspath,
                        apr_pool_t *scratch_pool);
 
-/* Install LOCAL_ABSPATHs working props as base props. */
-svn_error_t *
-svn_wc__working_props_committed(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                apr_pool_t *scratch_pool);
-
-
 /* Internal version of svn_wc_get_pristine_props().  */
 svn_error_t *
 svn_wc__get_pristine_props(apr_hash_t **props,
@@ -187,17 +163,6 @@ svn_wc__get_actual_props(apr_hash_t **pr
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool);
 
-
-/* Load the revert props for ENTRY at PATH returning them in *REVERT_PROPS_P.
-   Returned hash/values are allocated in RESULT_POOL. All temporary
-   allocations are made in SCRATCH_POOL.  */
-svn_error_t *
-svn_wc__get_revert_props(apr_hash_t **revert_props_p,
-                         svn_wc__db_t *db,
-                         const char *local_abspath,
-                         apr_pool_t *result_pool,
-                         apr_pool_t *scratch_pool);
-
 /* Set *MARKED to indicate whether the versioned file at LOCAL_ABSPATH in DB
  * has a "binary" file type, as indicated by its working svn:mime-type
  * property. See svn_mime_type_is_binary() for the interpretation. */

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_wc/questions.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_wc/questions.c Wed Sep 15 19:32:26 2010
@@ -114,13 +114,11 @@ compare_and_verify(svn_boolean_t *modifi
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(versioned_file_abspath));
 
-  SVN_ERR(svn_wc__get_eol_style(&eol_style, &eol_str, db,
-                                versioned_file_abspath, scratch_pool,
-                                scratch_pool));
-  SVN_ERR(svn_wc__get_keywords(&keywords, db, versioned_file_abspath, NULL,
-                               scratch_pool, scratch_pool));
-  SVN_ERR(svn_wc__get_special(&special, db, versioned_file_abspath,
-                              scratch_pool));
+  SVN_ERR(svn_wc__get_translate_info(&eol_style, &eol_str,
+                                     &keywords,
+                                     &special,
+                                     db, versioned_file_abspath,
+                                     scratch_pool, scratch_pool));
 
   need_translation = svn_subst_translation_required(eol_style, eol_str,
                                                     keywords, special, TRUE);
@@ -233,39 +231,19 @@ svn_error_t *
 svn_wc__internal_versioned_file_modcheck(svn_boolean_t *modified_p,
                                          svn_wc__db_t *db,
                                          const char *versioned_file_abspath,
-                                         const char *base_file_abspath,
+                                         svn_stream_t *pristine_stream,
                                          svn_boolean_t compare_textbases,
                                          apr_pool_t *scratch_pool)
 {
-  svn_stream_t *pristine_stream;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(base_file_abspath));
-  SVN_ERR(svn_stream_open_readonly(&pristine_stream, base_file_abspath,
-                                   scratch_pool, scratch_pool));
-
   return svn_error_return(compare_and_verify(modified_p, db,
                                              versioned_file_abspath,
                                              pristine_stream,
                                              compare_textbases,
-                                             FALSE,
+                                             FALSE /* verify_checksum */,
                                              scratch_pool));
 }
 
 svn_error_t *
-svn_wc__versioned_file_modcheck(svn_boolean_t *modified_p,
-                                svn_wc_context_t *wc_ctx,
-                                const char *versioned_file_abspath,
-                                const char *base_file_abspath,
-                                apr_pool_t *scratch_pool)
-{
-  return svn_error_return(svn_wc__internal_versioned_file_modcheck(
-                            modified_p, wc_ctx->db, versioned_file_abspath,
-                            base_file_abspath,
-                            TRUE /* compare_textbases */,
-                            scratch_pool));
-}
-
-svn_error_t *
 svn_wc__internal_text_modified_p(svn_boolean_t *modified_p,
                                  svn_wc__db_t *db,
                                  const char *local_abspath,

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_wc/relocate.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_wc/relocate.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_wc/relocate.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_wc/relocate.c Wed Sep 15 19:32:26 2010
@@ -30,8 +30,6 @@
 #include "svn_path.h"
 
 #include "wc.h"
-#include "entries.h"
-#include "lock.h"
 #include "props.h"
 
 #include "svn_private_config.h"
@@ -120,7 +118,7 @@ svn_wc_relocate4(svn_wc_context_t *wc_ct
      and that only for DAV RA implementations that rely on the DAV
      cache. */
   SVN_ERR(svn_wc__db_global_relocate(wc_ctx->db, local_abspath, new_repos_root,
-                                     FALSE, scratch_pool));
+                                     scratch_pool));
 
   if (!recurse)
     {

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_wc/revision_status.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_wc/revision_status.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_wc/revision_status.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_wc/revision_status.c Wed Sep 15 19:32:26 2010
@@ -83,9 +83,7 @@ analyze_status(const char *local_abspath
       return SVN_NO_ERROR;
     }
   else if (status == svn_wc__db_status_added
-           || status == svn_wc__db_status_obstructed_add
-           || status == svn_wc__db_status_deleted
-           || status == svn_wc__db_status_obstructed_delete)
+           || status == svn_wc__db_status_deleted)
     {
       wb->result->modified = TRUE; 
     }

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_wc/status.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_wc/status.c Wed Sep 15 19:32:26 2010
@@ -45,7 +45,6 @@
 #include "svn_private_config.h"
 
 #include "wc.h"
-#include "lock.h"
 #include "props.h"
 #include "entries.h"
 #include "translate.h"
@@ -241,20 +240,20 @@ internal_status(svn_wc_status3_t **statu
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool);
 
-/* Fill in *STATUS for LOCAL_ABSPATH, whose entry data is available in DB.
-   Allocate *STATUS in RESULT_POOL.  Use SCRATCH_POOL for temporary
-   allocations.
+/* Fill in *STATUS for LOCAL_ABSPATH, using DB. Allocate *STATUS in
+   RESULT_POOL and use SCRATCH_POOL for temporary allocations.
 
    PARENT_REPOS_ROOT_URL and PARENT_REPOS_RELPATH are the the repository root
    and repository relative path of the parent of LOCAL_ABSPATH or NULL if
    LOCAL_ABSPATH doesn't have a versioned parent directory.
 
-   PATH_KIND is the node kind of LOCAL_ABSPATH as determined by the caller.
-   PATH_SPECIAL indicates whether the entry is a special file.
+   DIRENT is the local representation of LOCAL_ABSPATH in the working copy or
+   NULL if the node does not exist on disk.
 
-   If GET_ALL is zero, and ENTRY is not locally modified, then *STATUS
-   will be set to NULL.  If GET_ALL is non-zero, then *STATUS will be
+   If GET_ALL is FALSE, and LOCAL_ABSPATH is not locally modified, then
+   *STATUS will be set to NULL.  If GET_ALL is non-zero, then *STATUS will be
    allocated and returned no matter what.
+
    The status struct's repos_lock field will be set to REPOS_LOCK.
 */
 static svn_error_t *
@@ -263,8 +262,7 @@ assemble_status(svn_wc_status3_t **statu
                 const char *local_abspath,
                 const char *parent_repos_root_url,
                 const char *parent_repos_relpath,
-                svn_node_kind_t path_kind,
-                svn_boolean_t path_special,
+                const svn_io_dirent2_t *dirent,
                 svn_boolean_t get_all,
                 const svn_lock_t *repos_lock,
                 apr_pool_t *result_pool,
@@ -286,6 +284,8 @@ assemble_status(svn_wc_status3_t **statu
   svn_boolean_t have_base;
   svn_boolean_t conflicted;
   svn_boolean_t copied = FALSE;
+  svn_filesize_t translated_size;
+  apr_time_t last_mod_time;
   svn_depth_t depth;
   svn_error_t *err;
 
@@ -297,9 +297,9 @@ assemble_status(svn_wc_status3_t **statu
   SVN_ERR(svn_wc__db_read_info(&db_status, &db_kind, &revision,
                                &repos_relpath, &repos_root_url, NULL,
                                &changed_rev, &changed_date,
-                               &changed_author, NULL, &depth, NULL, NULL,
-                               NULL, &changelist, NULL, NULL, NULL, NULL,
-                               &prop_modified_p, &have_base, NULL,
+                               &changed_author, &last_mod_time, &depth, NULL,
+                               &translated_size, NULL, &changelist, NULL, NULL,
+                               NULL, NULL, &prop_modified_p, &have_base, NULL,
                                &conflicted, &lock, db, local_abspath,
                                result_pool, scratch_pool));
 
@@ -339,24 +339,14 @@ assemble_status(svn_wc_status3_t **statu
   if (!repos_root_url && parent_repos_root_url)
     repos_root_url = apr_pstrdup(result_pool, parent_repos_root_url);
 
-  /* Examine whether our directory metadata is present, and compensate
-     if it is missing.
-
-     There are a several kinds of obstruction that we detect here:
-
-     - versioned subdir is missing
-     - the versioned subdir's admin area is missing
-     - the versioned subdir has been replaced with a file/symlink
-
-     Net result: the target is obstructed and the metadata is unavailable.
-
-     Note: wc_db can also detect a versioned file that has been replaced
-     with a versioned subdir (moved from somewhere). We don't look for
-     that right away because the file's metadata is still present, so we
-     can examine properties and conflicts and whatnot.
+  /* Examine whether our target is missing or obstructed or missing.
 
-     ### note that most obstruction concepts disappear in single-db mode
-  */
+     While we are not completely in single-db mode yet, data about
+     obstructed or missing nodes might be incomplete here. This is
+     reported by svn_wc_db_status_obstructed_XXXX. In single-db
+     mode these obstructions are no longer reported and we have
+     to detect obstructions by looking at the on disk status in DIRENT.
+     */
   if (db_kind == svn_wc__db_kind_dir)
     {
       if (db_status == svn_wc__db_status_incomplete)
@@ -364,36 +354,39 @@ assemble_status(svn_wc_status3_t **statu
           /* Highest precedence.  */
           node_status = svn_wc_status_incomplete;
         }
-      else if (db_status == svn_wc__db_status_obstructed_delete)
+      else if (db_status == svn_wc__db_status_deleted)
         {
-          /* Deleted directories are never reported as missing.  */
-          if (path_kind == svn_node_none)
-            node_status = svn_wc_status_deleted;
-          else
-            node_status = svn_wc_status_obstructed;
+          node_status = svn_wc_status_deleted;
+
+          SVN_ERR(svn_wc__internal_node_get_schedule(NULL, &copied,
+                                                     db, local_abspath,
+                                                     scratch_pool));
         }
-      else if (db_status == svn_wc__db_status_obstructed
-               || db_status == svn_wc__db_status_obstructed_add)
+      else if (!dirent || dirent->kind != svn_node_dir)
         {
           /* A present or added directory should be on disk, so it is
              reported missing or obstructed.  */
-          if (path_kind == svn_node_none)
+          if (!dirent || dirent->kind == svn_node_none)
             node_status = svn_wc_status_missing;
           else
             node_status = svn_wc_status_obstructed;
         }
-      else if (db_status == svn_wc__db_status_deleted)
-        node_status = svn_wc_status_deleted;
     }
   else
     {
       if (db_status == svn_wc__db_status_deleted)
-        node_status = svn_wc_status_deleted;
-      else if (path_kind != svn_node_file)
+        {
+          node_status = svn_wc_status_deleted;
+
+          SVN_ERR(svn_wc__internal_node_get_schedule(NULL, &copied,
+                                                     db, local_abspath,
+                                                     scratch_pool));
+        }
+      else if (!dirent || dirent->kind != svn_node_file)
         {
           /* A present or added file should be on disk, so it is
              reported missing or obstructed.  */
-          if (path_kind == svn_node_none)
+          if (!dirent || dirent->kind == svn_node_none)
             node_status = svn_wc_status_missing;
           else
             node_status = svn_wc_status_obstructed;
@@ -430,72 +423,72 @@ assemble_status(svn_wc_status3_t **statu
         {
           apr_hash_t *props;
         
-          SVN_ERR(svn_wc__get_pristine_props(&props, db, local_abspath,
-                                             scratch_pool, scratch_pool));
-        
-          if (props != NULL && apr_hash_count(props) > 0)
-            has_props = TRUE;
-          else
-            {
-              SVN_ERR(svn_wc__get_actual_props(&props, db, local_abspath,
-                                               scratch_pool, scratch_pool));
+          SVN_ERR(svn_wc__db_read_pristine_props(&props, db, local_abspath,
+                                                 scratch_pool, scratch_pool));
 
-              has_props = (props != NULL && apr_hash_count(props) > 0);
-            }
+          has_props = (props != NULL && apr_hash_count(props) > 0);
         }
       if (has_props)
         prop_status = svn_wc_status_normal;
 
-      /* If the entry has a property file, see if it has local changes. */
-      /* ### we could compute this ourself, based on the prop hashes
-         ### fetched above. but for now, there is some trickery we may
-         ### need to rely upon in ths function. keep it for now.  */
-      /* ### see r944980 as an example of the brittleness of this stuff.  */
+      /* If the entry has a properties, see if it has local changes. */
       if (has_props)
-        {
-#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
-          SVN_ERR(svn_wc__props_modified(&prop_modified_p, db, local_abspath,
-                                         scratch_pool));
-#endif
-          prop_status = prop_modified_p ? svn_wc_status_modified
-                                        : svn_wc_status_normal;
-        }
+        prop_status = prop_modified_p ? svn_wc_status_modified
+                                      : svn_wc_status_normal;
 
 #ifdef HAVE_SYMLINK
       if (has_props)
-        SVN_ERR(svn_wc__get_special(&wc_special, db, local_abspath,
-                                    scratch_pool));
+        SVN_ERR(svn_wc__get_translate_info(NULL, NULL, NULL,
+                                           &wc_special,
+                                           db, local_abspath,
+                                           scratch_pool, scratch_pool));
       else
         wc_special = FALSE;
 #endif /* HAVE_SYMLINK */
 
       /* If the entry is a file, check for textual modifications */
-      if ((db_kind == svn_wc__db_kind_file
-           || db_kind == svn_wc__db_kind_symlink)
+      if (node_status != svn_wc_status_missing
+          && (db_kind == svn_wc__db_kind_file
+              || db_kind == svn_wc__db_kind_symlink)
 #ifdef HAVE_SYMLINK
-          && (wc_special == path_special)
+             && (wc_special == (dirent && dirent->special))
 #endif /* HAVE_SYMLINK */
           )
         {
-          err = svn_wc__internal_text_modified_p(&text_modified_p,
-                                                 db, local_abspath,
-                                                 FALSE, TRUE,
-                                                 scratch_pool);
-
-          if (err)
+          /* If the on-disk dirent exactly matches the expected state
+             skip all operations in svn_wc__internal_text_modified_p()
+             to avoid an extra filestat for every file, which can be
+             expensive on network drives as a filestat usually can't
+             be cached there */
+          if (dirent
+              && dirent->filesize != SVN_INVALID_FILESIZE
+              && dirent->mtime != 0
+              && translated_size == dirent->filesize
+              && last_mod_time == dirent->mtime)
+            text_modified_p = FALSE;
+          else
             {
-              if (!APR_STATUS_IS_EACCES(err->apr_err))
-                return svn_error_return(err);
+              err = svn_wc__internal_text_modified_p(&text_modified_p,
+                                                     db, local_abspath,
+                                                     FALSE, TRUE,
+                                                     scratch_pool);
+
+              if (err)
+                {
+                  if (!APR_STATUS_IS_EACCES(err->apr_err))
+                    return svn_error_return(err);
 
-              /* An access denied is very common on Windows when another
-                 application has the file open.  Previously we ignored
-                 this error in svn_wc__text_modified_internal_p, where it
-                 should have really errored. */
-              svn_error_clear(err);
+                  /* An access denied is very common on Windows when another
+                     application has the file open.  Previously we ignored
+                     this error in svn_wc__text_modified_internal_p, where it
+                     should have really errored. */
+                  svn_error_clear(err);
+                  text_modified_p = TRUE;
+                }
             }
         }
 #ifdef HAVE_SYMLINK
-      else if ( wc_special != path_special)
+      else if (wc_special != (dirent && dirent->special))
         node_status = svn_wc_status_obstructed;
 #endif /* HAVE_SYMLINK */
 
@@ -503,18 +496,7 @@ assemble_status(svn_wc_status3_t **statu
         text_status = svn_wc_status_modified;
     }
 
-  /* While tree conflicts aren't stored on the node themselves, check
-     explicitly for tree conflicts to allow our users to ignore this detail */
-  if (!conflicted)
-    {
-      svn_wc_conflict_description2_t *tree_conflict;
-
-      SVN_ERR(svn_wc__db_op_read_tree_conflict(&tree_conflict, db, local_abspath,
-                                              scratch_pool, scratch_pool));
-
-      conflicted = (tree_conflict != NULL);
-    }
-  else
+  if (conflicted)
     {
       svn_boolean_t text_conflicted, prop_conflicted, tree_conflicted;
 
@@ -535,28 +517,16 @@ assemble_status(svn_wc_status3_t **statu
             of medium precedence.  They also override any C or M that may
             be in the prop_status field at this point, although they do not
             override a C text status.*/
-
-      /* ### db_status, base_shadowed, and fetching base_status can
-         ### fully replace entry->schedule here.  */
-
       if (db_status == svn_wc__db_status_added)
         {
-          const svn_wc_entry_t *entry;
+          svn_wc_schedule_t schedule;
+          SVN_ERR(svn_wc__internal_node_get_schedule(&schedule, &copied,
+                                                     db, local_abspath,
+                                                     scratch_pool));
 
-          err = svn_wc__get_entry(&entry, db, local_abspath, FALSE,
-                                  svn_node_unknown, FALSE, result_pool,
-                                  scratch_pool);
-
-          if (err && err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND)
-            svn_error_clear(err);
-          else
-            SVN_ERR(err);
-
-          copied = entry->copied;
-
-          if (entry->schedule == svn_wc_schedule_add)
+          if (schedule == svn_wc_schedule_add)
             node_status = svn_wc_status_added;
-          else if (entry->schedule == svn_wc_schedule_replace)
+          else if (schedule == svn_wc_schedule_replace)
             node_status = svn_wc_status_replaced;
         }
     }
@@ -729,8 +699,7 @@ send_status_structure(const struct walk_
                       const char *local_abspath,
                       const char *parent_repos_root_url,
                       const char *parent_repos_relpath,
-                      svn_node_kind_t path_kind,
-                      svn_boolean_t path_special,
+                      const svn_io_dirent2_t *dirent,
                       svn_boolean_t get_all,
                       svn_wc_status_func4_t status_func,
                       void *status_baton,
@@ -779,7 +748,7 @@ send_status_structure(const struct walk_
 
   SVN_ERR(assemble_status(&statstruct, wb->db, local_abspath,
                           parent_repos_root_url, parent_repos_relpath,
-                          path_kind, path_special, get_all,
+                          dirent, get_all,
                           repos_lock, scratch_pool, scratch_pool));
 
   if (statstruct && status_func)
@@ -937,14 +906,15 @@ send_unversioned_item(const struct walk_
 static svn_error_t *
 get_dir_status(const struct walk_status_baton *wb,
                const char *local_abspath,
+               const char *selected,
+               svn_boolean_t skip_this_dir,
                const char *parent_repos_root_url,
                const char *parent_repos_relpath,
-               const char *selected,
+               const svn_io_dirent2_t *dirent,
                const apr_array_header_t *ignores,
                svn_depth_t depth,
                svn_boolean_t get_all,
                svn_boolean_t no_ignore,
-               svn_boolean_t skip_this_dir,
                svn_wc_status_func4_t status_func,
                void *status_baton,
                svn_cancel_func_t cancel_func,
@@ -961,8 +931,7 @@ handle_dir_entry(const struct walk_statu
                  svn_wc__db_kind_t db_kind,
                  const char *dir_repos_root_url,
                  const char *dir_repos_relpath,
-                 svn_node_kind_t path_kind,
-                 svn_boolean_t path_special,
+                 svn_io_dirent2_t *dirent,
                  const apr_array_header_t *ignores,
                  svn_depth_t depth,
                  svn_boolean_t get_all,
@@ -973,24 +942,28 @@ handle_dir_entry(const struct walk_statu
                  void *cancel_baton,
                  apr_pool_t *pool)
 {
-  /* We are looking at a directory on-disk.  */
-  if (path_kind == svn_node_dir
-      && db_kind == svn_wc__db_kind_dir)
+  /* We are looking at a directory on-disk.
+     With a db per directory the directory must exist to recurse, but
+     with single-db we only have to check for obstructions.
+
+     (Without recursing you would only see the root of a delete operation
+      in single db mode.)
+     ### TODO: Should we recurse on obstructions anyway?
+     ###       (Requires  changes to the test suite)
+   */
+  if (db_kind == svn_wc__db_kind_dir)
     {
       /* Descend only if the subdirectory is a working copy directory (which
          we've discovered because we got a THIS_DIR entry. And only descend
          if DEPTH permits it, of course.  */
 
-      if (status != svn_wc__db_status_obstructed
-          && status != svn_wc__db_status_obstructed_add
-          && status != svn_wc__db_status_obstructed_delete
-          && (depth == svn_depth_unknown
+      if ((depth == svn_depth_unknown
               || depth == svn_depth_immediates
               || depth == svn_depth_infinity))
         {
-          SVN_ERR(get_dir_status(wb, local_abspath, dir_repos_root_url,
-                                 dir_repos_relpath, NULL, ignores, depth,
-                                 get_all, no_ignore, FALSE,
+          SVN_ERR(get_dir_status(wb, local_abspath, NULL, FALSE,
+                                 dir_repos_root_url, dir_repos_relpath,
+                                 dirent, ignores, depth, get_all, no_ignore,
                                  status_func, status_baton, cancel_func,
                                  cancel_baton,
                                  pool));
@@ -1001,8 +974,8 @@ handle_dir_entry(const struct walk_statu
              directory entry but DEPTH is limiting our recursion.  */
           SVN_ERR(send_status_structure(wb, local_abspath,
                                         dir_repos_root_url,
-                                        dir_repos_relpath, svn_node_dir,
-                                        FALSE /* path_special */, get_all,
+                                        dir_repos_relpath,
+                                        dirent, get_all,
                                         status_func, status_baton, pool));
         }
     }
@@ -1011,8 +984,8 @@ handle_dir_entry(const struct walk_statu
       /* This is a file/symlink on-disk or not a directory in the db.  */
       SVN_ERR(send_status_structure(wb, local_abspath,
                                     dir_repos_root_url,
-                                    dir_repos_relpath, path_kind,
-                                    path_special, get_all,
+                                    dir_repos_relpath,
+                                    dirent, get_all,
                                     status_func, status_baton, pool));
     }
 
@@ -1082,19 +1055,23 @@ handle_externals(const struct walk_statu
    status will not be reported.  However, upon recursing, all subdirs
    *will* be reported, regardless of this parameter's value.
 
+   DIRENT is LOCAL_ABSPATH's own dirent and is only needed if it is reported,
+   so if SKIP_THIS_DIR or SELECTED is not-NULL DIRENT can be left NULL.
+
    Other arguments are the same as those passed to
    svn_wc_get_status_editor5().  */
 static svn_error_t *
 get_dir_status(const struct walk_status_baton *wb,
                const char *local_abspath,
+               const char *selected,
+               svn_boolean_t skip_this_dir,
                const char *parent_repos_root_url,
                const char *parent_repos_relpath,
-               const char *selected,
+               const svn_io_dirent2_t *dirent,
                const apr_array_header_t *ignore_patterns,
                svn_depth_t depth,
                svn_boolean_t get_all,
                svn_boolean_t no_ignore,
-               svn_boolean_t skip_this_dir,
                svn_wc_status_func4_t status_func,
                void *status_baton,
                svn_cancel_func_t cancel_func,
@@ -1109,6 +1086,7 @@ get_dir_status(const struct walk_status_
   svn_wc__db_status_t dir_status;
   svn_depth_t dir_depth;
   apr_pool_t *iterpool, *subpool = svn_pool_create(scratch_pool);
+  svn_error_t *err;
 
   /* See if someone wants to cancel this operation. */
   if (cancel_func)
@@ -1129,7 +1107,16 @@ get_dir_status(const struct walk_status_
     SVN_ERR(svn_hash_from_cstring_keys(&nodes, child_nodes, subpool));
   }
 
-  SVN_ERR(svn_io_get_dirents2(&dirents, local_abspath, subpool));
+  err = svn_io_get_dirents3(&dirents, local_abspath, FALSE, subpool, subpool);
+  if (err
+      && (APR_STATUS_IS_ENOENT(err->apr_err)
+         || SVN__APR_STATUS_IS_ENOTDIR(err->apr_err)))
+    {
+      svn_error_clear(err);
+      dirents = apr_hash_make(subpool);
+    }
+  else
+    SVN_ERR(err);
 
   SVN_ERR(svn_wc__db_read_info(&dir_status, NULL, NULL, &dir_repos_relpath,
                                &dir_repos_root_url, NULL, NULL, NULL, NULL,
@@ -1209,8 +1196,8 @@ get_dir_status(const struct walk_status_
       if (! skip_this_dir)
         SVN_ERR(send_status_structure(wb, local_abspath,
                                       parent_repos_root_url,
-                                      parent_repos_relpath, svn_node_dir,
-                                      FALSE /* path_special */, get_all,
+                                      parent_repos_relpath,
+                                      dirent, get_all,
                                       status_func, status_baton,
                                       iterpool));
 
@@ -1227,7 +1214,7 @@ get_dir_status(const struct walk_status_
       const void *key;
       apr_ssize_t klen;
       const char *node_abspath;
-      svn_io_dirent_t *dirent_p;
+      svn_io_dirent2_t *dirent_p;
 
       svn_pool_clear(iterpool);
 
@@ -1242,7 +1229,6 @@ get_dir_status(const struct walk_status_
           /* Versioned node */
           svn_wc__db_status_t node_status;
           svn_wc__db_kind_t node_kind;
-          svn_boolean_t hidden;
 
           SVN_ERR(svn_wc__db_read_info(&node_status, &node_kind, NULL, NULL,
                                    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -1250,16 +1236,9 @@ get_dir_status(const struct walk_status_
                                    NULL, NULL, NULL, NULL, NULL, NULL,
                                    wb->db, node_abspath, iterpool, iterpool));
 
-          SVN_ERR(svn_wc__db_node_hidden(&hidden, wb->db, node_abspath,
-                                         iterpool));
-
-          /* Hidden looks in the parent stubs, which should not be necessary
-             later. Also skip excluded/absent/not-present working nodes, which
-             only have an implied status via their parent. */
-          if (!hidden
+          if (node_status != svn_wc__db_status_not_present
               && node_status != svn_wc__db_status_excluded
-              && node_status != svn_wc__db_status_absent
-              && node_status != svn_wc__db_status_not_present)
+              && node_status != svn_wc__db_status_absent)
             {
               if (depth == svn_depth_files && node_kind == svn_wc__db_kind_dir)
                 continue;
@@ -1271,9 +1250,7 @@ get_dir_status(const struct walk_status_
                                        node_kind,
                                        dir_repos_root_url,
                                        dir_repos_relpath,
-                                       dirent_p ? dirent_p->kind
-                                                : svn_node_none,
-                                       dirent_p ? dirent_p->special : FALSE,
+                                       dirent_p,
                                        ignore_patterns,
                                        depth == svn_depth_infinity
                                                            ? depth
@@ -1599,8 +1576,6 @@ make_dir_baton(void **dir_baton,
      our purposes includes being an external or ignored item). */
   if (status_in_parent
       && (status_in_parent->node_status != svn_wc_status_unversioned)
-      && (status_in_parent->node_status != svn_wc_status_missing)
-      && (status_in_parent->node_status != svn_wc_status_obstructed)
       && (status_in_parent->node_status != svn_wc_status_external)
       && (status_in_parent->node_status != svn_wc_status_ignored)
       && (status_in_parent->kind == svn_node_dir)
@@ -1614,13 +1589,17 @@ make_dir_baton(void **dir_baton,
       const svn_wc_status3_t *this_dir_status;
       const apr_array_header_t *ignores = eb->ignores;
 
-      SVN_ERR(get_dir_status(&eb->wb, local_abspath,
+      SVN_ERR(get_dir_status(&eb->wb, local_abspath, NULL, TRUE,
                              status_in_parent->repos_root_url,
                              status_in_parent->repos_relpath,
-                             NULL, ignores, d->depth == svn_depth_files ?
-                             svn_depth_files : svn_depth_immediates,
-                             TRUE, TRUE, TRUE, hash_stash, d->statii, NULL,
-                             NULL, pool));
+                             NULL /* dirent */, ignores,
+                             d->depth == svn_depth_files
+                                      ? svn_depth_files
+                                      : svn_depth_immediates,
+                             TRUE, TRUE,
+                             hash_stash, d->statii,
+                             eb->cancel_func, eb->cancel_baton,
+                             pool));
 
       /* If we found a depth here, it should govern. */
       this_dir_status = apr_hash_get(d->statii, d->local_abspath,
@@ -1768,7 +1747,7 @@ handle_statii(struct edit_baton *eb,
       status_baton = &sb;
     }
 
-  /* Loop over all the statuses still in our hash, handling each one. */
+  /* Loop over all the statii still in our hash, handling each one. */
   for (hi = apr_hash_first(pool, statii); hi; hi = apr_hash_next(hi))
     {
       const char *local_abspath = svn__apr_hash_index_key(hi);
@@ -1779,18 +1758,18 @@ handle_statii(struct edit_baton *eb,
 
       /* Now, handle the status.  We don't recurse for svn_depth_immediates
          because we already have the subdirectories' statii. */
-      if (status->node_status != svn_wc_status_obstructed
-          && status->node_status != svn_wc_status_missing
-          && status->versioned && status->kind == svn_node_dir
+      if (status->versioned && status->kind == svn_node_dir
           && (depth == svn_depth_unknown
               || depth == svn_depth_infinity))
         {
           SVN_ERR(get_dir_status(&eb->wb,
-                                 local_abspath, dir_repos_root_url,
-                                 dir_repos_relpath, NULL, ignores, depth,
-                                 eb->get_all, eb->no_ignore, TRUE,
-                                 status_func, status_baton, eb->cancel_func,
-                                 eb->cancel_baton, iterpool));
+                                 local_abspath, NULL, TRUE,
+                                 dir_repos_root_url, dir_repos_relpath,
+                                 NULL /* dirent */,
+                                 ignores, depth, eb->get_all, eb->no_ignore,
+                                 status_func, status_baton,
+                                 eb->cancel_func, eb->cancel_baton,
+                                 iterpool));
         }
       if (dir_was_deleted)
         status->repos_node_status = svn_wc_status_deleted;
@@ -2027,7 +2006,8 @@ close_directory(void *dir_baton,
         was_deleted = TRUE;
 
       /* Now do the status reporting. */
-      SVN_ERR(handle_statii(eb, dir_status ? dir_status->repos_root_url : NULL,
+      SVN_ERR(handle_statii(eb,
+                            dir_status ? dir_status->repos_root_url : NULL,
                             dir_status ? dir_status->repos_relpath : NULL,
                             db->statii, was_deleted, db->depth, pool));
       if (dir_status && svn_wc__is_sendable_status(dir_status, eb->no_ignore,
@@ -2051,10 +2031,12 @@ close_directory(void *dir_baton,
               if (tgt_status->versioned
                   && tgt_status->kind == svn_node_dir)
                 {
-                  SVN_ERR(get_dir_status(&eb->wb, eb->target_abspath,
-                                         NULL, NULL, NULL, eb->ignores, 
+                  SVN_ERR(get_dir_status(&eb->wb,
+                                         eb->target_abspath, NULL, TRUE,
+                                         NULL, NULL, NULL /* dirent */,
+                                         eb->ignores,
                                          eb->default_depth,
-                                         eb->get_all, eb->no_ignore, TRUE,
+                                         eb->get_all, eb->no_ignore,
                                          eb->status_func, eb->status_baton,
                                          eb->cancel_func, eb->cancel_baton,
                                          pool));
@@ -2070,7 +2052,8 @@ close_directory(void *dir_baton,
           /* Otherwise, we report on all our children and ourself.
              Note that our directory couldn't have been deleted,
              because it is the root of the edit drive. */
-          SVN_ERR(handle_statii(eb, eb->anchor_status->repos_root_url,
+          SVN_ERR(handle_statii(eb,
+                                eb->anchor_status->repos_root_url,
                                 eb->anchor_status->repos_relpath,
                                 db->statii, FALSE, eb->default_depth, pool));
           if (svn_wc__is_sendable_status(eb->anchor_status, eb->no_ignore,
@@ -2381,8 +2364,11 @@ svn_wc_walk_status(svn_wc_context_t *wc_
                    void *cancel_baton,
                    apr_pool_t *scratch_pool)
 {
-  svn_node_kind_t kind, local_kind;
+  svn_node_kind_t kind;
   struct walk_status_baton wb;
+  const svn_io_dirent2_t *dirent;
+  const char *anchor_abspath, *target_name;
+  svn_boolean_t skip_root;
 
   wb.db = wc_ctx->db;
   wb.target_abspath = local_abspath;
@@ -2403,62 +2389,41 @@ svn_wc_walk_status(svn_wc_context_t *wc_
     }
 
   SVN_ERR(svn_wc_read_kind(&kind, wc_ctx, local_abspath, FALSE, scratch_pool));
-  SVN_ERR(svn_io_check_path(local_abspath, &local_kind, scratch_pool));
+  SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, TRUE,
+                             scratch_pool, scratch_pool));
 
-  if (kind == svn_node_file && local_kind == svn_node_file)
+  if (kind == svn_node_file && dirent->kind == svn_node_file)
     {
-      SVN_ERR(get_dir_status(&wb,
-                             svn_dirent_dirname(local_abspath, scratch_pool),
-                             NULL,
-                             NULL,
-                             svn_dirent_basename(local_abspath, NULL),
-                             ignore_patterns,
-                             depth,
-                             get_all,
-                             TRUE,
-                             TRUE,
-                             status_func,
-                             status_baton,
-                             cancel_func,
-                             cancel_baton,
-                             scratch_pool));
-    }
-  else if (kind == svn_node_dir && local_kind == svn_node_dir)
-    {
-      SVN_ERR(get_dir_status(&wb,
-                             local_abspath,
-                             NULL,
-                             NULL,
-                             NULL,
-                             ignore_patterns,
-                             depth,
-                             get_all,
-                             no_ignore,
-                             FALSE,
-                             status_func,
-                             status_baton,
-                             cancel_func,
-                             cancel_baton,
-                             scratch_pool));
+      anchor_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+      target_name = svn_dirent_basename(local_abspath, NULL);
+      skip_root = TRUE;
     }
-  else
+  else if (kind == svn_node_dir && dirent->kind == svn_node_dir)
     {
-      SVN_ERR(get_dir_status(&wb,
-                             svn_dirent_dirname(local_abspath, scratch_pool),
-                             NULL,
-                             NULL,
-                             svn_dirent_basename(local_abspath, NULL),
-                             ignore_patterns,
-                             depth,
-                             get_all,
-                             no_ignore,
-                             TRUE,
-                             status_func,
-                             status_baton,
-                             cancel_func,
-                             cancel_baton,
-                             scratch_pool));
+      anchor_abspath = local_abspath;
+      target_name = NULL;
+      skip_root = FALSE;
     }
+  else
+    {
+      anchor_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+      target_name = svn_dirent_basename(local_abspath, NULL);
+      skip_root = FALSE;
+    }
+
+  SVN_ERR(get_dir_status(&wb,
+                         anchor_abspath,
+                         target_name,
+                         skip_root,
+                         NULL, NULL, /* parent info */
+                         dirent,
+                         ignore_patterns,
+                         depth,
+                         get_all,
+                         no_ignore,
+                         status_func, status_baton,
+                         cancel_func, cancel_baton,
+                         scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -2510,9 +2475,8 @@ internal_status(svn_wc_status3_t **statu
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
 {
-  svn_node_kind_t path_kind;
+  const svn_io_dirent2_t *dirent;
   svn_wc__db_kind_t node_kind;
-  svn_boolean_t path_special;
   const char *parent_repos_relpath;
   const char *parent_repos_root_url;
   svn_wc__db_status_t node_status;
@@ -2520,8 +2484,8 @@ internal_status(svn_wc_status3_t **statu
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  SVN_ERR(svn_io_check_special_path(local_abspath, &path_kind, &path_special,
-                                    scratch_pool));
+  SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, TRUE,
+                             scratch_pool, scratch_pool));
 
   err = svn_wc__db_read_info(&node_status, &node_kind, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -2530,10 +2494,9 @@ internal_status(svn_wc_status3_t **statu
                              scratch_pool, scratch_pool);
 
   if ((err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-      || node_status == svn_wc__db_status_obstructed
-      || node_status == svn_wc__db_status_obstructed_add
-      || node_status == svn_wc__db_status_obstructed_delete
-      || node_status == svn_wc__db_status_not_present)
+      || node_status == svn_wc__db_status_not_present
+      || node_status == svn_wc__db_status_absent
+      || node_status == svn_wc__db_status_excluded)
     {
       svn_error_clear(err);
       node_kind = svn_wc__db_kind_unknown;
@@ -2541,22 +2504,10 @@ internal_status(svn_wc_status3_t **statu
   else
     SVN_ERR(err);
 
-  if (node_kind != svn_wc__db_kind_unknown)
-    {
-      svn_boolean_t hidden;
-
-      /* Check for hidden in the parent stub */
-      SVN_ERR(svn_wc__db_node_hidden(&hidden, db, local_abspath,
-                                     scratch_pool));
-
-      if (hidden)
-        node_kind = svn_wc__db_kind_unknown;
-    }
-
   if (node_kind == svn_wc__db_kind_unknown)
     return svn_error_return(assemble_unversioned(status,
                                                  db, local_abspath,
-                                                 path_kind,
+                                                 dirent->kind,
                                                  FALSE /* is_ignored */,
                                                  result_pool, scratch_pool));
 
@@ -2601,8 +2552,8 @@ internal_status(svn_wc_status3_t **statu
 
   return svn_error_return(assemble_status(status, db, local_abspath,
                                           parent_repos_root_url,
-                                          parent_repos_relpath, path_kind,
-                                          path_special,
+                                          parent_repos_relpath,
+                                          dirent,
                                           TRUE /* get_all */,
                                           NULL /* repos_lock */,
                                           result_pool, scratch_pool));

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_wc/translate.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_wc/translate.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_wc/translate.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_wc/translate.c Wed Sep 15 19:32:26 2010
@@ -43,7 +43,6 @@
 #include "adm_files.h"
 #include "translate.h"
 #include "props.h"
-#include "lock.h"
 
 #include "svn_private_config.h"
 #include "private/svn_wc_private.h"
@@ -83,7 +82,11 @@ svn_wc__internal_translated_stream(svn_s
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(svn_dirent_is_absolute(versioned_abspath));
 
-  SVN_ERR(svn_wc__get_special(&special, db, versioned_abspath, scratch_pool));
+  SVN_ERR(svn_wc__get_translate_info(&style, &eol,
+                                     &keywords,
+                                     &special,
+                                     db, versioned_abspath,
+                                     scratch_pool, scratch_pool));
 
   if (special)
     {
@@ -95,11 +98,6 @@ svn_wc__internal_translated_stream(svn_s
                                           scratch_pool);
     }
 
-  SVN_ERR(svn_wc__get_eol_style(&style, &eol, db, versioned_abspath,
-                                scratch_pool, scratch_pool));
-  SVN_ERR(svn_wc__get_keywords(&keywords, db, versioned_abspath, NULL,
-                               scratch_pool, scratch_pool));
-
   if (to_nf)
     SVN_ERR(svn_stream_open_readonly(stream, local_abspath, result_pool,
                                      scratch_pool));
@@ -152,25 +150,6 @@ svn_wc__internal_translated_stream(svn_s
 
 
 svn_error_t *
-svn_wc_translated_stream2(svn_stream_t **stream,
-                          svn_wc_context_t *wc_ctx,
-                          const char *local_abspath,
-                          const char *versioned_abspath,
-                          apr_uint32_t flags,
-                          apr_pool_t *result_pool,
-                          apr_pool_t *scratch_pool)
-{
-  return svn_error_return(svn_wc__internal_translated_stream(stream,
-                                                             wc_ctx->db,
-                                                             local_abspath,
-                                                             versioned_abspath,
-                                                             flags,
-                                                             result_pool,
-                                                             scratch_pool));
-}
-
-
-svn_error_t *
 svn_wc__internal_translated_file(const char **xlated_abspath,
                                  const char *src,
                                  svn_wc__db_t *db,
@@ -189,11 +168,11 @@ svn_wc__internal_translated_file(const c
 
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(versioned_abspath));
-  SVN_ERR(svn_wc__get_eol_style(&style, &eol, db, versioned_abspath,
-                                scratch_pool, scratch_pool));
-  SVN_ERR(svn_wc__get_keywords(&keywords, db, versioned_abspath, NULL,
-                               scratch_pool, scratch_pool));
-  SVN_ERR(svn_wc__get_special(&special, db, versioned_abspath, scratch_pool));
+  SVN_ERR(svn_wc__get_translate_info(&style, &eol,
+                                     &keywords,
+                                     &special,
+                                     db, versioned_abspath,
+                                     scratch_pool, scratch_pool));
 
   if (! svn_subst_translation_required(style, eol, keywords, special, TRUE)
       && (! (flags & SVN_WC_TRANSLATE_FORCE_COPY)))
@@ -259,48 +238,6 @@ svn_wc__internal_translated_file(const c
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_wc_translated_file3(const char **xlated_abspath,
-                        const char *src,
-                        svn_wc_context_t *wc_ctx,
-                        const char *versioned_abspath,
-                        apr_uint32_t flags,
-                        svn_cancel_func_t cancel_func,
-                        void *cancel_baton,
-                        apr_pool_t *result_pool,
-                        apr_pool_t *scratch_pool)
-{
-  return svn_wc__internal_translated_file(xlated_abspath, src, wc_ctx->db,
-                                          versioned_abspath, flags,
-                                          cancel_func, cancel_baton,
-                                          result_pool, scratch_pool);
-}
-
-
-svn_error_t *
-svn_wc__get_eol_style(svn_subst_eol_style_t *style,
-                      const char **eol,
-                      svn_wc__db_t *db,
-                      const char *local_abspath,
-                      apr_pool_t *result_pool,
-                      apr_pool_t *scratch_pool)
-{
-  const svn_string_t *propval;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  /* Get the property value. */
-  SVN_ERR(svn_wc__internal_propget(&propval, db, local_abspath,
-                                   SVN_PROP_EOL_STYLE, result_pool,
-                                   scratch_pool));
-
-  /* Convert it. */
-  svn_subst_eol_style_from_value(style, eol, propval ? propval->data : NULL);
-
-  return SVN_NO_ERROR;
-}
-
-
 void
 svn_wc__eol_value_from_string(const char **value, const char *eol)
 {
@@ -316,56 +253,82 @@ svn_wc__eol_value_from_string(const char
     *value = NULL;
 }
 
-
 svn_error_t *
-svn_wc__get_keywords(apr_hash_t **keywords,
-                     svn_wc__db_t *db,
-                     const char *local_abspath,
-                     const char *force_list,
-                     apr_pool_t *result_pool,
-                     apr_pool_t *scratch_pool)
+svn_wc__get_translate_info(svn_subst_eol_style_t *style,
+                           const char **eol,
+                           apr_hash_t **keywords,
+                           svn_boolean_t *special,
+                           svn_wc__db_t *db,
+                           const char *local_abspath,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
 {
-  const char *list;
-  svn_revnum_t changed_rev;
-  apr_time_t changed_date;
-  const char *changed_author;
-  const char *url;
-
+  apr_hash_t *props;
+  svn_string_t *propval;
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  /* Choose a property list to parse:  either the one that came into
-     this function, or the one attached to PATH. */
-  if (force_list == NULL)
-    {
-      const svn_string_t *propval;
-
-      SVN_ERR(svn_wc__internal_propget(&propval, db, local_abspath,
-                                       SVN_PROP_KEYWORDS, scratch_pool,
-                                       scratch_pool));
+  SVN_ERR(svn_wc__get_actual_props(&props, db, local_abspath,
+                                   scratch_pool, scratch_pool));
 
-      /* The easy answer. */
-      if (propval == NULL)
-        {
-          *keywords = NULL;
-          return SVN_NO_ERROR;
-        }
+  if (eol)
+    {
+      propval = props ? apr_hash_get(props, SVN_PROP_EOL_STYLE,
+                                     APR_HASH_KEY_STRING) : NULL;
 
-      list = propval->data;
+      svn_subst_eol_style_from_value(style, eol, propval ? propval->data : NULL);
+    }
+
+  if (keywords)
+    {
+      propval = props ? apr_hash_get(props, SVN_PROP_KEYWORDS,
+                                     APR_HASH_KEY_STRING) : NULL;
+
+      if (!propval || propval->len == 0)
+        *keywords = NULL;
+      else
+        SVN_ERR(svn_wc__expand_keywords(keywords,
+                                        db, local_abspath,
+                                        propval->data,
+                                        result_pool, scratch_pool));
+    }
+  if (special)
+    {
+      propval = props ? apr_hash_get(props, SVN_PROP_SPECIAL,
+                                     APR_HASH_KEY_STRING) : NULL;
+
+      *special = (propval != NULL);
     }
-  else
-    list = force_list;
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__expand_keywords(apr_hash_t **keywords,
+                        svn_wc__db_t *db,
+                        const char *local_abspath,
+                        const char *keyword_list,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool)
+{
+  svn_revnum_t changed_rev;
+  apr_time_t changed_date;
+  const char *changed_author;
+  const char *url;
 
   SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL,
                                NULL, NULL, &changed_rev,
-                               &changed_date, &changed_author, NULL, NULL,
+                               &changed_date, &changed_author, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               db, local_abspath, scratch_pool, scratch_pool));
+                               NULL,
+                               db, local_abspath,
+                               scratch_pool, scratch_pool));
+
   SVN_ERR(svn_wc__internal_node_get_url(&url, db, local_abspath,
                                         scratch_pool, scratch_pool));
 
   SVN_ERR(svn_subst_build_keywords2(keywords,
-                                    list,
+                                    keyword_list,
                                     apr_psprintf(scratch_pool, "%ld",
                                                  changed_rev),
                                     url,
@@ -379,26 +342,6 @@ svn_wc__get_keywords(apr_hash_t **keywor
   return SVN_NO_ERROR;
 }
 
-
-svn_error_t *
-svn_wc__get_special(svn_boolean_t *special,
-                    svn_wc__db_t *db,
-                    const char *local_abspath,
-                    apr_pool_t *scratch_pool)
-{
-  const svn_string_t *propval;
-
-  /* Get the property value. */
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-  SVN_ERR(svn_wc__internal_propget(&propval, db, local_abspath,
-                                   SVN_PROP_SPECIAL, scratch_pool,
-                                   scratch_pool));
-  *special = propval != NULL;
-
-  return SVN_NO_ERROR;
-}
-
-
 svn_error_t *
 svn_wc__maybe_set_executable(svn_boolean_t *did_set,
                              svn_wc__db_t *db,