Author: philip
Date: Mon Dec  6 11:23:46 2010
New Revision: 1042586

URL: http://svn.apache.org/viewvc?rev=1042586&view=rev
Log:
For SVN_WC__OP_DEPTH, use base-deleted nodes at a higher op-depth
to represent deletes within a copy.  This causes an additional 18
regression test FAILs.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_DELETE_NOT_PRESENT_NODES_RECURSIVE): Rename to...
  (STMT_DELETE_CHILD_NODES_RECURSIVE): ...this, make presence a parameter.
  (STMT_INSERT_WORKING_NODE_FROM_NODE): New.

* subversion/libsvn_wc/wc_db.c
  (delete_not_present_children): Rename to...
  (remove_children): ...this, add status and op_depth parameters.

* subversion/tests/libsvn_wc/op-depth-test.c
  (test_delete_of_copies): Adjust expected values.
  (test_delete_of_replace): New.
  (test_funcs): Add test_delete_of_replace.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1042586&r1=1042585&r2=1042586&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Mon Dec  6 11:23:46 
2010
@@ -329,10 +329,10 @@ DELETE FROM actual_node
 WHERE wc_id = ?1 AND local_relpath = ?2
       AND tree_conflict_data IS NULL;
 
--- STMT_DELETE_NOT_PRESENT_NODES_RECURSIVE
+-- STMT_DELETE_CHILD_NODES_RECURSIVE
 DELETE FROM nodes
 WHERE wc_id = ?1 AND local_relpath LIKE ?2 ESCAPE '#' AND op_depth = ?3
-  AND presence = 'not-present';
+  AND presence = ?4
 
 -- STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST
 UPDATE actual_node
@@ -525,6 +525,19 @@ SELECT wc_id, local_relpath, ?3 AS op_de
 FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
+-- STMT_INSERT_WORKING_NODE_FROM_NODE
+INSERT OR REPLACE INTO nodes (
+    wc_id, local_relpath, op_depth, parent_relpath, presence, kind, checksum,
+    changed_revision, changed_date, changed_author, depth, symlink_target,
+    translated_size, last_mod_time, properties)
+SELECT wc_id, local_relpath, ?3 AS op_depth, parent_relpath, ?4 AS presence,
+       kind, checksum, changed_revision, changed_date, changed_author, depth,
+       symlink_target, translated_size, last_mod_time, properties
+FROM nodes
+WHERE wc_id = ?1 AND local_relpath = ?2
+ORDER BY op_depth DESC
+LIMIT 1;
+
 -- STMT_INSERT_WORKING_NODE_FROM_BASE_COPY
 INSERT INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1042586&r1=1042585&r2=1042586&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Mon Dec  6 11:23:46 2010
@@ -4436,31 +4436,42 @@ svn_wc__db_temp_op_set_dir_depth(svn_wc_
 
    ### Do we need to handle incomplete here? */
 static svn_error_t *
-delete_not_present_children(svn_wc__db_pdh_t *pdh,
-                            const char *local_relpath,
-                            apr_pool_t *scratch_pool)
+remove_children(svn_wc__db_pdh_t *pdh,
+                const char *local_relpath,
+                svn_wc__db_status_t status,
+                apr_int64_t op_depth,
+                apr_pool_t *scratch_pool)
 {
   svn_sqlite__stmt_t *stmt;
-#ifdef SVN_WC__OP_DEPTH
-  apr_int64_t op_depth = relpath_depth(local_relpath);
-#else
-  apr_int64_t op_depth = 2;  /* ### temporary op_depth */
-#endif
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
-                                    STMT_DELETE_NOT_PRESENT_NODES_RECURSIVE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isi", pdh->wcroot->wc_id,
+                                    STMT_DELETE_CHILD_NODES_RECURSIVE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "isit", pdh->wcroot->wc_id,
                             construct_like_arg(local_relpath,
                                                scratch_pool),
-                            op_depth));
+                            op_depth, presence_map, status));
   SVN_ERR(svn_sqlite__step_done(stmt));
 
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+db_working_actual_remove(svn_wc__db_pdh_t *pdh,
+                         const char *local_relpath,
+                         apr_pool_t *scratch_pool);
+
+static svn_error_t *
+info_below_working(svn_boolean_t *have_base,
+                   svn_boolean_t *have_work,
+                   svn_wc__db_status_t *status,
+                   svn_wc__db_pdh_t *pdh,
+                   const char *local_relpath,
+                   apr_pool_t *scratch_pool);
+
 /* Update the working node for LOCAL_ABSPATH setting presence=STATUS */
 static svn_error_t *
