You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/04/19 14:22:41 UTC
svn commit: r1739918 - /subversion/trunk/subversion/libsvn_client/conflicts.c
Author: stsp
Date: Tue Apr 19 12:22:41 2016
New Revision: 1739918
URL: http://svn.apache.org/viewvc?rev=1739918&view=rev
Log:
Reduce recently introduced code duplication in the conflict resolver.
* subversion/libsvn_client/conflicts.c
(merge_incoming_added_file_replace): New. Shared implementation for ...
(resolve_merge_incoming_added_file_replace,
configure_option_merge_incoming_added_file_replace): ... these functions.
Modified:
subversion/trunk/subversion/libsvn_client/conflicts.c
Modified: subversion/trunk/subversion/libsvn_client/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/conflicts.c?rev=1739918&r1=1739917&r2=1739918&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_client/conflicts.c Tue Apr 19 12:22:41 2016
@@ -3727,12 +3727,14 @@ resolve_merge_incoming_added_file_text_m
return SVN_NO_ERROR;
}
-/* Implements conflict_option_resolve_func_t. */
+/* Resolve a file/file "incoming add vs local obstruction" tree conflict by
+ * replacing the local file with the incoming file. If MERGE_FILES is set,
+ * also merge the files after replacing. */
static svn_error_t *
-resolve_merge_incoming_added_file_replace(
- svn_client_conflict_option_t *option,
- svn_client_conflict_t *conflict,
- apr_pool_t *scratch_pool)
+merge_incoming_added_file_replace(svn_client_conflict_option_t *option,
+ svn_client_conflict_t *conflict,
+ svn_boolean_t merge_files,
+ apr_pool_t *scratch_pool)
{
svn_ra_session_t *ra_session;
const char *url;
@@ -3753,9 +3755,6 @@ resolve_merge_incoming_added_file_replac
const char *working_file_tmp_abspath;
svn_stream_t *working_file_stream;
apr_hash_t *working_props;
- apr_file_t *empty_file;
- const char *empty_file_abspath;
- apr_array_header_t *propdiffs;
svn_error_t *err;
local_abspath = svn_client_conflict_get_local_abspath(conflict);
@@ -3782,10 +3781,6 @@ resolve_merge_incoming_added_file_replac
SVN_ERR(svn_wc_prop_list2(&working_props, ctx->wc_ctx, local_abspath,
scratch_pool, scratch_pool));
- /* Create a property diff against an empty base. */
- SVN_ERR(svn_prop_diffs(&propdiffs, apr_hash_make(scratch_pool),
- working_props, scratch_pool));
-
/* Fetch the incoming added file from the repository. */
SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
&incoming_new_repos_relpath, &incoming_new_pegrev,
@@ -3816,12 +3811,6 @@ resolve_merge_incoming_added_file_replac
/* Reset the stream in preparation for adding its content to WC. */
SVN_ERR(svn_stream_reset(incoming_new_stream));
- /* 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));
-
SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
local_abspath,
scratch_pool, scratch_pool));
@@ -3856,11 +3845,65 @@ resolve_merge_incoming_added_file_replac
ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
}
- /* Resolve to current working copy state. */
+ /* Resolve to current working copy state. svn_wc_merge5() requires this. */
err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath, scratch_pool);
if (err)
goto unlock_wc;
+ if (merge_files)
+ {
+ 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;
+
+ /* 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. */
+ err = svn_io_open_unique_file3(&empty_file, &empty_file_abspath, NULL,
+ svn_io_file_del_on_pool_cleanup,
+ scratch_pool, scratch_pool);
+ if (err)
+ goto unlock_wc;
+
+ /* Create a property diff against an empty base. */
+ err = svn_prop_diffs(&propdiffs, apr_hash_make(scratch_pool),
+ working_props, scratch_pool);
+ if (err)
+ goto unlock_wc;
+
+ /* Perform the file merge. */
+ err = svn_wc_merge5(&merge_content_outcome, &merge_props_outcome,
+ ctx->wc_ctx, empty_file_abspath,
+ working_file_tmp_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 */
+ ctx->cancel_func, ctx->cancel_baton,
+ scratch_pool);
+ if (err)
+ goto unlock_wc;
+
+ 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);
+ }
+ }
+
unlock_wc:
err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
lock_abspath,
@@ -3886,191 +3929,28 @@ unlock_wc:
/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
-resolve_merge_incoming_added_file_replace_and_merge(
+resolve_merge_incoming_added_file_replace(
svn_client_conflict_option_t *option,
svn_client_conflict_t *conflict,
apr_pool_t *scratch_pool)
{
- svn_ra_session_t *ra_session;
- const char *url;
- const char *corrected_url;
- const char *repos_root_url;
- const char *repos_uuid;
- const char *incoming_new_repos_relpath;
- svn_revnum_t incoming_new_pegrev;
- apr_file_t *incoming_new_file;
- svn_stream_t *incoming_new_stream;
- apr_hash_t *incoming_new_props;
- const char *local_abspath;
- const char *lock_abspath;
- svn_client_ctx_t *ctx = conflict->ctx;
- svn_wc_merge_outcome_t merge_content_outcome;
- svn_wc_notify_state_t merge_props_outcome;
- const char *wc_tmpdir;
- apr_file_t *working_file_tmp;
- svn_stream_t *working_file_tmp_stream;
- const char *working_file_tmp_abspath;
- svn_stream_t *working_file_stream;
- apr_hash_t *working_props;
- apr_file_t *empty_file;
- const char *empty_file_abspath;
- apr_array_header_t *propdiffs;
- svn_error_t *err;
-
- local_abspath = svn_client_conflict_get_local_abspath(conflict);
-
- /* Set up tempory storage for the working version of file. */
- SVN_ERR(svn_wc__get_tmpdir(&wc_tmpdir, ctx->wc_ctx, local_abspath,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_io_open_unique_file3(&working_file_tmp,
- &working_file_tmp_abspath, wc_tmpdir,
- svn_io_file_del_on_pool_cleanup,
- scratch_pool, scratch_pool));
- working_file_tmp_stream = svn_stream_from_aprfile2(working_file_tmp,
- FALSE, scratch_pool);
-
- /* Copy the working file to temporary storage. */
- SVN_ERR(svn_stream_open_readonly(&working_file_stream, local_abspath,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_stream_copy3(working_file_stream, working_file_tmp_stream,
- ctx->cancel_baton, ctx->cancel_baton,
- scratch_pool));
- SVN_ERR(svn_io_file_flush(working_file_tmp, 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 against an empty base. */
- SVN_ERR(svn_prop_diffs(&propdiffs, apr_hash_make(scratch_pool),
- working_props, scratch_pool));
-
- /* Fetch the incoming added file from the repository. */
- SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
- &incoming_new_repos_relpath, &incoming_new_pegrev,
- NULL, conflict, scratch_pool,
- scratch_pool));
- SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, &repos_uuid,
- conflict, scratch_pool,
- scratch_pool));
- url = svn_path_url_add_component2(repos_root_url, incoming_new_repos_relpath,
- scratch_pool);
- SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
- url, NULL, NULL, FALSE, FALSE,
- conflict->ctx, scratch_pool,
- scratch_pool));
- if (corrected_url)
- url = corrected_url;
- SVN_ERR(svn_io_open_unique_file3(&incoming_new_file, NULL, wc_tmpdir,
- svn_io_file_del_on_pool_cleanup,
- scratch_pool, scratch_pool));
- incoming_new_stream = svn_stream_from_aprfile2(incoming_new_file, TRUE,
- scratch_pool);
- SVN_ERR(svn_ra_get_file(ra_session, "", incoming_new_pegrev,
- incoming_new_stream, NULL, /* fetched_rev */
- &incoming_new_props, scratch_pool));
- /* Flush file to disk. */
- SVN_ERR(svn_io_file_flush(incoming_new_file, scratch_pool));
-
- /* Reset the stream in preparation for adding its content to WC. */
- SVN_ERR(svn_stream_reset(incoming_new_stream));
-
- /* 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));
-
- SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
- local_abspath,
- scratch_pool, scratch_pool));
-
- /* ### The following WC modifications should be atomic. */
-
- /* Replace the working file with the file from the repository. */
- err = svn_wc_delete4(ctx->wc_ctx, local_abspath, FALSE, FALSE,
- ctx->cancel_func, ctx->cancel_baton,
- ctx->notify_func2, ctx->notify_baton2,
- scratch_pool);
- if (err)
- goto unlock_wc;
- err = svn_wc_add_repos_file4(ctx->wc_ctx, local_abspath,
- incoming_new_stream,
- NULL, /* ### could we merge first, then set
- ### the merged content here? */
- incoming_new_props,
- NULL, /* ### merge props first, set here? */
- url, incoming_new_pegrev,
- ctx->cancel_func, ctx->cancel_baton,
- scratch_pool);
- if (err)
- goto unlock_wc;
-
- if (ctx->notify_func2)
- {
- svn_wc_notify_t *notify = svn_wc_create_notify(local_abspath,
- svn_wc_notify_add,
- scratch_pool);
- notify->kind = svn_node_file;
- ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
- }
-
- /* Resolve to current working copy state. svn_wc_merge5() requires this. */
- err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath, scratch_pool);
- if (err)
- goto unlock_wc;
-
- /* Perform the file merge. */
- err = svn_wc_merge5(&merge_content_outcome, &merge_props_outcome,
- ctx->wc_ctx, empty_file_abspath,
- working_file_tmp_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 */
- ctx->cancel_func, ctx->cancel_baton,
- 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);
- }
-
-
-unlock_wc:
- err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
- lock_abspath,
- scratch_pool));
- svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
- SVN_ERR(err);
-
- SVN_ERR(svn_stream_close(incoming_new_stream));
-
- if (ctx->notify_func2)
- {
- svn_wc_notify_t *notify = svn_wc_create_notify(local_abspath,
- svn_wc_notify_resolved,
- scratch_pool);
-
- ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
- }
-
- conflict->resolution_tree = svn_client_conflict_option_get_id(option);
+ return svn_error_trace(merge_incoming_added_file_replace(option,
+ conflict,
+ FALSE,
+ scratch_pool));
+}
- return SVN_NO_ERROR;
+/* Implements conflict_option_resolve_func_t. */
+static svn_error_t *
+resolve_merge_incoming_added_file_replace_and_merge(
+ svn_client_conflict_option_t *option,
+ svn_client_conflict_t *conflict,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_trace(merge_incoming_added_file_replace(option,
+ conflict,
+ TRUE,
+ scratch_pool));
}
/* Resolver options for a text conflict */