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 2011/04/19 19:53:17 UTC

svn commit: r1095148 - /subversion/trunk/subversion/libsvn_wc/update_editor.c

Author: rhuijben
Date: Tue Apr 19 17:53:17 2011
New Revision: 1095148

URL: http://svn.apache.org/viewvc?rev=1095148&view=rev
Log:
* subversion/libsvn_wc/update_editor.c
  (delete_entry): Use scratch pool. Check the right layer before doing the
    db obly work. Remove and/or fix outdated comments.

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

Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1095148&r1=1095147&r2=1095148&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Tue Apr 19 17:53:17 2011
@@ -1571,76 +1571,97 @@ delete_entry(const char *path,
   struct edit_baton *eb = pb->edit_baton;
   const char *base = svn_relpath_basename(path, NULL);
   const char *local_abspath;
-  const char *their_relpath;
+  const char *repos_relpath;
   svn_wc__db_kind_t kind;
   svn_boolean_t conflicted;
+  svn_boolean_t have_base;
+  svn_boolean_t have_work;
   svn_wc_conflict_description2_t *tree_conflict = NULL;
-  const char *dir_abspath;
-  svn_skel_t *work_item;
+  svn_skel_t *work_item = NULL;
   svn_wc__db_status_t status;
-
-  local_abspath = svn_dirent_join(pb->local_abspath, base, pool);
-  dir_abspath = svn_dirent_dirname(local_abspath, pool);
-  their_relpath = svn_relpath_join(pb->new_relpath, base, pool);
+  svn_wc__db_status_t base_status;
+  apr_pool_t *scratch_pool;
+  svn_boolean_t deleting_target;
 
   if (pb->skip_this)
     return SVN_NO_ERROR;
 
-  SVN_ERR(check_path_under_root(pb->local_abspath, base, pool));
+  scratch_pool = svn_pool_create(pb->pool);
+
+  SVN_ERR(check_path_under_root(pb->local_abspath, base, scratch_pool));
+
+  local_abspath = svn_dirent_join(pb->local_abspath, base, scratch_pool);
+
+  deleting_target =  (strcmp(local_abspath, eb->target_abspath) == 0);
 
   /* Detect obstructing working copies */
   {
     svn_boolean_t is_root;
 
     SVN_ERR(svn_wc__db_is_wcroot(&is_root, eb->db, local_abspath,
-                                 pool));
+                                 scratch_pool));
 
     if (is_root)
       {
         /* Just skip this node; a future update will handle it */
         remember_skipped_tree(eb, local_abspath, pool);
         do_notification(eb, local_abspath, svn_node_unknown,
-                        svn_wc_notify_update_skip_obstruction, pool);
+                        svn_wc_notify_update_skip_obstruction, scratch_pool);
+
+        svn_pool_destroy(scratch_pool);
 
         return SVN_NO_ERROR;
       }
   }
 
-  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
+  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, &repos_relpath, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, &conflicted,
-                               NULL, NULL, NULL, NULL, NULL, NULL,
-                               eb->db, local_abspath, pool, pool));
+                               NULL, NULL, NULL, NULL, NULL, NULL, &conflicted,
+                               NULL, NULL, NULL,
+                               &have_base, NULL, &have_work,
+                               eb->db, local_abspath,
+                               scratch_pool, scratch_pool));
+
+  if (!have_work)
+    base_status = status;
+  else
+    SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, NULL, &repos_relpath,
+                                     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                     eb->db, local_abspath,
+                                     scratch_pool, scratch_pool));
 
   /* Is this path a conflict victim? */
   if (conflicted)
-    SVN_ERR(node_already_conflicted(&conflicted, eb->db,
-                                    local_abspath, pool));
+    SVN_ERR(node_already_conflicted(&conflicted, eb->db, local_abspath,
+                                    scratch_pool));
   if (conflicted)
     {
-      SVN_ERR(remember_skipped_tree(eb, local_abspath, pool));
+      SVN_ERR(remember_skipped_tree(eb, local_abspath, scratch_pool));
 
-      /* ### TODO: Also print victim_path in the skip msg. */
       do_notification(eb, local_abspath, svn_node_unknown, svn_wc_notify_skip,
-                      pool);
+                      scratch_pool);
+
+      svn_pool_destroy(scratch_pool);
 
       return SVN_NO_ERROR;
     }
 
-    /* Receive the remote removal of excluded/absent/not present node.
-       Do not notify.
 
-       ### This is wrong if svn_wc__db_status_excluded refers to a
-           working node replacing the base node.  */
-  if (status == svn_wc__db_status_not_present
-      || status == svn_wc__db_status_excluded
-      || status == svn_wc__db_status_absent)
+
+    /* Receive the remote removal of excluded/absent/not present node.
+       Do not notify, but perform the change even when the node is shadowed */
+  if (base_status == svn_wc__db_status_not_present
+      || base_status == svn_wc__db_status_excluded
+      || base_status == svn_wc__db_status_absent)
     {
-      SVN_ERR(svn_wc__db_base_remove(eb->db, local_abspath, pool));
+      SVN_ERR(svn_wc__db_base_remove(eb->db, local_abspath, scratch_pool));
 
-      if (strcmp(local_abspath, eb->target_abspath) == 0)
+      if (deleting_target)
         eb->target_deleted = TRUE;
 
+      svn_pool_destroy(scratch_pool);
+
       return SVN_NO_ERROR;
     }
 
