You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2013/04/09 15:16:54 UTC
svn commit: r1466018 - in /subversion/trunk/subversion:
libsvn_wc/questions.c libsvn_wc/update_editor.c libsvn_wc/wc.h
tests/libsvn_wc/op-depth-test.c
Author: philip
Date: Tue Apr 9 13:16:53 2013
New Revision: 1466018
URL: http://svn.apache.org/r1466018
Log:
Fix issue 4347, resolve assert after update with tree-conflict.
* subversion/libsvn_wc/wc.h
(svn_wc__conflicted_for_update_p): Add parameter to return whether ignored.
* subversion/libsvn_wc/questions.c
(internal_conflicted_p): Change parameter to return whether ignored.
(svn_wc__internal_conflicted_p): Adjust call.
(svn_wc__conflicted_for_update_p): Add parameter to return whether ignored.
* subversion/libsvn_wc/update_editor.c
(already_in_a_tree_conflict, node_already_conflicted): Add parameter
to return whether ignored.
(open_root, add_directory, open_directory, add_file, open_file): Set
shadowed when ignoring a conflict.
(delete_entry): Adjust call.
* subversion/tests/libsvn_wc/op-depth-test.c
(update_with_tree_conflict): Extend to test second case.
(test_funcs): Mark update_with_tree_conflict PASS.
Modified:
subversion/trunk/subversion/libsvn_wc/questions.c
subversion/trunk/subversion/libsvn_wc/update_editor.c
subversion/trunk/subversion/libsvn_wc/wc.h
subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
Modified: subversion/trunk/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/questions.c?rev=1466018&r1=1466017&r2=1466018&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/questions.c (original)
+++ subversion/trunk/subversion/libsvn_wc/questions.c Tue Apr 9 13:16:53 2013
@@ -367,7 +367,7 @@ static svn_error_t *
internal_conflicted_p(svn_boolean_t *text_conflicted_p,
svn_boolean_t *prop_conflicted_p,
svn_boolean_t *tree_conflicted_p,
- svn_boolean_t ignore_move_edit,
+ svn_boolean_t *ignore_move_edit_p,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *scratch_pool)
@@ -388,6 +388,8 @@ internal_conflicted_p(svn_boolean_t *tex
*prop_conflicted_p = FALSE;
if (tree_conflicted_p)
*tree_conflicted_p = FALSE;
+ if (ignore_move_edit_p)
+ *ignore_move_edit_p = FALSE;
return SVN_NO_ERROR;
}
@@ -471,18 +473,27 @@ internal_conflicted_p(svn_boolean_t *tex
}
}
- if (tree_conflicted_p && *tree_conflicted_p && ignore_move_edit)
+ if (ignore_move_edit_p)
{
- svn_wc_conflict_reason_t reason;
- svn_wc_conflict_action_t action;
+ *ignore_move_edit_p = FALSE;
+ if (tree_conflicted_p && *tree_conflicted_p)
+ {
+ svn_wc_conflict_reason_t reason;
+ svn_wc_conflict_action_t action;
- SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, NULL,
- db, local_abspath, conflicts,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, NULL,
+ db, local_abspath,
+ conflicts,
+ scratch_pool,
+ scratch_pool));
- if (reason == svn_wc_conflict_reason_moved_away
- && action == svn_wc_conflict_action_edit)
- *tree_conflicted_p = FALSE;
+ if (reason == svn_wc_conflict_reason_moved_away
+ && action == svn_wc_conflict_action_edit)
+ {
+ *tree_conflicted_p = FALSE;
+ *ignore_move_edit_p = TRUE;
+ }
+ }
}
if (resolved_text || resolved_props)
@@ -513,23 +524,28 @@ svn_wc__internal_conflicted_p(svn_boolea
apr_pool_t *scratch_pool)
{
SVN_ERR(internal_conflicted_p(text_conflicted_p, prop_conflicted_p,
- tree_conflicted_p, FALSE,
+ tree_conflicted_p, NULL,
db, local_abspath, scratch_pool));
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__conflicted_for_update_p(svn_boolean_t *conflicted_p,
+ svn_boolean_t *conflict_ignored_p,
svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t tree_only,
apr_pool_t *scratch_pool)
{
svn_boolean_t text_conflicted, prop_conflicted, tree_conflicted;
+ svn_boolean_t conflict_ignored;
+
+ if (!conflict_ignored_p)
+ conflict_ignored_p = &conflict_ignored;
SVN_ERR(internal_conflicted_p(tree_only ? NULL: &text_conflicted,
tree_only ? NULL: &prop_conflicted,
- &tree_conflicted, TRUE,
+ &tree_conflicted, conflict_ignored_p,
db, local_abspath, scratch_pool));
if (tree_only)
*conflicted_p = tree_conflicted;
Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1466018&r1=1466017&r2=1466018&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Tue Apr 9 13:16:53 2013
@@ -618,6 +618,7 @@ make_dir_baton(struct dir_baton **d_p,
/* Forward declarations. */
static svn_error_t *
already_in_a_tree_conflict(svn_boolean_t *conflicted,
+ svn_boolean_t *ignored,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *scratch_pool);
@@ -1168,7 +1169,7 @@ open_root(void *edit_baton,
{
struct edit_baton *eb = edit_baton;
struct dir_baton *db;
- svn_boolean_t already_conflicted;
+ svn_boolean_t already_conflicted, conflict_ignored;
svn_error_t *err;
svn_wc__db_status_t status;
svn_wc__db_status_t base_status;
@@ -1182,8 +1183,8 @@ open_root(void *edit_baton,
SVN_ERR(make_dir_baton(&db, NULL, eb, NULL, FALSE, pool));
*dir_baton = db;
- err = already_in_a_tree_conflict(&already_conflicted, eb->db,
- db->local_abspath, pool);
+ err = already_in_a_tree_conflict(&already_conflicted, &conflict_ignored,
+ eb->db, db->local_abspath, pool);
if (err)
{
@@ -1191,7 +1192,7 @@ open_root(void *edit_baton,
return svn_error_trace(err);
svn_error_clear(err);
- already_conflicted = FALSE;
+ already_conflicted = conflict_ignored = FALSE;
}
else if (already_conflicted)
{
@@ -1222,7 +1223,11 @@ open_root(void *edit_baton,
eb->db, db->local_abspath,
db->pool, pool));
- if (have_work)
+ if (conflict_ignored)
+ {
+ db->shadowed = TRUE;
+ }
+ else if (have_work)
{
const char *move_src_root_abspath;
@@ -1636,6 +1641,7 @@ check_tree_conflict(svn_skel_t **pconfli
*/
static svn_error_t *
already_in_a_tree_conflict(svn_boolean_t *conflicted,
+ svn_boolean_t *ignored,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *scratch_pool)
@@ -1645,7 +1651,7 @@ already_in_a_tree_conflict(svn_boolean_t
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- *conflicted = FALSE;
+ *conflicted = *ignored = FALSE;
while (TRUE)
{
@@ -1653,9 +1659,10 @@ already_in_a_tree_conflict(svn_boolean_t
svn_pool_clear(iterpool);
- SVN_ERR(svn_wc__conflicted_for_update_p(conflicted, db, ancestor_abspath,
- TRUE, scratch_pool));
- if (*conflicted)
+ SVN_ERR(svn_wc__conflicted_for_update_p(conflicted, ignored, db,
+ ancestor_abspath, TRUE,
+ scratch_pool));
+ if (*conflicted || *ignored)
break;
SVN_ERR(svn_wc__db_is_wcroot(&is_wc_root, db, ancestor_abspath,
@@ -1674,11 +1681,13 @@ already_in_a_tree_conflict(svn_boolean_t
/* Temporary helper until the new conflict handling is in place */
static svn_error_t *
node_already_conflicted(svn_boolean_t *conflicted,
+ svn_boolean_t *conflict_ignored,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
- SVN_ERR(svn_wc__conflicted_for_update_p(conflicted, db, local_abspath, FALSE,
+ SVN_ERR(svn_wc__conflicted_for_update_p(conflicted, conflict_ignored, db,
+ local_abspath, FALSE,
scratch_pool));
return SVN_NO_ERROR;
@@ -1779,8 +1788,8 @@ delete_entry(const char *path,
if (pb->shadowed)
conflicted = FALSE; /* Conflict applies to WORKING */
else if (conflicted)
- SVN_ERR(node_already_conflicted(&conflicted, eb->db, local_abspath,
- scratch_pool));
+ SVN_ERR(node_already_conflicted(&conflicted, NULL,
+ eb->db, local_abspath, scratch_pool));
if (conflicted)
{
SVN_ERR(remember_skipped_tree(eb, local_abspath, scratch_pool));
@@ -1795,7 +1804,6 @@ delete_entry(const char *path,
}
-
/* Receive the remote removal of excluded/server-excluded/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
@@ -1970,6 +1978,7 @@ add_directory(const char *path,
svn_wc__db_status_t status;
svn_node_kind_t wc_kind;
svn_boolean_t conflicted;
+ svn_boolean_t conflict_ignored = FALSE;
svn_boolean_t versioned_locally_and_present;
svn_skel_t *tree_conflict = NULL;
svn_error_t *err;
@@ -2128,8 +2137,8 @@ add_directory(const char *path,
conflicted = FALSE; /* No skip */
}
else
- SVN_ERR(node_already_conflicted(&conflicted, eb->db,
- db->local_abspath, pool));
+ SVN_ERR(node_already_conflicted(&conflicted, &conflict_ignored,
+ eb->db, db->local_abspath, pool));
}
/* Now the "usual" behaviour if already conflicted. Skip it. */
@@ -2166,6 +2175,10 @@ add_directory(const char *path,
svn_wc_notify_skip_conflicted, pool);
return SVN_NO_ERROR;
}
+ else if (conflict_ignored)
+ {
+ db->shadowed = TRUE;
+ }
if (db->shadowed)
{
@@ -2318,6 +2331,7 @@ open_directory(const char *path,
struct edit_baton *eb = pb->edit_baton;
svn_boolean_t have_work;
svn_boolean_t conflicted;
+ svn_boolean_t conflict_ignored = FALSE;
svn_skel_t *tree_conflict = NULL;
svn_wc__db_status_t status, base_status;
svn_node_kind_t wc_kind;
@@ -2380,8 +2394,8 @@ open_directory(const char *path,
if (db->shadowed)
conflicted = FALSE; /* Conflict applies to WORKING */
else if (conflicted)
- SVN_ERR(node_already_conflicted(&conflicted, eb->db,
- db->local_abspath, pool));
+ SVN_ERR(node_already_conflicted(&conflicted, &conflict_ignored,
+ eb->db, db->local_abspath, pool));
if (conflicted)
{
SVN_ERR(remember_skipped_tree(eb, db->local_abspath, pool));
@@ -2394,6 +2408,10 @@ open_directory(const char *path,
return SVN_NO_ERROR;
}
+ else if (conflict_ignored)
+ {
+ db->shadowed = TRUE;
+ }
/* Is this path a fresh tree conflict victim? If so, skip the tree
with one notification. */
@@ -3066,6 +3084,7 @@ add_file(const char *path,
svn_wc__db_status_t status = svn_wc__db_status_normal;
apr_pool_t *scratch_pool;
svn_boolean_t conflicted = FALSE;
+ svn_boolean_t conflict_ignored = FALSE;
svn_boolean_t versioned_locally_and_present = FALSE;
svn_skel_t *tree_conflict = NULL;
svn_error_t *err = SVN_NO_ERROR;
@@ -3212,8 +3231,8 @@ add_file(const char *path,
conflicted = FALSE; /* No skip */
}
else
- SVN_ERR(node_already_conflicted(&conflicted, eb->db,
- fb->local_abspath, pool));
+ SVN_ERR(node_already_conflicted(&conflicted, &conflict_ignored,
+ eb->db, fb->local_abspath, pool));
}
/* Now the usual conflict handling: skip. */
@@ -3245,6 +3264,10 @@ add_file(const char *path,
return SVN_NO_ERROR;
}
+ else if (conflict_ignored)
+ {
+ fb->shadowed = TRUE;
+ }
if (fb->shadowed)
{
@@ -3380,6 +3403,7 @@ open_file(const char *path,
struct edit_baton *eb = pb->edit_baton;
struct file_baton *fb;
svn_boolean_t conflicted;
+ svn_boolean_t conflict_ignored = FALSE;
svn_boolean_t have_work;
svn_wc__db_status_t status;
svn_node_kind_t wc_kind;
@@ -3444,8 +3468,8 @@ open_file(const char *path,
if (fb->shadowed)
conflicted = FALSE; /* Conflict applies to WORKING */
else if (conflicted)
- SVN_ERR(node_already_conflicted(&conflicted, eb->db,
- fb->local_abspath, pool));
+ SVN_ERR(node_already_conflicted(&conflicted, &conflict_ignored,
+ eb->db, fb->local_abspath, pool));
if (conflicted)
{
SVN_ERR(remember_skipped_tree(eb, fb->local_abspath, pool));
@@ -3460,6 +3484,10 @@ open_file(const char *path,
return SVN_NO_ERROR;
}
+ else if (conflict_ignored)
+ {
+ fb->shadowed = TRUE;
+ }
/* Check for conflicts only when we haven't already recorded
* a tree-conflict on a parent node. */
Modified: subversion/trunk/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc.h?rev=1466018&r1=1466017&r2=1466018&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc.h Tue Apr 9 13:16:53 2013
@@ -504,10 +504,13 @@ svn_wc__internal_conflicted_p(svn_boolea
apr_pool_t *scratch_pool);
/* Similar to svn_wc__internal_conflicted_p(), but ignores
- * moved-away-edit tree conflicts. Also ignores text and property
- * conflicts if TREE_ONLY is TRUE */
+ * moved-away-edit tree conflicts. If CONFLICT_IGNORED_P is not NULL
+ * then sets *CONFLICT_IGNORED_P TRUE if a tree-conflict is ignored
+ * and FALSE otherwise. Also ignores text and property conflicts if
+ * TREE_ONLY is TRUE */
svn_error_t *
svn_wc__conflicted_for_update_p(svn_boolean_t *conflicted_p,
+ svn_boolean_t *conflict_ignored_p,
svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t tree_only,
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=1466018&r1=1466017&r2=1466018&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Tue Apr 9 13:16:53 2013
@@ -8104,6 +8104,47 @@ update_with_tree_conflict(const svn_test
SVN_ERR(check_db_rows(&b, "", nodes));
}
+ /* Same again but second update is A/B rather than A which triggers
+ the problem through open_root rather than open_directory. */
+ SVN_ERR(sbox_wc_revert(&b, "", svn_depth_infinity));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+ SVN_ERR(sbox_wc_update_depth(&b, "A", 2, svn_depth_empty, FALSE));
+ SVN_ERR(sbox_wc_update(&b, "A/B", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 2, "A/B/C"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 1, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_infinity,
+ svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 2, "A/B/C"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 2, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "A2/B/C", "normal", 2, "A/B/C", MOVED_HERE},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
return SVN_NO_ERROR;
}
@@ -8258,7 +8299,7 @@ struct svn_test_descriptor_t test_funcs[
"move retract (issue 4336)"),
SVN_TEST_OPTS_PASS(move_delete_file_externals,
"move/delete file externals (issue 4293)"),
- SVN_TEST_OPTS_XFAIL(update_with_tree_conflict,
+ SVN_TEST_OPTS_PASS(update_with_tree_conflict,
"update with tree conflict (issue 4347)"),
SVN_TEST_NULL
};