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/08/10 22:56:05 UTC

svn commit: r984206 [21/35] - in /subversion/branches/ignore-mergeinfo: ./ build/ build/generator/ build/generator/templates/ build/hudson/ build/hudson/jobs/subversion-1.6.x-solaris/ build/hudson/jobs/subversion-1.6.x-ubuntu/ build/hudson/jobs/subvers...

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/props.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/props.h?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/props.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/props.h Tue Aug 10 20:55:56 2010
@@ -37,6 +37,19 @@
 extern "C" {
 #endif /* __cplusplus */
 
+/* BASE_MERGE is a pre-1.7 concept on property merging. It allowed callers
+   to alter the pristine properties *outside* of an editor drive. That is
+   very dangerous: the pristines should always correspond to something from
+   the repository, and that should only arrive through the update editor.
+
+   For 1.7, we're removing this support. Some old code is being left around
+   in case we decide to change this.
+
+   For more information, see ^/notes/api-errata/wc006.txt
+*/
+#undef SVN__SUPPORT_BASE_MERGE
+
+
 typedef enum svn_wc__props_kind_t
 {
   svn_wc__props_base = 0,
@@ -44,13 +57,6 @@ typedef enum svn_wc__props_kind_t
   svn_wc__props_working
 } svn_wc__props_kind_t;
 
-
-/* If the working item at PATH has properties attached, set HAS_PROPS. */
-svn_error_t *svn_wc__has_props(svn_boolean_t *has_props,
-                               svn_wc__db_t *db,
-                               const char *local_abspath,
-                               apr_pool_t *pool);
-
 
 /* Internal function for diffing props. See svn_wc_get_prop_diffs2(). */
 svn_error_t *
@@ -120,6 +126,7 @@ svn_wc__merge_props(svn_wc_notify_state_
                     apr_hash_t **new_actual_props,
                     svn_wc__db_t *db,
                     const char *local_abspath,
+                    svn_wc__db_kind_t kind,
                     const svn_wc_conflict_version_t *left_version,
                     const svn_wc_conflict_version_t *right_version,
                     apr_hash_t *server_baseprops,
@@ -136,34 +143,11 @@ svn_wc__merge_props(svn_wc_notify_state_
                     apr_pool_t *scratch_pool);
 
 
-/* Set a single 'wcprop' NAME to VALUE for versioned object LOCAL_ABSPATH.
-   If VALUE is null, remove property NAME.  */
-svn_error_t *svn_wc__wcprop_set(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                const char *name,
-                                const svn_string_t *value,
-                                apr_pool_t *scratch_pool);
-
 /* Given PROPERTIES is array of @c svn_prop_t structures. Returns TRUE if any
    of the PROPERTIES are the known "magic" ones that might require
    changing the working file. */
 svn_boolean_t svn_wc__has_magic_property(const apr_array_header_t *properties);
 
-/* 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. If FORCE_BASE_INSTALL properties are always installed in BASE_NODE,
-   even though WORKING is used as pristine for the current node.
-   Use SCRATCH_POOL for temporary allocations. */
-svn_error_t *
-svn_wc__install_props(svn_wc__db_t *db,
-                      const char *local_abspath,
-                      apr_hash_t *pristine_props,
-                      apr_hash_t *props,
-                      svn_boolean_t install_pristine_props,
-                      svn_boolean_t force_base_install,
-                      apr_pool_t *scratch_pool);
-
 
 /* Delete PROPS_KIND props for LOCAL_ABSPATH */
 svn_error_t *
@@ -185,28 +169,34 @@ svn_wc__working_props_committed(svn_wc__
                                 const char *local_abspath,
                                 apr_pool_t *scratch_pool);
 
-/* Load the base and working props for ENTRY at PATH returning
-   them in *BASE_PROPS_P and *PROPS_P respectively.
-   Any of BASE_PROPS and PROPS may be NULL.
-   Returned hashes/values are allocated in RESULT_POOL. All temporary
-   allocations are made in SCRATCH_POOL.  */
+
+/* Internal version of svn_wc_get_pristine_props().  */
 svn_error_t *
-svn_wc__load_props(apr_hash_t **base_props_p,
-                   apr_hash_t **props_p,
-                   svn_wc__db_t *db,
-                   const char *local_abspath,
-                   apr_pool_t *result_pool,
-                   apr_pool_t *scratch_pool);
+svn_wc__get_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);
+
+
+/* Internal version of svn_wc_prop_list2().  */
+svn_error_t *
+svn_wc__get_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);
+
 
 /* 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__load_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_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
@@ -218,6 +208,39 @@ svn_wc__marked_as_binary(svn_boolean_t *
                          apr_pool_t *scratch_pool);
 
 
+svn_error_t *
+svn_wc__get_prejfile_abspath(const char **prejfile_abspath,
+                             svn_wc__db_t *db,
+                             const char *local_abspath,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool);
+
+svn_error_t *
+svn_wc__create_prejfile(const char **tmp_prejfile_abspath,
+                        svn_wc__db_t *db,
+                        const char *local_abspath,
+                        const svn_skel_t *conflict_skel,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool);
+
+
+/* Just like svn_wc_merge_props3(), but WITH a BASE_MERGE parameter.  */
+svn_error_t *
+svn_wc__perform_props_merge(svn_wc_notify_state_t *state,
+                            svn_wc__db_t *db,
+                            const char *local_abspath,
+                            const svn_wc_conflict_version_t *left_version,
+                            const svn_wc_conflict_version_t *right_version,
+                            apr_hash_t *baseprops,
+                            const apr_array_header_t *propchanges,
+                            svn_boolean_t base_merge,
+                            svn_boolean_t dry_run,
+                            svn_wc_conflict_resolver_func_t conflict_func,
+                            void *conflict_baton,
+                            svn_cancel_func_t cancel_func,
+                            void *cancel_baton,
+                            apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/questions.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/questions.c Tue Aug 10 20:55:56 2010
@@ -35,19 +35,15 @@
 #include "svn_string.h"
 #include "svn_error.h"
 #include "svn_dirent_uri.h"
-#include "svn_path.h"
 #include "svn_time.h"
 #include "svn_io.h"
 #include "svn_props.h"
 
 #include "wc.h"
 #include "adm_files.h"
-#include "entries.h"
 #include "props.h"
 #include "translate.h"
 #include "wc_db.h"
-#include "lock.h"
-#include "tree_conflicts.h"
 
 #include "svn_private_config.h"
 #include "private/svn_wc_private.h"
@@ -84,11 +80,18 @@
 
 
 /* Set *MODIFIED_P to TRUE if (after translation) VERSIONED_FILE_ABSPATH
- * differs from BASE_FILE_ABSPATH, else to FALSE if not.  Also verify that
- * BASE_FILE_ABSPATH matches the stored checksum for VERSIONED_FILE_ABSPATH,
+ * differs from PRISTINE_STREAM, else to FALSE if not.  Also verify that
+ * PRISTINE_STREAM matches the stored checksum for VERSIONED_FILE_ABSPATH,
  * if verify_checksum is TRUE. If checksum does not match, return the error
  * SVN_ERR_WC_CORRUPT_TEXT_BASE.
  *
+ * If COMPARE_TEXTBASES is true, translate VERSIONED_FILE_ABSPATH's EOL
+ * style and keywords to repository-normal form according to its properties,
+ * and compare the result with PRISTINE_STREAM.  If COMPARE_TEXTBASES is
+ * false, translate PRISTINE_STREAM's EOL style and keywords to working-copy
+ * form according to VERSIONED_FILE_ABSPATH's properties, and compare the
+ * result with VERSIONED_FILE_ABSPATH.
+ *
  * PRISTINE_STREAM will be closed before a successful return.
  *
  * DB is a wc_db; use SCRATCH_POOL for temporary allocation.
@@ -141,11 +144,15 @@ compare_and_verify(svn_boolean_t *modifi
                                        NULL, NULL,
                                        db, versioned_file_abspath,
                                        scratch_pool, scratch_pool));
+          /* SVN_EXPERIMENTAL_PRISTINE:
+             node_checksum is originally MD-5 but will later be SHA-1.  To
+             allow for this, we calculate CHECKSUM as the same kind so that
+             we can compare them. */
 
           if (node_checksum)
             pristine_stream = svn_stream_checksummed2(pristine_stream,
                                                       &checksum, NULL,
-                                                      svn_checksum_md5, TRUE,
+                                                      node_checksum->kind, TRUE,
                                                       scratch_pool);
         }
 
@@ -167,17 +174,19 @@ compare_and_verify(svn_boolean_t *modifi
                        && eol_style != svn_subst_eol_style_none)
                 return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL, NULL, NULL);
 
-              /* Wrap file stream to detranslate into normal form. */
+              /* Wrap file stream to detranslate into normal form,
+               * "repairing" the EOL style if it is inconsistent. */
               v_stream = svn_subst_stream_translated(v_stream,
                                                      eol_str,
-                                                     TRUE,
+                                                     TRUE /* repair */,
                                                      keywords,
                                                      FALSE /* expand */,
                                                      scratch_pool);
             }
           else if (need_translation)
             {
-              /* Wrap base stream to translate into working copy form. */
+              /* Wrap base stream to translate into working copy form, and
+               * arrange to throw an error if its EOL style is inconsistent. */
               pristine_stream = svn_subst_stream_translated(pristine_stream,
                                                             eol_str, FALSE,
                                                             keywords, TRUE,
@@ -247,12 +256,12 @@ svn_wc__versioned_file_modcheck(svn_bool
                                 svn_wc_context_t *wc_ctx,
                                 const char *versioned_file_abspath,
                                 const char *base_file_abspath,
-                                svn_boolean_t compare_textbases,
                                 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, compare_textbases,
+                            base_file_abspath,
+                            TRUE /* compare_textbases */,
                             scratch_pool));
 }
 
