Author: stsp Date: Wed Oct 12 12:34:18 2016 New Revision: 1764447 URL: http://svn.apache.org/viewvc?rev=1764447&view=rev Log: Don't flag an unnecessary tree conflict while resolving 'add vs add'.
* subversion/libsvn_client/conflicts.c (merge_added_files): New helper function. (diff_file_added): If a file already exists then just merge with the incoming file and return. * subversion/tests/libsvn_client/conflicts-test.c (test_merge_incoming_added_dir_merge, test_merge_incoming_added_dir_merge2, test_merge_incoming_added_dir_merge3): Adjust test expectations accordingly. Modified: subversion/trunk/subversion/libsvn_client/conflicts.c subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c Modified: subversion/trunk/subversion/libsvn_client/conflicts.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/conflicts.c?rev=1764447&r1=1764446&r2=1764447&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_client/conflicts.c (original) +++ subversion/trunk/subversion/libsvn_client/conflicts.c Wed Oct 12 12:34:18 2016 @@ -5640,6 +5640,66 @@ diff_dir_added(const char *relpath, return SVN_NO_ERROR; } +static svn_error_t * +merge_added_files(const char *local_abspath, + const char *incoming_added_file_abspath, + apr_hash_t *incoming_added_file_props, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool) +{ + svn_wc_merge_outcome_t merge_content_outcome; + svn_wc_notify_state_t merge_props_outcome; + apr_file_t *empty_file; + const char *empty_file_abspath; + apr_array_header_t *propdiffs; + apr_hash_t *working_props; + + /* Create an empty file as fake "merge-base" for the two added files. + * The files are not ancestrally related so this is the best we can do. */ + SVN_ERR(svn_io_open_unique_file3(&empty_file, &empty_file_abspath, NULL, + svn_io_file_del_on_pool_cleanup, + scratch_pool, scratch_pool)); + + /* Get a copy of the working file's properties. */ + SVN_ERR(svn_wc_prop_list2(&working_props, ctx->wc_ctx, local_abspath, + scratch_pool, scratch_pool)); + + /* Create a property diff for the files. */ + SVN_ERR(svn_prop_diffs(&propdiffs, incoming_added_file_props, + working_props, scratch_pool)); + + /* Perform the file merge. */ + SVN_ERR(svn_wc_merge5(&merge_content_outcome, &merge_props_outcome, + ctx->wc_ctx, empty_file_abspath, + incoming_added_file_abspath, local_abspath, + NULL, NULL, NULL, /* labels */ + NULL, NULL, /* conflict versions */ + FALSE, /* dry run */ + NULL, NULL, /* diff3_cmd, merge_options */ + NULL, propdiffs, + NULL, NULL, /* conflict func/baton */ + NULL, NULL, /* don't allow user to cancel here */ + scratch_pool)); + + if (ctx->notify_func2) + { + svn_wc_notify_t *notify = svn_wc_create_notify( + local_abspath, + svn_wc_notify_update_update, + scratch_pool); + + if (merge_content_outcome == svn_wc_merge_conflict) + notify->content_state = svn_wc_notify_state_conflicted; + else + notify->content_state = svn_wc_notify_state_merged; + notify->prop_state = merge_props_outcome; + notify->kind = svn_node_file; + ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool); + } + + return SVN_NO_ERROR; +} + /* An svn_diff_tree_processor_t callback. */ static svn_error_t * diff_file_added(const char *relpath, @@ -5666,6 +5726,18 @@ diff_file_added(const char *relpath, FALSE, FALSE, scratch_pool)); SVN_ERR(svn_io_check_path(local_abspath, &on_disk_kind, scratch_pool)); + if (db_kind == svn_node_file && db_kind == svn_node_file) + { + propsarray = svn_prop_hash_to_array(right_props, scratch_pool); + SVN_ERR(svn_categorize_props(propsarray, NULL, NULL, ®ular_props, + scratch_pool)); + SVN_ERR(merge_added_files(local_abspath, right_file, + svn_prop_array_to_hash(regular_props, + scratch_pool), + b->ctx, scratch_pool)); + return SVN_NO_ERROR; + } + if (db_kind != svn_node_none && db_kind != svn_node_unknown) { SVN_ERR(raise_tree_conflict( Modified: subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c?rev=1764447&r1=1764446&r2=1764447&view=diff ============================================================================== --- subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c (original) +++ subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c Wed Oct 12 12:34:18 2016 @@ -792,31 +792,10 @@ test_merge_incoming_added_dir_merge(cons props_conflicted->nelts == 0 && !tree_conflicted); - - /* There should now be an 'add vs add' conflict on the new file. */ new_file_path = svn_relpath_join(branch_path, svn_relpath_join(new_dir_name, new_file_name, b->pool), b->pool); - SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_file_path), - ctx, b->pool, b->pool)); - 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); - - /* Resolve the tree conflict. */ - SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool)); - SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_file_path), - ctx, b->pool, b->pool)); - SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, b->pool)); - SVN_ERR(svn_client_conflict_tree_resolve_by_id( - conflict, - svn_client_conflict_option_incoming_added_file_text_merge, ctx, - b->pool)); /* Ensure that the file has the expected status. */ SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, new_file_path), @@ -923,30 +902,10 @@ test_merge_incoming_added_dir_merge2(con props_conflicted->nelts == 0 && !tree_conflicted); - /* There should now be an 'add vs add' conflict on the new file. */ new_file_path = svn_relpath_join(branch_path, svn_relpath_join(new_dir_name, new_file_name, b->pool), b->pool); - SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_file_path), - ctx, b->pool, b->pool)); - 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); - - /* Resolve the tree conflict. */ - SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool)); - SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_file_path), - ctx, b->pool, b->pool)); - SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, b->pool)); - SVN_ERR(svn_client_conflict_tree_resolve_by_id( - conflict, - svn_client_conflict_option_incoming_added_file_text_merge, ctx, - b->pool)); /* Ensure that the file has the expected status. */ SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, new_file_path), @@ -1063,25 +1022,6 @@ test_merge_incoming_added_dir_merge3(con svn_relpath_join(new_dir_name, new_file_name, b->pool), b->pool); - SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_file_path), - ctx, b->pool, b->pool)); - 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); - - /* Resolve the tree conflict. */ - SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool)); - SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_file_path), - ctx, b->pool, b->pool)); - SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, b->pool)); - SVN_ERR(svn_client_conflict_tree_resolve_by_id( - conflict, - svn_client_conflict_option_incoming_added_file_text_merge, ctx, - b->pool)); /* Ensure that the file has the expected status. */ SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, new_file_path),