Author: rhuijben
Date: Tue Feb 17 14:42:28 2015
New Revision: 1660393

URL: http://svn.apache.org/r1660393
Log:
On move-update layer copying remove ACTUAL nodes for nodes that no longer
exist and are not delete-delete conflicted.

While not really a bug, leaving dangling ACTUAL records creates nonstandard
database states and therefore may trigger untested code paths.
(You might see this as changelists or property changes on newly added
 files/directories)

* subversion/libsvn_wc/wc-queries.sql
  (STMT_CLEAR_ACTUAL_NODE_LEAVING_CONFLICT): New statement.

* subversion/libsvn_wc/wc_db.c
  (clear_or_remove_actual): New function.
  (svn_wc__db_op_copy_layer_internal): Call clear_or_remove_actual on
    removed nodes. Remove TODO comment.

* subversion/tests/libsvn_wc/op-depth-test.c
  (move_update_delete_mods,
   move4_update_delself_AAA): Extend expectations to make it easier
     to spot problems.

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=1660393&r1=1660392&r2=1660393&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Tue Feb 17 14:42:28 
2015
@@ -815,6 +815,17 @@ SET properties = NULL,
     right_checksum = NULL
 WHERE wc_id = ?1 AND local_relpath = ?2
 
+-- STMT_CLEAR_ACTUAL_NODE_LEAVING_CONFLICT
+UPDATE actual_node
+SET properties = NULL,
+    text_mod = NULL,
+    tree_conflict_data = NULL,
+    older_checksum = NULL,
+    left_checksum = NULL,
+    right_checksum = NULL,
+    changelist = NULL
+WHERE wc_id = ?1 AND local_relpath = ?2
+
 -- STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE
 UPDATE actual_node
 SET properties = NULL,

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1660393&r1=1660392&r2=1660393&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Tue Feb 17 14:42:28 2015
@@ -4831,6 +4831,72 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
   return SVN_NO_ERROR;
 }
 
+/* Remove unneeded actual nodes for svn_wc__db_op_copy_layer_internal */
+static svn_error_t *
+clear_or_remove_actual(svn_wc__db_wcroot_t *wcroot,
+                       const char *local_relpath,
+                       int op_depth,
+                       apr_pool_t *scratch_pool)
+{
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row, shadowed;
+  svn_boolean_t keep_conflict = FALSE;
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_SELECT_NODE_INFO));
+
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+  if (have_row)
+    {
+      svn_wc__db_status_t presence;
+
+      shadowed = (svn_sqlite__column_int(stmt, 0) > op_depth);
+      presence = svn_sqlite__column_token(stmt, 3, presence_map);
+
+      if (shadowed && presence == svn_wc__db_status_base_deleted)
+        {
+          keep_conflict = TRUE;
+          SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+          if (have_row)
+            shadowed = (svn_sqlite__column_int(stmt, 0) > op_depth);
+          else
+            shadowed = FALSE;
+        }
+    }
+  else
+    shadowed = FALSE;
+
+  SVN_ERR(svn_sqlite__reset(stmt));
+  if (shadowed)
+    return SVN_NO_ERROR;
+
+  if (keep_conflict)
+    {
+      /* We don't want to accidentally remove delete-delete conflicts */
+      SVN_ERR(svn_sqlite__get_statement(
+                          &stmt, wcroot->sdb,
+                          STMT_CLEAR_ACTUAL_NODE_LEAVING_CONFLICT));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_DELETE_ACTUAL_EMPTY));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+  else
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_DELETE_ACTUAL_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_wc__db_op_copy_layer_internal(svn_wc__db_wcroot_t *wcroot,
                                   const char *src_op_relpath,
@@ -4962,6 +5028,12 @@ svn_wc__db_op_copy_layer_internal(svn_wc
         err = svn_sqlite__step_done(stmt2);
 
       /* stmt2 is reset (never modified or by step_done) */
+      if (err)
+        break;
+
+      /* Delete ACTUAL information about this node that we just deleted */
+      err = clear_or_remove_actual(wcroot, dst_relpath, dst_op_depth,
+                                   scratch_pool);
 
       if (err)
         break;
@@ -4979,8 +5051,6 @@ svn_wc__db_op_copy_layer_internal(svn_wc
 
   SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
 
-  /* ### TODO: Did we handle ACTUAL as intended? */
-
   SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
 
   if (conflict)

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=1660393&r1=1660392&r2=1660393&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Tue Feb 17 
14:42:28 2015
@@ -6111,7 +6111,16 @@ move_update_delete_mods(const svn_test_o
       {2, "B2/C/f",  "normal",       1, "A/B/C/f"},
       {0}
     };
+    conflict_info_t conflicts[] = {
+      {"B2/C", FALSE, FALSE, {svn_wc_conflict_action_delete,
+                              svn_wc_conflict_reason_edited}},
+      {"B2/D", FALSE, FALSE, {svn_wc_conflict_action_delete,
+                              svn_wc_conflict_reason_deleted}},
+      { 0 }
+    };
+
     SVN_ERR(check_db_rows(&b, "", nodes));
+    SVN_ERR(check_db_conflicts(&b, "", conflicts));
   }
 
   SVN_ERR(check_tree_conflict_repos_path(&b, "B2/C", "A/B/C", "A/B/C"));
@@ -9955,7 +9964,21 @@ move4_update_delself_AAA(const svn_test_
 
         { 0 },
       };
-        SVN_ERR(check_db_rows(&b, "", nodes));
+      conflict_info_t conflicts[] = {
+        {"A_moved/A/A", FALSE, FALSE, {svn_wc_conflict_action_delete,
+                                       svn_wc_conflict_reason_moved_away, 
"A_moved/A/A"}},
+        {"B",           FALSE, FALSE, {svn_wc_conflict_action_edit,
+                                       svn_wc_conflict_reason_moved_away, 
"B"}},
+        {"C/A",         FALSE, FALSE, {svn_wc_conflict_action_edit,
+                                       svn_wc_conflict_reason_moved_away, 
"C/A"}},
+        {"D/A/A",       FALSE, FALSE, {svn_wc_conflict_action_delete,
+                                       svn_wc_conflict_reason_moved_away, 
"D/A/A"}},
+
+        { 0 },
+      };
+
+      SVN_ERR(check_db_rows(&b, "", nodes));
+      SVN_ERR(check_db_conflicts(&b, "", conflicts));
     }
 
     SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,


Reply via email to