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

svn commit: r943568 - in /subversion/trunk/subversion: include/svn_wc.h libsvn_wc/status.c

Author: gstein
Date: Wed May 12 16:22:37 2010
New Revision: 943568

URL: http://svn.apache.org/viewvc?rev=943568&view=rev
Log:
Split assemble_unversioned() out of assemble_status() for clarity. Adjust
some parameters and assumptions around these two functions.

* subversion/libsvn_wc/status.c:
  (assemble_status): ENTRY cannot be NULL, and PATH_KIND/SPECIAL MUST be
    provided. REPOS_LOCKS/REPOS_ROOT were only used by one code path, so
    the lookup code is moved there (send_status_structure) and the
    parmeter pair is replaced by REPOS_LOCK. ripped out all the
    unversioned status creation, moved to assemble_unversioned.
  (assemble_unversioned): new function, with a chunk of assemble_status
  (send_status_structure): look up REPOS_LOCK here and pass it to
    assemble_status.
  (send_unversioned_item): no need to take PATH_SPECIAL. rename param to
    SCRATCH_POOL. rejigger this function to use assemble_unversioned. no
    need to check status->repos_lock to determine whether to send this,
    since that cannot happen
  (handle_dir_entry): put constant values for PATH_KIND/SPECIAL in one
    path, since we know those. add param comments.
  (get_dir_status): add some param comments. remove PATH_SPECIAL from
    calls to send_unversioned_item.
  (tweak_statushash): constify the REPOS_LOCK param
  (close_file): constify the REPOS_LOCK localvar.
  (internal_status): fetch PATH_KIND/SPECIAL for passing to the assemble
    functions. no need to init ENTRY since we definitely assign it. if
    ENTRY is NULL, then use assemble_unversioned. adjust params to the
    assemble_status function.

* subversion/include/svn_wc.h:
  (svn_wc_status3_t): constify REPOS_LOCK member. remove @since tag on the
    URL member.
  (svn_wc_status2_t): remove closing comment about dup_status2 since we
    will never append members now.

Modified:
    subversion/trunk/subversion/include/svn_wc.h
    subversion/trunk/subversion/libsvn_wc/status.c

Modified: subversion/trunk/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_wc.h?rev=943568&r1=943567&r2=943568&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_wc.h (original)
+++ subversion/trunk/subversion/include/svn_wc.h Wed May 12 16:22:37 2010
@@ -3550,11 +3550,9 @@ typedef struct svn_wc_status3_t
   enum svn_wc_status_kind repos_prop_status;
 
   /** The entry's lock in the repository, if any. */
-  svn_lock_t *repos_lock;
+  const svn_lock_t *repos_lock;
 
-  /** Set to the URI (actual or expected) of the item.
-   * @since New in 1.3
-   */
+  /** Set to the URI (actual or expected) of the item. */
   const char *url;
 
   /**
@@ -3763,7 +3761,6 @@ typedef struct svn_wc_status2_t
    */
   enum svn_wc_status_kind pristine_prop_status;
 
-  /* NOTE! Please update svn_wc_dup_status2() when adding new fields here. */
 } svn_wc_status2_t;
 
 

