You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2010/08/09 16:52:56 UTC

svn commit: r983665 - in /subversion/trunk/subversion/libsvn_wc: update_editor.c workqueue.c workqueue.h

Author: rhuijben
Date: Mon Aug  9 14:52:56 2010
New Revision: 983665

URL: http://svn.apache.org/viewvc?rev=983665&view=rev
Log:
Remove the usage of the last loggy operation by declaring a new workingqueue
operation.

The new workingqueue operation has a stricter description than the old
operation, but for this patch I start by just moving the original code
without applying the restrictions.

A separate commit will remove the loggy support from the workqueue.

* subversion/libsvn_wc/update_editor.c
  (includes): Remove log.h
  (do_entry_deletion): Queue base remove workqueue item and remove direct
    removal on switch as svn_wc__internal_remove_from_revision_control
    already checks this in a better way than described here.

* subversion/libsvn_wc/workqueue.c
  (OP_BASE_REMOVE): New define.
  (basic_delete_entry): New function. Copied from log.c
  (run_base_remove): New function.
  (svn_wc__wq_build_base_remove): New function.
  (dispatch_table): Add OP_BASE_REMOVE.

* subversion/libsvn_wc/workqueue.h
  (svn_wc__wq_build_base_remove): New function.

Modified:
    subversion/trunk/subversion/libsvn_wc/update_editor.c
    subversion/trunk/subversion/libsvn_wc/workqueue.c
    subversion/trunk/subversion/libsvn_wc/workqueue.h

Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=983665&r1=983664&r2=983665&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Mon Aug  9 14:52:56 2010
@@ -48,7 +48,6 @@
 #include "svn_iter.h"
 
 #include "wc.h"
-#include "log.h"
 #include "adm_files.h"
 #include "entries.h"
 #include "lock.h"
