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,