Modified: subversion/trunk/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/status.c?rev=943568&r1=943567&r2=943568&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/status.c (original)
+++ subversion/trunk/subversion/libsvn_wc/status.c Wed May 12 16:22:37 2010
@@ -250,20 +250,12 @@ internal_status(svn_wc_status3_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,9 +265,7 @@ internal_status(svn_wc_status3_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_status3_t **status,
@@ -287,8 +277,7 @@ assemble_status(svn_wc_status3_t **statu
                 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)
 {
@@ -314,32 +303,7 @@ assemble_status(svn_wc_status3_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;
-
-  /* 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));
+  SVN_ERR_ASSERT(entry != NULL);
 
   /* Find out whether the path is a tree conflict victim.
    * This function will set tree_conflict to NULL if the path
@@ -347,61 +311,6 @@ assemble_status(svn_wc_status3_t **statu
   SVN_ERR(svn_wc__db_op_read_tree_conflict(&tree_conflict, db, local_abspath,
                                            scratch_pool, scratch_pool));
 
-  if (! entry)
-    {
-      /* 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->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 (is_ignored)
-            stat->text_status = svn_wc_status_ignored;
-          else
-            stat->text_status = svn_wc_status_unversioned;
-        }
-
-      /* 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;
-
-      stat->repos_lock = repos_lock;
-      stat->url = NULL;
-      stat->revision = SVN_INVALID_REVNUM;
-      stat->changed_rev = SVN_INVALID_REVNUM;
-      stat->changed_author = NULL;
-      stat->changed_date = 0;
-      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->lock_token = NULL;
-      stat->lock_owner = NULL;
-      stat->lock_comment = NULL;
-      stat->lock_creation_date = 0;
-      /* 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->versioned = FALSE;
-
-      *status = stat;
-      return SVN_NO_ERROR;
-    }
-
   SVN_ERR(svn_wc__db_read_info(&db_status, &db_kind, &revision,
                                NULL, NULL, NULL,
                                &changed_rev, &changed_date, &changed_author,
@@ -668,8 +577,12 @@ assemble_status(svn_wc_status3_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)
+        && (! entry->lock_token)
+        && (! repos_lock)
+        && (! entry->changelist)
         && (! tree_conflict))
       {
         *status = NULL;
@@ -714,6 +627,65 @@ assemble_status(svn_wc_status3_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->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);
+
+  *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().  */
@@ -731,12 +703,33 @@ send_status_structure(const struct walk_
                       apr_pool_t *pool)
 {
   svn_wc_status3_t *statstruct;
+  const svn_lock_t *repos_lock = NULL;
 
   SVN_ERR_ASSERT(entry != NULL);
 
+  /* Check for a repository lock. */
+  if (wb->repos_locks)
+    {
+      const char *abs_path;  /* uri-encoded repos_relpath  */
+
+      if (entry->url)
+        abs_path = entry->url + strlen(wb->repos_root);
+      else if (parent_entry && parent_entry->url)
+        abs_path = svn_uri_join(parent_entry->url + strlen(wb->repos_root),
+                                svn_dirent_basename(local_abspath, NULL),
+                                pool);
+      else
+        abs_path = NULL;
+
+      if (abs_path)
+        repos_lock = apr_hash_get(wb->repos_locks,
+                                  svn_path_uri_decode(abs_path, pool),
+                                  APR_HASH_KEY_STRING);
+    }
+
   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,
+                          is_ignored, repos_lock,
                           pool, pool));
 
   if (statstruct && status_func)
@@ -851,31 +844,26 @@ 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_boolean_t is_ignored;
+  svn_boolean_t is_external;
   svn_wc_status3_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 /* entry */,
-                          NULL /* parent_entry */,
-                          path_kind, path_special,
-                          FALSE /* get_all */,
-                          ignore,
-                          NULL /* repos_locks */,
-                          wb->repos_root,
-                          pool, pool));
+  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;
 
@@ -883,13 +871,13 @@ send_unversioned_item(const struct walk_
    * delete on a locally deleted path during an update. Don't ever ignore
    * those! */
   if (status->conflicted)
-    ignore = FALSE;
+    is_ignored = 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 svn_error_return((*status_func)(status_baton, local_abspath, status,
-                                           pool));
+  /* 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;
 }
@@ -959,8 +947,9 @@ handle_dir_entry(const struct walk_statu
           /* 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, entry,
-                                        dir_entry, path_kind, path_special,
-                                        get_all, FALSE,
+                                        dir_entry,
+                                        svn_node_dir, FALSE /* path_special */,
+                                        get_all, FALSE /* is_ignored */,
                                         status_func, status_baton, pool));
         }
     }
@@ -969,9 +958,10 @@ handle_dir_entry(const struct walk_statu
       /* This is a file/symlink on-disk.  */
       SVN_ERR(send_status_structure(wb, local_abspath, entry,
                                     dir_entry, path_kind, path_special,
-                                    get_all, FALSE,
+                                    get_all, FALSE /* is_ignored */,
                                     status_func, status_baton, pool));
     }
+
   return SVN_NO_ERROR;
 }
 
@@ -1137,9 +1127,11 @@ get_dir_status(const struct walk_status_
       /* 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));
+                                      dir_entry, parent_entry,
+                                      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)
@@ -1242,7 +1234,6 @@ get_dir_status(const struct walk_status_
                                         node_abspath,
                                         dirent_p ? dirent_p->kind
                                                  : svn_node_none,
-                                        dirent_p ? dirent_p->special : FALSE,
                                         patterns,
                                         no_ignore,
                                         status_func,
@@ -1270,7 +1261,6 @@ get_dir_status(const struct walk_status_
       SVN_ERR(send_unversioned_item(wb,
                                     node_abspath,
                                     dirent_p->kind,
-                                    dirent_p->special,
                                     patterns,
                                     no_ignore || selected,
                                     status_func, status_baton,
@@ -1345,7 +1335,7 @@ 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_status3_t *statstruct;
@@ -2158,7 +2148,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))
@@ -2475,12 +2465,17 @@ internal_status(svn_wc_status3_t **statu
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
 {
-  const svn_wc_entry_t *entry = NULL;
+  svn_node_kind_t path_kind;
+  svn_boolean_t path_special;
+  const svn_wc_entry_t *entry;
   const svn_wc_entry_t *parent_entry = NULL;
   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
@@ -2497,13 +2492,19 @@ internal_status(svn_wc_status3_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)))
     {
       const char *parent_abspath = svn_dirent_dirname(local_abspath,
                                                       scratch_pool);
@@ -2522,12 +2523,12 @@ internal_status(svn_wc_status3_t **statu
         return svn_error_return(err);
     }
 
-  return svn_error_return(assemble_status(status, db, local_abspath, entry,
-                                          parent_entry, svn_node_unknown,
-                                          FALSE /* path_special (bogus) */,
+  return svn_error_return(assemble_status(status, db, local_abspath,
+                                          entry, parent_entry,
+                                          path_kind, path_special,
                                           TRUE /* get_all */,
                                           FALSE /* is_ignored */,
-                                          NULL, NULL,
+                                          NULL /* repos_lock */,
                                           result_pool, scratch_pool));
 }