@@ -558,41 +567,3 @@ svn_wc__marked_as_binary(svn_boolean_t *
 
   return SVN_NO_ERROR;
 }
-
-
-/* Equivalent to the old notion of "entry->schedule == schedule_replace"  */
-svn_error_t *
-svn_wc__internal_is_replaced(svn_boolean_t *replaced,
-                             svn_wc__db_t *db,
-                             const char *local_abspath,
-                             apr_pool_t *scratch_pool)
-{
-  svn_wc__db_status_t status;
-  svn_boolean_t base_shadowed;
-  svn_wc__db_status_t base_status;
-
-  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, NULL, &base_shadowed,
-            NULL, NULL,
-            db, local_abspath,
-            scratch_pool, scratch_pool));
-  if (base_shadowed)
-    SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, NULL,
-                                     NULL, NULL, NULL,
-                                     NULL, NULL, NULL,
-                                     NULL, NULL, NULL,
-                                     NULL, NULL, NULL,
-                                     db, local_abspath,
-                                     scratch_pool, scratch_pool));
-
-  *replaced = ((status == svn_wc__db_status_added
-                || status == svn_wc__db_status_obstructed_add)
-               && base_shadowed
-               && base_status != svn_wc__db_status_not_present);
-
-  return SVN_NO_ERROR;
-}

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/relocate.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/relocate.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/relocate.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/relocate.c Tue Aug 10 20:55:56 2010
@@ -88,12 +88,13 @@ svn_wc_relocate4(svn_wc_context_t *wc_ct
   const char *old_repos_root;
   const char *old_url;
   const char *new_repos_root;
+  const char *uuid;
 
   SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, &repos_relpath,
-                               &old_repos_root,
+                               &old_repos_root, &uuid,
+                               NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                wc_ctx->db, local_abspath, scratch_pool,
                                scratch_pool));
 
