Author: ehu
Date: Fri Oct 15 14:59:20 2010
New Revision: 1022959

URL: http://svn.apache.org/viewvc?rev=1022959&view=rev
Log:
Simplify revert processing: all reverts go through revert_admin_things(),
instead of sometimes routing through
svn_wc__internal_remove_from_revision_control() and sometimes through
revert_admin_things().


 * subversion/tests/libsvn_wc/revert_tests.py
   (status_of_missing_dir_after_revert_replaced_with_history): Adjust
    expected output to see only the notification of the op_root,
    same as normal/non-replacing adds.

 * subversion/libsvn_wc/adm_ops.c
   (revert_admin_things): Add revert_root parameter to pass around to
    the wc_db functions which need it now.
   (revert_entry): Take a revert_root parameter to pass to
    revert_admin_things().  Don't use the 'remove from revision control'
    APIs anymore for added and copied paths, instead use the
    'revert admin things' route for all cases.
   (revert_internal): Take a revert_root parameter to pass around.
    To mimic svn_wc__internal_remove_from_version_control(), disable
    notifications on copy/move-reversals.  Like the aforementioned function,
    call svn_wc__adm_destroy() after reverting an added (not replaced)
    directory.

 * subversion/libsvn_wc/workqueue.c
   (run_revert): Move decision to call svn_wc__db_temp_op_remove_working()
    to svn_wc__wq_add_revert().
   (svn_wc__wq_add_revert): Take a revert_root parameter.  In the issue #2101
    handling, check explicitly for deletes (wich is what the issue is about),
    instead of the node type.  Implement logic to determine whether
    run_revert() should call svn_wc__db_temp_op_remove_working().