-db_working_update_presence(svn_wc__db_status_t status,
+db_working_update_presence(apr_int64_t op_depth,
+                           svn_wc__db_status_t status,
                            svn_wc__db_pdh_t *pdh,
                            const char *local_relpath,
                            apr_pool_t *scratch_pool)
@@ -4475,11 +4486,55 @@ db_working_update_presence(svn_wc__db_st
 
   if (status == svn_wc__db_status_base_deleted)
     {
-      /* Switching to base-deleted is undoing an add/copy.  If this
-         was a copy then any children of the copy will now be
-         not-present and should be removed.  By this stage an add will
-         have no children. */
-      SVN_ERR(delete_not_present_children(pdh, local_relpath, scratch_pool));
+      /* Switching to base-deleted is undoing an add/copy.  By this
+         stage an add will have no children. */
+#ifdef SVN_WC__OP_DEPTH
+      const apr_array_header_t *children;
+      apr_pool_t *iterpool;
+      int i;
+
+      /* Children of the copy will be marked deleted in the layer
+         above. */
+      SVN_ERR(remove_children(pdh, local_relpath,
+                              svn_wc__db_status_base_deleted, op_depth + 1,
+                              scratch_pool));
+
+      /* Children of the copy that overlay a lower level become
+         base_deleted, otherwise they get removed. */
+      SVN_ERR(gather_repo_children(&children, pdh, local_relpath, op_depth,
+                                   scratch_pool, scratch_pool));
+      iterpool = svn_pool_create(scratch_pool);
+      for (i = 0; i < children->nelts; ++i)
+        {
+          const char *name = APR_ARRAY_IDX(children, i, const char *);
+          const char *child_relpath;
+          svn_boolean_t below_base, below_work;
+          svn_wc__db_status_t below_status;
+
+          svn_pool_clear(iterpool);
+
+          child_relpath = svn_relpath_join(local_relpath, name, iterpool);
+          SVN_ERR(info_below_working(&below_base, &below_work, &below_status,
+                                     pdh, child_relpath, iterpool));
+          if ((below_base || below_work)
+              && (below_status == svn_wc__db_status_normal
+                  || below_status == svn_wc__db_status_added
+                  || below_status == svn_wc__db_status_incomplete))
+            SVN_ERR(db_working_update_presence(op_depth,
+                                               svn_wc__db_status_base_deleted,
+                                               pdh, child_relpath, iterpool));
+          else
+            SVN_ERR(db_working_actual_remove(pdh, child_relpath, iterpool));
+        }
+      svn_pool_destroy(iterpool);
+#else
+      /* If this was a copy then any children of the copy will now be
+         not-present and should be removed. */
+      SVN_ERR(remove_children(pdh, local_relpath,
+                              svn_wc__db_status_not_present,
+                              2 /* ### temporary op_depth */,
+                              scratch_pool));
+#endif
 
       /* Reset the copyfrom in case this was a copy.
          ### What else should be reset? Properties? Or copy the node again? */
@@ -4535,7 +4590,19 @@ db_working_actual_remove(svn_wc__db_pdh_
   SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step_done(stmt));
 
-  SVN_ERR(delete_not_present_children(pdh, local_relpath, scratch_pool));
+#ifndef SVN_WC__OP_DEPTH
+  SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_not_present,
+                          2 /* ### temporary op_depth */, scratch_pool));
+#else
+  SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_base_deleted,
+                          op_depth + 1, scratch_pool));
+  SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_normal,
+                          op_depth, scratch_pool));
+  SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_not_present,
+                          op_depth, scratch_pool));
+  SVN_ERR(remove_children(pdh, local_relpath, svn_wc__db_status_incomplete,
+                          op_depth, scratch_pool));
+#endif
 
   /* Postcondition: There are no NODES rows in this subtree, at same or
    * greater op_depth. */
@@ -4586,8 +4653,13 @@ db_working_insert(svn_wc__db_status_t st
   apr_int64_t op_depth = 2; /* ### temporary op_depth */
 #endif
 
+#ifdef SVN_WC__OP_DEPTH
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_INSERT_WORKING_NODE_FROM_NODE));
+#else
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_INSERT_WORKING_NODE_FROM_BASE));
+#endif
   SVN_ERR(svn_sqlite__bindf(stmt, "isit", pdh->wcroot->wc_id,
                             local_relpath, op_depth, presence_map, status));
   SVN_ERR(svn_sqlite__insert(NULL, stmt));
