Author: philip
Date: Fri Dec 14 19:04:15 2012
New Revision: 1422041
URL: http://svn.apache.org/viewvc?rev=1422041&view=rev
Log:
Start adding tree-conflicts when following a move to resolve
a tree-conflict.
* subversion/libsvn_wc/wc_db_update_move.c
(check_shadowed_node): Remove.
(check_tree_conflict): New.
(tc_editor_alter_directory, tc_editor_alter_file): Use check_tree_conflict
instead of check_shadowed_node and do it earlier.
(get_tc_info): Do the scan dance to get tree-conflicts from the working
tree.
* subversion/tests/libsvn_wc/op-depth-test.c
(test_funcs): Remove XFAIL from nested_move_update.
Modified:
subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
Modified: subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c?rev=1422041&r1=1422040&r2=1422041&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c Fri Dec 14
19:04:15 2012
@@ -220,26 +220,64 @@ update_working_props(svn_wc_notify_state
}
-/* Check whether the node at LOCAL_RELPATH in the working copy at WCROOT
- * is shadowed by some node at a higher op depth than EXPECTED_OP_DEPTH. */
+/* If LOCAL_ABSPATH is shadowed then raise a tree-conflict on the root
+ of the obstruction if such a tree-conflict does not already exist. */
static svn_error_t *
-check_shadowed_node(svn_boolean_t *is_shadowed,
- int expected_op_depth,
+check_tree_conflict(svn_boolean_t *is_conflicted,
+ struct tc_editor_baton *b,
const char *local_relpath,
- svn_wc__db_wcroot_t *wcroot)
+ apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
+ int dst_op_depth = relpath_depth(b->move_root_dst_relpath);
+ int op_depth;
+ const char *conflict_root_relpath = local_relpath;
+ svn_skel_t *conflict;
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
STMT_SELECT_LOWEST_WORKING_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
- expected_op_depth));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", b->wcroot->wc_id, local_relpath,
+ dst_op_depth));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (have_row)
+ op_depth = svn_sqlite__column_int(stmt, 0);
SVN_ERR(svn_sqlite__reset(stmt));
- *is_shadowed = have_row;
+ if (!have_row)
+ {
+ *is_conflicted = FALSE;
+ return SVN_NO_ERROR;
+ }
+
+ while (relpath_depth(conflict_root_relpath) > op_depth)
+ conflict_root_relpath = svn_relpath_dirname(conflict_root_relpath,
+ scratch_pool);
+
+ SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, b->wcroot,
+ conflict_root_relpath,
+ scratch_pool, scratch_pool));
+
+ if (conflict)
+ /* ### TODO: check this is the right sort of tree-conflict? */
+ return SVN_NO_ERROR;
+
+ conflict = svn_wc__conflict_skel_create(scratch_pool);
+ SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
+ conflict, NULL,
+ svn_dirent_join(b->wcroot->abspath, conflict_root_relpath,
+ scratch_pool),
+ svn_wc_conflict_reason_moved_away,
+ svn_wc_conflict_action_edit,
+ scratch_pool,
+ scratch_pool));
+
+ SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict, b->old_version,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, conflict_root_relpath,
+ conflict, scratch_pool));
+ *is_conflicted = TRUE;
return SVN_NO_ERROR;
}
@@ -258,9 +296,14 @@ tc_editor_alter_directory(void *baton,
svn_kind_t move_dst_kind;
working_node_version_t old_version, new_version;
svn_wc__db_status_t status;
+ svn_boolean_t is_conflicted;
SVN_ERR_ASSERT(expected_move_dst_revision == b->old_version->peg_rev);
+ SVN_ERR(check_tree_conflict(&is_conflicted, b, dst_relpath, scratch_pool));
+ if (is_conflicted)
+ return SVN_NO_ERROR;
+
/* Get kind, revision, and checksum of the moved-here node. */
SVN_ERR(svn_wc__db_depth_get_info(&status, &move_dst_kind,
&move_dst_revision,
&move_dst_repos_relpath, NULL, NULL, NULL,
@@ -280,59 +323,45 @@ tc_editor_alter_directory(void *baton,
if (new_props)
{
- svn_boolean_t is_shadowed;
+ const char *dst_abspath = svn_dirent_join(b->wcroot->abspath,
+ dst_relpath,
+ scratch_pool);
+ svn_wc_notify_state_t prop_state;
+ svn_skel_t *conflict_skel = NULL;
+ apr_hash_t *actual_props;
+ apr_array_header_t *propchanges;
+
+ SVN_ERR(update_working_props(&prop_state, &conflict_skel,
+ &propchanges, &actual_props,
+ b->db, dst_abspath,
+ &old_version, &new_version,
+ b->result_pool, scratch_pool));
- /* If the node is shadowed by a higher layer, we need to flag a
- * tree conflict and must not touch the working node. */
- SVN_ERR(check_shadowed_node(&is_shadowed,
- relpath_depth(b->move_root_dst_relpath),
- dst_relpath, b->wcroot));
- if (is_shadowed)
+ if (conflict_skel)
{
- /* ### TODO flag tree conflict */
+ SVN_ERR(create_conflict_markers(b->work_items, dst_abspath,
+ b->db, move_dst_repos_relpath,
+ conflict_skel,
+ &old_version, &new_version,
+ b->result_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, dst_relpath,
+ conflict_skel,
+ scratch_pool));
}
- else
- {
- const char *dst_abspath = svn_dirent_join(b->wcroot->abspath,
- dst_relpath,
- scratch_pool);
- svn_wc_notify_state_t prop_state;
- svn_skel_t *conflict_skel = NULL;
- apr_hash_t *actual_props;
- apr_array_header_t *propchanges;
-
- SVN_ERR(update_working_props(&prop_state, &conflict_skel,
- &propchanges, &actual_props,
- b->db, dst_abspath,
- &old_version, &new_version,
- b->result_pool, scratch_pool));
-
- if (conflict_skel)
- {
- SVN_ERR(create_conflict_markers(b->work_items, dst_abspath,
- b->db, move_dst_repos_relpath,
- conflict_skel,
- &old_version, &new_version,
- b->result_pool, scratch_pool));
- SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, dst_relpath,
- conflict_skel,
- scratch_pool));
- }
- if (b->notify_func)
- {
- svn_wc_notify_t *notify;
+ if (b->notify_func)
+ {
+ svn_wc_notify_t *notify;
- notify = svn_wc_create_notify(dst_abspath,
- svn_wc_notify_update_update,
- scratch_pool);
- notify->kind = svn_node_dir;
- notify->content_state = svn_wc_notify_state_inapplicable;
- notify->prop_state = prop_state;
- notify->old_revision = b->old_version->peg_rev;
- notify->revision = b->new_version->peg_rev;
- b->notify_func(b->notify_baton, notify, scratch_pool);
- }
+ notify = svn_wc_create_notify(dst_abspath,
+ svn_wc_notify_update_update,
+ scratch_pool);
+ notify->kind = svn_node_dir;
+ notify->content_state = svn_wc_notify_state_inapplicable;
+ notify->prop_state = prop_state;
+ notify->old_revision = b->old_version->peg_rev;
+ notify->revision = b->new_version->peg_rev;
+ b->notify_func(b->notify_baton, notify, scratch_pool);
}
}
@@ -489,6 +518,11 @@ tc_editor_alter_file(void *baton,
svn_revnum_t move_dst_revision;
svn_kind_t move_dst_kind;
working_node_version_t old_version, new_version;
+ svn_boolean_t is_conflicted;
+
+ SVN_ERR(check_tree_conflict(&is_conflicted, b, dst_relpath, scratch_pool));
+ if (is_conflicted)
+ return SVN_NO_ERROR;
/* Get kind, revision, and checksum of the moved-here node. */
SVN_ERR(svn_wc__db_depth_get_info(NULL, &move_dst_kind, &move_dst_revision,
@@ -514,30 +548,16 @@ tc_editor_alter_file(void *baton,
if (!svn_checksum_match(new_checksum, old_version.checksum)
/* ### || props have changed */)
{
- svn_boolean_t is_shadowed;
+ svn_skel_t *work_item;
- /* If the node is shadowed by a higher layer, we need to flag a
- * tree conflict and must not touch the working file. */
- SVN_ERR(check_shadowed_node(&is_shadowed,
- relpath_depth(b->move_root_dst_relpath),
- dst_relpath, b->wcroot));
- if (is_shadowed)
- {
- /* ### TODO flag tree conflict */
- }
- else
- {
- svn_skel_t *work_item;
-
- SVN_ERR(update_working_file(&work_item, dst_relpath,
- move_dst_repos_relpath,
- &old_version, &new_version,
- b->wcroot, b->db,
- b->notify_func, b->notify_baton,
- b->result_pool, scratch_pool));
- *b->work_items = svn_wc__wq_merge(*b->work_items, work_item,
- b->result_pool);
- }
+ SVN_ERR(update_working_file(&work_item, dst_relpath,
+ move_dst_repos_relpath,
+ &old_version, &new_version,
+ b->wcroot, b->db,
+ b->notify_func, b->notify_baton,
+ b->result_pool, scratch_pool));
+ *b->work_items = svn_wc__wq_merge(*b->work_items, work_item,
+ b->result_pool);
}
return SVN_NO_ERROR;
@@ -739,14 +759,55 @@ get_tc_info(svn_wc_operation_t *operatio
const char *repos_relpath;
svn_revnum_t revision;
svn_node_kind_t node_kind;
+ svn_wc__db_status_t status;
+
+ /* The scan dance: read_info then scan_delete then base_get
+ or scan_addition. Use the internal/relpath functions
+ here? */
+ SVN_ERR(svn_wc__db_read_info(&status, &kind, &revision,
+ &repos_relpath, &repos_root_url,
+ &repos_uuid, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ db, src_abspath, result_pool,
+ scratch_pool));
+ if (status == svn_wc__db_status_deleted)
+ {
+ const char *base_del_abspath, *work_del_abspath;
+ SVN_ERR(svn_wc__db_scan_deletion(&base_del_abspath, NULL,
+ &work_del_abspath,
+ NULL, db, src_abspath,
+ scratch_pool, scratch_pool));
+ SVN_ERR_ASSERT(base_del_abspath || work_del_abspath);
+ if (base_del_abspath)
+ {
+ 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,
NULL,
+ db, src_abspath,
result_pool,
+ scratch_pool));
+ }
+ else if (work_del_abspath)
+ {
+ work_del_abspath = svn_dirent_dirname(work_del_abspath,
+ scratch_pool);
+ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath,
+ &repos_root_url,
&repos_uuid,
+ NULL, NULL, NULL,
+ &revision, NULL, NULL,
+ db, work_del_abspath,
+ scratch_pool,
scratch_pool));
+ repos_relpath = svn_relpath_join(repos_relpath,
+ svn_dirent_skip_ancestor(work_del_abspath,
+ src_abspath),
+ scratch_pool);
+ }
+ }
- /* Construct new_version from BASE info. */
- 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, NULL,
- db, src_abspath, result_pool,
- scratch_pool));
node_kind = svn__node_kind_from_kind(kind);
*new_version = svn_wc_conflict_version_create2(repos_root_url,
repos_uuid,
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=1422041&r1=1422040&r2=1422041&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Fri Dec 14
19:04:15 2012
@@ -5325,7 +5325,7 @@ struct svn_test_descriptor_t test_funcs[
"mixed_rev_move"),
SVN_TEST_OPTS_PASS(update_prop_mod_into_moved,
"update_prop_mod_into_moved"),
- SVN_TEST_OPTS_XFAIL(nested_move_update,
+ SVN_TEST_OPTS_PASS(nested_move_update,
"nested_move_update"),
SVN_TEST_NULL
};