You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by sv...@apache.org on 2018/10/02 04:00:38 UTC
svn commit: r1842587 - in /subversion/branches/1.10.x: ./ STATUS
subversion/libsvn_client/conflicts.c
subversion/tests/libsvn_client/conflicts-test.c
Author: svn-role
Date: Tue Oct 2 04:00:38 2018
New Revision: 1842587
URL: http://svn.apache.org/viewvc?rev=1842587&view=rev
Log:
Merge the r1836960 group from trunk:
* r1836960, r1836968
Fix issue #4766, "resolver adds unrelated moves to move target list"
Justification:
Undesirable resolver behaviour: If an item was moved, all other items
moved within the same revision will be considered viable merge targets.
Notes:
r1836960 adds a regression test
r1836968 fixes the bug
Votes:
+1: stsp, rhuijben, jcorvel
Modified:
subversion/branches/1.10.x/ (props changed)
subversion/branches/1.10.x/STATUS
subversion/branches/1.10.x/subversion/libsvn_client/conflicts.c
subversion/branches/1.10.x/subversion/tests/libsvn_client/conflicts-test.c
Propchange: subversion/branches/1.10.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Oct 2 04:00:38 2018
@@ -102,4 +102,4 @@
/subversion/branches/verify-at-commit:1462039-1462408
/subversion/branches/verify-keep-going:1439280-1546110
/subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1817837,1817856,1818577-1818578,1818584,1818651,1818662,1818727,1818801,1818803,1818807,1818868,1818871,1819036-1819037,1819043,1819049,1819052,1819093,1819146,1819162,1819444,1819556-1819557,1819603,1819804,1819911,1820044,1820046-1820047,1820518,1820627,1820718,1820778,1821183,1821224,1821621,1821678,1822401,1822587,1822591,1822996,1823202-1823203,1823211,1823327,1823791,1823966,1823989,1824033,1825024,1825045,1825215,1825266,1825306,1825709,1825711,1825721,1825736,1825778,1825783,1825787-1825788,1825979,1826720-1826721,1826747,1826811,1826814,1826877,1826907,1826971,1827105,1827114,1827191,1827562,1827574,1827670,1828613,1829012,1829015,1829241,1829260,1829344,1830083,1830882-1830883,1830885,1830900-1830901,1831110,1831112,1831540,1833465,1833621,1833836,1833842,1833864,1833866,1833895,1833897,1833899,1833901,1835760,1836306,1836762,1836802,1836963,1836976,1837037,1837790,1838813,1839662,1839703,1839734,1840991,1842262,1842264
+/subversion/trunk:1817837,1817856,1818577-1818578,1818584,1818651,1818662,1818727,1818801,1818803,1818807,1818868,1818871,1819036-1819037,1819043,1819049,1819052,1819093,1819146,1819162,1819444,1819556-1819557,1819603,1819804,1819911,1820044,1820046-1820047,1820518,1820627,1820718,1820778,1821183,1821224,1821621,1821678,1822401,1822587,1822591,1822996,1823202-1823203,1823211,1823327,1823791,1823966,1823989,1824033,1825024,1825045,1825215,1825266,1825306,1825709,1825711,1825721,1825736,1825778,1825783,1825787-1825788,1825979,1826720-1826721,1826747,1826811,1826814,1826877,1826907,1826971,1827105,1827114,1827191,1827562,1827574,1827670,1828613,1829012,1829015,1829241,1829260,1829344,1830083,1830882-1830883,1830885,1830900-1830901,1831110,1831112,1831540,1833465,1833621,1833836,1833842,1833864,1833866,1833895,1833897,1833899,1833901,1835760,1836306,1836762,1836802,1836960,1836963,1836968,1836976,1837037,1837790,1838813,1839662,1839703,1839734,1840991,1842262,1842264
Modified: subversion/branches/1.10.x/STATUS
URL: http://svn.apache.org/viewvc/subversion/branches/1.10.x/STATUS?rev=1842587&r1=1842586&r2=1842587&view=diff
==============================================================================
--- subversion/branches/1.10.x/STATUS (original)
+++ subversion/branches/1.10.x/STATUS Tue Oct 2 04:00:38 2018
@@ -20,14 +20,3 @@ Veto-blocked changes:
Approved changes:
=================
-
- * r1836960, r1836968
- Fix issue #4766, "resolver adds unrelated moves to move target list"
- Justification:
- Undesirable resolver behaviour: If an item was moved, all other items
- moved within the same revision will be considered viable merge targets.
- Notes:
- r1836960 adds a regression test
- r1836968 fixes the bug
- Votes:
- +1: stsp, rhuijben, jcorvel
Modified: subversion/branches/1.10.x/subversion/libsvn_client/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10.x/subversion/libsvn_client/conflicts.c?rev=1842587&r1=1842586&r2=1842587&view=diff
==============================================================================
--- subversion/branches/1.10.x/subversion/libsvn_client/conflicts.c (original)
+++ subversion/branches/1.10.x/subversion/libsvn_client/conflicts.c Tue Oct 2 04:00:38 2018
@@ -2102,33 +2102,6 @@ trace_moved_node_backwards(apr_hash_t *m
return SVN_NO_ERROR;
}
-static svn_error_t *
-reparent_session_and_fetch_node_kind(svn_node_kind_t *node_kind,
- svn_ra_session_t *ra_session,
- const char *url,
- svn_revnum_t peg_rev,
- apr_pool_t *scratch_pool)
-{
- svn_error_t *err;
-
- err = svn_ra_reparent(ra_session, url, scratch_pool);
- if (err)
- {
- if (err->apr_err == SVN_ERR_RA_ILLEGAL_URL)
- {
- svn_error_clear(err);
- *node_kind = svn_node_unknown;
- return SVN_NO_ERROR;
- }
-
- return svn_error_trace(err);
- }
-
- SVN_ERR(svn_ra_check_path(ra_session, "", peg_rev, node_kind, scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
/* Scan MOVES_TABLE for moves which affect a particular deleted node, and
* build a set of new move information for this node.
* Return heads of all possible move chains in *MOVES.
@@ -2175,22 +2148,29 @@ find_operative_moves(apr_array_header_t
svn_pool_clear(iterpool);
move = APR_ARRAY_IDX(moves_in_deleted_rev, i, struct repos_move_info *);
- relpath = svn_relpath_skip_ancestor(move->moved_from_repos_relpath,
+ if (strcmp(move->moved_from_repos_relpath, deleted_repos_relpath) == 0)
+ {
+ APR_ARRAY_PUSH(*moves, struct repos_move_info *) = move;
+ continue;
+ }
+
+ /* Test for an operative nested move. */
+ relpath = svn_relpath_skip_ancestor(move->moved_to_repos_relpath,
deleted_repos_relpath);
if (relpath && relpath[0] != '\0')
{
- svn_node_kind_t node_kind;
+ struct repos_move_info *nested_move;
+ const char *actual_deleted_repos_relpath;
- url = svn_path_url_add_component2(repos_root_url,
- deleted_repos_relpath,
- iterpool);
- SVN_ERR(reparent_session_and_fetch_node_kind(&node_kind,
- ra_session, url,
- rev_below(deleted_rev),
- iterpool));
- move = new_path_adjusted_move(move, relpath, node_kind, result_pool);
+ actual_deleted_repos_relpath =
+ svn_relpath_join(move->moved_from_repos_relpath, relpath,
+ iterpool);
+ nested_move = map_deleted_path_to_move(actual_deleted_repos_relpath,
+ moves_in_deleted_rev,
+ iterpool);
+ if (nested_move)
+ APR_ARRAY_PUSH(*moves, struct repos_move_info *) = nested_move;
}
- APR_ARRAY_PUSH(*moves, struct repos_move_info *) = move;
}
if (url != NULL)
Modified: subversion/branches/1.10.x/subversion/tests/libsvn_client/conflicts-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10.x/subversion/tests/libsvn_client/conflicts-test.c?rev=1842587&r1=1842586&r2=1842587&view=diff
==============================================================================
--- subversion/branches/1.10.x/subversion/tests/libsvn_client/conflicts-test.c (original)
+++ subversion/branches/1.10.x/subversion/tests/libsvn_client/conflicts-test.c Tue Oct 2 04:00:38 2018
@@ -164,6 +164,7 @@ static const char *trunk_path = "A";
static const char *branch_path = "A_branch";
static const char *branch2_path = "A_branch2";
static const char *new_file_name = "newfile.txt";
+static const char *new_file2_name = "newfile2.txt";
static const char *new_file_name_branch = "newfile-on-branch.txt";
static const char *deleted_file_name = "mu";
static const char *deleted_dir_name = "B";
@@ -1291,6 +1292,7 @@ test_merge_incoming_added_dir_replace_an
static svn_error_t *
create_wc_with_incoming_delete_file_merge_conflict(svn_test__sandbox_t *b,
svn_boolean_t move,
+ svn_boolean_t move_unrelated,
svn_boolean_t do_switch)
{
svn_client_ctx_t *ctx;
@@ -1312,6 +1314,17 @@ create_wc_with_incoming_delete_file_merg
deleted_path = svn_relpath_join(trunk_path, deleted_file_name, b->pool);
move_target_path = svn_relpath_join(trunk_path, new_file_name, b->pool);
SVN_ERR(sbox_wc_move(b, deleted_path, move_target_path));
+ if (move_unrelated)
+ {
+ /* Move an unrelated file on trunk as part of the same commit. */
+ deleted_path = svn_relpath_join(trunk_path,
+ svn_relpath_join(deleted_dir_name,
+ deleted_dir_child,
+ b->pool),
+ b->pool);
+ move_target_path = svn_relpath_join(trunk_path, new_file2_name, b->pool);
+ SVN_ERR(sbox_wc_move(b, deleted_path, move_target_path));
+ }
SVN_ERR(sbox_wc_commit(b, ""));
}
else
@@ -1377,7 +1390,8 @@ test_merge_incoming_delete_file_ignore(c
SVN_ERR(svn_test__sandbox_create(b, "merge_incoming_delete_file_ignore",
opts, pool));
- SVN_ERR(create_wc_with_incoming_delete_file_merge_conflict(b, FALSE, FALSE));
+ SVN_ERR(create_wc_with_incoming_delete_file_merge_conflict(b, FALSE, FALSE,
+ FALSE));
/* Resolve the tree conflict. */
SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
@@ -1469,7 +1483,8 @@ test_merge_incoming_delete_file_accept(c
SVN_ERR(svn_test__sandbox_create(b, "merge_incoming_delete_file_accept",
opts, pool));
- SVN_ERR(create_wc_with_incoming_delete_file_merge_conflict(b, FALSE, FALSE));
+ SVN_ERR(create_wc_with_incoming_delete_file_merge_conflict(b, FALSE, FALSE,
+ FALSE));
/* Resolve the tree conflict. */
SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
@@ -1564,7 +1579,8 @@ test_merge_incoming_move_file_text_merge
SVN_ERR(svn_test__sandbox_create(b, "merge_incoming_move_file_text_merge",
opts, pool));
- SVN_ERR(create_wc_with_incoming_delete_file_merge_conflict(b, TRUE, FALSE));
+ SVN_ERR(create_wc_with_incoming_delete_file_merge_conflict(b, TRUE, FALSE,
+ FALSE));
/* Resolve the tree conflict. */
SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
@@ -1970,7 +1986,8 @@ test_switch_incoming_move_file_text_merg
SVN_ERR(svn_test__sandbox_create(b, "switch_incoming_move_file_text_merge",
opts, pool));
- SVN_ERR(create_wc_with_incoming_delete_file_merge_conflict(b, TRUE, TRUE));
+ SVN_ERR(create_wc_with_incoming_delete_file_merge_conflict(b, TRUE, FALSE,
+ TRUE));
/* Resolve the tree conflict. */
SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
@@ -5394,6 +5411,176 @@ test_merge_two_added_dirs_assertion_fail
return SVN_NO_ERROR;
}
+/* Test for issue #4766: resolver adds unrelated moves to move target list */
+static svn_error_t *
+test_merge_incoming_delete_file_unrelated_move(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b));
+ svn_client_ctx_t *ctx;
+ const char *deleted_path;
+ svn_client_conflict_t *conflict;
+ svn_boolean_t tree_conflicted;
+ svn_boolean_t text_conflicted;
+ apr_array_header_t *props_conflicted;
+ struct status_baton sb;
+ struct svn_client_status_t *status;
+ svn_opt_revision_t opt_rev;
+ apr_array_header_t *possible_moved_to_repos_relpaths;
+ apr_array_header_t *options;
+ svn_client_conflict_option_t *option;
+ const char *new_file_path;
+ const char *moved_to_repos_path;
+ svn_node_kind_t kind;
+ svn_stringbuf_t *buf;
+
+ SVN_ERR(svn_test__sandbox_create(b,
+ "merge_incoming_delete_file_unrelated_move",
+ opts, pool));
+
+ SVN_ERR(create_wc_with_incoming_delete_file_merge_conflict(b, TRUE, TRUE,
+ FALSE));
+
+ /* Resolve the tree conflict. */
+ SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+ deleted_path = svn_relpath_join(branch_path, deleted_file_name, b->pool);
+ SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, deleted_path),
+ ctx, b->pool, b->pool));
+
+ {
+ svn_client_conflict_option_id_t expected_opts[] = {
+ svn_client_conflict_option_postpone,
+ svn_client_conflict_option_accept_current_wc_state,
+ svn_client_conflict_option_incoming_delete_ignore,
+ svn_client_conflict_option_incoming_delete_accept,
+ -1 /* end of list */
+ };
+ SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts,
+ b->pool));
+ }
+
+ SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, b->pool));
+
+ {
+ svn_client_conflict_option_id_t expected_opts[] = {
+ svn_client_conflict_option_postpone,
+ svn_client_conflict_option_accept_current_wc_state,
+ svn_client_conflict_option_incoming_move_file_text_merge,
+ -1 /* end of list */
+ };
+ SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts,
+ b->pool));
+ }
+
+ SVN_ERR(svn_client_conflict_tree_get_resolution_options(&options, conflict,
+ ctx, b->pool,
+ b->pool));
+ option = svn_client_conflict_option_find_by_id(
+ options, svn_client_conflict_option_incoming_move_file_text_merge);
+ SVN_TEST_ASSERT(option != NULL);
+
+ /* Assert that only one move target candidate has been found in repository. */
+ SVN_ERR(svn_client_conflict_option_get_moved_to_repos_relpath_candidates(
+ &possible_moved_to_repos_relpaths, option, b->pool, b->pool));
+
+ SVN_TEST_INT_ASSERT(possible_moved_to_repos_relpaths->nelts, 1);
+ moved_to_repos_path = svn_relpath_join(trunk_path, new_file_name, b->pool);
+ SVN_TEST_STRING_ASSERT(
+ APR_ARRAY_IDX(possible_moved_to_repos_relpaths, 0, const char *), moved_to_repos_path);
+
+ SVN_ERR(svn_client_conflict_tree_resolve_by_id(
+ conflict, svn_client_conflict_option_incoming_move_file_text_merge,
+ ctx, b->pool));
+
+ /* Ensure that the deleted file has the expected status. */
+ opt_rev.kind = svn_opt_revision_working;
+ sb.result_pool = b->pool;
+ SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, deleted_path),
+ &opt_rev, svn_depth_unknown, TRUE, TRUE,
+ TRUE, TRUE, FALSE, TRUE, NULL,
+ status_func, &sb, b->pool));
+ status = sb.status;
+ SVN_TEST_ASSERT(status->kind == svn_node_file);
+ SVN_TEST_ASSERT(status->versioned);
+ SVN_TEST_ASSERT(!status->conflicted);
+ SVN_TEST_ASSERT(status->node_status == svn_wc_status_deleted);
+ SVN_TEST_ASSERT(status->text_status == svn_wc_status_normal);
+ SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+ SVN_TEST_ASSERT(!status->copied);
+ SVN_TEST_ASSERT(!status->switched);
+ SVN_TEST_ASSERT(!status->file_external);
+ SVN_TEST_ASSERT(status->moved_from_abspath == NULL);
+ new_file_path = svn_relpath_join(branch_path, new_file_name, b->pool);
+ SVN_TEST_STRING_ASSERT(status->moved_to_abspath,
+ sbox_wc_path(b, new_file_path));
+
+ SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, deleted_path),
+ ctx, b->pool, b->pool));
+
+ /* The file should not be in conflict. */
+ SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted,
+ &props_conflicted,
+ &tree_conflicted,
+ conflict, b->pool, b->pool));
+ SVN_TEST_ASSERT(!text_conflicted &&
+ props_conflicted->nelts == 0 &&
+ !tree_conflicted);
+
+ /* Ensure that the moved file has the expected status. */
+ opt_rev.kind = svn_opt_revision_working;
+ sb.result_pool = b->pool;
+ SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, new_file_path),
+ &opt_rev, svn_depth_unknown, TRUE, TRUE,
+ TRUE, TRUE, FALSE, TRUE, NULL,
+ status_func, &sb, b->pool));
+ status = sb.status;
+ SVN_TEST_ASSERT(status->kind == svn_node_file);
+ SVN_TEST_ASSERT(status->versioned);
+ SVN_TEST_ASSERT(!status->conflicted);
+ SVN_TEST_ASSERT(status->node_status == svn_wc_status_added);
+ SVN_TEST_ASSERT(status->text_status == svn_wc_status_normal);
+ SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+ SVN_TEST_ASSERT(status->copied);
+ SVN_TEST_ASSERT(!status->switched);
+ SVN_TEST_ASSERT(!status->file_external);
+ SVN_TEST_STRING_ASSERT(status->moved_from_abspath,
+ sbox_wc_path(b, deleted_path));
+ SVN_TEST_ASSERT(status->moved_to_abspath == NULL);
+
+ /* Ensure that the original file was removed. */
+ SVN_ERR(svn_io_check_path(sbox_wc_path(b, deleted_path), &kind, b->pool));
+ SVN_TEST_ASSERT(kind == svn_node_none);
+
+ /* Ensure that the moved file has the expected content. */
+ SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, new_file_path),
+ b->pool));
+ SVN_TEST_STRING_ASSERT(buf->data, modified_file_on_branch_content);
+
+ /* Ensure that the unrelated moved file has the expected status. */
+ opt_rev.kind = svn_opt_revision_working;
+ sb.result_pool = b->pool;
+ SVN_ERR(svn_client_status6(NULL, ctx,
+ sbox_wc_path(b, svn_relpath_join(branch_path,
+ new_file2_name, b->pool)),
+ &opt_rev, svn_depth_unknown, TRUE, TRUE,
+ TRUE, TRUE, FALSE, TRUE, NULL,
+ status_func, &sb, b->pool));
+ status = sb.status;
+ SVN_TEST_ASSERT(status->kind == svn_node_file);
+ SVN_TEST_ASSERT(status->versioned);
+ SVN_TEST_ASSERT(!status->conflicted);
+ SVN_TEST_ASSERT(status->node_status == svn_wc_status_added);
+ SVN_TEST_ASSERT(status->text_status == svn_wc_status_normal);
+ SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+ SVN_TEST_ASSERT(status->copied);
+ SVN_TEST_ASSERT(!status->switched);
+ SVN_TEST_ASSERT(!status->file_external);
+ SVN_TEST_ASSERT(status->moved_from_abspath == NULL);
+ SVN_TEST_ASSERT(status->moved_to_abspath == NULL);
+
+ return SVN_NO_ERROR;
+}
+
/* ========================================================================== */
@@ -5488,6 +5675,8 @@ static struct svn_test_descriptor_t test
"update incoming delete to deleted file (#4739)"),
SVN_TEST_OPTS_PASS(test_merge_two_added_dirs_assertion_failure,
"merge two added dirs assertion failure (#4744)"),
+ SVN_TEST_OPTS_PASS(test_merge_incoming_delete_file_unrelated_move,
+ "do not suggest unrelated move targets (#4766)"),
SVN_TEST_NULL
};