@@ -111,7 +112,7 @@ svn_wc_relocate4(svn_wc_context_t *wc_ct
     return svn_error_createf(SVN_ERR_WC_INVALID_RELOCATION, NULL,
                              _("Given destination URL invalid: '%s'"), to);
 
-  SVN_ERR(validator(validator_baton, NULL, to, new_repos_root, scratch_pool));
+  SVN_ERR(validator(validator_baton, uuid, to, new_repos_root, scratch_pool));
 
   /* ### FIXME: This will ultimately cause the DAV cache to be
      recursively cleared, which is great in the recursive case, but

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/revision_status.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/revision_status.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/revision_status.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/revision_status.c Tue Aug 10 20:55:56 2010
@@ -40,8 +40,16 @@ struct walk_baton
   svn_wc__db_t *db;
 };
 
-/* An svn_wc__node_found_func_t callback function for analyzing the status
- * of nodes */
+/* An svn_wc__node_found_func_t callback function for analyzing the wc
+ * status of LOCAL_ABSPATH.  Update the status information in BATON->result.
+ * BATON is a 'struct walk_baton'.
+ *
+ * Implementation note: Since it can be invoked for a lot of paths in
+ * a wc but some data, i.e. if the wc is switched or has modifications, is
+ * expensive to calculate, we optimize by checking if those values are
+ * already set before runnning the db operations.
+ *
+ * Temporary allocations are made in SCRATCH_POOL. */
 static svn_error_t *
 analyze_status(const char *local_abspath,
                void *baton,
@@ -50,10 +58,9 @@ analyze_status(const char *local_abspath
   struct walk_baton *wb = baton;
   svn_revnum_t changed_rev;
   svn_revnum_t revision;
+  svn_revnum_t item_rev; 
   svn_depth_t depth;
   svn_wc__db_status_t status;
-  svn_boolean_t wc_root;
-  svn_boolean_t switched;
 
   SVN_ERR(svn_wc__db_read_info(&status, NULL, &revision, NULL, 
                                NULL, NULL, &changed_rev, 
@@ -71,24 +78,36 @@ analyze_status(const char *local_abspath
       wb->result->sparse_checkout = TRUE;
       return SVN_NO_ERROR;
     }
-
-  if (status == svn_wc__db_status_not_present)
-    return SVN_NO_ERROR;
+  else if (status == svn_wc__db_status_not_present)
+    {
+      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)
+    {
+      wb->result->modified = TRUE; 
+    }
 
   if (! wb->result->switched)
     {
+      svn_boolean_t wc_root;
+      svn_boolean_t switched;
+
       SVN_ERR(svn_wc__check_wc_root(&wc_root, NULL, &switched, wb->db,
                                     local_abspath, scratch_pool));
 
       wb->result->switched |= switched;
     }
 
+  item_rev = (wb->committed
+              ? changed_rev
+              : revision);
+
   /* Added files have a revision of no interest */
-  if (revision != SVN_INVALID_REVNUM)
+  if (item_rev != SVN_INVALID_REVNUM)
     {
-      svn_revnum_t item_rev = (wb->committed
-                               ? changed_rev
-                               : revision);
 
       if (wb->result->min_rev == SVN_INVALID_REVNUM
           || item_rev < wb->result->min_rev)
@@ -101,22 +120,27 @@ analyze_status(const char *local_abspath
 
   if (! wb->result->modified)
     {
-      svn_boolean_t text_mod;
       svn_boolean_t props_mod;
 
       SVN_ERR(svn_wc__props_modified(&props_mod, wb->db, local_abspath,
                                      scratch_pool));
+      wb->result->modified |= props_mod;
+    }
+
+  if (! wb->result->modified)
+    {
+      svn_boolean_t text_mod;
 
       SVN_ERR(svn_wc__internal_text_modified_p(&text_mod, wb->db,
                                                local_abspath,
                                                FALSE,
                                                TRUE,
                                                scratch_pool));
-      wb->result->modified |= (text_mod || props_mod);
+      wb->result->modified |= text_mod; 
     }
 
-  wb->result->sparse_checkout |= ((depth != svn_depth_infinity 
-                                  && depth != svn_depth_unknown));
+  wb->result->sparse_checkout |= (depth != svn_depth_infinity 
+                                  && depth != svn_depth_unknown);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/status.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/status.c Tue Aug 10 20:55:56 2010
@@ -126,7 +126,7 @@ struct edit_baton
   const apr_array_header_t *ignores;
 
   /* Status item for the path represented by the anchor of the edit. */
-  svn_wc_status2_t *anchor_status;
+  svn_wc_status3_t *anchor_status;
 
   /* Was open_root() called for this edit drive? */
   svn_boolean_t root_opened;
@@ -178,7 +178,7 @@ struct dir_baton
   svn_boolean_t text_changed;
 
   /* Working copy status structures for children of this directory.
-     This hash maps const char * abspaths  to svn_wc_status2_t *
+     This hash maps const char * abspaths  to svn_wc_status3_t *
      status items. */
   apr_hash_t *statii;
 
@@ -188,7 +188,7 @@ struct dir_baton
   /* The URI to this item in the repository. */
   const char *url;
 
-  /* out-of-date info corresponding to ood_* fields in svn_wc_status2_t. */
+  /* out-of-date info corresponding to ood_* fields in svn_wc_status3_t. */
   svn_revnum_t ood_last_cmt_rev;
   apr_time_t ood_last_cmt_date;
   svn_node_kind_t ood_kind;
@@ -230,7 +230,7 @@ struct file_baton
   /* The URI to this item in the repository. */
   const char *url;
 
-  /* out-of-date info corresponding to ood_* fields in svn_wc_status2_t. */
+  /* out-of-date info corresponding to ood_* fields in svn_wc_status3_t. */
   svn_revnum_t ood_last_cmt_rev;
   apr_time_t ood_last_cmt_date;
   svn_node_kind_t ood_kind;
@@ -240,7 +240,7 @@ struct file_baton
 
 /** Code **/
 static svn_error_t *
-internal_status(svn_wc_status2_t **status,
+internal_status(svn_wc_status3_t **status,
                 svn_wc__db_t *db,
                 const char *local_abspath,
                 apr_pool_t *result_pool,
@@ -250,20 +250,12 @@ internal_status(svn_wc_status2_t **statu
    *STATUS in POOL.  LOCAL_ABSPATH must be absolute.  Use SCRATCH_POOL for
    temporary allocations.
 
-   ENTRY may be null, for non-versioned entities.  In this case, we
-   will assemble a special status structure item which implies a
-   non-versioned thing.
-
    PARENT_ENTRY is the entry for the parent directory of LOCAL_ABSPATH, it
-   may be NULL if ENTRY is NULL or if LOCAL_ABSPATH is a working copy root.
+   may be NULL if LOCAL_ABSPATH is a working copy root.
    The lifetime of PARENT_ENTRY's pool is not important.
 
    PATH_KIND is the node kind of LOCAL_ABSPATH as determined by the caller.
-   NOTE: this may be svn_node_unknown if the caller has made no such
-   determination.
-
-   If PATH_KIND is not svn_node_unknown, PATH_SPECIAL indicates whether
-   the entry is a special file.
+   PATH_SPECIAL indicates whether the entry is a special file.
 
    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
@@ -273,33 +265,42 @@ internal_status(svn_wc_status2_t **statu
    the text_status to svn_wc_status_none.  Otherwise set the
    text_status to svn_wc_status_unversioned.
 
-   If non-NULL, look up a repository lock in REPOS_LOCKS and set the repos_lock
-   field of the status struct to that lock if it exists.  If REPOS_LOCKS is
-   non-NULL, REPOS_ROOT must contain the repository root URL of the entry.
+   The status struct's repos_lock field will be set to REPOS_LOCK.
 */
 static svn_error_t *
-assemble_status(svn_wc_status2_t **status,
+assemble_status(svn_wc_status3_t **status,
                 svn_wc__db_t *db,
                 const char *local_abspath,
-                const svn_wc_entry_t *entry,
-                const svn_wc_entry_t *parent_entry,
+                const char *parent_repos_root_url,
+                const char *parent_repos_relpath,
                 svn_node_kind_t path_kind,
                 svn_boolean_t path_special,
                 svn_boolean_t get_all,
                 svn_boolean_t is_ignored,
-                apr_hash_t *repos_locks,
-                const char *repos_root,
+                const svn_lock_t *repos_lock,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
 {
-  svn_wc_status2_t *stat;
+  svn_wc_status3_t *stat;
+  svn_wc__db_status_t db_status;
+  svn_wc__db_kind_t db_kind;
+  const char *repos_relpath;
+  const char *repos_root_url;
+  const char *url;
   svn_boolean_t locked_p = FALSE;
   svn_boolean_t switched_p = FALSE;
   const svn_wc_conflict_description2_t *tree_conflict;
   svn_boolean_t file_external_p = FALSE;
-#ifdef HAVE_SYMLINK
-  svn_boolean_t wc_special;
-#endif /* HAVE_SYMLINK */
+  svn_wc__db_lock_t *lock;
+  svn_revnum_t revision;
+  svn_revnum_t changed_rev;
+  const char *changed_author;
+  apr_time_t changed_date;
+  const char *changelist;
+  svn_boolean_t base_shadowed;
+  svn_boolean_t conflicted;
+  const svn_wc_entry_t *entry;
+  svn_error_t *err;
 
   /* Defaults for two main variables. */
   enum svn_wc_status_kind final_text_status = svn_wc_status_normal;
@@ -308,32 +309,13 @@ assemble_status(svn_wc_status2_t **statu
   enum svn_wc_status_kind pristine_text_status = svn_wc_status_none;
   enum svn_wc_status_kind pristine_prop_status = svn_wc_status_none;
 
-  svn_lock_t *repos_lock = NULL;
+  err = svn_wc__get_entry(&entry, db, local_abspath, FALSE, svn_node_unknown,
+                          FALSE, result_pool, scratch_pool);
 
-  /* Check for a repository lock. */
-  if (repos_locks)
-    {
-      const char *abs_path;
-
-      if (entry && entry->url)
-        abs_path = entry->url + strlen(repos_root);
-      else if (parent_entry && parent_entry->url)
-        abs_path = svn_uri_join(parent_entry->url + strlen(repos_root),
-                                svn_dirent_basename(local_abspath, NULL),
-                                scratch_pool);
-      else
-        abs_path = NULL;
-
-      if (abs_path)
-        repos_lock = apr_hash_get(repos_locks,
-                                  svn_path_uri_decode(abs_path, scratch_pool),
-                                  APR_HASH_KEY_STRING);
-    }
-
-  /* Check the path kind for PATH. */
-  if (path_kind == svn_node_unknown)
-    SVN_ERR(svn_io_check_special_path(local_abspath, &path_kind, &path_special,
-                                      scratch_pool));
+  if (err && err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND)
+    svn_error_clear(err);
+  else
+    SVN_ERR(err);
 
   /* Find out whether the path is a tree conflict victim.
    * This function will set tree_conflict to NULL if the path
@@ -341,91 +323,110 @@ assemble_status(svn_wc_status2_t **statu
   SVN_ERR(svn_wc__db_op_read_tree_conflict(&tree_conflict, db, local_abspath,
                                            scratch_pool, scratch_pool));
 
-  if (! entry)
+  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, NULL, NULL, NULL,
+                               NULL, &changelist, NULL, NULL, NULL, NULL,
+                               NULL, NULL, &base_shadowed, &conflicted,
+                               &lock, db, local_abspath, result_pool,
+                               scratch_pool));
+
+  /* ### Temporary until we've revved svn_wc_status3_t to only use
+   * ### repos_{root_url,relpath} */
+  SVN_ERR(svn_wc__internal_node_get_url(&url, db, local_abspath,
+                                        result_pool, scratch_pool));
+
+  SVN_ERR(svn_wc__internal_is_file_external(&file_external_p, db,
+                                            local_abspath, scratch_pool));
+
+  /** File externals are switched files, but they are not shown as
+      such.  To be switched it must have both an URL and a parent with
+      an URL, at the very least. */
+  if (! file_external_p)
     {
-      /* return a fairly blank structure. */
-      stat = apr_pcalloc(result_pool, sizeof(*stat));
-      stat->entry = NULL;
-      stat->text_status = svn_wc_status_none;
-      stat->prop_status = svn_wc_status_none;
-      stat->repos_text_status = svn_wc_status_none;
-      stat->repos_prop_status = svn_wc_status_none;
-      stat->locked = FALSE;
-      stat->copied = FALSE;
-      stat->switched = FALSE;
-      stat->tree_conflict = svn_wc__cd2_to_cd(tree_conflict, result_pool);
-      stat->file_external = FALSE;
-
-      /* If this path has no entry, but IS present on disk, it's
-         unversioned.  If this file is being explicitly ignored (due
-         to matching an ignore-pattern), the text_status is set to
-         svn_wc_status_ignored.  Otherwise the text_status is set to
-         svn_wc_status_unversioned. */
-      if (path_kind != svn_node_none)
+      if (parent_repos_root_url && repos_root_url &&
+          (strcmp(parent_repos_root_url, repos_root_url) == 0))
         {
-          if (is_ignored)
-            stat->text_status = svn_wc_status_ignored;
+          const char *base = svn_dirent_basename(local_abspath, scratch_pool);
+
+          if (! repos_relpath)
+            {
+              repos_relpath = svn_relpath_join( parent_repos_relpath, base,
+                                                result_pool);
+              /* If _read_info() doesn't give us a repos_relpath, it means
+               * that it is implied by the parent, thus the path can not be
+               * switched. */
+              switched_p = FALSE;
+            }
           else
-            stat->text_status = svn_wc_status_unversioned;
+            {
+              switched_p = (strcmp(svn_relpath_join(parent_repos_relpath, base,
+                                                    scratch_pool),
+                                   repos_relpath) != 0);
+            }
         }
+    }
 
-      /* If this path has no entry, is NOT present on disk, and IS a
-         tree conflict victim, count it as missing. */
-      if ((path_kind == svn_node_none) && tree_conflict)
-        stat->text_status = svn_wc_status_missing;
+  /* Examine whether our directory metadata is present, and compensate
+     if it is missing.
 
-      stat->repos_lock = repos_lock;
-      stat->url = NULL;
-      stat->ood_last_cmt_rev = SVN_INVALID_REVNUM;
-      stat->ood_last_cmt_date = 0;
-      stat->ood_kind = svn_node_none;
-      stat->ood_last_cmt_author = NULL;
+     There are a several kinds of obstruction that we detect here:
 
-      *status = stat;
-      return SVN_NO_ERROR;
-    }
+     - versioned subdir is missing
+     - the versioned subdir's admin area is missing
+     - the versioned subdir has been replaced with a file/symlink
 
-  /* Someone either deleted the administrative directory in the versioned
-     subdir, or deleted the directory altogether and created a new one.
-     In any case, what is currently there is in the way.
-   */
-  if (entry->kind == svn_node_dir)
+     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.
+
+     ### note that most obstruction concepts disappear in single-db mode
+  */
+  if (db_kind == svn_wc__db_kind_dir)
     {
-      if (path_kind == svn_node_dir)
+      if (db_status == svn_wc__db_status_incomplete)
         {
-          if (svn_wc__adm_missing(db, local_abspath, scratch_pool))
+          /* Highest precedence.  */
+          final_text_status = svn_wc_status_incomplete;
+        }
+      else if (db_status == svn_wc__db_status_obstructed_delete)
+        {
+          /* Deleted directories are never reported as missing.  */
+          if (path_kind == svn_node_none)
+            final_text_status = svn_wc_status_deleted;
+          else
+            final_text_status = svn_wc_status_obstructed;
+        }
+      else if (db_status == svn_wc__db_status_obstructed
+               || db_status == svn_wc__db_status_obstructed_add)
+        {
+          /* A present or added directory should be on disk, so it is
+             reported missing or obstructed.  */
+          if (path_kind == svn_node_none)
+            final_text_status = svn_wc_status_missing;
+          else
             final_text_status = svn_wc_status_obstructed;
         }
-      else if (path_kind != svn_node_none)
-        final_text_status = svn_wc_status_obstructed;
     }
 
-  /** File externals are switched files, but they are not shown as
-      such.  To be switched it must have both an URL and a parent with
-      an URL, at the very least.  If this is the root folder on the
-      (virtual) disk, entry and parent_entry will be equal. */
-  if (entry->file_external_path)
-    {
-      file_external_p = TRUE;
-    }
-  else if (entry->url && parent_entry && parent_entry->url &&
-           entry != parent_entry)
-    {
-      /* An item is switched if:
-         parent-url + basename(path) != entry->url  */
-      switched_p = (strcmp(
-                     svn_uri_join(parent_entry->url,
-                          svn_path_uri_encode(svn_dirent_basename(
-                                                local_abspath, NULL),
-                                              scratch_pool),
-                          scratch_pool), entry->url) != 0);
-    }
+  /* If FINAL_TEXT_STATUS is still normal, after the above checks, then
+     we should proceed to refine the status.
 
-  if (final_text_status != svn_wc_status_obstructed)
+     If it was changed, then the subdir is incomplete or missing/obstructed.
+     It means that no further information is available, and we should skip
+     all this work.  */
+  if (final_text_status == svn_wc_status_normal)
     {
       svn_boolean_t has_props;
       svn_boolean_t prop_modified_p = FALSE;
       svn_boolean_t text_modified_p = FALSE;
+#ifdef HAVE_SYMLINK
+      svn_boolean_t wc_special;
+#endif /* HAVE_SYMLINK */
 
       /* Implement predecence rules: */
 
@@ -434,11 +435,25 @@ assemble_status(svn_wc_status2_t **statu
             precedence over M. */
 
       /* Does the entry have props? */
-      SVN_ERR(svn_wc__has_props(&has_props, db, local_abspath, scratch_pool));
+      {
+        apr_hash_t *pristine;
+        apr_hash_t *actual;
+
+        SVN_ERR(svn_wc__get_pristine_props(&pristine, db, local_abspath,
+                                           scratch_pool, scratch_pool));
+        SVN_ERR(svn_wc__get_actual_props(&actual, db, local_abspath,
+                                         scratch_pool, scratch_pool));
+        has_props = ((pristine != NULL && apr_hash_count(pristine) > 0)
+                     || (actual != NULL && apr_hash_count(actual) > 0));
+      }
       if (has_props)
         final_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.  */
       SVN_ERR(svn_wc__props_modified(&prop_modified_p, db, local_abspath,
                                      scratch_pool));
 
@@ -455,17 +470,16 @@ assemble_status(svn_wc_status2_t **statu
 #endif /* HAVE_SYMLINK */
 
       /* If the entry is a file, check for textual modifications */
-      if ((entry->kind == svn_node_file)
+      if ((db_kind == svn_wc__db_kind_file)
 #ifdef HAVE_SYMLINK
           && (wc_special == path_special)
 #endif /* HAVE_SYMLINK */
           )
         {
-          svn_error_t *err = svn_wc__internal_text_modified_p(&text_modified_p,
-                                                              db,
-                                                              local_abspath,
-                                                              FALSE, TRUE,
-                                                              scratch_pool);
+          err = svn_wc__internal_text_modified_p(&text_modified_p,
+                                                 db, local_abspath,
+                                                 FALSE, TRUE,
+                                                 scratch_pool);
 
           if (err)
             {
@@ -517,6 +531,9 @@ assemble_status(svn_wc_status2_t **statu
             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 (entry->schedule == svn_wc_schedule_add
           && final_text_status != svn_wc_status_conflicted)
         {
@@ -563,14 +580,18 @@ assemble_status(svn_wc_status2_t **statu
           if (final_text_status != svn_wc_status_deleted)
             final_text_status = svn_wc_status_missing;
         }
-      else if (path_kind != entry->kind)
+      /* ### We can do this db_kind to node_kind translation since the cases
+       * where db_kind would have been unknown are treated as unversioned
+       * paths and thus have already returned. */
+      else if (path_kind != (db_kind == svn_wc__db_kind_dir ?  
+                                        svn_node_dir : svn_node_file))
         final_text_status = svn_wc_status_obstructed;
 #ifdef HAVE_SYMLINK
       else if ( wc_special != path_special)
         final_text_status = svn_wc_status_obstructed;
 #endif /* HAVE_SYMLINK */
 
-      if (path_kind == svn_node_dir && entry->kind == svn_node_dir)
+      if (path_kind == svn_node_dir && db_kind == svn_wc__db_kind_dir)
         SVN_ERR(svn_wc__db_wclocked(&locked_p, db, local_abspath,
                                     scratch_pool));
     }
@@ -583,8 +604,12 @@ assemble_status(svn_wc_status2_t **statu
          || (final_text_status == svn_wc_status_normal))
         && ((final_prop_status == svn_wc_status_none)
             || (final_prop_status == svn_wc_status_normal))
-        && (! locked_p) && (! switched_p) && (! file_external_p)
-        && (! entry->lock_token) && (! repos_lock) && (! entry->changelist)
+        && (! locked_p)
+        && (! switched_p)
+        && (! file_external_p)
+        && (! lock) 
+        && (! repos_lock)
+        && (! changelist)
         && (! tree_conflict))
       {
         *status = NULL;
@@ -595,7 +620,9 @@ assemble_status(svn_wc_status2_t **statu
   /* 6. Build and return a status structure. */
 
   stat = apr_pcalloc(result_pool, sizeof(**status));
-  stat->entry = svn_wc_entry_dup(entry, result_pool);
+  stat->kind = entry->kind;
+  stat->depth = entry->depth;
+  stat->entry = entry;
   stat->text_status = final_text_status;
   stat->prop_status = final_prop_status;
   stat->repos_text_status = svn_wc_status_none;   /* default */
@@ -605,14 +632,26 @@ assemble_status(svn_wc_status2_t **statu
   stat->file_external = file_external_p;
   stat->copied = entry->copied;
   stat->repos_lock = repos_lock;
-  stat->url = (entry->url ? entry->url : NULL);
+  stat->url = url;
+  stat->revision = revision;
+  stat->changed_rev = changed_rev;
+  stat->changed_author = changed_author;
+  stat->changed_date = changed_date;
   stat->ood_last_cmt_rev = SVN_INVALID_REVNUM;
   stat->ood_last_cmt_date = 0;
   stat->ood_kind = svn_node_none;
   stat->ood_last_cmt_author = NULL;
-  stat->tree_conflict = svn_wc__cd2_to_cd(tree_conflict, result_pool);
   stat->pristine_text_status = pristine_text_status;
   stat->pristine_prop_status = pristine_prop_status;
+  stat->lock_token = lock ? lock->token : NULL;
+  stat->lock_owner = lock ? lock->owner : NULL;
+  stat->lock_comment = lock ? lock->comment : NULL;
+  stat->lock_creation_date = lock ? lock->date : 0;
+  stat->conflicted = conflicted;
+  stat->versioned = TRUE;
+  stat->changelist = changelist;
+  stat->repos_root_url = repos_root_url;
+  stat->repos_relpath = repos_relpath;
 
   *status = stat;
 
@@ -620,31 +659,135 @@ assemble_status(svn_wc_status2_t **statu
 }
 
 
+static svn_error_t *
+assemble_unversioned(svn_wc_status3_t **status,
+                     svn_wc__db_t *db,
+                     const char *local_abspath,
+                     svn_node_kind_t path_kind,
+                     svn_boolean_t is_ignored,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
+{
+  svn_wc_status3_t *stat;
+  const svn_wc_conflict_description2_t *tree_conflict;
+
+  /* Find out whether the path is a tree conflict victim.
+     This function will set tree_conflict to NULL if the path
+     is not a victim. */
+  SVN_ERR(svn_wc__db_op_read_tree_conflict(&tree_conflict,
+                                           db, local_abspath,
+                                           scratch_pool, scratch_pool));
+
+  /* return a fairly blank structure. */
+  stat = apr_pcalloc(result_pool, sizeof(**status));
+
+  /*stat->versioned = FALSE;*/
+  stat->kind = svn_node_unknown; /* not versioned */
+  stat->depth = svn_depth_unknown;
+  stat->text_status = svn_wc_status_none;
+  stat->prop_status = svn_wc_status_none;
+  stat->repos_text_status = svn_wc_status_none;
+  stat->repos_prop_status = svn_wc_status_none;
+
+  /* If this path has no entry, but IS present on disk, it's
+     unversioned.  If this file is being explicitly ignored (due
+     to matching an ignore-pattern), the text_status is set to
+     svn_wc_status_ignored.  Otherwise the text_status is set to
+     svn_wc_status_unversioned. */
+  if (path_kind != svn_node_none)
+    {
+      if (is_ignored)
+        stat->text_status = svn_wc_status_ignored;
+      else
+        stat->text_status = svn_wc_status_unversioned;
+    }
+  else if (tree_conflict != NULL)
+    {
+      /* If this path has no entry, is NOT present on disk, and IS a
+         tree conflict victim, count it as missing. */
+      stat->text_status = svn_wc_status_missing;
+    }
+
+  stat->revision = SVN_INVALID_REVNUM;
+  stat->changed_rev = SVN_INVALID_REVNUM;
+  stat->ood_last_cmt_rev = SVN_INVALID_REVNUM;
+  stat->ood_kind = svn_node_none;
+
+  /* For the case of an incoming delete to a locally deleted path during
+     an update, we get a tree conflict. */
+  stat->conflicted = (tree_conflict != NULL);
+  stat->changelist = NULL;
+
+  *status = stat;
+  return SVN_NO_ERROR;
+}
+
+
 /* Given an ENTRY object representing PATH, build a status structure
    and pass it off to the STATUS_FUNC/STATUS_BATON.  All other
    arguments are the same as those passed to assemble_status().  */
 static svn_error_t *
 send_status_structure(const struct walk_status_baton *wb,
                       const char *local_abspath,
-                      const svn_wc_entry_t *entry,
-                      const svn_wc_entry_t *parent_entry,
+                      const char *parent_repos_root_url,
+                      const char *parent_repos_relpath,
                       svn_node_kind_t path_kind,
                       svn_boolean_t path_special,
                       svn_boolean_t get_all,
                       svn_boolean_t is_ignored,
                       svn_wc_status_func4_t status_func,
                       void *status_baton,
-                      apr_pool_t *pool)
+                      apr_pool_t *scratch_pool)
 {
-  svn_wc_status2_t *statstruct;
+  svn_wc_status3_t *statstruct;
+  const svn_lock_t *repos_lock = NULL;
+
+  /* Check for a repository lock. */
+  if (wb->repos_locks)
+    {
+      const char *repos_relpath;
+      svn_wc__db_status_t status;
+      svn_boolean_t base_shadowed;
+
+      SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, &repos_relpath, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, &base_shadowed, NULL, NULL, 
+                                   wb->db, local_abspath,
+                                   scratch_pool, scratch_pool));
 
-  SVN_ERR(assemble_status(&statstruct, wb->db, local_abspath, entry,
-                          parent_entry, path_kind, path_special, get_all,
-                          is_ignored, wb->repos_locks, wb->repos_root,
-                          pool, pool));
+      /* A switched path can be deleted: check the right relpath */
+      if (status == svn_wc__db_status_deleted && base_shadowed)
+        SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, NULL,
+                                           NULL, wb->db, local_abspath,
+                                           scratch_pool, scratch_pool));
+
+      if (!repos_relpath && parent_repos_relpath)
+        repos_relpath = svn_relpath_join(parent_repos_relpath,
+                                         svn_dirent_basename(local_abspath,
+                                                             NULL),
+                                         scratch_pool);
+
+
+      if (repos_relpath)
+        {
+          /* repos_lock still uses the deprecated filesystem absolute path
+             format */
+          repos_lock = apr_hash_get(wb->repos_locks,
+                                    svn_uri_join("/", repos_relpath,
+                                                 scratch_pool),
+                                    APR_HASH_KEY_STRING);
+        }
+    }
+
+  SVN_ERR(assemble_status(&statstruct, wb->db, local_abspath,
+                          parent_repos_root_url, parent_repos_relpath,
+                          path_kind, path_special, get_all, is_ignored,
+                          repos_lock, scratch_pool, scratch_pool));
 
   if (statstruct && status_func)
-    return status_func(status_baton, local_abspath, statstruct, pool);
+    return svn_error_return((*status_func)(status_baton, local_abspath,
+                                           statstruct, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -754,36 +897,40 @@ static svn_error_t *
 send_unversioned_item(const struct walk_status_baton *wb,
                       const char *local_abspath,
                       svn_node_kind_t path_kind,
-                      svn_boolean_t path_special,
                       const apr_array_header_t *patterns,
                       svn_boolean_t no_ignore,
                       svn_wc_status_func4_t status_func,
                       void *status_baton,
-                      apr_pool_t *pool)
+                      apr_pool_t *scratch_pool)
 {
-  svn_boolean_t ignore, is_external;
-  svn_wc_status2_t *status;
-
-  ignore = svn_wc_match_ignore_list(svn_dirent_basename(local_abspath, NULL),
-                                    patterns, pool);
-
-  is_external = is_external_path(wb->externals, local_abspath, pool);
-
-  SVN_ERR(assemble_status(&status, wb->db, local_abspath, NULL, NULL,
-                          path_kind, path_special, FALSE, ignore,
-                          wb->repos_locks, wb->repos_root, pool, pool));
+  svn_boolean_t is_ignored;
+  svn_boolean_t is_external;
+  svn_wc_status3_t *status;
+
+  is_ignored = svn_wc_match_ignore_list(
+                 svn_dirent_basename(local_abspath, NULL),
+                 patterns, scratch_pool);
+
+  SVN_ERR(assemble_unversioned(&status,
+                               wb->db, local_abspath,
+                               path_kind, is_ignored,
+                               scratch_pool, scratch_pool));
 
+  is_external = is_external_path(wb->externals, local_abspath, scratch_pool);
   if (is_external)
     status->text_status = svn_wc_status_external;
 
-  /* Don't ever ignore tree conflict victims. */
-  if (status->tree_conflict)
-    ignore = FALSE;
-
-  /* If we aren't ignoring it, or if it's an externals path, or it has a lock
-     in the repository, pass this entry to the status func. */
-  if (no_ignore || (! ignore) || is_external || status->repos_lock)
-    return (status_func)(status_baton, local_abspath, status, pool);
+  /* We can have a tree conflict on an unversioned path, i.e. an incoming
+   * delete on a locally deleted path during an update. Don't ever ignore
+   * those! */
+  if (status->conflicted)
+    is_ignored = FALSE;
+
+  /* If we aren't ignoring it, or if it's an externals path, pass this
+     entry to the status func. */
+  if (no_ignore || (! is_ignored) || is_external)
+    return svn_error_return((*status_func)(status_baton, local_abspath,
+                                           status, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -793,74 +940,82 @@ send_unversioned_item(const struct walk_
 static svn_error_t *
 get_dir_status(const struct walk_status_baton *wb,
                const char *local_abspath,
-               const svn_wc_entry_t *parent_entry,
+               const char *parent_repos_root_url,
+               const char *parent_repos_relpath,
                const char *selected,
                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_boolean_t get_excluded,
                svn_wc_status_func4_t status_func,
                void *status_baton,
                svn_cancel_func_t cancel_func,
                void *cancel_baton,
                apr_pool_t *scratch_pool);
 
-/* Handle LOCAL_ABSPATH (whose entry is ENTRY) as a directory entry
-   of the directory whose entry is DIR_ENTRY.  All other arguments
+/* Handle LOCAL_ABSPATH (whose entry is ENTRY).  All other arguments
    are the same as those passed to get_dir_status(), the function
    for which this one is a helper.  */
 static svn_error_t *
 handle_dir_entry(const struct walk_status_baton *wb,
                  const char *local_abspath,
-                 const svn_wc_entry_t *dir_entry,
                  const svn_wc_entry_t *entry,
-                 svn_node_kind_t kind,
-                 svn_boolean_t special,
+                 const char *dir_repos_root_url,
+                 const char *dir_repos_relpath,
+                 svn_node_kind_t path_kind,
+                 svn_boolean_t path_special,
                  const apr_array_header_t *ignores,
                  svn_depth_t depth,
                  svn_boolean_t get_all,
                  svn_boolean_t no_ignore,
-                 svn_boolean_t get_excluded,
                  svn_wc_status_func4_t status_func,
                  void *status_baton,
                  svn_cancel_func_t cancel_func,
                  void *cancel_baton,
                  apr_pool_t *pool)
 {
-  if (kind == svn_node_dir)
+  /* We are looking at a directory on-disk.  */
+  if (path_kind == svn_node_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 (!*entry->name
+      if (*entry->name == '\0'
           && (depth == svn_depth_unknown
               || depth == svn_depth_immediates
               || depth == svn_depth_infinity))
         {
-          SVN_ERR(get_dir_status(wb, local_abspath, dir_entry, NULL, ignores,
-                                 depth, get_all, no_ignore, FALSE,
-                                 get_excluded, status_func, status_baton,
-                                 cancel_func, cancel_baton, pool));
+          SVN_ERR(get_dir_status(wb, local_abspath, dir_repos_root_url,
+                                 dir_repos_relpath, NULL, ignores, depth,
+                                 get_all, no_ignore, FALSE,
+                                 status_func, status_baton, cancel_func,
+                                 cancel_baton,
+                                 pool));
         }
       else
         {
-          /* FULL_ENTRY is still a stub (an obstructed subdir), or DEPTH
-             is limiting us. Send just this directory.  */
-          SVN_ERR(send_status_structure(wb, local_abspath, entry,
-                                        dir_entry, kind, special, get_all,
-                                        FALSE,
+          /* ENTRY is a child entry (file or parent stub). Or we have a
+             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, FALSE /* is_ignored */,
                                         status_func, status_baton, pool));
         }
     }
   else
     {
-      /* File entries are ... just fine! */
-      SVN_ERR(send_status_structure(wb, local_abspath, entry,
-                                    dir_entry, kind, special, get_all, FALSE,
+      /* This is a file/symlink on-disk.  */
+      SVN_ERR(send_status_structure(wb, local_abspath,
+                                    dir_repos_root_url,
+                                    dir_repos_relpath, path_kind,
+                                    path_special, get_all, 
+                                    FALSE /* is_ignored */,
                                     status_func, status_baton, pool));
     }
+
   return SVN_NO_ERROR;
 }
 
@@ -916,7 +1071,7 @@ handle_externals(const struct walk_statu
 }
 
 
-/* Send svn_wc_status2_t * structures for the directory LOCAL_ABSPATH and
+/* Send svn_wc_status3_t * structures for the directory LOCAL_ABSPATH and
    for all its entries through STATUS_FUNC/STATUS_BATON, or, if SELECTED
    is non-NULL, only for that directory entry.
 
@@ -927,22 +1082,19 @@ 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.
 
-   If GET_EXCLUDED is TRUE, then statuses for the roots of excluded
-   subtrees are reported, otherwise they are ignored.
-
    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 svn_wc_entry_t *parent_entry,
+               const char *parent_repos_root_url,
+               const char *parent_repos_relpath,
                const char *selected,
                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_boolean_t get_excluded,
                svn_wc_status_func4_t status_func,
                void *status_baton,
                svn_cancel_func_t cancel_func,
@@ -950,9 +1102,12 @@ get_dir_status(const struct walk_status_
                apr_pool_t *scratch_pool)
 {
   apr_hash_index_t *hi;
-  const svn_wc_entry_t *dir_entry;
+  const char *dir_repos_root_url;
+  const char *dir_repos_relpath;
   apr_hash_t *dirents, *nodes, *conflicts, *all_children;
   apr_array_header_t *patterns = NULL;
+  svn_wc__db_status_t dir_status;
+  svn_depth_t dir_depth;
   apr_pool_t *iterpool, *subpool = svn_pool_create(scratch_pool);
 
   /* See if someone wants to cancel this operation. */
@@ -975,9 +1130,36 @@ get_dir_status(const struct walk_status_
   }
 
   SVN_ERR(svn_io_get_dirents2(&dirents, local_abspath, subpool));
-  /* Get this directory's entry. */
-  SVN_ERR(svn_wc__get_entry(&dir_entry, wb->db, local_abspath, FALSE,
-                            svn_node_dir, FALSE, subpool, iterpool));
+
+  SVN_ERR(svn_wc__db_read_info(&dir_status, NULL, NULL, &dir_repos_relpath,
+                               &dir_repos_root_url, NULL, NULL, NULL, NULL,
+                               NULL, &dir_depth, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, wb->db, local_abspath, scratch_pool,
+                               scratch_pool));
+
+  if (dir_repos_relpath == NULL)
+    {
+      if (parent_repos_root_url != NULL)
+        {
+          dir_repos_root_url = parent_repos_root_url;
+          dir_repos_relpath = svn_relpath_join(
+                                    parent_repos_relpath,
+                                    svn_dirent_basename(local_abspath, NULL),
+                                    scratch_pool);
+        }
+      else if (dir_status != svn_wc__db_status_deleted
+               && dir_status != svn_wc__db_status_added)
+        SVN_ERR(svn_wc__db_scan_base_repos(&dir_repos_relpath,
+                                           &dir_repos_root_url,
+                                           NULL, wb->db, local_abspath,
+                                           scratch_pool, scratch_pool));
+      else
+        {
+          dir_repos_relpath = NULL;
+          dir_repos_root_url = NULL;
+        }
+    }
 
   if (selected == NULL)
     {
@@ -1015,20 +1197,23 @@ get_dir_status(const struct walk_status_
         apr_hash_set(conflicts, selected, APR_HASH_KEY_STRING, "");
     }
 
-  /* If "this dir" has "svn:externals" property set on it, store the
-     name and value in traversal_info, along with this directory's depth.
-     (Also, we want to track the externals internally so we can report
-     status more accurately.) */
-  SVN_ERR(handle_externals(wb, local_abspath, dir_entry->depth, iterpool));
+  /* If "this dir" has "svn:externals" property set on it, send the name and
+     value to wc->external_func along with this directory's depth. (Also,
+     we want to track the externals internally so we can report status more
+     accurately.) */
+  SVN_ERR(handle_externals(wb, local_abspath, dir_depth, iterpool));
 
   if (!selected)
     {
       /* Handle "this-dir" first. */
       if (! skip_this_dir)
         SVN_ERR(send_status_structure(wb, local_abspath,
-                                      dir_entry, parent_entry, svn_node_dir,
-                                      FALSE, get_all, FALSE, status_func,
-                                      status_baton, iterpool));
+                                      parent_repos_root_url,
+                                      parent_repos_relpath, svn_node_dir,
+                                      FALSE /* path_special */,
+                                      get_all, FALSE /* is_ignored */,
+                                      status_func, status_baton,
+                                      iterpool));
 
       /* If the requested depth is empty, we only need status on this-dir. */
       if (depth == svn_depth_empty)
@@ -1049,6 +1234,8 @@ get_dir_status(const struct walk_status_
 
       apr_hash_this(hi, &key, &klen, NULL);
 
+      node_abspath = svn_dirent_join(local_abspath, key, iterpool);
+
       dirent_p = apr_hash_get(dirents, key, klen);
 
       if (apr_hash_get(nodes, key, klen))
@@ -1056,23 +1243,23 @@ get_dir_status(const struct walk_status_
           /* Versioned node */
           svn_error_t *err;
           const svn_wc_entry_t *entry;
-
           svn_boolean_t hidden;
-          node_abspath = svn_dirent_join(local_abspath, key, iterpool);
 
           SVN_ERR(svn_wc__db_node_hidden(&hidden, wb->db, node_abspath,
                                          iterpool));
 
-          if (!hidden || get_excluded)
+          if (!hidden)
             {
               err = svn_wc__get_entry(&entry, wb->db, node_abspath, FALSE,
-                                      dirent_p ? dirent_p->kind
-                                               : svn_node_unknown,
-                                      FALSE, iterpool, iterpool);
+                                      svn_node_unknown, FALSE,
+                                      iterpool, iterpool);
               if (err)
                 {
                   if (err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND)
-                    svn_error_clear(err);
+                    {
+                      /* We asked for the contents, but got the stub.  */
+                      svn_error_clear(err);
+                    }
                   else if (err && err->apr_err == SVN_ERR_WC_MISSING)
                     {
                       svn_error_clear(err);
@@ -1096,11 +1283,12 @@ get_dir_status(const struct walk_status_
               if (depth == svn_depth_files && entry->kind == svn_node_dir)
                 continue;
 
-              /* Handle this directory entry (possibly recursing). */
+              /* Handle this entry (possibly recursing). */
               SVN_ERR(handle_dir_entry(wb,
                                        node_abspath,
-                                       dir_entry,
                                        entry,
+                                       dir_repos_root_url,
+                                       dir_repos_relpath,
                                        dirent_p ? dirent_p->kind
                                                 : svn_node_none,
                                        dirent_p ? dirent_p->special : FALSE,
@@ -1109,7 +1297,7 @@ get_dir_status(const struct walk_status_
                                                            ? depth
                                                            : svn_depth_empty,
                                        get_all,
-                                       no_ignore, get_excluded,
+                                       no_ignore,
                                        status_func, status_baton,
                                        cancel_func, cancel_baton, iterpool));
               continue;
@@ -1126,11 +1314,9 @@ get_dir_status(const struct walk_status_
                                             iterpool));
 
           SVN_ERR(send_unversioned_item(wb,
-                                        svn_dirent_join(local_abspath, key,
-                                                        iterpool),
+                                        node_abspath,
                                         dirent_p ? dirent_p->kind
                                                  : svn_node_none,
-                                        dirent_p ? dirent_p->special : FALSE,
                                         patterns,
                                         no_ignore,
                                         status_func,
@@ -1156,10 +1342,8 @@ get_dir_status(const struct walk_status_
                                         iterpool));
 
       SVN_ERR(send_unversioned_item(wb,
-                                    svn_dirent_join(local_abspath, key,
-                                                    iterpool),
+                                    node_abspath,
                                     dirent_p->kind,
-                                    dirent_p->special,
                                     patterns,
                                     no_ignore || selected,
                                     status_func, status_baton,
@@ -1182,14 +1366,14 @@ get_dir_status(const struct walk_status_
 static svn_error_t *
 hash_stash(void *baton,
            const char *path,
-           const svn_wc_status2_t *status,
+           const svn_wc_status3_t *status,
            apr_pool_t *scratch_pool)
 {
   apr_hash_t *stat_hash = baton;
   apr_pool_t *hash_pool = apr_hash_pool_get(stat_hash);
   assert(! apr_hash_get(stat_hash, path, APR_HASH_KEY_STRING));
   apr_hash_set(stat_hash, apr_pstrdup(hash_pool, path),
-               APR_HASH_KEY_STRING, svn_wc_dup_status2(status, hash_pool));
+               APR_HASH_KEY_STRING, svn_wc_dup_status3(status, hash_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1234,10 +1418,10 @@ tweak_statushash(void *baton,
                  enum svn_wc_status_kind repos_text_status,
                  enum svn_wc_status_kind repos_prop_status,
                  svn_revnum_t deleted_rev,
-                 svn_lock_t *repos_lock,
+                 const svn_lock_t *repos_lock,
                  apr_pool_t *scratch_pool)
 {
-  svn_wc_status2_t *statstruct;
+  svn_wc_status3_t *statstruct;
   apr_pool_t *pool;
   apr_hash_t *statushash;
 
@@ -1356,19 +1540,19 @@ find_dir_url(const struct dir_baton *db,
 {
   /* If we have no name, we're the root, return the anchor URL. */
   if (! db->name)
-    return db->edit_baton->anchor_status->entry->url;
+    return db->edit_baton->anchor_status->url;
   else
     {
       const char *url;
       struct dir_baton *pb = db->parent_baton;
-      const svn_wc_status2_t *status = apr_hash_get(pb->statii,
+      const svn_wc_status3_t *status = apr_hash_get(pb->statii,
                                                     db->local_abspath,
                                                     APR_HASH_KEY_STRING);
-      /* Note that status->entry->url is NULL in the case of a missing
+      /* Note that status->url is NULL in the case of a missing
        * directory, which means we need to recurse up another level to
        * get a useful URL. */
-      if (status && status->entry && status->entry->url)
-        return status->entry->url;
+      if (status)
+        return status->url;
 
       url = find_dir_url(pb, pool);
       if (url)
@@ -1392,7 +1576,7 @@ make_dir_baton(void **dir_baton,
   struct edit_baton *eb = edit_baton;
   struct dir_baton *d = apr_pcalloc(pool, sizeof(*d));
   const char *local_abspath;
-  const svn_wc_status2_t *status_in_parent;
+  const svn_wc_status3_t *status_in_parent;
 
   SVN_ERR_ASSERT(path || (! pb));
 
@@ -1453,7 +1637,7 @@ make_dir_baton(void **dir_baton,
       && (status_in_parent->text_status != svn_wc_status_obstructed)
       && (status_in_parent->text_status != svn_wc_status_external)
       && (status_in_parent->text_status != svn_wc_status_ignored)
-      && (status_in_parent->entry->kind == svn_node_dir)
+      && (status_in_parent->kind == svn_node_dir)
       && (! d->excluded)
       && (d->depth == svn_depth_unknown
           || d->depth == svn_depth_infinity
@@ -1461,24 +1645,25 @@ make_dir_baton(void **dir_baton,
           || d->depth == svn_depth_immediates)
           )
     {
-      const svn_wc_status2_t *this_dir_status;
+      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,
-                             status_in_parent->entry, NULL,
-                             ignores, d->depth == svn_depth_files ?
+                             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, FALSE, hash_stash, d->statii,
-                             NULL, NULL, pool));
+                             TRUE, TRUE, TRUE, hash_stash, d->statii, NULL,
+                             NULL, pool));
 
       /* If we found a depth here, it should govern. */
       this_dir_status = apr_hash_get(d->statii, d->local_abspath,
                                      APR_HASH_KEY_STRING);
-      if (this_dir_status && this_dir_status->entry
+      if (this_dir_status && this_dir_status->versioned
           && (d->depth == svn_depth_unknown
-              || d->depth > status_in_parent->entry->depth))
+              || d->depth > status_in_parent->depth))
         {
-          d->depth = this_dir_status->entry->depth;
+          d->depth = this_dir_status->depth;
         }
     }
 
@@ -1516,7 +1701,7 @@ make_file_baton(struct dir_baton *parent
 
 
 svn_boolean_t
-svn_wc__is_sendable_status(const svn_wc_status2_t *status,
+svn_wc__is_sendable_status(const svn_wc_status3_t *status,
                            svn_boolean_t no_ignore,
                            svn_boolean_t get_all)
 {
@@ -1550,7 +1735,7 @@ svn_wc__is_sendable_status(const svn_wc_
   if ((status->prop_status != svn_wc_status_none)
       && (status->prop_status != svn_wc_status_normal))
     return TRUE;
-  if (status->tree_conflict)
+  if (status->conflicted)
     return TRUE;
 
   /* If it's locked or switched, send it. */
@@ -1562,11 +1747,11 @@ svn_wc__is_sendable_status(const svn_wc_
     return TRUE;
 
   /* If there is a lock token, send it. */
-  if (status->entry && status->entry->lock_token)
+  if (status->versioned && status->lock_token)
     return TRUE;
 
   /* If the entry is associated with a changelist, send it. */
-  if (status->entry && status->entry->changelist)
+  if (status->versioned && status->changelist)
     return TRUE;
 
   /* Otherwise, don't send it. */
@@ -1588,11 +1773,11 @@ struct status_baton
 static svn_error_t *
 mark_deleted(void *baton,
              const char *local_abspath,
-             const svn_wc_status2_t *status,
+             const svn_wc_status3_t *status,
              apr_pool_t *scratch_pool)
 {
   struct status_baton *sb = baton;
-  svn_wc_status2_t *new_status = svn_wc_dup_status2(status, scratch_pool);
+  svn_wc_status3_t *new_status = svn_wc_dup_status3(status, scratch_pool);
   new_status->repos_text_status = svn_wc_status_deleted;
   return sb->real_status_func(sb->real_status_baton, local_abspath,
                               new_status, scratch_pool);
@@ -1607,7 +1792,8 @@ mark_deleted(void *baton,
    a deletion.  Use POOL for all allocations. */
 static svn_error_t *
 handle_statii(struct edit_baton *eb,
-              const svn_wc_entry_t *dir_entry,
+              const char *dir_repos_root_url,
+              const char *dir_repos_relpath,
               apr_hash_t *statii,
               svn_boolean_t dir_was_deleted,
               svn_depth_t depth,
@@ -1615,7 +1801,7 @@ handle_statii(struct edit_baton *eb,
 {
   const apr_array_header_t *ignores = eb->ignores;
   apr_hash_index_t *hi;
-  apr_pool_t *subpool = svn_pool_create(pool);
+  apr_pool_t *iterpool = svn_pool_create(pool);
   svn_wc_status_func4_t status_func = eb->status_func;
   void *status_baton = eb->status_baton;
   struct status_baton sb;
@@ -1631,40 +1817,36 @@ handle_statii(struct edit_baton *eb,
   /* Loop over all the statuses still in our hash, handling each one. */
   for (hi = apr_hash_first(pool, statii); hi; hi = apr_hash_next(hi))
     {
-      const char *path = svn__apr_hash_index_key(hi);
-      svn_wc_status2_t *status = svn__apr_hash_index_val(hi);
+      const char *local_abspath = svn__apr_hash_index_key(hi);
+      svn_wc_status3_t *status = svn__apr_hash_index_val(hi);
 
       /* Clear the subpool. */
-      svn_pool_clear(subpool);
+      svn_pool_clear(iterpool);
 
       /* Now, handle the status.  We don't recurse for svn_depth_immediates
          because we already have the subdirectories' statii. */
       if (status->text_status != svn_wc_status_obstructed
           && status->text_status != svn_wc_status_missing
-          && status->entry && status->entry->kind == svn_node_dir
+          && status->versioned && status->kind == svn_node_dir
           && (depth == svn_depth_unknown
               || depth == svn_depth_infinity))
         {
-          const char *local_abspath;
-
-          SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, subpool));
-
           SVN_ERR(get_dir_status(&eb->wb,
-                                 local_abspath,
-                                 dir_entry, NULL,
-                                 ignores, depth, eb->get_all,
-                                 eb->no_ignore, TRUE, FALSE, status_func,
-                                 status_baton, eb->cancel_func,
-                                 eb->cancel_baton, subpool));
+                                 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));
         }
       if (dir_was_deleted)
         status->repos_text_status = svn_wc_status_deleted;
       if (svn_wc__is_sendable_status(status, eb->no_ignore, eb->get_all))
-        SVN_ERR((eb->status_func)(eb->status_baton, path, status, subpool));
+        SVN_ERR((eb->status_func)(eb->status_baton, local_abspath, status,
+                                  iterpool));
     }
 
   /* Destroy the subpool. */
-  svn_pool_destroy(subpool);
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
@@ -1709,21 +1891,16 @@ delete_entry(const char *path,
   struct dir_baton *db = parent_baton;
   struct edit_baton *eb = db->edit_baton;
   const char *local_abspath = svn_dirent_join(eb->anchor_abspath, path, pool);
-  const svn_wc_entry_t *entry;
+  svn_wc__db_kind_t kind;
 
   /* Note:  when something is deleted, it's okay to tweak the
      statushash immediately.  No need to wait until close_file or
      close_dir, because there's no risk of having to honor the 'added'
      flag.  We already know this item exists in the working copy. */
 
-  /* Read the parent's entries file.  If the deleted thing is not
-     versioned in this working copy, it was probably deleted via this
-     working copy.  No need to report such a thing. */
-  SVN_ERR(svn_wc__get_entry(&entry, eb->db, local_abspath, FALSE,
-                            svn_node_unknown, FALSE, pool, pool));
-
+  SVN_ERR(svn_wc__db_read_kind(&kind, eb->db, local_abspath, FALSE, pool));
   SVN_ERR(tweak_statushash(db, db, TRUE, eb->db,
-                           local_abspath, entry->kind == svn_node_dir,
+                           local_abspath, kind == svn_wc__db_kind_dir,
                            svn_wc_status_deleted, 0, revision, NULL, pool));
 
   /* Mark the parent dir -- it lost an entry (unless that parent dir
@@ -1732,7 +1909,7 @@ delete_entry(const char *path,
   if (db->parent_baton && (! *eb->target_basename))
     SVN_ERR(tweak_statushash(db->parent_baton, db, TRUE,eb->db,
                              db->local_abspath,
-                             entry->kind == svn_node_dir,
+                             kind == svn_wc__db_kind_dir,
                              svn_wc_status_modified, 0, SVN_INVALID_REVNUM,
                              NULL, pool));
 
@@ -1862,7 +2039,7 @@ close_directory(void *dir_baton,
           eb->anchor_status->repos_text_status = repos_text_status;
 
           /* If the root dir is out of date set the ood info directly too. */
-          if (db->ood_last_cmt_rev != eb->anchor_status->entry->revision)
+          if (db->ood_last_cmt_rev != eb->anchor_status->revision)
             {
               eb->anchor_status->ood_last_cmt_rev = db->ood_last_cmt_rev;
               eb->anchor_status->ood_last_cmt_date = db->ood_last_cmt_date;
@@ -1878,7 +2055,7 @@ close_directory(void *dir_baton,
   if (pb && ! db->excluded)
     {
       svn_boolean_t was_deleted = FALSE;
-      const svn_wc_status2_t *dir_status;
+      const svn_wc_status3_t *dir_status;
 
       /* See if the directory was deleted or replaced. */
       dir_status = apr_hash_get(pb->statii, db->local_abspath,
@@ -1889,7 +2066,8 @@ close_directory(void *dir_baton,
         was_deleted = TRUE;
 
       /* Now do the status reporting. */
-      SVN_ERR(handle_statii(eb, dir_status ? dir_status->entry : 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,
                                                   eb->get_all))
@@ -1903,20 +2081,19 @@ close_directory(void *dir_baton,
          target, we should only report the target. */
       if (*eb->target_basename)
         {
-          const svn_wc_status2_t *tgt_status;
+          const svn_wc_status3_t *tgt_status;
 
           tgt_status = apr_hash_get(db->statii, eb->target_abspath,
                                     APR_HASH_KEY_STRING);
           if (tgt_status)
             {
-              if (tgt_status->entry
-                  && tgt_status->entry->kind == svn_node_dir)
+              if (tgt_status->versioned
+                  && tgt_status->kind == svn_node_dir)
                 {
                   SVN_ERR(get_dir_status(&eb->wb, eb->target_abspath,
-                                         tgt_status->entry, NULL,
-                                         eb->ignores, eb->default_depth,
+                                         NULL, NULL, NULL, eb->ignores, 
+                                         eb->default_depth,
                                          eb->get_all, eb->no_ignore, TRUE,
-                                         FALSE,
                                          eb->status_func, eb->status_baton,
                                          eb->cancel_func, eb->cancel_baton,
                                          pool));
@@ -1932,7 +2109,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->entry,
+          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,
                                          eb->get_all))
@@ -2047,7 +2225,7 @@ close_file(void *file_baton,
   struct file_baton *fb = file_baton;
   enum svn_wc_status_kind repos_text_status;
   enum svn_wc_status_kind repos_prop_status;
-  svn_lock_t *repos_lock = NULL;
+  const svn_lock_t *repos_lock = NULL;
 
   /* If nothing has changed, return. */
   if (! (fb->added || fb->prop_changed || fb->text_changed))
@@ -2104,7 +2282,6 @@ close_edit(void *edit_baton,
                              eb->default_depth,
                              eb->get_all,
                              eb->no_ignore,
-                             FALSE,
                              eb->ignores,
                              eb->status_func,
                              eb->status_baton,
@@ -2225,7 +2402,6 @@ svn_wc_walk_status(svn_wc_context_t *wc_
                    svn_depth_t depth,
                    svn_boolean_t get_all,
                    svn_boolean_t no_ignore,
-                   svn_boolean_t get_excluded,
                    const apr_array_header_t *ignore_patterns,
                    svn_wc_status_func4_t status_func,
                    void *status_baton,
@@ -2256,7 +2432,7 @@ svn_wc_walk_status(svn_wc_context_t *wc_
       ignore_patterns = ignores;
     }
 
-  SVN_ERR(svn_wc__node_get_kind(&kind, wc_ctx, local_abspath, FALSE, scratch_pool));
+  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));
 
   if (kind == svn_node_file && local_kind == svn_node_file)
@@ -2264,13 +2440,13 @@ svn_wc_walk_status(svn_wc_context_t *wc_
       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,
-                             get_excluded,
                              status_func,
                              status_baton,
                              cancel_func,
@@ -2283,12 +2459,12 @@ svn_wc_walk_status(svn_wc_context_t *wc_
                              local_abspath,
                              NULL,
                              NULL,
+                             NULL,
                              ignore_patterns,
                              depth,
                              get_all,
                              no_ignore,
                              FALSE,
-                             get_excluded,
                              status_func,
                              status_baton,
                              cancel_func,
@@ -2300,13 +2476,13 @@ svn_wc_walk_status(svn_wc_context_t *wc_
       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,
-                             get_excluded,
                              status_func,
                              status_baton,
                              cancel_func,
@@ -2358,21 +2534,28 @@ svn_wc_get_default_ignores(apr_array_hea
 
 /* */
 static svn_error_t *
-internal_status(svn_wc_status2_t **status,
+internal_status(svn_wc_status3_t **status,
                 svn_wc__db_t *db,
                 const char *local_abspath,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
 {
-  const svn_wc_entry_t *entry = NULL;
-  const svn_wc_entry_t *parent_entry = NULL;
+  svn_node_kind_t path_kind;
+  svn_boolean_t path_special;
+  const svn_wc_entry_t *entry;
+  const char *parent_repos_relpath;
+  const char *parent_repos_root_url;
   svn_error_t *err;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
+  SVN_ERR(svn_io_check_special_path(local_abspath, &path_kind, &path_special,
+                                    scratch_pool));
+
   err = svn_wc__get_entry(&entry, db, local_abspath, TRUE,
                           svn_node_unknown, FALSE, scratch_pool, scratch_pool);
   if (err && (err->apr_err == SVN_ERR_WC_MISSING
+                || err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY
                 || err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND
                 || err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND))
     {
@@ -2385,38 +2568,70 @@ internal_status(svn_wc_status2_t **statu
   if (entry)
     {
       svn_boolean_t hidden;
-      SVN_ERR(svn_wc__entry_is_hidden(&hidden, entry));
 
+      SVN_ERR(svn_wc__entry_is_hidden(&hidden, entry));
       if (hidden)
         entry = NULL;
     }
+  if (entry == NULL)
+    return svn_error_return(assemble_unversioned(status,
+                                                 db, local_abspath,
+                                                 path_kind,
+                                                 FALSE /* is_ignored */,
+                                                 result_pool, scratch_pool));
 
-  if (entry && !svn_dirent_is_root(local_abspath, strlen(local_abspath)))
+  if (!svn_dirent_is_root(local_abspath, strlen(local_abspath)))
     {
+      svn_wc__db_status_t parent_status;
       const char *parent_abspath = svn_dirent_dirname(local_abspath,
                                                       scratch_pool);
 
-      err = svn_wc__get_entry(&parent_entry, db, parent_abspath, TRUE,
-                              svn_node_dir, FALSE, scratch_pool, scratch_pool);
-      if (err && (err->apr_err == SVN_ERR_WC_MISSING
-                    || err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND
-                    || err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND))
+      err = svn_wc__db_read_info(&parent_status, NULL, NULL,
+                                 &parent_repos_relpath, &parent_repos_root_url,
+                                 NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, db, parent_abspath, result_pool,
+                                 scratch_pool);
+
+      if (err && (err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY
+                  || err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND))
         {
           svn_error_clear(err);
-          parent_entry = NULL;
+          parent_repos_root_url = NULL;
+          parent_repos_relpath = NULL;
         }
       else if (err)
         return svn_error_return(err);
+
+      if (!err 
+          && parent_repos_relpath == NULL 
+          && parent_status != svn_wc__db_status_added
+          && parent_status != svn_wc__db_status_deleted)
+        SVN_ERR(svn_wc__db_scan_base_repos(&parent_repos_relpath,
+                                           &parent_repos_root_url, NULL,
+                                           db, local_abspath,
+                                           result_pool, scratch_pool));
+    }
+  else
+    {
+      parent_repos_root_url = NULL;
+      parent_repos_relpath = NULL;
     }
 
-  return assemble_status(status, db, local_abspath, entry,
-                         parent_entry, svn_node_unknown, FALSE, /* bogus */
-                         TRUE, FALSE, NULL, NULL, result_pool, scratch_pool);
+  return svn_error_return(assemble_status(status, db, local_abspath,
+                                          parent_repos_root_url,
+                                          parent_repos_relpath, path_kind,
+                                          path_special,
+                                          TRUE /* get_all */,
+                                          FALSE /* is_ignored */,
+                                          NULL /* repos_lock */,
+                                          result_pool, scratch_pool));
 }
 
 
 svn_error_t *
-svn_wc_status3(svn_wc_status2_t **status,
+svn_wc_status3(svn_wc_status3_t **status,
                svn_wc_context_t *wc_ctx,
                const char *local_abspath,
                apr_pool_t *result_pool,
@@ -2427,12 +2642,11 @@ svn_wc_status3(svn_wc_status2_t **status
                     scratch_pool));
 }
 
-
-svn_wc_status2_t *
-svn_wc_dup_status2(const svn_wc_status2_t *orig_stat,
+svn_wc_status3_t *
+svn_wc_dup_status3(const svn_wc_status3_t *orig_stat,
                    apr_pool_t *pool)
 {
-  svn_wc_status2_t *new_stat = apr_palloc(pool, sizeof(*new_stat));
+  svn_wc_status3_t *new_stat = apr_palloc(pool, sizeof(*new_stat));
 
   /* Shallow copy all members. */
   *new_stat = *orig_stat;
@@ -2447,13 +2661,36 @@ svn_wc_dup_status2(const svn_wc_status2_
   if (orig_stat->url)
     new_stat->url = apr_pstrdup(pool, orig_stat->url);
 
+  if (orig_stat->changed_author)
+    new_stat->changed_author = apr_pstrdup(pool, orig_stat->changed_author);
+
   if (orig_stat->ood_last_cmt_author)
     new_stat->ood_last_cmt_author
       = apr_pstrdup(pool, orig_stat->ood_last_cmt_author);
 
-  if (orig_stat->tree_conflict)
-    new_stat->tree_conflict
-      = svn_wc__conflict_description_dup(orig_stat->tree_conflict, pool);
+  if (orig_stat->lock_token)
+    new_stat->lock_token
+      = apr_pstrdup(pool, orig_stat->lock_token);
+
+  if (orig_stat->lock_owner)
+    new_stat->lock_owner
+      = apr_pstrdup(pool, orig_stat->lock_owner);
+
+  if (orig_stat->lock_comment)
+    new_stat->lock_comment
+      = apr_pstrdup(pool, orig_stat->lock_comment);
+
+  if (orig_stat->changelist)
+    new_stat->changelist
+      = apr_pstrdup(pool, orig_stat->changelist);
+
+  if (orig_stat->repos_root_url)
+    new_stat->repos_root_url
+      = apr_pstrdup(pool, orig_stat->repos_root_url);
+
+  if (orig_stat->repos_relpath)
+    new_stat->repos_relpath
+      = apr_pstrdup(pool, orig_stat->repos_relpath);
 
   /* Return the new hotness. */
   return new_stat;