@@ -2219,56 +2218,21 @@ do_entry_deletion(struct edit_baton *eb,
   if (strcmp(local_abspath, eb->target_abspath) != 0)
     {
       /* Delete, and do not leave a not-present node.  */
-      SVN_ERR(svn_wc__loggy_delete_entry(&work_item,
-                                         eb->db, dir_abspath, local_abspath,
-                                         SVN_INVALID_REVNUM,
-                                         svn_wc__db_kind_unknown,
-                                         pool));
+      SVN_ERR(svn_wc__wq_build_base_remove(&work_item,
+                                           eb->db, local_abspath, FALSE,
+                                           pool, pool));
       SVN_ERR(svn_wc__db_wq_add(eb->db, dir_abspath, work_item, pool));
     }
   else
     {
       /* Delete, leaving a not-present node.  */
-      SVN_ERR(svn_wc__loggy_delete_entry(&work_item,
-                                         eb->db, dir_abspath, local_abspath,
-                                         *eb->target_revision,
-                                         kind,
-                                         pool));
+      SVN_ERR(svn_wc__wq_build_base_remove(&work_item,
+                                           eb->db, local_abspath, TRUE,
+                                           pool, pool));
       SVN_ERR(svn_wc__db_wq_add(eb->db, dir_abspath, work_item, pool));
       eb->target_deleted = TRUE;
     }
 
-  if (eb->switch_relpath)
-    {
-      /* The SVN_WC__LOG_DELETE_ENTRY log item will cause
-       * svn_wc_remove_from_revision_control() to be run.  But that
-       * function checks whether the deletion target's URL is child of
-       * its parent directory's URL, and if it's not, then the entry
-       * in parent won't be deleted (because presumably the child
-       * represents a disjoint working copy, i.e., it is a wc_root).
-       *
-       * However, during a switch this works against us, because by
-       * the time we get here, the parent's URL has already been
-       * changed.  So we manually remove the child from revision
-       * control after the delete-entry item has been written in the
-       * parent's log, but before it is run, so the only work left for
-       * the log item is to remove the entry in the parent directory.
-       */
-
-      if (kind == svn_wc__db_kind_dir)
-        {
-          SVN_ERR(leftmod_error_chain(
-                    svn_wc__internal_remove_from_revision_control(
-                      eb->db,
-                      local_abspath,
-                      TRUE, /* destroy */
-                      FALSE, /* instant error */
-                      eb->cancel_func,
-                      eb->cancel_baton,
-                      pool)));
-        }
-    }
-
   /* Note: these two lines are duplicated in the tree-conflicts bail out
    * above. */
   SVN_ERR(svn_wc__wq_run(eb->db, dir_abspath,

Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=983665&r1=983664&r2=983665&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Mon Aug  9 14:52:56 2010
@@ -45,6 +45,7 @@
 #define OP_REVERT "revert"
 #define OP_KILLME "killme"
 #define OP_LOGGY "loggy"
+#define OP_BASE_REMOVE "base-remove"
 #define OP_DELETION_POSTCOMMIT "deletion-postcommit"
 /* Arguments of OP_POSTCOMMIT:
  *   (local_abspath, revnum, date, [author], [checksum],
@@ -640,6 +641,177 @@ svn_wc__wq_add_killme(svn_wc__db_t *db,
 #endif
 
 /* ------------------------------------------------------------------------ */
+/* OP_REMOVE_BASE  */
+
+/* Ben sez:  this log command is (at the moment) only executed by the
+   update editor.  It attempts to forcefully remove working data. */
+/* Delete a node from version control, and from disk if unmodified.
+ * LOCAL_ABSPATH is the name of the file or directory to be deleted.
+ * If it is unversioned,
+ * do nothing and return no error. Otherwise, delete its WC entry and, if
+ * the working version is unmodified, delete it from disk. */
+static svn_error_t *
+basic_delete_entry(svn_wc__db_t *db,
+                   const char *local_abspath,
+                   apr_pool_t *scratch_pool)
+{
+  svn_wc__db_kind_t kind;
+  svn_boolean_t hidden;
+  svn_error_t *err;
+
+  /* Figure out if 'name' is a dir or a file */
+  SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, TRUE, scratch_pool));
+  if (kind == svn_wc__db_kind_unknown)
+    return SVN_NO_ERROR; /* Already gone */
+
+  SVN_ERR(svn_wc__db_node_hidden(&hidden, db, local_abspath, scratch_pool));
+  if (hidden)
+    return SVN_NO_ERROR;
+
+  /* Remove the object from revision control -- whether it's a
+     single file or recursive directory removal.  Attempt
+     to destroy all working files & dirs too.
+
+     ### We pass NULL, NULL for cancel_func and cancel_baton below.
+     ### If they were available, it would be nice to use them. */
+  if (kind == svn_wc__db_kind_dir)
+    {
+      svn_wc__db_status_t status;
+
+      SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL,
+                                      NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                      NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                      NULL, NULL, NULL, NULL,
+                                   db, local_abspath,
+                                   scratch_pool, scratch_pool));
+      if (status == svn_wc__db_status_obstructed ||
+          status == svn_wc__db_status_obstructed_add ||
+          status == svn_wc__db_status_obstructed_delete)
+        {
+          /* Removing a missing wcroot is easy, just remove its parent entry
+             ### BH: I can't tell why we don't use this for adds.
+                     We might want to remove WC obstructions?
+
+             We don't have a missing status in the final version of WC-NG,
+             so why bother researching its history.
+          */
+          if (status != svn_wc__db_status_obstructed_add)
+            {
+              SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
+                                                      scratch_pool));
+
+              return SVN_NO_ERROR;
+            }
+        }
+    }
+
+  err = svn_wc__internal_remove_from_revision_control(db,
+                                                      local_abspath,
+                                                      TRUE, /* destroy */
+                                                      FALSE, /* instant_error*/
+                                                      NULL, NULL,
+                                                      scratch_pool);
+
+  if (err && err->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD)
+    {
+      svn_error_clear(err);
+      return SVN_NO_ERROR;
+    }
+  else
+    {
+      return svn_error_return(err);
+    }
+}
+
+/* Process the OP_REMOVE_BASE work item WORK_ITEM.
+ * See svn_wc__wq_build_remove_base() which generates this work item.
+ * Implements (struct work_item_dispatch).func. */
+
+static svn_error_t *
+run_base_remove(svn_wc__db_t *db,
+                const svn_skel_t *work_item,
+                const char *wri_abspath,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
+                apr_pool_t *scratch_pool)
+{
+  const svn_skel_t *arg1 = work_item->children->next;
+  const char *local_abspath;
+  svn_boolean_t keep_not_present;
+  svn_revnum_t revision;
+  const char *repos_relpath, *repos_root_url, *repos_uuid;
+  svn_wc__db_kind_t kind;
+
+  local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
+  keep_not_present = svn_skel__parse_int(arg1->next, scratch_pool) != 0;
+
+  if (keep_not_present)
+    {
+      SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &revision, &repos_relpath,
+                                       &repos_root_url, &repos_uuid, NULL,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL,
+                                       db, local_abspath,
+                                       scratch_pool, scratch_pool));
+
+      if (!repos_relpath)
+        SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url,
+                                           &repos_uuid,
+                                           db, local_abspath, scratch_pool,
+                                           scratch_pool));
+
+#ifndef SVN_WC__SINGLE_DB
+      /* ### When LOCAL_ABSPATH is obstructed, we might not receive a valid
+         ### revision here. For the small time that is left until Single-DB
+         ### just mark the not-present node as revision 0, as we are not
+         ### interested in the revision of not-present nodes anyway.
+
+         ### Triggered by update_tests.py 15: issue #919, updates that delete
+       */
+      if (!SVN_IS_VALID_REVNUM(revision))
+        revision = 0;
+#endif
+    }
+
+  SVN_ERR(basic_delete_entry(db, local_abspath, scratch_pool));
+
+  if (keep_not_present)
+    {
+      SVN_ERR(svn_wc__db_base_add_absent_node(db, local_abspath,
+                                              repos_relpath,
+                                              repos_root_url,
+                                              repos_uuid,
+                                              revision,
+                                              kind,
+                                              svn_wc__db_status_not_present,
+                                              NULL,
+                                              NULL,
+                                              scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__wq_build_base_remove(svn_skel_t **work_item,
+                             svn_wc__db_t *db,
+                             const char *local_abspath,
+                             svn_boolean_t keep_not_present,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool)
+{
+  *work_item = svn_skel__make_empty_list(result_pool);
+
+  /* If a SOURCE_ABSPATH was provided, then put it into the skel. If this
+     value is not provided, then the file's pristine contents will be used.  */
+
+  svn_skel__prepend_int(keep_not_present, *work_item, result_pool);
+  svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),
+                        *work_item, result_pool);
+  svn_skel__prepend_str(OP_BASE_REMOVE, *work_item, result_pool);
+
+  return SVN_NO_ERROR;
+}
 
 /* OP_LOGGY  */
 
@@ -2313,6 +2485,7 @@ static const struct work_item_dispatch d
   { OP_SYNC_FILE_FLAGS, run_sync_file_flags },
   { OP_PREJ_INSTALL, run_prej_install },
   { OP_RECORD_FILEINFO, run_record_fileinfo },
+  { OP_BASE_REMOVE, run_base_remove },
   { OP_TMP_SET_TEXT_CONFLICT_MARKERS, run_set_text_conflict_markers },
   { OP_TMP_SET_PROPERTY_CONFLICT_MARKER, run_set_property_conflict_marker },
   { OP_PRISTINE_GET_TRANSLATED, run_pristine_get_translated },

Modified: subversion/trunk/subversion/libsvn_wc/workqueue.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.h?rev=983665&r1=983664&r2=983665&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.h Mon Aug  9 14:52:56 2010
@@ -196,6 +196,23 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
                       svn_boolean_t use_commit_times,
                       apr_pool_t *scratch_pool);
 
+/* Set *WORK_ITEM to a new work item that will remove all the data of
+   the BASE_NODE of LOCAL_ABSPATH and all it's descendants, but keeping
+   any WORKING_NODE data.
+
+   ### This is only used from update_editor.c's do_entry_deletion() and
+   ### the current implementation doesn't check if it removes more than
+   ### just this documented behavior. (It is just a copy of the old loggy
+   ### code)
+ */
+svn_error_t *
+svn_wc__wq_build_base_remove(svn_skel_t **work_item,
+                             svn_wc__db_t *db,
+                             const char *local_abspath,
+                             svn_boolean_t keep_not_present,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool);
+
 #ifndef SVN_WC__SINGLE_DB
 /* Handle the old "KILLME" concept -- perform the actual deletion of a
    subdir (or just its admin area) during post-commit processing of a