@@ -4795,7 +4867,10 @@ temp_op_delete_txn(void *baton, svn_sqli
 {
   struct temp_op_delete_baton *b = baton;
   svn_wc__db_status_t status, new_working_status;
-  svn_boolean_t have_work, new_have_work;
+  svn_boolean_t have_work, add_work = FALSE, del_work = FALSE, mod_work = 
FALSE;
+#ifndef SVN_WC__OP_DEPTH
+  svn_boolean_t new_have_work;
+#endif
 
   SVN_ERR(read_info(&status,
                     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -4805,8 +4880,10 @@ temp_op_delete_txn(void *baton, svn_sqli
                     b->pdh, b->local_relpath,
                     scratch_pool, scratch_pool));
 
+#ifndef SVN_WC__OP_DEPTH
   new_have_work = have_work;
   new_working_status = status;
+#endif
 
   if (!have_work)
     {
@@ -4814,13 +4891,17 @@ temp_op_delete_txn(void *baton, svn_sqli
       if (status == svn_wc__db_status_normal
           || status == svn_wc__db_status_incomplete)
         {
+#ifdef SVN_WC__OP_DEPTH
+          add_work = TRUE;
+#else
           new_have_work = TRUE;
           new_working_status = svn_wc__db_status_base_deleted;
+#endif
         }
     }
   else if (status == svn_wc__db_status_added)
     {
-      /* ADD/COPY-HERE/MOVE-HERE */
+      /* ADD/COPY-HERE/MOVE-HERE that could be a replace */
       svn_boolean_t add_or_root_of_copy;
 
       SVN_ERR(is_add_or_root_of_copy(&add_or_root_of_copy,
@@ -4833,24 +4914,51 @@ temp_op_delete_txn(void *baton, svn_sqli
           SVN_ERR(info_below_working(&below_base, &below_work, &below_status,
                                      b->pdh, b->local_relpath, scratch_pool));
 
+#ifdef SVN_WC__OP_DEPTH
+          if ((below_base || below_work)
+              && below_status != svn_wc__db_status_not_present)
+            mod_work = TRUE;
+          else
+            del_work = TRUE;
+#else
           if (below_base && below_status != svn_wc__db_status_not_present)
             new_working_status = svn_wc__db_status_base_deleted;
           else
             new_have_work = FALSE;
+#endif
         }
       else
-        new_working_status = svn_wc__db_status_not_present;
+        {
+#ifdef SVN_WC__OP_DEPTH
+          add_work = TRUE;
+#else
+          new_working_status = svn_wc__db_status_not_present;
+#endif
+        }
     }
   else if (status == svn_wc__db_status_incomplete)
     {
       svn_boolean_t add_or_root_of_copy;
       SVN_ERR(is_add_or_root_of_copy(&add_or_root_of_copy,
                                      b->pdh, b->local_relpath, scratch_pool));
+#ifdef SVN_WC__OP_DEPTH
+      if (add_or_root_of_copy)
+        del_work = TRUE;
+      else
+        add_work = TRUE;
+#else
       if (add_or_root_of_copy)
         new_have_work = FALSE;
+#endif
     }
 
-  if (!new_have_work && have_work)
+#ifndef SVN_WC__OP_DEPTH
+  del_work = !new_have_work && have_work;
+  add_work = new_have_work && !have_work;
+  mod_work = new_have_work && have_work && new_working_status != status;
+#endif
+
+  if (del_work)
     {
       SVN_ERR(db_working_actual_remove(b->pdh, b->local_relpath, 
scratch_pool));
 
@@ -4858,15 +4966,21 @@ temp_op_delete_txn(void *baton, svn_sqli
       SVN_ERR(svn_wc__db_temp_forget_directory(b->db, b->local_abspath,
                                                scratch_pool));
     }
-  else if (new_have_work && !have_work)
+  else if (add_work)
     {
+#ifdef SVN_WC__OP_DEPTH
+      new_working_status = svn_wc__db_status_base_deleted;
+#endif
       SVN_ERR(db_working_insert(new_working_status, b->pdh, b->local_relpath,
                                 scratch_pool));
     }
-  else if (new_have_work && have_work
-           && new_working_status != status)
+  else if (mod_work)
     {
-      SVN_ERR(db_working_update_presence(new_working_status, b->pdh,
+#ifdef SVN_WC__OP_DEPTH
+      new_working_status = svn_wc__db_status_base_deleted;
+#endif
+      SVN_ERR(db_working_update_presence(relpath_depth(b->local_relpath),
+                                         new_working_status, b->pdh,
                                          b->local_relpath, scratch_pool));
     }
   else
@@ -6993,7 +7107,7 @@ scan_deletion(const char **base_del_relp
         }
 
       /* We need the presence of the WORKING node. Note that legal values
-         are: normal, not-present, base-deleted.  */
+         are: normal, not-present, base-deleted, incomplete.  */
       work_presence = svn_sqlite__column_token(stmt, 1, presence_map);
 
       /* The starting node should be deleted.  */
@@ -7006,6 +7120,8 @@ scan_deletion(const char **base_del_relp
                                  path_for_error_message(wcroot,
                                                         local_relpath,
                                                         scratch_pool));
+
+      /* ### incomplete not handled */
       SVN_ERR_ASSERT(work_presence == svn_wc__db_status_normal
                      || work_presence == svn_wc__db_status_not_present
                      || work_presence == svn_wc__db_status_base_deleted);
@@ -7074,9 +7190,16 @@ scan_deletion(const char **base_del_relp
                                     svn_sqlite__column_text(stmt, 2, NULL));
         }
 
+#ifdef SVN_WC__OP_DEPTH
+      if (work_del_relpath != NULL
+          && work_presence == svn_wc__db_status_normal
+          && (child_presence == svn_wc__db_status_not_present
+              || child_presence == svn_wc__db_status_base_deleted))
+#else
       if (work_del_relpath != NULL
           && work_presence == svn_wc__db_status_normal
           && child_presence == svn_wc__db_status_not_present)
+#endif
         {
           /* Parent is normal, but child was deleted. Therefore, the child
              is the root of a WORKING subtree deletion.  */

Modified: subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c?rev=1042586&r1=1042585&r2=1042586&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Mon Dec  6 
11:23:46 2010
@@ -938,9 +938,12 @@ test_delete_of_copies(const svn_test_opt
                          FALSE, TRUE, NULL, NULL, NULL, NULL, pool));
   {
     nodes_row_t rows[] = {
-      { 2, "A/B-copied/E",       "not-present",       1, "A/B/E" },
-      { 2, "A/B-copied/E/alpha", "not-present",       1, "A/B/E/alpha" },
-      { 2, "A/B-copied/E/beta",  "not-present",       1, "A/B/E/beta" },
+      { 2, "A/B-copied/E",       "normal",       1, "A/B/E" },
+      { 2, "A/B-copied/E/alpha", "normal",       1, "A/B/E/alpha" },
+      { 2, "A/B-copied/E/beta",  "normal",       1, "A/B/E/beta" },
+      { 3, "A/B-copied/E",       "base-deleted", NO_COPY_FROM },
+      { 3, "A/B-copied/E/alpha", "base-deleted", NO_COPY_FROM },
+      { 3, "A/B-copied/E/beta",  "base-deleted", NO_COPY_FROM },
       { 0 }
     };
     SVN_ERR(check_db_rows(&b, "A/B-copied/E", rows));
@@ -949,13 +952,15 @@ test_delete_of_copies(const svn_test_opt
   SVN_ERR(wc_copy(&b, "A/D/G", "A/B-copied/E"));
   {
     nodes_row_t rows[] = {
-      { 2, "A/B-copied/E",       "not-present",       1, "A/B/E" },
-      { 2, "A/B-copied/E/alpha", "not-present",       1, "A/B/E/alpha" },
-      { 2, "A/B-copied/E/beta",  "not-present",       1, "A/B/E/beta" },
-      { 3, "A/B-copied/E",       "normal",            1, "A/D/G" },
-      { 3, "A/B-copied/E/pi",    "normal",            1, "A/D/G/pi" },
-      { 3, "A/B-copied/E/rho",   "normal",            1, "A/D/G/rho" },
-      { 3, "A/B-copied/E/tau",   "normal",            1, "A/D/G/tau" },
+      { 2, "A/B-copied/E",       "normal",       1, "A/B/E" },
+      { 2, "A/B-copied/E/alpha", "normal",       1, "A/B/E/alpha" },
+      { 2, "A/B-copied/E/beta",  "normal",       1, "A/B/E/beta" },
+      { 3, "A/B-copied/E",       "normal",       1, "A/D/G" },
+      { 3, "A/B-copied/E/alpha", "base-deleted", NO_COPY_FROM },
+      { 3, "A/B-copied/E/beta",  "base-deleted", NO_COPY_FROM },
+      { 3, "A/B-copied/E/pi",    "normal",       1, "A/D/G/pi" },
+      { 3, "A/B-copied/E/rho",   "normal",       1, "A/D/G/rho" },
+      { 3, "A/B-copied/E/tau",   "normal",       1, "A/D/G/tau" },
       { 0 }
     };
     SVN_ERR(check_db_rows(&b, "A/B-copied/E", rows));
@@ -965,13 +970,16 @@ test_delete_of_copies(const svn_test_opt
                          FALSE, TRUE, NULL, NULL, NULL, NULL, pool));
   {
     nodes_row_t rows[] = {
-      { 2, "A/B-copied/E",       "not-present",       1, "A/B/E" },
-      { 2, "A/B-copied/E/alpha", "not-present",       1, "A/B/E/alpha" },
-      { 2, "A/B-copied/E/beta",  "not-present",       1, "A/B/E/beta" },
-      { 3, "A/B-copied/E",       "normal",            1, "A/D/G" },
-      { 3, "A/B-copied/E/pi",    "normal",            1, "A/D/G/pi" },
-      { 3, "A/B-copied/E/rho",   "not-present",       1, "A/D/G/rho" },
-      { 3, "A/B-copied/E/tau",   "normal",            1, "A/D/G/tau" },
+      { 2, "A/B-copied/E",       "normal",       1, "A/B/E" },
+      { 2, "A/B-copied/E/alpha", "normal",       1, "A/B/E/alpha" },
+      { 2, "A/B-copied/E/beta",  "normal",       1, "A/B/E/beta" },
+      { 3, "A/B-copied/E",       "normal",       1, "A/D/G" },
+      { 3, "A/B-copied/E/alpha", "base-deleted", NO_COPY_FROM },
+      { 3, "A/B-copied/E/beta",  "base-deleted", NO_COPY_FROM },
+      { 3, "A/B-copied/E/pi",    "normal",       1, "A/D/G/pi" },
+      { 3, "A/B-copied/E/rho",   "normal",       1, "A/D/G/rho" },
+      { 3, "A/B-copied/E/tau",   "normal",       1, "A/D/G/tau" },
+      { 4, "A/B-copied/E/rho",   "base-deleted", NO_COPY_FROM },
       { 0 }
     };
     SVN_ERR(check_db_rows(&b, "A/B-copied/E", rows));
@@ -981,9 +989,12 @@ test_delete_of_copies(const svn_test_opt
                          FALSE, TRUE, NULL, NULL, NULL, NULL, pool));
   {
     nodes_row_t rows[] = {
-      { 2, "A/B-copied/E",       "not-present",       1, "A/B/E" },
-      { 2, "A/B-copied/E/alpha", "not-present",       1, "A/B/E/alpha" },
-      { 2, "A/B-copied/E/beta",  "not-present",       1, "A/B/E/beta" },
+      { 2, "A/B-copied/E",       "normal",       1, "A/B/E" },
+      { 2, "A/B-copied/E/alpha", "normal",       1, "A/B/E/alpha" },
+      { 2, "A/B-copied/E/beta",  "normal",       1, "A/B/E/beta" },
+      { 3, "A/B-copied/E",       "base-deleted", NO_COPY_FROM },
+      { 3, "A/B-copied/E/alpha", "base-deleted", NO_COPY_FROM },
+      { 3, "A/B-copied/E/beta",  "base-deleted", NO_COPY_FROM },
       { 0 }
     };
     SVN_ERR(check_db_rows(&b, "A/B-copied/E", rows));
@@ -995,7 +1006,8 @@ test_delete_of_copies(const svn_test_opt
                          FALSE, TRUE, NULL, NULL, NULL, NULL, pool));
   {
     nodes_row_t rows[] = {
-      { 3, "A/B-copied/E/F", "not-present",       1, "A/B/F" },
+      { 3, "A/B-copied/E/F", "normal",       1, "A/B/F" },
+      { 4, "A/B-copied/E/F", "base-deleted", NO_COPY_FROM },
       { 0 }
     };
     SVN_ERR(check_db_rows(&b, "A/B-copied/E/F", rows));
@@ -1750,6 +1762,79 @@ test_mixed_rev_copy(const svn_test_opts_
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_delete_of_replace(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  wc_baton_t b;
+
+  b.pool = pool;
+  SVN_ERR(svn_test__create_repos_and_wc(&b.repos_url, &b.wc_abspath,
+                                        "delete_of_replace", opts, pool));
+  SVN_ERR(svn_wc_context_create(&b.wc_ctx, NULL, pool, pool));
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_mkdir(&b, "A/B/C"));
+  SVN_ERR(wc_mkdir(&b, "A/B/C/F"));
+  SVN_ERR(wc_mkdir(&b, "A/B/C/F/K"));
+  SVN_ERR(wc_mkdir(&b, "A/B/C/G"));
+  SVN_ERR(wc_mkdir(&b, "A/B/C/G/K"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 1));
+
+  SVN_ERR(wc_copy(&b, "A", "X"));
+  SVN_ERR(wc_move(&b, "X/B/C/F", "X/B/C/H"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 2));
+
+  SVN_ERR(wc_delete(&b, "A/B"));
+  SVN_ERR(wc_copy(&b, "X/B", "A/B"));
+  {
+    nodes_row_t rows[] = {
+      { 0, "A",         "normal",       2, "A" },
+      { 0, "A/B",       "normal",       2, "A/B" },
+      { 0, "A/B/C",     "normal",       2, "A/B/C" },
+      { 0, "A/B/C/F",   "normal",       2, "A/B/C/F" },
+      { 0, "A/B/C/F/K", "normal",       2, "A/B/C/F/K" },
+      { 0, "A/B/C/G",   "normal",       2, "A/B/C/G" },
+      { 0, "A/B/C/G/K", "normal",       2, "A/B/C/G/K" },
+      { 2, "A/B",       "normal",       2, "X/B" },
+      { 2, "A/B/C",     "normal",       2, "X/B/C" },
+      { 2, "A/B/C/F",   "base-deleted", NO_COPY_FROM },
+      { 2, "A/B/C/F/K", "base-deleted", NO_COPY_FROM },
+      { 2, "A/B/C/G",   "normal",       2, "X/B/C/G" },
+      { 2, "A/B/C/G/K", "normal",       2, "X/B/C/G/K" },
+      { 2, "A/B/C/H",   "normal",       2, "X/B/C/H" },
+      { 2, "A/B/C/H/K", "normal",       2, "X/B/C/H/K" },
+      { 0 }
+    };
+    SVN_ERR(check_db_rows(&b, "A", rows));
+  }
+
+  SVN_ERR(wc_delete(&b, "A/B"));
+  {
+    nodes_row_t rows[] = {
+      { 0, "A",         "normal",       2, "A" },
+      { 0, "A/B",       "normal",       2, "A/B" },
+      { 0, "A/B/C",     "normal",       2, "A/B/C" },
+      { 0, "A/B/C/F",   "normal",       2, "A/B/C/F" },
+      { 0, "A/B/C/F/K", "normal",       2, "A/B/C/F/K" },
+      { 0, "A/B/C/G",   "normal",       2, "A/B/C/G" },
+      { 0, "A/B/C/G/K", "normal",       2, "A/B/C/G/K" },
+      { 2, "A/B",       "base-deleted", NO_COPY_FROM },
+      { 2, "A/B/C",     "base-deleted", NO_COPY_FROM },
+      { 2, "A/B/C/F",   "base-deleted", NO_COPY_FROM },
+      { 2, "A/B/C/F/K", "base-deleted", NO_COPY_FROM },
+      { 2, "A/B/C/G",   "base-deleted", NO_COPY_FROM },
+      { 2, "A/B/C/G/K", "base-deleted", NO_COPY_FROM },
+      { 0 }
+    };
+    SVN_ERR(check_db_rows(&b, "A", rows));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+
 /* ---------------------------------------------------------------------- */
 /* The list of test functions */
 
@@ -1794,5 +1879,8 @@ struct svn_test_descriptor_t test_funcs[
     SVN_TEST_OPTS_WIMP(test_mixed_rev_copy,
                        "test_mixed_rev_copy",
                        "needs op_depth"),
+    SVN_TEST_OPTS_WIMP(test_delete_of_replace,
+                       "test_delete_of_replace",
+                       "needs op_depth"),
     SVN_TEST_NULL
   };


Reply via email to