Modified:
    subversion/trunk/subversion/libsvn_wc/adm_ops.c
    subversion/trunk/subversion/libsvn_wc/workqueue.c
    subversion/trunk/subversion/libsvn_wc/workqueue.h
    subversion/trunk/subversion/tests/cmdline/revert_tests.py

Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1022959&r1=1022958&r2=1022959&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Fri Oct 15 14:59:20 2010
@@ -1250,11 +1250,13 @@ svn_wc__register_file_external(svn_wc_co
 static svn_error_t *
 revert_admin_things(svn_boolean_t *reverted,
                     svn_wc__db_t *db,
+                    const char *revert_root,
                     const char *local_abspath,
                     svn_boolean_t use_commit_times,
                     apr_pool_t *pool)
 {
-  SVN_ERR(svn_wc__wq_add_revert(reverted, db, local_abspath, use_commit_times,
+  SVN_ERR(svn_wc__wq_add_revert(reverted, db,
+                                revert_root, local_abspath, use_commit_times,
                                 pool));
   SVN_ERR(svn_wc__wq_run(db, local_abspath, NULL, NULL, pool));
 
@@ -1277,6 +1279,7 @@ revert_admin_things(svn_boolean_t *rever
 static svn_error_t *
 revert_entry(svn_depth_t *depth,
              svn_wc__db_t *db,
+             const char *revert_root,
              const char *local_abspath,
              svn_node_kind_t disk_kind,
              svn_boolean_t use_commit_times,
@@ -1326,89 +1329,9 @@ revert_entry(svn_depth_t *depth,
   else
     is_add_root = FALSE;
 
-  /* Additions. */
-  if (!replaced
-      && is_add_root)
-    {
-      const char *repos_relpath;
-      const char *repos_root_url;
-      const char *repos_uuid;
-      /* Before removing item from revision control, notice if the
-         BASE_NODE is in a 'not-present' state. */
-      svn_boolean_t was_not_present = FALSE;
-
-      /* NOTE: if WAS_NOT_PRESENT gets set, then we have BASE nodes.
-         The code below will then figure out the repository information, so
-         that we can later insert a node for the same repository. */
-
-      if (have_base
-          && base_status == svn_wc__db_status_not_present)
-        {
-          /* Remember the BASE revision. (already handled)  */
-          /* Remember the repository this node is associated with.  */
-
-          was_not_present = TRUE;
-
-          SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath,
-                                             &repos_root_url,
-                                             &repos_uuid,
-                                             db, local_abspath,
-                                             pool, pool));
-        }
-
-      /* ### much of this is probably bullshit. we should be able to just
-         ### remove the WORKING and ACTUAL rows, and be done. but we're
-         ### not quite there yet, so nodes get fully removed and then
-         ### shoved back into the database. this is why we need to record
-         ### the repository information, and the BASE revision.  */
-
-      if (kind == svn_wc__db_kind_file
-          || kind == svn_wc__db_kind_dir)
-        {
-          SVN_ERR(svn_wc__internal_remove_from_revision_control(db,
-                                                                local_abspath,
-                                                                FALSE, FALSE,
-                                                                cancel_func,
-                                                                cancel_baton,
-                                                                pool));
-        }
-      else  /* Else it's `none', or something exotic like a symlink... */
-        {
-          return svn_error_createf(SVN_ERR_NODE_UNKNOWN_KIND, NULL,
-                                   _("Unknown or unexpected kind for path "
-                                     "'%s'"),
-                                   svn_dirent_local_style(local_abspath,
-                                                          pool));
-
-        }
-
-      /* Recursivity is taken care of by svn_wc_remove_from_revision_control,
-         and we've definitely reverted PATH at this point. */
-      *depth = svn_depth_empty;
-      reverted = TRUE;
-
-      /* If the removed item was *also* in a 'not-present' state, make
-         sure we leave a not-present node behind */
-      if (was_not_present)
-        {
-          SVN_ERR(svn_wc__db_base_add_not_present_node(
-                    db, local_abspath,
-                    repos_relpath, repos_root_url, repos_uuid,
-                    base_revision,
-                    base_kind,
-                    NULL, NULL,
-                    pool));
-        }
-    }
-  /* Regular prop and text edit. */
-  /* Deletions and replacements. */
-  else if (status == svn_wc__db_status_normal
-           || status == svn_wc__db_status_deleted
-           || replaced
-           || (status == svn_wc__db_status_added && !is_add_root))
     {
       /* Revert the prop and text mods (if any). */
-      SVN_ERR(revert_admin_things(&reverted, db, local_abspath,
+      SVN_ERR(revert_admin_things(&reverted, db, revert_root, local_abspath,
                                   use_commit_times, pool));
 
       /* Force recursion on replaced directories. */
@@ -1496,6 +1419,7 @@ verify_revert_depth(svn_wc__db_t *db,
    documentation. */
 static svn_error_t *
 revert_internal(svn_wc__db_t *db,
+                const char *revert_root,
                 const char *local_abspath,
                 svn_depth_t depth,
                 svn_boolean_t use_commit_times,
@@ -1510,7 +1434,9 @@ revert_internal(svn_wc__db_t *db,
   svn_wc__db_status_t status;
   svn_wc__db_kind_t db_kind;
   svn_boolean_t unversioned;
+  svn_boolean_t have_base;
   const svn_wc_conflict_description2_t *tree_conflict;
+  const char *op_root_abspath = NULL;
   svn_error_t *err;
 
   /* Check cancellation here, so recursive calls get checked early. */
@@ -1523,7 +1449,7 @@ revert_internal(svn_wc__db_t *db,
   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, NULL, NULL, NULL,
+                             NULL, NULL, NULL, NULL, &have_base, NULL, NULL,
                              NULL,
                              db, local_abspath, pool, pool);
 
@@ -1595,17 +1521,17 @@ revert_internal(svn_wc__db_t *db,
        _("Cannot revert '%s': unsupported node kind in working copy"),
        svn_dirent_local_style(local_abspath, pool));
 
+  if (status == svn_wc__db_status_added)
+    SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
+                                     NULL, NULL, NULL, NULL, NULL,
+                                     db, local_abspath, pool, pool));
+
   /* Safeguard 4:  Make sure we don't revert deeper then asked */
   if (status == svn_wc__db_status_added
       && db_kind == svn_wc__db_kind_dir
       && depth >= svn_depth_empty
       && depth < svn_depth_infinity)
     {
-      const char *op_root_abspath;
-      SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
-                                       NULL, NULL, NULL, NULL, NULL,
-                                       db, local_abspath, pool, pool));
-
       /* If this node is an operation root for a copy/add, then reverting
          it will change its descendants, if it has any. */
       if (strcmp(local_abspath, op_root_abspath) == 0)
@@ -1634,7 +1560,7 @@ revert_internal(svn_wc__db_t *db,
       /* Actually revert this entry.  If this is a working copy root,
          we provide a base_name from the parent path. */
       if (!unversioned)
-        SVN_ERR(revert_entry(&depth, db, local_abspath, disk_kind,
+        SVN_ERR(revert_entry(&depth, db, revert_root, local_abspath, disk_kind,
                              use_commit_times,
                              cancel_func, cancel_baton,
                              &reverted, pool));
@@ -1647,6 +1573,15 @@ revert_internal(svn_wc__db_t *db,
                        pool);
     }
 
+
+  if (op_root_abspath && strcmp(local_abspath, op_root_abspath) == 0)
+    /* If this is a copy or add root, disable notifications for the children,
+       because wc-1.0 used to behave like that. */
+    {
+      notify_func = NULL;
+      notify_baton = NULL;
+    }
+
   /* Finally, recurse if requested. */
   if (!unversioned && db_kind == svn_wc__db_kind_dir && depth > 
svn_depth_empty)
     {
@@ -1690,7 +1625,7 @@ revert_internal(svn_wc__db_t *db,
             continue;
 
           /* Revert the entry. */
-          SVN_ERR(revert_internal(db, node_abspath,
+          SVN_ERR(revert_internal(db, revert_root, node_abspath,
                                   depth_under_here, use_commit_times,
                                   changelist_hash, cancel_func, cancel_baton,
                                   notify_func, notify_baton, iterpool));
@@ -1734,7 +1669,8 @@ revert_internal(svn_wc__db_t *db,
                                 const svn_wc_conflict_description2_t *);
 
                 if (conflict->kind == svn_wc_conflict_kind_tree)
-                  SVN_ERR(revert_internal(db, conflict->local_abspath,
+                  SVN_ERR(revert_internal(db, revert_root,
+                                          conflict->local_abspath,
                                           svn_depth_empty,
                                           use_commit_times, changelist_hash,
                                           cancel_func, cancel_baton,
@@ -1747,6 +1683,14 @@ revert_internal(svn_wc__db_t *db,
       svn_pool_destroy(iterpool);
     }
 
+  if (! have_base && status == svn_wc__db_status_added
+      && db_kind == svn_wc__db_kind_dir)
+    {
+      /* Non-replacements have their admin area deleted. wc-1.0 */
+      SVN_ERR(svn_wc__adm_destroy(db, local_abspath,
+                                  cancel_func, cancel_baton, pool));
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -1769,7 +1713,7 @@ svn_wc_revert4(svn_wc_context_t *wc_ctx,
     SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists, pool));
 
   return svn_error_return(revert_internal(wc_ctx->db,
-                                          local_abspath, depth,
+                                          local_abspath, local_abspath, depth,
                                           use_commit_times, changelist_hash,
                                           cancel_func, cancel_baton,
                                           notify_func, notify_baton,

Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=1022959&r1=1022958&r2=1022959&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Fri Oct 15 14:59:20 2010
@@ -186,14 +186,14 @@ run_revert(svn_wc__db_t *db,
   const char *parent_abspath;
   svn_boolean_t conflicted;
   apr_int64_t val;
-  svn_boolean_t is_wc_root;
   svn_boolean_t reinstall_working;
+  svn_boolean_t remove_working;
 
   /* We need a NUL-terminated path, so copy it out of the skel.  */
   local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
 
-  /* ### OP_DEPTH legacy; to be removed. */
   SVN_ERR(svn_skel__parse_int(&val, arg1->next, scratch_pool));
+  remove_working = (val != 0);
 
   SVN_ERR(svn_skel__parse_int(&val, arg1->next->next, scratch_pool));
   reinstall_working = (val != 0);
@@ -213,14 +213,11 @@ run_revert(svn_wc__db_t *db,
 
   if (kind == svn_wc__db_kind_dir)
     {
-      SVN_ERR(svn_wc__db_is_wcroot(&is_wc_root, db, local_abspath,
-                                   scratch_pool));
       parent_abspath = local_abspath;
     }
   else
     {
       parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-      is_wc_root = FALSE; /* non-directories can't be roots */
     }
 
   if (conflicted)
@@ -294,26 +291,11 @@ run_revert(svn_wc__db_t *db,
     }
 
 
-  if (! is_wc_root) {
-    /* A working copy root can't have a working node. Don't try removing. */
-    const char *op_root_abspath = NULL;
-
-
-
-    /* Remove the WORKING version of the node */
-    /* If the node is not the operation root,
-       we should not delete the working node */
-    if (status == svn_wc__db_status_added)
-      SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
-                                       NULL, NULL, NULL, NULL, NULL,
-                                       db, local_abspath,
-                                       scratch_pool, scratch_pool));
-
-    if (!op_root_abspath
-        || (strcmp(op_root_abspath, local_abspath) == 0))
+  if (remove_working)
+    {
       SVN_ERR(svn_wc__db_temp_op_remove_working(db, local_abspath,
                                                 scratch_pool));
-  }
+    }
 
   return SVN_NO_ERROR;
 }
@@ -363,6 +345,7 @@ verify_pristine_present(svn_wc__db_t *db
 svn_error_t *
 svn_wc__wq_add_revert(svn_boolean_t *will_revert,
                       svn_wc__db_t *db,
+                      const char *revert_root,
                       const char *local_abspath,
                       svn_boolean_t use_commit_times,
                       apr_pool_t *scratch_pool)
@@ -370,6 +353,7 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
   svn_wc__db_status_t status;
   svn_wc__db_kind_t kind;
   svn_boolean_t replaced;
+  svn_boolean_t remove_working = FALSE;
   svn_boolean_t reinstall_working;
 
   SVN_ERR(svn_wc__db_read_info(
@@ -380,8 +364,11 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
             db, local_abspath,
             scratch_pool, scratch_pool));
 
-  /* Special handling for issue #2101.  */
-  if (kind == svn_wc__db_kind_file)
+  /* Special handling for issue #2101, which is specifically
+     about reverting copies of 'deleted' files and dirs, being inserted
+     in the copy as a schedule-delete files, yet can't be reverted. */
+  if (kind == svn_wc__db_kind_file
+      && status == svn_wc__db_status_deleted)
     SVN_ERR(verify_pristine_present(db, local_abspath, scratch_pool));
 
   /* Gather a few items *before* the revert work-item has a chance to run.
@@ -447,6 +434,26 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
       *will_revert = *will_revert || reinstall_working;
     }
 
+
+  if (status == svn_wc__db_status_added)
+    {
+      /* When looking at an added, non-replacing node, it's entry
+         will have to be removed after revert: if not, it'll look
+         like it's still under version control. */
+      const char *op_root_abspath;
+
+      SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL,
+                                       db, local_abspath,
+                                       scratch_pool, scratch_pool));
+
+      if (svn_dirent_is_ancestor(revert_root, op_root_abspath))
+        remove_working = TRUE;
+    }
+  else
+    remove_working = TRUE;
+
+
   /* Don't even bother to queue a work item if there is nothing to do.  */
   if (*will_revert)
     {
@@ -458,10 +465,7 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
          we only need the work_item to survive for the duration of wq_add.  */
       svn_skel__prepend_int(use_commit_times, work_item, scratch_pool);
       svn_skel__prepend_int(reinstall_working, work_item, scratch_pool);
-
-      /* ### OP_DEPTH The 'replaced' item is here for backward compat;
-         the wq-consumer doesn't use this value anymore. */
-      svn_skel__prepend_int(replaced, work_item, scratch_pool);
+      svn_skel__prepend_int(remove_working, work_item, scratch_pool);
       svn_skel__prepend_str(local_abspath, work_item, scratch_pool);
       svn_skel__prepend_str(OP_REVERT, work_item, scratch_pool);
 

Modified: subversion/trunk/subversion/libsvn_wc/workqueue.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.h?rev=1022959&r1=1022958&r2=1022959&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.h Fri Oct 15 14:59:20 2010
@@ -188,10 +188,12 @@ svn_wc__wq_build_record_fileinfo(svn_ske
                                  apr_pool_t *result_pool);
 
 
-/* Record a work item to revert LOCAL_ABSPATH.  */
+/* Record a work item to revert LOCAL_ABSPATH;
+   REVERT_ROOT designates the root of the entire revert operation. */
 svn_error_t *
 svn_wc__wq_add_revert(svn_boolean_t *will_revert,
                       svn_wc__db_t *db,
+                      const char *revert_root,
                       const char *local_abspath,
                       svn_boolean_t use_commit_times,
                       apr_pool_t *scratch_pool);

Modified: subversion/trunk/subversion/tests/cmdline/revert_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/revert_tests.py?rev=1022959&r1=1022958&r2=1022959&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/revert_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/revert_tests.py Fri Oct 15 
14:59:20 2010
@@ -847,15 +847,7 @@ def status_of_missing_dir_after_revert_r
                                        dry_run = 0)
 
   # now test if the revert works ok
-  revert_paths = [G_path,
-                  os.path.join(G_path, 'alpha'),
-                  os.path.join(G_path, 'beta')]
-
-  if svntest.main.wc_is_singledb(wc_dir):
-    # These nodes are not lost in single-db
-    revert_paths += [ os.path.join(G_path, 'pi'),
-                      os.path.join(G_path, 'rho'),
-                      os.path.join(G_path, 'tau')]
+  revert_paths = [G_path]
 
   expected_output = svntest.verify.UnorderedOutput([
     "Reverted '%s'\n" % path for path in revert_paths])


Reply via email to