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 2011/08/24 17:16:55 UTC

svn commit: r1161147 [6/9] - in /subversion/branches/revprop-packing: ./ build/ build/ac-macros/ notes/ subversion/bindings/ctypes-python/csvn/ subversion/bindings/ctypes-python/test/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/or...

Modified: subversion/branches/revprop-packing/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_wc/node.c?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_wc/node.c Wed Aug 24 15:16:50 2011
@@ -182,7 +182,7 @@ svn_wc__internal_get_repos_info(const ch
       const char *base_del_abspath, *wrk_del_abspath;
 
       SVN_ERR(svn_wc__db_scan_deletion(&base_del_abspath, NULL,
-                                       &wrk_del_abspath,
+                                       &wrk_del_abspath, NULL,
                                        db, local_abspath,
                                        scratch_pool, scratch_pool));
 
@@ -748,6 +748,33 @@ svn_wc__node_is_status_deleted(svn_boole
 }
 
 svn_error_t *
+svn_wc__node_get_deleted_ancestor(const char **deleted_ancestor_abspath,
+                                  svn_wc_context_t *wc_ctx,
+                                  const char *local_abspath,
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool)
+{
+  svn_wc__db_status_t status;
+
+  *deleted_ancestor_abspath = NULL;
+
+  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, NULL,
+                               NULL, NULL, NULL, NULL, NULL,
+                               wc_ctx->db, local_abspath,
+                               scratch_pool, scratch_pool));
+
+  if (status == svn_wc__db_status_deleted)
+    SVN_ERR(svn_wc__db_scan_deletion(deleted_ancestor_abspath, NULL, NULL,
+                                     NULL, wc_ctx->db, local_abspath,
+                                     result_pool, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_wc__node_is_status_server_excluded(svn_boolean_t *is_server_excluded,
                                        svn_wc_context_t *wc_ctx,
                                        const char *local_abspath,
@@ -990,7 +1017,7 @@ svn_wc__internal_get_commit_base_rev(svn
       const char *work_del_abspath;
 
       SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
-                                       &work_del_abspath,
+                                       &work_del_abspath, NULL,
                                        db, local_abspath,
                                        scratch_pool, scratch_pool));
       if (work_del_abspath != NULL)
@@ -1133,7 +1160,7 @@ svn_wc__internal_node_get_schedule(svn_w
 
               /* Find out details of our deletion.  */
               SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
-                                               &work_del_abspath,
+                                               &work_del_abspath, NULL,
                                                db, local_abspath,
                                                scratch_pool, scratch_pool));
 
@@ -1620,7 +1647,6 @@ svn_wc__check_for_obstructions(svn_wc_no
                                svn_node_kind_t *kind,
                                svn_boolean_t *added,
                                svn_boolean_t *deleted,
-                               svn_boolean_t *conflicted,
                                svn_wc_context_t *wc_ctx,
                                const char *local_abspath,
                                svn_boolean_t no_wcroot_check,
@@ -1629,7 +1655,6 @@ svn_wc__check_for_obstructions(svn_wc_no
   svn_wc__db_status_t status;
   svn_wc__db_kind_t db_kind;
   svn_node_kind_t disk_kind;
-  svn_boolean_t conflicted_p;
   svn_error_t *err;
 
   *obstruction_state = svn_wc_notify_state_inapplicable;
@@ -1639,14 +1664,12 @@ svn_wc__check_for_obstructions(svn_wc_no
     *added = FALSE;
   if (deleted)
     *deleted = FALSE;
-  if (conflicted)
-    *conflicted = FALSE;
 
   SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
 
   err = svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, &conflicted_p, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL,
                              wc_ctx->db, local_abspath,
                              scratch_pool, scratch_pool);
@@ -1752,16 +1775,32 @@ svn_wc__check_for_obstructions(svn_wc_no
         SVN_ERR_MALFUNCTION();
     }
 
-  if (conflicted_p && (conflicted != NULL))
-    {
-      svn_boolean_t text_c, prop_c, tree_c;
+  return SVN_NO_ERROR;
+}
 
-      SVN_ERR(svn_wc__internal_conflicted_p(&text_c, &prop_c, &tree_c,
-                                            wc_ctx->db, local_abspath,
-                                            scratch_pool));
 
-      *conflicted = (text_c || prop_c || tree_c);
-    }
+svn_error_t *
+svn_wc__node_was_moved_away(const char **moved_to_abspath,
+                            const char **op_root_abspath,
+                            svn_wc_context_t *wc_ctx,
+                            const char *local_abspath,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  svn_boolean_t is_deleted;
+
+  if (moved_to_abspath)
+    *moved_to_abspath = NULL;
+  if (op_root_abspath)
+    *op_root_abspath = NULL;
+
+  SVN_ERR(svn_wc__node_is_status_deleted(&is_deleted, wc_ctx, local_abspath,
+                                         scratch_pool));
+  if (is_deleted)
+    SVN_ERR(svn_wc__db_scan_deletion(NULL, moved_to_abspath, NULL,
+                                     op_root_abspath, wc_ctx->db,
+                                     local_abspath,
+                                     result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/revprop-packing/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_wc/status.c?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_wc/status.c Wed Aug 24 15:16:50 2011
@@ -273,6 +273,68 @@ read_info(const struct svn_wc__db_info_t
                                        &mtb->lock, NULL, NULL,
                                        db, local_abspath,
                                        result_pool, scratch_pool));
+
+      if (mtb->status == svn_wc__db_status_deleted)
+        {
+          const char *moved_to_abspath;
+          const char *moved_to_op_root_abspath;
+          
+          /* NOTE: we can't use op-root-ness as a condition here since a base
+           * node can be the root of a move and still not be an explicit
+           * op-root (having a working node with op_depth == pathelements).
+           *
+           * Both these (almost identical) situations showcase this:
+           *   svn mv a/b bb
+           *   svn del a
+           * and
+           *   svn mv a aa  
+           *   svn mv aa/b bb
+           * In both, 'bb' is moved from 'a/b', but 'a/b' has no op_depth>0
+           * node at all, as its parent 'a' is locally deleted. */
+
+          SVN_ERR(svn_wc__db_scan_deletion(NULL,
+                                           &moved_to_abspath,
+                                           NULL,
+                                           &moved_to_op_root_abspath,
+                                           db, local_abspath,
+                                           scratch_pool, scratch_pool));
+          if (moved_to_abspath != NULL
+              && moved_to_op_root_abspath != NULL
+              && strcmp(moved_to_abspath, moved_to_op_root_abspath) == 0)
+            {
+              mtb->moved_to_abspath = apr_pstrdup(result_pool,
+                                                  moved_to_abspath);
+            }
+          /* ### ^^^ THIS SUCKS. For at least two reasons:
+           * 1) We scan the node deletion and that's technically not necessary.
+           *    We'd be fine to know if this is an actual root of a move.
+           * 2) From the elaborately calculated results, we backwards-guess
+           *    whether this is a root.
+           * It works ok, and this code only gets called when a node is an
+           * explicit target of a 'status'. But it would be better to do this
+           * differently.
+           * We could return moved-to via svn_wc__db_base_get_info() (called
+           * just above), but as moved-to is only intended to be returned for
+           * roots of a move, that doesn't fit too well. */
+        }
+    }
+
+  /* ### svn_wc__db_read_info() could easily return the moved-here flag. But
+   * for now... (The per-dir query for recursive status is far more optimal.)
+   * Note that this actually scans around to get the full path, for a bool.
+   * This bool then gets returned, later is evaluated, and if true leads to
+   * the same paths being scanned again. We'd want to obtain this bool here as
+   * cheaply as svn_wc__db_read_children_info() does. */
+  if (mtb->status == svn_wc__db_status_added)
+    {
+      const char *moved_from_abspath = NULL;
+      SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL, NULL,
+                                       &moved_from_abspath,
+                                       NULL,
+                                       db, local_abspath,
+                                       result_pool, scratch_pool));
+      mtb->moved_here = (moved_from_abspath != NULL);
     }
 
   mtb->has_checksum = (checksum != NULL);
@@ -365,7 +427,7 @@ internal_status(svn_wc_status3_t **statu
 /* Fill in *STATUS for LOCAL_ABSPATH, using DB. Allocate *STATUS in
    RESULT_POOL and use SCRATCH_POOL for temporary allocations.
 
-   PARENT_REPOS_ROOT_URL and PARENT_REPOS_RELPATH are the the repository root
+   PARENT_REPOS_ROOT_URL and PARENT_REPOS_RELPATH are the repository root
    and repository relative path of the parent of LOCAL_ABSPATH or NULL if
    LOCAL_ABSPATH doesn't have a versioned parent directory.
 
@@ -403,6 +465,7 @@ assemble_status(svn_wc_status3_t **statu
   const char *repos_relpath;
   const char *repos_root_url;
   const char *repos_uuid;
+  const char *moved_from_abspath = NULL;
   svn_filesize_t filesize = (dirent && (dirent->kind == svn_node_file))
                                 ? dirent->filesize
                                 : SVN_INVALID_FILESIZE;
@@ -423,17 +486,13 @@ assemble_status(svn_wc_status3_t **statu
       /* A node is switched if it doesn't have the implied repos_relpath */
       const char *name = svn_relpath_skip_ancestor(parent_repos_relpath,
                                                    info->repos_relpath);
-      switched_p = !name || (strcmp(name, svn_dirent_basename(local_abspath, NULL)) != 0);
+      switched_p = !name || (strcmp(name,
+                                    svn_dirent_basename(local_abspath, NULL))
+                             != 0);
     }
 
-  /* Examine whether our target is missing or obstructed or missing.
-
-     While we are not completely in single-db mode yet, data about
-     obstructed or missing nodes might be incomplete here. This is
-     reported by svn_wc_db_status_obstructed_XXXX. In single-db
-     mode these obstructions are no longer reported and we have
-     to detect obstructions by looking at the on disk status in DIRENT.
-     */
+  /* Examine whether our target is missing or obstructed. To detect
+   * obstructions, we have to look at the on-disk status in DIRENT. */
   if (info->kind == svn_wc__db_kind_dir)
     {
       if (info->status == svn_wc__db_status_incomplete)
@@ -605,9 +664,19 @@ assemble_status(svn_wc_status3_t **statu
               else if (schedule == svn_wc_schedule_replace)
                 node_status = svn_wc_status_replaced;
             }
+
+          /* Get moved-from info (only for potential op-roots of a move). */
+          if (info->moved_here && info->op_root)
+            SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
+                                             NULL, NULL, NULL, NULL,
+                                             &moved_from_abspath,
+                                             NULL,
+                                             db, local_abspath,
+                                             result_pool, scratch_pool));
         }
     }
 