@@ -1652,29 +1673,32 @@ delete_entry(const char *path,
   /* Check for conflicts only when we haven't already recorded
    * a tree-conflict on a parent node. */
   if (!pb->shadowed)
-    SVN_ERR(check_tree_conflict(&tree_conflict, eb, local_abspath,
-                                status, kind, TRUE,
-                                svn_wc_conflict_action_delete, svn_node_none,
-                                their_relpath, pool));
+    {
+      const char *their_relpath = repos_relpath;
+
+      if (eb->switch_relpath)
+        their_relpath = svn_relpath_join(pb->new_relpath, base, scratch_pool);
+
+      SVN_ERR(check_tree_conflict(&tree_conflict, eb, local_abspath,
+                                  status, kind, TRUE,
+                                  svn_wc_conflict_action_delete, svn_node_none,
+                                  repos_relpath, scratch_pool));
+    }
 
   if (tree_conflict != NULL)
     {
-      /* When we raise a tree conflict on a node, we want to avoid
-       * making any changes inside it. (Will an update ever try to make
-       * further changes to or inside a directory it's just deleted?)
-       *
-       * ### BH: Only if a new node is added in it's place.
-       *          See svn_delta.h for further details. */
+      /* When we raise a tree conflict on a node, we don't want to mark the
+       * node as skipped, to allow a replacement to continue doing at least
+       * a bit of its work (possibly adding a not present node, for the
+       * next update) */
 
-      /* ### Note that we still add this on the parent of a node, so it is
-         ### safe to add it now, while we remove the node later */
       SVN_ERR(svn_wc__db_op_set_tree_conflict(eb->db,
-                                              tree_conflict->local_abspath,
+                                              local_abspath,
                                               tree_conflict,
-                                              pool));
+                                              scratch_pool));
 
       do_notification(eb, local_abspath, svn_node_unknown,
-                      svn_wc_notify_tree_conflict, pool);
+                      svn_wc_notify_tree_conflict, scratch_pool);
 
       if (tree_conflict->reason == svn_wc_conflict_reason_edited)
         {
@@ -1685,28 +1709,21 @@ delete_entry(const char *path,
            * we must schedule the existing content for re-addition as a copy
            * of what it was, but with its local modifications preserved. */
 
-          SVN_ERR(svn_wc__db_temp_op_make_copy(eb->db, local_abspath, pool));
+          SVN_ERR(svn_wc__db_temp_op_make_copy(eb->db, local_abspath,
+                                               scratch_pool));
 
           /* Fall through to remove the BASE_NODEs properly, with potentially
              keeping a not-present marker */
         }
-      else if (tree_conflict->reason == svn_wc_conflict_reason_deleted)
+      else if (tree_conflict->reason == svn_wc_conflict_reason_deleted
+               || tree_conflict->reason == svn_wc_conflict_reason_replaced)
         {
-          /* The item does not exist locally (except perhaps as a skeleton
-           * directory tree) because it was already scheduled for delete.
+          /* The item does not exist locally because it was already shadowed.
            * We must complete the deletion, leaving the tree conflict info
            * as the only difference from a normal deletion. */
 
           /* Fall through to the normal "delete" code path. */
         }
-      else if (tree_conflict->reason == svn_wc_conflict_reason_replaced)
-        {
-          /* The item was locally replaced with something else. We should
-           * remove the BASE node below the new working node, which turns
-           * the replacement in an addition. */
-
-           /* Fall through to the normal "delete" code path. */
-        }
       else
         SVN_ERR_MALFUNCTION();  /* other reasons are not expected here */
     }
@@ -1719,27 +1736,28 @@ delete_entry(const char *path,
      If the thing being deleted is the *target* of this update, then
      we need to recreate a 'deleted' entry, so that the parent can give
      accurate reports about itself in the future. */
-  if (strcmp(local_abspath, eb->target_abspath) != 0)
+  if (! deleting_target)
     {
       /* Delete, and do not leave a not-present node.  */
       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));
+                                           scratch_pool, scratch_pool));
     }
   else
     {
       /* Delete, leaving a not-present node.  */
       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));
+                                           scratch_pool, scratch_pool));
       eb->target_deleted = TRUE;
     }
 
-  SVN_ERR(svn_wc__wq_run(eb->db, dir_abspath,
+  SVN_ERR(svn_wc__db_wq_add(eb->db, pb->local_abspath, work_item,
+                                scratch_pool));
+
+  SVN_ERR(svn_wc__wq_run(eb->db, pb->local_abspath,
                          eb->cancel_func, eb->cancel_baton,
-                         pool));
+                         scratch_pool));
 
   /* Notify. (If tree_conflict, we've already notified.) */
   if (tree_conflict == NULL)
@@ -1755,9 +1773,11 @@ delete_entry(const char *path,
       else
         node_kind = svn_node_file;
 
-      do_notification(eb, local_abspath, node_kind, action, pool);
+      do_notification(eb, local_abspath, node_kind, action, scratch_pool);
     }
 
+  svn_pool_destroy(scratch_pool);
+
   return SVN_NO_ERROR;
 }