+
   if (node_status == svn_wc_status_normal)
     node_status = text_status;
 
@@ -700,6 +769,9 @@ assemble_status(svn_wc_status3_t **statu
   stat->repos_relpath = repos_relpath;
   stat->repos_uuid = repos_uuid;
 
+  stat->moved_from_abspath = moved_from_abspath;
+  stat->moved_to_abspath = info->moved_to_abspath;
+
   *status = stat;
 
   return SVN_NO_ERROR;
@@ -1057,8 +1129,8 @@ get_dir_status(const struct walk_status_
          don't all map the same types, but only the keys of the result
          hash are subsequently used. */
       SVN_ERR(svn_wc__db_read_children_info(&nodes, &conflicts,
-                                        wb->db, local_abspath,
-                                        subpool, iterpool));
+                                            wb->db, local_abspath,
+                                            subpool, iterpool));
 
       all_children = apr_hash_overlay(subpool, nodes, dirents);
       if (apr_hash_count(conflicts) > 0)
@@ -1705,7 +1777,7 @@ handle_statii(struct edit_baton *eb,
 
 /*** The callbacks we'll plug into an svn_delta_editor_t structure. ***/
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 set_target_revision(void *edit_baton,
                     svn_revnum_t target_revision,
@@ -1717,7 +1789,7 @@ set_target_revision(void *edit_baton,
 }
 
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 open_root(void *edit_baton,
           svn_revnum_t base_revision,
@@ -1730,7 +1802,7 @@ open_root(void *edit_baton,
 }
 
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 delete_entry(const char *path,
              svn_revnum_t revision,
@@ -1766,7 +1838,7 @@ delete_entry(const char *path,
 }
 
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 add_directory(const char *path,
               void *parent_baton,
@@ -1792,7 +1864,7 @@ add_directory(const char *path,
 }
 
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 open_directory(const char *path,
                void *parent_baton,
@@ -1805,7 +1877,7 @@ open_directory(const char *path,
 }
 
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 change_dir_prop(void *dir_baton,
                 const char *name,
@@ -1836,7 +1908,7 @@ change_dir_prop(void *dir_baton,
 
 
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 close_directory(void *dir_baton,
                 apr_pool_t *pool)
@@ -1986,7 +2058,7 @@ close_directory(void *dir_baton,
 
 
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 add_file(const char *path,
          void *parent_baton,
@@ -2009,7 +2081,7 @@ add_file(const char *path,
 }
 
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 open_file(const char *path,
           void *parent_baton,
@@ -2025,7 +2097,7 @@ open_file(const char *path,
 }
 
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 apply_textdelta(void *file_baton,
                 const char *base_checksum,
@@ -2046,7 +2118,7 @@ apply_textdelta(void *file_baton,
 }
 
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 change_file_prop(void *file_baton,
                  const char *name,
@@ -2078,7 +2150,7 @@ change_file_prop(void *file_baton,
 }
 
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 close_file(void *file_baton,
            const char *text_checksum,  /* ignored, as we receive no data */
@@ -2135,7 +2207,7 @@ close_file(void *file_baton,
                           SVN_INVALID_REVNUM, repos_lock, pool);
 }
 
-/* */
+/* An svn_delta_editor_t function. */
 static svn_error_t *
 close_edit(void *edit_baton,
            apr_pool_t *pool)
@@ -2464,21 +2536,24 @@ internal_status(svn_wc_status3_t **statu
                              db, local_abspath,
                              scratch_pool, scratch_pool);
 
-  if ((err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-      || node_status == svn_wc__db_status_not_present
-      || node_status == svn_wc__db_status_server_excluded
-      || node_status == svn_wc__db_status_excluded)
+  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
     {
       svn_error_clear(err);
       node_kind = svn_wc__db_kind_unknown;
-
       /* Ensure conflicted is always set, but don't hide tree conflicts
          on 'hidden' nodes. */
-      if (err)
-        conflicted = FALSE;
+      conflicted = FALSE;
+    }
+  else if (err)
+    {
+        return svn_error_trace(err);
+    }
+  else if (node_status == svn_wc__db_status_not_present
+           || node_status == svn_wc__db_status_server_excluded
+           || node_status == svn_wc__db_status_excluded)
+    {
+      node_kind = svn_wc__db_kind_unknown;
     }
-  else
-    SVN_ERR(err);
 
   if (node_kind == svn_wc__db_kind_unknown)
     return svn_error_trace(assemble_unversioned(status,
@@ -2588,6 +2663,14 @@ svn_wc_dup_status3(const svn_wc_status3_
     new_stat->repos_uuid
       = apr_pstrdup(pool, orig_stat->repos_uuid);
 
+  if (orig_stat->moved_from_abspath)
+    new_stat->moved_from_abspath
+      = apr_pstrdup(pool, orig_stat->moved_from_abspath);
+
+  if (orig_stat->moved_to_abspath)
+    new_stat->moved_to_abspath
+      = apr_pstrdup(pool, orig_stat->moved_to_abspath);
+
   /* Return the new hotness. */
   return new_stat;
 }

Modified: subversion/branches/revprop-packing/subversion/libsvn_wc/tree_conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_wc/tree_conflicts.c?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_wc/tree_conflicts.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_wc/tree_conflicts.c Wed Aug 24 15:16:50 2011
@@ -76,6 +76,8 @@ const svn_token_map_t svn_wc__conflict_r
   { "added",       svn_wc_conflict_reason_added },
   { "replaced",    svn_wc_conflict_reason_replaced },
   { "unversioned", svn_wc_conflict_reason_unversioned },
+  { "moved-here", svn_wc_conflict_reason_moved_here },
+  { "moved-away", svn_wc_conflict_reason_moved_away },
   { NULL }
 };
 

Modified: subversion/branches/revprop-packing/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_wc/update_editor.c?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_wc/update_editor.c Wed Aug 24 15:16:50 2011
@@ -699,6 +699,10 @@ struct file_baton
   /* Absolute path to this file */
   const char *local_abspath;
 
+  /* Absolute path to the new location of the file if it was moved away.
+   * If the file was not moved away, this is NULL. */
+  const char *moved_to_abspath;
+
   /* The repository relative path this file will correspond to. */
   const char *new_relpath;
 
@@ -775,7 +779,6 @@ make_file_baton(struct file_baton **f_p,
 {
   struct edit_baton *eb = pb->edit_baton;
   apr_pool_t *file_pool = svn_pool_create(pb->pool);
-
   struct file_baton *f = apr_pcalloc(file_pool, sizeof(*f));
 
   SVN_ERR_ASSERT(path);
@@ -1272,7 +1275,8 @@ create_tree_conflict(svn_wc_conflict_des
   /* Get the source-left information, i.e. the local state of the node
    * before any changes were made to the working copy, i.e. the state the
    * node would have if it was reverted. */
-  if (reason == svn_wc_conflict_reason_added)
+  if (reason == svn_wc_conflict_reason_added ||
+      reason == svn_wc_conflict_reason_moved_here)
     {
       svn_wc__db_status_t added_status;
 
@@ -1327,6 +1331,7 @@ create_tree_conflict(svn_wc_conflict_des
        * and that other case should also be handled. */
       SVN_ERR_ASSERT(reason == svn_wc_conflict_reason_edited
                      || reason == svn_wc_conflict_reason_deleted
+                     || reason == svn_wc_conflict_reason_moved_away
                      || reason == svn_wc_conflict_reason_replaced
                      || reason == svn_wc_conflict_reason_obstructed);
 
@@ -1364,7 +1369,8 @@ create_tree_conflict(svn_wc_conflict_des
       /* This is an 'update', so REPOS_RELPATH would be the same as for
        * source-left. However, we don't have a source-left for locally
        * added files. */
-      right_repos_relpath = (reason == svn_wc_conflict_reason_added ?
+      right_repos_relpath = ((reason == svn_wc_conflict_reason_added ||
+                              reason == svn_wc_conflict_reason_moved_here) ?
                              added_repos_relpath : left_repos_relpath);
       if (! right_repos_relpath)
         right_repos_relpath = their_relpath;
@@ -1451,6 +1457,7 @@ check_tree_conflict(svn_wc_conflict_desc
                     svn_wc_conflict_action_t action,
                     svn_node_kind_t their_node_kind,
                     const char *their_relpath,
+                    const char *moved_to_abspath,
                     apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool)
 {
@@ -1496,7 +1503,18 @@ check_tree_conflict(svn_wc_conflict_desc
              * would not have been called in the first place. */
             SVN_ERR_ASSERT(action == svn_wc_conflict_action_add);
 
-            reason = svn_wc_conflict_reason_added;
+            /* Scan the addition in case our caller didn't. */
+            if (working_status == svn_wc__db_status_added)
+              SVN_ERR(svn_wc__db_scan_addition(&working_status, NULL, NULL,
+                                               NULL, NULL, NULL, NULL,
+                                               NULL, NULL, NULL, NULL,
+                                               eb->db, local_abspath,
+                                               scratch_pool, scratch_pool));
+
+            if (working_status == svn_wc__db_status_moved_here)
+              reason = svn_wc_conflict_reason_moved_here;
+            else
+              reason = svn_wc_conflict_reason_added;
           }
         else
           {
@@ -1507,8 +1525,8 @@ check_tree_conflict(svn_wc_conflict_desc
 
 
       case svn_wc__db_status_deleted:
-        /* The node is locally deleted. */
-        reason = svn_wc_conflict_reason_deleted;
+        if (!moved_to_abspath)
+          reason = svn_wc_conflict_reason_deleted;
         break;
 
       case svn_wc__db_status_incomplete:
@@ -1573,6 +1591,7 @@ check_tree_conflict(svn_wc_conflict_desc
    * would not have been called in the first place.*/
   if (reason == svn_wc_conflict_reason_edited
       || reason == svn_wc_conflict_reason_deleted
+      || reason == svn_wc_conflict_reason_moved_away
       || reason == svn_wc_conflict_reason_replaced)
     /* When the node existed before (it was locally deleted, replaced or
      * edited), then 'update' cannot add it "again". So it can only send
@@ -1580,7 +1599,8 @@ check_tree_conflict(svn_wc_conflict_desc
     SVN_ERR_ASSERT(action == svn_wc_conflict_action_edit
                    || action == svn_wc_conflict_action_delete
                    || action == svn_wc_conflict_action_replace);
-  else if (reason == svn_wc_conflict_reason_added)
+  else if (reason == svn_wc_conflict_reason_added ||
+           reason == svn_wc_conflict_reason_moved_here)
     /* When the node did not exist before (it was locally added), then 'update'
      * cannot want to modify it in any way. It can only send _action_add. */
     SVN_ERR_ASSERT(action == svn_wc_conflict_action_add);
@@ -1797,7 +1817,7 @@ delete_entry(const char *path,
       SVN_ERR(check_tree_conflict(&tree_conflict, eb, local_abspath,
                                   status, kind, TRUE,
                                   svn_wc_conflict_action_delete, svn_node_none,
-                                  repos_relpath, pb->pool, scratch_pool));
+                                  repos_relpath, NULL, pb->pool, scratch_pool));
     }
 
   if (tree_conflict != NULL)
@@ -1835,6 +1855,7 @@ delete_entry(const char *path,
              keeping a not-present marker */
         }
       else if (tree_conflict->reason == svn_wc_conflict_reason_deleted
+               || tree_conflict->reason == svn_wc_conflict_reason_moved_away
                || tree_conflict->reason == svn_wc_conflict_reason_replaced)
         {
           /* The item does not exist locally because it was already shadowed.
@@ -2154,7 +2175,7 @@ add_directory(const char *path,
                                       status, wc_kind, FALSE,
                                       svn_wc_conflict_action_add,
                                       svn_node_dir, db->new_relpath,
-                                      pool, pool));
+                                      NULL, pool, pool));
         }
 
       if (tree_conflict == NULL)
@@ -2346,7 +2367,7 @@ open_directory(const char *path,
     SVN_ERR(check_tree_conflict(&tree_conflict, eb, db->local_abspath,
                                 status, wc_kind, TRUE,
                                 svn_wc_conflict_action_edit, svn_node_dir,
-                                db->new_relpath, db->pool, pool));
+                                db->new_relpath, NULL, db->pool, pool));
 
   /* Remember the roots of any locally deleted trees. */
   if (tree_conflict != NULL)
@@ -2355,6 +2376,7 @@ open_directory(const char *path,
       /* Other modifications wouldn't be a tree conflict */
       SVN_ERR_ASSERT(
                 tree_conflict->reason == svn_wc_conflict_reason_deleted ||
+                tree_conflict->reason == svn_wc_conflict_reason_moved_away ||
                 tree_conflict->reason == svn_wc_conflict_reason_replaced);
 
       /* Continue updating BASE */
@@ -3179,7 +3201,7 @@ add_file(const char *path,
                                       fb->local_abspath,
                                       status, wc_kind, FALSE,
                                       svn_wc_conflict_action_add,
-                                      svn_node_file, fb->new_relpath,
+                                      svn_node_file, fb->new_relpath, NULL,
                                       scratch_pool, scratch_pool));
         }
 
@@ -3312,6 +3334,12 @@ open_file(const char *path,
                                      eb->db, fb->local_abspath,
                                      fb->pool, scratch_pool));
 
+  /* If the file has moved locally look up its new location. */
+  if (status == svn_wc__db_status_deleted)
+    SVN_ERR(svn_wc__db_scan_deletion(NULL, &fb->moved_to_abspath, NULL, NULL,
+                                     eb->db, fb->local_abspath,
+                                     fb->pool, scratch_pool));
+
   /* Is this path a conflict victim? */
   if (conflicted)
     SVN_ERR(node_already_conflicted(&conflicted, eb->db,
@@ -3339,7 +3367,8 @@ open_file(const char *path,
     SVN_ERR(check_tree_conflict(&tree_conflict, eb, fb->local_abspath,
                                 status, wc_kind, TRUE,
                                 svn_wc_conflict_action_edit, svn_node_file,
-                                fb->new_relpath, fb->pool, scratch_pool));
+                                fb->new_relpath, fb->moved_to_abspath,
+                                fb->pool, scratch_pool));
 
   /* Is this path the victim of a newly-discovered tree conflict? */
   if (tree_conflict != NULL)
@@ -3349,6 +3378,7 @@ open_file(const char *path,
       /* Other modifications wouldn't be a tree conflict */
       SVN_ERR_ASSERT(
                 tree_conflict->reason == svn_wc_conflict_reason_deleted ||
+                tree_conflict->reason == svn_wc_conflict_reason_moved_away||
                 tree_conflict->reason == svn_wc_conflict_reason_replaced);
 
       /* Continue updating BASE */
@@ -3683,6 +3713,8 @@ merge_file(svn_skel_t **work_items,
   svn_boolean_t is_locally_modified;
   enum svn_wc_merge_outcome_t merge_outcome = svn_wc_merge_unchanged;
   svn_skel_t *work_item;
+  const char *working_abspath = fb->moved_to_abspath ? fb->moved_to_abspath
+                                                     : fb->local_abspath;
 
   SVN_ERR_ASSERT(! fb->shadowed && !fb->obstruction_found);
 
@@ -3727,7 +3759,7 @@ merge_file(svn_skel_t **work_items,
          files that do not exist and for directories. */
 
       SVN_ERR(svn_wc__internal_file_modified_p(&is_locally_modified,
-                                               eb->db, fb->local_abspath,
+                                               eb->db, working_abspath,
                                                FALSE /* exact_comparison */,
                                                scratch_pool));
     }
@@ -3771,7 +3803,7 @@ merge_file(svn_skel_t **work_items,
       SVN_ERR(svn_wc__perform_file_merge(work_items,
                                          &merge_outcome,
                                          eb->db,
-                                         fb->local_abspath,
+                                         working_abspath,
                                          pb->local_abspath,
                                          fb->new_text_base_sha1_checksum,
                                          fb->add_existed
@@ -3803,7 +3835,7 @@ merge_file(svn_skel_t **work_items,
       SVN_ERR(svn_wc__get_translate_info(NULL, NULL,
                                          &keywords,
                                          NULL,
-                                         eb->db, fb->local_abspath,
+                                         eb->db, working_abspath,
                                          actual_props, TRUE,
                                          scratch_pool, scratch_pool));
       if (magic_props_changed || keywords)
@@ -3823,7 +3855,7 @@ merge_file(svn_skel_t **work_items,
               /* Copy and DEtranslate the working file to a temp text-base.
                  Note that detranslation is done according to the old props. */
               SVN_ERR(svn_wc__internal_translated_file(
-                        &tmptext, fb->local_abspath, eb->db, fb->local_abspath,
+                        &tmptext, working_abspath, eb->db, working_abspath,
                         SVN_WC_TRANSLATE_TO_NF
                           | SVN_WC_TRANSLATE_NO_OUTPUT_CLEANUP,
                         eb->cancel_func, eb->cancel_baton,
@@ -3865,7 +3897,7 @@ merge_file(svn_skel_t **work_items,
         }
 
       SVN_ERR(svn_wc__wq_build_record_fileinfo(&work_item,
-                                               eb->db, fb->local_abspath,
+                                               eb->db, working_abspath,
                                                set_date,
                                                result_pool, scratch_pool));
       *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
@@ -3920,6 +3952,9 @@ close_file(void *file_baton,
   svn_skel_t *work_item;
   apr_pool_t *scratch_pool = fb->pool; /* Destroyed at function exit */
   svn_boolean_t keep_recorded_info = FALSE;
+  const svn_checksum_t *new_checksum;
+  const char *working_abspath = fb->moved_to_abspath ? fb->moved_to_abspath
+                                                     : fb->local_abspath;
 
   if (fb->skip_this)
     {
@@ -3935,10 +3970,13 @@ close_file(void *file_baton,
   if (fb->new_text_base_md5_checksum && expected_md5_checksum
       && !svn_checksum_match(expected_md5_checksum,
                              fb->new_text_base_md5_checksum))
-    return svn_checksum_mismatch_err(expected_md5_checksum,
-                            fb->new_text_base_md5_checksum, scratch_pool,
-                            _("Checksum mismatch for '%s'"),
-                            svn_dirent_local_style(fb->local_abspath, pool));
+    return svn_error_trace(
+                svn_checksum_mismatch_err(expected_md5_checksum,
+                                          fb->new_text_base_md5_checksum,
+                                          scratch_pool,
+                                          _("Checksum mismatch for '%s'"),
+                                          svn_dirent_local_style(
+                                                fb->local_abspath, pool)));
 
   /* Gather the changes for each kind of property.  */
   SVN_ERR(svn_categorize_props(fb->propchanges, &entry_prop_changes,
@@ -4007,7 +4045,7 @@ close_file(void *file_baton,
   if ((!fb->adding_file || fb->add_existed)
       && !fb->shadowed)
     SVN_ERR(svn_wc__get_actual_props(&local_actual_props,
-                                     eb->db, fb->local_abspath,
+                                     eb->db, working_abspath,
                                      scratch_pool, scratch_pool));
   if (local_actual_props == NULL)
     local_actual_props = apr_hash_make(scratch_pool);
@@ -4085,7 +4123,7 @@ close_file(void *file_baton,
                                       svn_wc__db_status_added,
                                       svn_wc__db_kind_file, TRUE,
                                       svn_wc_conflict_action_add,
-                                      svn_node_file, fb->new_relpath,
+                                      svn_node_file, fb->new_relpath, NULL,
                                       scratch_pool, scratch_pool));
           SVN_ERR_ASSERT(tree_conflict != NULL);
           SVN_ERR(svn_wc__db_op_set_tree_conflict(eb->db,
@@ -4115,7 +4153,7 @@ close_file(void *file_baton,
                                   &new_base_props,
                                   &new_actual_props,
                                   eb->db,
-                                  fb->local_abspath,
+                                  working_abspath,
                                   svn_wc__db_kind_file,
                                   NULL /* left_version */,
                                   NULL /* right_version */,
@@ -4147,7 +4185,7 @@ close_file(void *file_baton,
               if (eb->notify_func)
                 {
                   svn_wc_notify_t *notify =svn_wc_create_notify(
-                                fb->local_abspath,
+                                working_abspath,
                                 svn_wc_notify_update_skip_access_denied,
                                 scratch_pool);
 
@@ -4194,7 +4232,7 @@ close_file(void *file_baton,
 
           SVN_ERR(svn_wc__wq_build_file_install(&work_item,
                                                 eb->db,
-                                                fb->local_abspath,
+                                                working_abspath,
                                                 install_from,
                                                 eb->use_commit_times,
                                                 record_fileinfo,
@@ -4210,7 +4248,7 @@ close_file(void *file_baton,
 
              Note: this will also update the executable flag, but ... meh.  */
           SVN_ERR(svn_wc__wq_build_sync_file_flags(&work_item, eb->db,
-                                                   fb->local_abspath,
+                                                   working_abspath,
                                                    scratch_pool, scratch_pool));
           all_work_items = svn_wc__wq_merge(all_work_items, work_item,
                                             scratch_pool);
@@ -4228,7 +4266,7 @@ close_file(void *file_baton,
       /* Remove the INSTALL_FROM file, as long as it doesn't refer to the
          working file.  */
       if (install_from != NULL
-          && strcmp(install_from, fb->local_abspath) != 0)
+          && strcmp(install_from, working_abspath) != 0)
         {
           SVN_ERR(svn_wc__wq_build_file_remove(&work_item, eb->db,
                                                install_from,
@@ -4279,43 +4317,62 @@ close_file(void *file_baton,
     }
 
   /* Insert/replace the BASE node with all of the new metadata.  */
-  {
-      /* Set the 'checksum' column of the file's BASE_NODE row to
-       * NEW_TEXT_BASE_SHA1_CHECKSUM.  The pristine text identified by that
-       * checksum is already in the pristine store. */
-    const svn_checksum_t *new_checksum = fb->new_text_base_sha1_checksum;
-
-    /* If we don't have a NEW checksum, then the base must not have changed.
-       Just carry over the old checksum.  */
-    if (new_checksum == NULL)
-      new_checksum = fb->original_checksum;
-
-    SVN_ERR(svn_wc__db_base_add_file(eb->db, fb->local_abspath,
-                                     eb->wcroot_abspath,
-                                     fb->new_relpath,
-                                     eb->repos_root, eb->repos_uuid,
-                                     *eb->target_revision,
-                                     new_base_props,
-                                     fb->changed_rev,
-                                     fb->changed_date,
-                                     fb->changed_author,
-                                     new_checksum,
-                                     (dav_prop_changes->nelts > 0)
-                                       ? svn_prop_array_to_hash(
-                                                        dav_prop_changes,
-                                                        scratch_pool)
-                                       : NULL,
-                                     NULL /* conflict */,
-                                     (! fb->shadowed) && new_base_props,
-                                     new_actual_props,
-                                     keep_recorded_info,
-                                     (fb->shadowed && fb->obstruction_found),
-                                     all_work_items,
-                                     scratch_pool));
-  }
+
+  /* Set the 'checksum' column of the file's BASE_NODE row to
+   * NEW_TEXT_BASE_SHA1_CHECKSUM.  The pristine text identified by that
+   * checksum is already in the pristine store. */
+  new_checksum = fb->new_text_base_sha1_checksum;
+
+  /* If we don't have a NEW checksum, then the base must not have changed.
+     Just carry over the old checksum.  */
+  if (new_checksum == NULL)
+    new_checksum = fb->original_checksum;
+
+  SVN_ERR(svn_wc__db_base_add_file(eb->db, fb->local_abspath,
+                                   eb->wcroot_abspath,
+                                   fb->new_relpath,
+                                   eb->repos_root, eb->repos_uuid,
+                                   *eb->target_revision,
+                                   new_base_props,
+                                   fb->changed_rev,
+                                   fb->changed_date,
+                                   fb->changed_author,
+                                   new_checksum,
+                                   (dav_prop_changes->nelts > 0)
+                                     ? svn_prop_array_to_hash(
+                                                      dav_prop_changes,
+                                                      scratch_pool)
+                                     : NULL,
+                                   NULL /* conflict */,
+                                   (! fb->shadowed) && new_base_props,
+                                   new_actual_props,
+                                   keep_recorded_info,
+                                   (fb->shadowed && fb->obstruction_found),
+                                   all_work_items,
+                                   scratch_pool));
 
   /* Deal with the WORKING tree, based on updates to the BASE tree.  */
 
+  if (fb->moved_to_abspath)
+    {
+      /* Perform another in-DB move of the file to sync meta-data
+       * of the moved-away node with the new BASE node. */
+      SVN_ERR(svn_wc__db_op_copy_file(eb->db, fb->moved_to_abspath,
+                                      new_actual_props,
+                                      fb->changed_rev,
+                                      fb->changed_date,
+                                      fb->changed_author,
+                                      fb->new_relpath,
+                                      eb->repos_root,
+                                      eb->repos_uuid,
+                                      *eb->target_revision,
+                                      new_checksum,
+                                      TRUE /* is_move */,
+                                      NULL /* conflict */,
+                                      NULL, /* no work, just modify DB */
+                                      scratch_pool));
+    }
+
   /* If this file was locally-added and is now being added by the update, we
      can toss the local-add, turning this into a local-edit.
      If the local file is replaced, we don't want to touch ACTUAL. */
@@ -4349,7 +4406,10 @@ close_file(void *file_baton,
           action = svn_wc_notify_update_add;
         }
 
-      notify = svn_wc_create_notify(fb->local_abspath, action, scratch_pool);
+      /* If the file was moved-away, notify for the moved-away node.
+       * The original location only had its BASE info changed and
+       * we don't usually notify about such changes. */ 
+      notify = svn_wc_create_notify(working_abspath, action, scratch_pool);
       notify->kind = svn_node_file;
       notify->content_state = content_state;
       notify->prop_state = prop_state;
@@ -5425,6 +5485,7 @@ svn_wc_add_repos_file4(svn_wc_context_t 
                                   original_uuid,
                                   copyfrom_rev,
                                   new_text_base_sha1_checksum,
+                                  FALSE /* is_move */,
                                   NULL /* conflict */,
                                   NULL /* work_items */,
                                   pool));

Modified: subversion/branches/revprop-packing/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_wc/upgrade.c?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_wc/upgrade.c Wed Aug 24 15:16:50 2011
@@ -1106,6 +1106,18 @@ migrate_text_bases(apr_hash_t **text_bas
             is_revert_base = FALSE;
           }
 
+        if (! versioned_file_name)
+          {
+             /* Some file that doesn't end with .svn-base or .svn-revert.
+                No idea why that would be in our administrative area, but
+                we shouldn't segfault on this case.
+
+                Note that we already copied this file in the pristine store,
+                but the next cleanup will take care of that.
+              */
+            continue;
+          }
+
         /* Create a new info struct for this versioned file, or fill in the
          * existing one if this is the second text-base we've found for it. */
         info = apr_hash_get(*text_bases_info, versioned_file_name,
@@ -1902,12 +1914,12 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
                              scratch_pool));
   SVN_ERR(svn_wc__ensure_directory(root_adm_abspath, scratch_pool));
 
-  /* Create an empty sqlite database for this directory. */
+  /* Create an empty sqlite database for this directory and store it in DB. */
   SVN_ERR(svn_wc__db_upgrade_begin(&data.sdb,
                                    &data.repos_id, &data.wc_id,
-                                   data.root_abspath,
+                                   db, data.root_abspath,
                                    this_dir->repos, this_dir->uuid,
-                                   scratch_pool, scratch_pool));
+                                   scratch_pool));
 
   /* Migrate the entries over to the new database.
    ### We need to think about atomicity here.
@@ -1952,7 +1964,6 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
   SVN_ERR(svn_wc__db_wq_add(db, data.root_abspath, work_items, scratch_pool));
 
   SVN_ERR(svn_wc__db_wclock_release(db, data.root_abspath, scratch_pool));
-  SVN_ERR(svn_sqlite__close(data.sdb));
   SVN_ERR(svn_wc__db_close(db));
 
   /* Renaming the db file is what makes the pre-wcng into a wcng */

Modified: subversion/branches/revprop-packing/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_wc/wc-metadata.sql?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_wc/wc-metadata.sql Wed Aug 24 15:16:50 2011
@@ -316,8 +316,8 @@ CREATE TABLE NODES (
      BASE node, the location of the initial checkout.
 
      When op_depth != 0, they indicate where this node was copied/moved from.
-     In this case, the fields are set only on the root of the operation,
-     and are NULL for all children. */
+     In this case, the fields are set for the root of the operation and for all
+     children. */
   repos_id  INTEGER REFERENCES REPOSITORY (id),
   repos_path  TEXT,
   revision  INTEGER,
@@ -384,7 +384,8 @@ CREATE TABLE NODES (
      perhaps add a column called "moved_from". */
 
   /* Boolean value, specifying if this node was moved here (rather than just
-     copied). The source of the move is specified in copyfrom_*.  */
+     copied). The source of the move is implied by a different node with
+     a moved_to column pointing at this node. */
   moved_here  INTEGER,
 
   /* If the underlying node was moved away (rather than just deleted), this
@@ -392,8 +393,8 @@ CREATE TABLE NODES (
      This is set only on the root of a move, and is NULL for all children.
 
      Note that moved_to never refers to *this* node. It always refers
-     to the "underlying" node, whether that is BASE or a child node
-     implied from a parent's move/copy.  */
+     to the "underlying" node in the BASE tree. A non-NULL moved_to column
+     is only valid in rows where op_depth == 0. */
   moved_to  TEXT,
 
 

Modified: subversion/branches/revprop-packing/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_wc/wc-queries.sql?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_wc/wc-queries.sql Wed Aug 24 15:16:50 2011
@@ -29,7 +29,7 @@
 -- STMT_SELECT_NODE_INFO
 SELECT op_depth, repos_id, repos_path, presence, kind, revision, checksum,
   translated_size, changed_revision, changed_date, changed_author, depth,
-  symlink_target, last_mod_time, properties
+  symlink_target, last_mod_time, properties, moved_here
 FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2
 ORDER BY op_depth DESC
@@ -37,8 +37,11 @@ ORDER BY op_depth DESC
 -- STMT_SELECT_NODE_INFO_WITH_LOCK
 SELECT op_depth, nodes.repos_id, nodes.repos_path, presence, kind, revision,
   checksum, translated_size, changed_revision, changed_date, changed_author,
-  depth, symlink_target, last_mod_time, properties, lock_token, lock_owner,
-  lock_comment, lock_date
+  depth, symlink_target, last_mod_time, properties, moved_here,
+  /* All the columns until now must match those returned by
+     STMT_SELECT_NODE_INFO. The implementation of svn_wc__db_read_info()
+     assumes that these columns are followed by the lock information) */
+  lock_token, lock_owner, lock_comment, lock_date
 FROM nodes
 LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
   AND nodes.repos_path = lock.repos_relpath
@@ -48,7 +51,8 @@ ORDER BY op_depth DESC
 -- STMT_SELECT_BASE_NODE
 SELECT repos_id, repos_path, presence, kind, revision, checksum,
   translated_size, changed_revision, changed_date, changed_author, depth,
-  symlink_target, last_mod_time, properties, file_external IS NOT NULL
+  symlink_target, last_mod_time, properties, file_external IS NOT NULL,
+  moved_to
 FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
 
@@ -56,6 +60,10 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 SELECT nodes.repos_id, nodes.repos_path, presence, kind, revision,
   checksum, translated_size, changed_revision, changed_date, changed_author,
   depth, symlink_target, last_mod_time, properties, file_external IS NOT NULL,
+  moved_to,
+  /* All the columns until now must match those returned by
+     STMT_SELECT_BASE_NODE. The implementation of svn_wc__db_base_get_info()
+     assumes that these columns are followed by the lock information) */
   lock_token, lock_owner, lock_comment, lock_date
 FROM nodes
 LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
@@ -119,7 +127,7 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 SELECT op_depth, nodes.repos_id, nodes.repos_path, presence, kind, revision,
   checksum, translated_size, changed_revision, changed_date, changed_author,
   depth, symlink_target, last_mod_time, properties, lock_token, lock_owner,
-  lock_comment, lock_date, local_relpath
+  lock_comment, lock_date, local_relpath, moved_here, moved_to
 FROM nodes
 LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
   AND nodes.repos_path = lock.repos_relpath
@@ -158,9 +166,9 @@ INSERT OR REPLACE INTO nodes (
   wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
   revision, presence, depth, kind, changed_revision, changed_date,
   changed_author, checksum, properties, translated_size, last_mod_time,
-  dav_cache, symlink_target, file_external)
+  dav_cache, symlink_target, file_external, moved_to, moved_here)
 VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14,
-        ?15, ?16, ?17, ?18, ?19, ?20)
+        ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22)
 
 -- STMT_SELECT_OP_DEPTH_CHILDREN
 SELECT local_relpath FROM nodes
@@ -178,7 +186,7 @@ WHERE wc_id = ?1 AND parent_relpath = ?2
 DELETE FROM nodes
 WHERE wc_id = ?1
   AND (local_relpath = ?2
-       OR ((local_relpath > ?2 || '/') AND (local_relpath < ?2 || '0')))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND (op_depth < ?3
        OR (op_depth = ?3 AND presence = 'base-deleted'))
 
@@ -186,7 +194,7 @@ WHERE wc_id = ?1
 SELECT local_relpath FROM nodes
 WHERE wc_id = ?1 AND op_depth = ?3
   AND (parent_relpath = ?2
-       OR ((parent_relpath > ?2 || '/') AND (parent_relpath < ?2 || '0')))
+       OR IS_STRICT_DESCENDANT_OF(parent_relpath, ?2))
   AND presence == 'not-present'
 
 -- STMT_COMMIT_DESCENDANT_TO_BASE
@@ -263,7 +271,7 @@ LEFT JOIN lock ON nodes.repos_id = lock.
 WHERE wc_id = ?1 AND op_depth = 0
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 
 -- STMT_INSERT_WCROOT
 INSERT INTO wcroot (local_abspath)
@@ -278,7 +286,7 @@ SELECT dav_cache FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
 
 -- STMT_SELECT_DELETION_INFO
-SELECT nodes_base.presence, nodes_work.presence, nodes_work.moved_to,
+SELECT nodes_base.presence, nodes_work.presence, nodes_base.moved_to,
        nodes_work.op_depth
 FROM nodes AS nodes_work
 LEFT OUTER JOIN nodes nodes_base ON nodes_base.wc_id = nodes_work.wc_id
@@ -298,7 +306,7 @@ UPDATE nodes SET dav_cache = NULL
 WHERE dav_cache IS NOT NULL AND wc_id = ?1 AND op_depth = 0
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 
 -- STMT_RECURSIVE_UPDATE_NODE_REPO
 UPDATE nodes SET repos_id = ?4, dav_cache = NULL
@@ -306,7 +314,7 @@ WHERE wc_id = ?1
   AND repos_id = ?3
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 
 -- STMT_UPDATE_LOCK_REPOS_ID
 UPDATE lock SET repos_id = ?2
@@ -476,7 +484,7 @@ FROM nodes_current
 WHERE wc_id = ?1
        AND (?2 = ''
             OR local_relpath = ?2 
-            OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+            OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 
 -- STMT_INSERT_TARGET_WITH_CHANGELIST
 INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
@@ -509,7 +517,7 @@ SELECT N.wc_id, N.local_relpath, N.paren
  WHERE N.wc_id = ?1
        AND (?2 = ''
             OR N.local_relpath = ?2 
-            OR (N.local_relpath > ?2 || '/' AND N.local_relpath < ?2 || '0'))
+            OR IS_STRICT_DESCENDANT_OF(N.local_relpath, ?2))
        AND A.changelist = ?3
 
 -- STMT_SELECT_TARGETS
@@ -578,7 +586,7 @@ DELETE FROM nodes
 WHERE wc_id = ?1
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth >= ?3
 
 -- STMT_DELETE_ACTUAL_NODE
@@ -590,7 +598,7 @@ DELETE FROM actual_node
 WHERE wc_id = ?1
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 
 -- STMT_DELETE_ACTUAL_NODE_WITHOUT_CONFLICT
 DELETE FROM actual_node
@@ -603,19 +611,20 @@ WHERE wc_id = ?1
   AND local_relpath = ?2
   AND (changelist IS NULL
        OR NOT EXISTS (SELECT 1 FROM nodes_current c
-                      WHERE c.wc_id = ?1 AND c.local_relpath = local_relpath
-                        AND kind = 'file'))
+                      WHERE c.wc_id = ?1 AND c.local_relpath = ?2
+                        AND c.kind = 'file'))
 
 -- STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE
 DELETE FROM actual_node
 WHERE wc_id = ?1
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND (changelist IS NULL
        OR NOT EXISTS (SELECT 1 FROM nodes_current c
-                      WHERE c.wc_id = ?1 AND c.local_relpath = local_relpath
-                        AND kind = 'file'))
+                      WHERE c.wc_id = ?1 
+                        AND c.local_relpath = actual_node.local_relpath
+                        AND c.kind = 'file'))
 
 -- STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST
 UPDATE actual_node
@@ -646,7 +655,7 @@ SET properties = NULL,
 WHERE wc_id = ?1
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 
 -- STMT_UPDATE_NODE_BASE_DEPTH
 UPDATE nodes SET depth = ?3
@@ -778,7 +787,7 @@ DELETE FROM wc_lock
 WHERE wc_id = ?1
   AND (?2 = ''
        OR local_dir_relpath = ?2
-       OR (local_dir_relpath > ?2 || '/' AND local_dir_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_dir_relpath, ?2))
   AND NOT EXISTS (SELECT 1 FROM nodes
                    WHERE nodes.wc_id = ?1
                      AND nodes.local_relpath = wc_lock.local_dir_relpath)
@@ -811,18 +820,8 @@ SELECT wc_id, local_relpath, ?4 /*op_dep
        kind
 FROM nodes
 WHERE wc_id = ?1
-  AND (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0')
-  AND op_depth = ?3
-  AND presence NOT IN ('base-deleted', 'not-present', 'excluded', 'absent')
-
--- STMT_INSERT_DELETE_NODE
-INSERT INTO nodes (
-    wc_id, local_relpath, op_depth, parent_relpath, presence, kind, moved_to)
-SELECT wc_id, local_relpath, ?4 /*op_depth*/, parent_relpath, 'base-deleted',
-       kind, ?5 /* moved_to */
-FROM nodes
-WHERE wc_id = ?1
-  AND local_relpath = ?2
+  AND (local_relpath = ?2
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth = ?3
   AND presence NOT IN ('base-deleted', 'not-present', 'excluded', 'absent')
 
@@ -851,7 +850,7 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 UPDATE nodes SET op_depth = ?3 + 1
 WHERE wc_id = ?1
   AND (?2 = ''
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth = ?3
 
 -- STMT_DOES_NODE_EXIST
@@ -863,7 +862,7 @@ SELECT local_relpath FROM nodes
 WHERE wc_id = ?1
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth = 0 AND presence = 'absent'
 LIMIT 1
 
@@ -873,7 +872,7 @@ SELECT local_relpath FROM nodes
 WHERE wc_id = ?1
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth = 0
   AND presence = 'absent'
 
@@ -964,7 +963,7 @@ FROM externals
 WHERE wc_id = ?1 
   AND (?2 = ''
        OR def_local_relpath = ?2
-       OR (def_local_relpath > ?2 || '/' AND def_local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(def_local_relpath, ?2))
 
 -- STMT_UPDATE_EXTERNAL_FILEINFO
 UPDATE externals SET recorded_size = ?3, recorded_mod_time = ?4
@@ -983,7 +982,7 @@ FROM nodes n
 WHERE wc_id = ?1
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND kind = 'dir' AND presence='normal'
   AND op_depth=(SELECT MAX(op_depth) FROM nodes o
                 WHERE o.wc_id = ?1 AND o.local_relpath = n.local_relpath)
@@ -1111,14 +1110,18 @@ CREATE TEMPORARY TABLE revert_list (
    conflict_working TEXT,
    prop_reject TEXT,
    notify INTEGER,         /* 1 if an actual row had props or tree conflict */
+   op_depth INTEGER,
+   repos_id INTEGER,
+   kind TEXT,
    PRIMARY KEY (local_relpath, actual)
    );
 DROP TRIGGER IF EXISTS   trigger_revert_list_nodes;
 CREATE TEMPORARY TRIGGER trigger_revert_list_nodes
 BEFORE DELETE ON nodes
 BEGIN
-   INSERT OR REPLACE INTO revert_list(local_relpath, actual)
-   SELECT OLD.local_relpath, 0;
+   INSERT OR REPLACE INTO revert_list(local_relpath, actual, op_depth,
+                                      repos_id, kind)
+   SELECT OLD.local_relpath, 0, OLD.op_depth, OLD.repos_id, OLD.kind;
 END;
 DROP TRIGGER IF EXISTS   trigger_revert_list_actual_delete;
 CREATE TEMPORARY TRIGGER trigger_revert_list_actual_delete
@@ -1155,11 +1158,20 @@ DROP TRIGGER IF EXISTS trigger_revert_li
 DROP TRIGGER IF EXISTS trigger_revert_list_actual_update
 
 -- STMT_SELECT_REVERT_LIST
-SELECT conflict_old, conflict_new, conflict_working, prop_reject, notify, actual
+SELECT conflict_old, conflict_new, conflict_working, prop_reject, notify,
+       actual, op_depth, repos_id, kind
 FROM revert_list
 WHERE local_relpath = ?1
 ORDER BY actual DESC
 
+-- STMT_SELECT_REVERT_LIST_COPIED_CHILDREN
+SELECT local_relpath, kind
+FROM revert_list
+WHERE local_relpath LIKE ?1 ESCAPE '#'
+  AND op_depth >= ?2
+  AND repos_id IS NOT NULL
+ORDER BY local_relpath
+
 -- STMT_DELETE_REVERT_LIST
 DELETE FROM revert_list WHERE local_relpath = ?1
 
@@ -1191,7 +1203,7 @@ INSERT INTO delete_list(local_relpath)
 SELECT local_relpath FROM nodes n
 WHERE wc_id = ?1
   AND (local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth >= ?3
   AND presence NOT IN ('base-deleted', 'not-present', 'excluded', 'absent')
   AND op_depth = (SELECT MAX(op_depth) FROM nodes s
@@ -1216,7 +1228,7 @@ SELECT MIN(revision), MAX(revision),
   WHERE wc_id = ?1
     AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
     AND presence IN ('normal', 'incomplete')
     AND file_external IS NULL
     AND op_depth = 0
@@ -1226,7 +1238,7 @@ SELECT 1 FROM nodes
 WHERE wc_id = ?1
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth = 0
   AND (presence IN ('absent', 'excluded')
         OR depth NOT IN ('infinity', 'unknown'))
@@ -1238,7 +1250,7 @@ SELECT 1 FROM nodes
 WHERE wc_id = ?1
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth > 0
 LIMIT 1
 
@@ -1247,7 +1259,7 @@ SELECT 1 FROM actual_node
 WHERE wc_id = ?1
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND properties IS NOT NULL
 LIMIT 1
 
@@ -1270,7 +1282,7 @@ SELECT o.repos_path || '/' || SUBSTR(s.l
 FROM nodes AS o
 LEFT JOIN nodes AS s
 ON o.wc_id = s.wc_id
-   AND s.local_relpath > ?2 || '/' AND s.local_relpath < ?2 || '0'
+   AND IS_STRICT_DESCENDANT_OF(s.local_relpath, ?2)
    AND s.op_depth = 0
    AND s.repos_id = o.repos_id
    AND s.file_external IS NULL
@@ -1284,7 +1296,7 @@ SELECT SUBSTR(s.local_relpath, LENGTH(?2
 FROM nodes AS o
 LEFT JOIN nodes AS s
 ON o.wc_id = s.wc_id
-   AND s.local_relpath > ?2 || '/' AND s.local_relpath < ?2 || '0'
+   AND IS_STRICT_DESCENDANT_OF(s.local_relpath, ?2)
    AND s.op_depth = 0
    AND s.repos_id = o.repos_id
    AND s.file_external IS NULL
@@ -1325,22 +1337,39 @@ SELECT local_relpath, translated_size, l
 WHERE wc_id = ?1
   AND (?2 = ''
        OR local_relpath = ?2
-       OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth = 0
   AND kind='file'
   AND presence='normal'
   AND file_external IS NULL
 
 -- STMT_SELECT_MOVED_FROM_RELPATH
-SELECT local_relpath FROM nodes_current
-WHERE wc_id = ?1 AND moved_to = ?2
+SELECT local_relpath FROM nodes
+WHERE wc_id = ?1 AND moved_to = ?2 AND op_depth = 0
 
 -- STMT_UPDATE_MOVED_TO_RELPATH
-UPDATE NODES SET moved_to = ?3
-WHERE wc_id = ?1 AND local_relpath = ?2
-  AND op_depth =
-   (SELECT MAX(op_depth) FROM nodes
-    WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0)
+UPDATE nodes SET moved_to = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
+
+-- STMT_CLEAR_MOVED_TO_RELPATH
+UPDATE nodes SET moved_to = NULL
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
+
+-- STMT_CLEAR_MOVED_TO_RELPATH_RECURSIVE
+UPDATE nodes SET moved_to = NULL
+WHERE wc_id = ?1
+  AND (?2 = ''
+       OR local_relpath = ?2
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+  AND op_depth = 0
+
+/* This statement returns pairs of move-roots below the path ?2 in WC_ID ?1.
+ * Each row returns a moved-here path (always a child of ?2) in the first
+ * column, and its matching moved-away (deleted) path in the second column. */
+-- STMT_SELECT_MOVED_HERE_CHILDREN
+SELECT moved_to, local_relpath FROM nodes
+WHERE wc_id = ?1 AND op_depth = 0
+  AND IS_STRICT_DESCENDANT_OF(moved_to, ?2)
 
 /* ------------------------------------------------------------------------- */
 

Modified: subversion/branches/revprop-packing/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_wc/wc.h?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_wc/wc.h Wed Aug 24 15:16:50 2011
@@ -402,7 +402,7 @@ svn_wc__internal_file_modified_p(svn_boo
    conflict resolver as older_version and their_version.
 
    ## TODO: We should store the information in LEFT_VERSION and RIGHT_VERSION
-            in the workingcopy for future retrieval via svn info.
+            in the working copy for future retrieval via svn info.
 
    WRI_ABSPATH describes in which working copy information should be
    retrieved. (Interesting for merging file externals).