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 2015/07/31 11:44:10 UTC
svn commit: r1693557 - in /subversion/trunk/subversion: include/svn_client.h
libsvn_client/resolved.c
Author: stsp
Date: Fri Jul 31 09:44:10 2015
New Revision: 1693557
URL: http://svn.apache.org/r1693557
Log:
Bring back the svn_client_conflict_walk() API, this time implemented as a
thin wrapper on top of libsvn_wc's legacy conflict resolver, rather than
on top of the status walker. This avoids having to re-implement detection
of delayed or nested conflicts caused by tree conflict resolution.
The intention is to start using more svn_client_conflict APIs in the command
line client, which requires a conflict walk to implement its interactive mode.
Eventually, libsvn_wc will grow new conflict resolution abilities and we will
stop depending on legacy conflict resolution APIs within the new system.
* subversion/include/svn_client.h
(svn_client_conflict_walk_func_t, svn_client_conflict_walk): Declare.
* subversion/libsvn_client/resolved.c
(svn_client_conflict_t): Add a 'resolution' field which stores the resolution
option chosen by the user.
(conflict_option_id_to_wc_conflict_choice): Move this helper function further
up in the file to make it usable from more functions.
(conflict_get_internal): Initialise conflict->resolution.
(conflict_resolver_baton_t, conflict_resolver_func): New helper callback.
(svn_client_conflict_walk): Implement on top of svn_wc__resolve_conflicts().
(resolve_postpone, resolve_text_conflict, resolve_prop_conflict,
resolve_tree_conflict): Store chosen resolution in conflict->resolution.
Modified:
subversion/trunk/subversion/include/svn_client.h
subversion/trunk/subversion/libsvn_client/resolved.c
Modified: subversion/trunk/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1693557&r1=1693556&r2=1693557&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Fri Jul 31 09:44:10 2015
@@ -4411,6 +4411,37 @@ svn_client_conflict_from_wc_description2
apr_pool_t *scratch_pool);
/**
+ * Callback for svn_client_conflict_walk_conflicts();
+ *
+ * @since New in 1.10.
+ */
+typedef svn_error_t *(svn_client_conflict_walk_func_t)(
+ void *baton,
+ svn_client_conflict_t *conflict,
+ apr_pool_t *scratch_pool);
+
+/**
+ * Walk all conflicts within the specified @a depth of @a local_abspath.
+ * Pass each conflict found during the walk to the @conflict_walk_func
+ * callback, along with @a conflict_walk_func_baton.
+ * Use cancellation and notification support provided by client context @a ctx.
+ *
+ * This callback may choose to resolve the conflict. If the act of resolving
+ * a conflict creates new conflicts within the walked working copy (as might
+ * be the case for some tree conflicts), the callback will be invoked for each
+ * such new conflict as well.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_walk(const char *local_abspath,
+ svn_depth_t depth,
+ svn_client_conflict_walk_func_t conflict_walk_func,
+ void *conflict_walk_func_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
+
+/**
* Indicate the types of conflicts present on the working copy node
* described by @a conflict. Any output argument may be @c NULL if
* the caller is not interested in the status of a particular type.
Modified: subversion/trunk/subversion/libsvn_client/resolved.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/resolved.c?rev=1693557&r1=1693556&r2=1693557&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/resolved.c (original)
+++ subversion/trunk/subversion/libsvn_client/resolved.c Fri Jul 31 09:44:10 2015
@@ -157,12 +157,61 @@ struct svn_client_conflict_t
svn_client_ctx_t *ctx;
apr_hash_t *prop_conflicts;
+ /* Indicates which option was chosen to resolve this conflict. */
+ svn_client_conflict_option_id_t resolution;
+
/* For backwards compat. */
const svn_wc_conflict_description2_t *legacy_text_conflict;
const svn_wc_conflict_description2_t *legacy_prop_conflict;
const svn_wc_conflict_description2_t *legacy_tree_conflict;
};
+/*
+ * Return a legacy conflict choice corresponding to OPTION_ID.
+ * Return svn_wc_conflict_choose_undefined if no corresponding
+ * legacy conflict choice exists.
+ */
+static svn_wc_conflict_choice_t
+conflict_option_id_to_wc_conflict_choice(
+ svn_client_conflict_option_id_t option_id)
+{
+
+ switch (option_id)
+ {
+ case svn_client_conflict_option_undefined:
+ return svn_wc_conflict_choose_undefined;
+
+ case svn_client_conflict_option_postpone:
+ return svn_wc_conflict_choose_postpone;
+
+ case svn_client_conflict_option_base_text:
+ return svn_wc_conflict_choose_base;
+
+ case svn_client_conflict_option_incoming_new_text:
+ return svn_wc_conflict_choose_theirs_full;
+
+ case svn_client_conflict_option_working_text:
+ return svn_wc_conflict_choose_mine_full;
+
+ case svn_client_conflict_option_incoming_new_text_for_conflicted_hunks_only:
+ return svn_wc_conflict_choose_theirs_conflict;
+
+ case svn_client_conflict_option_working_text_for_conflicted_hunks_only:
+ return svn_wc_conflict_choose_mine_conflict;
+
+ case svn_client_conflict_option_merged_text:
+ return svn_wc_conflict_choose_merged;
+
+ case svn_client_conflict_option_unspecified:
+ return svn_wc_conflict_choose_unspecified;
+
+ default:
+ break;
+ }
+
+ return svn_wc_conflict_choose_undefined;
+}
+
static void
add_legacy_desc_to_conflict(const svn_wc_conflict_description2_t *desc,
svn_client_conflict_t *conflict,
@@ -206,12 +255,14 @@ conflict_get_internal(svn_client_conflic
{
/* Add a single legacy conflict descriptor. */
(*conflict)->local_abspath = desc->local_abspath;
+ (*conflict)->resolution = svn_client_conflict_option_undefined;
add_legacy_desc_to_conflict(desc, *conflict, result_pool);
return SVN_NO_ERROR;
}
(*conflict)->local_abspath = apr_pstrdup(result_pool, local_abspath);
+ (*conflict)->resolution = svn_client_conflict_option_undefined;
(*conflict)->ctx = ctx;
/* Add all legacy conflict descriptors we can find. Eventually, this code
@@ -257,6 +308,87 @@ svn_client_conflict_from_wc_description2
result_pool, scratch_pool));
}
+/* Baton type for conflict_resolver_func(). */
+struct conflict_resolver_baton_t {
+
+ svn_client_conflict_walk_func_t *conflict_walk_func;
+ void *conflict_walk_func_baton;
+ svn_client_ctx_t *ctx;
+
+} conflict_walk_baton_t;
+
+/* Implements svn_wc_conflict_resolver_func2_t for now because
+ * libsvn_wc does not support our new conflict type yet. */
+static svn_error_t *
+conflict_resolver_func(svn_wc_conflict_result_t **result,
+ const svn_wc_conflict_description2_t *description,
+ void *baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ struct conflict_resolver_baton_t *b = baton;
+ svn_client_conflict_t *conflict;
+ const char *local_abspath;
+ svn_wc_conflict_choice_t conflict_choice;
+
+ local_abspath = description->local_abspath;
+ SVN_ERR(svn_client_conflict_get(&conflict, local_abspath, b->ctx,
+ scratch_pool, scratch_pool));
+
+ SVN_ERR(b->conflict_walk_func(b->conflict_walk_func_baton,
+ conflict, scratch_pool));
+
+ conflict_choice = conflict_option_id_to_wc_conflict_choice(
+ conflict->resolution);
+ *result = svn_wc_create_conflict_result(conflict_choice, NULL,
+ result_pool);
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_conflict_walk(const char *local_abspath,
+ svn_depth_t depth,
+ svn_client_conflict_walk_func_t conflict_walk_func,
+ void *conflict_walk_func_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ struct conflict_resolver_baton_t b;
+ const char *lock_abspath;
+ svn_error_t *err;
+
+ b.conflict_walk_func = conflict_walk_func;
+ b.conflict_walk_func_baton = conflict_walk_func_baton;
+ b.ctx = ctx;
+
+ SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
+ local_abspath,
+ scratch_pool, scratch_pool));
+ /* ### TODO: svn_wc__resolve_conflicts() should be changed to support
+ * ### iteration without relying on svn_wc_conflict_resolver_func2_t */
+ err = svn_wc__resolve_conflicts(ctx->wc_ctx, local_abspath,
+ depth,
+ TRUE /* resolve_text */,
+ "" /* resolve_prop (ALL props) */,
+ TRUE /* resolve_tree */,
+ svn_wc_conflict_choose_unspecified,
+ conflict_resolver_func, &b,
+ ctx->cancel_func, ctx->cancel_baton,
+ ctx->notify_func2, ctx->notify_baton2,
+ scratch_pool);
+
+ 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);
+
+
+
+ return SVN_NO_ERROR;
+}
+
+/* Resolves conflict to OPTION and sets CONFLICT->RESOLUTION accordingly. */
typedef svn_error_t *(*conflict_option_resolve_func_t)(
svn_client_conflict_option_t *option,
svn_client_conflict_t *conflict,
@@ -277,55 +409,10 @@ resolve_postpone(svn_client_conflict_opt
apr_pool_t *scratch_pool)
{
/* Nothing to do. */
+ conflict->resolution = svn_client_conflict_option_postpone;
return SVN_NO_ERROR;
}
-/*
- * Return a legacy conflict choice corresponding to OPTION_ID.
- * Return svn_wc_conflict_choose_undefined if no corresponding
- * legacy conflict choice exists.
- */
-static svn_wc_conflict_choice_t
-conflict_option_id_to_wc_conflict_choice(
- svn_client_conflict_option_id_t option_id)
-{
-
- switch (option_id)
- {
- case svn_client_conflict_option_undefined:
- return svn_wc_conflict_choose_undefined;
-
- case svn_client_conflict_option_postpone:
- return svn_wc_conflict_choose_postpone;
-
- case svn_client_conflict_option_base_text:
- return svn_wc_conflict_choose_base;
-
- case svn_client_conflict_option_incoming_new_text:
- return svn_wc_conflict_choose_theirs_full;
-
- case svn_client_conflict_option_working_text:
- return svn_wc_conflict_choose_mine_full;
-
- case svn_client_conflict_option_incoming_new_text_for_conflicted_hunks_only:
- return svn_wc_conflict_choose_theirs_conflict;
-
- case svn_client_conflict_option_working_text_for_conflicted_hunks_only:
- return svn_wc_conflict_choose_mine_conflict;
-
- case svn_client_conflict_option_merged_text:
- return svn_wc_conflict_choose_merged;
-
- case svn_client_conflict_option_unspecified:
- return svn_wc_conflict_choose_unspecified;
-
- default:
- break;
- }
-
- return svn_wc_conflict_choose_undefined;
-}
-
/*
* Resolve the conflict at LOCAL_ABSPATH. Currently only supports
* an OPTION_ID which can be mapped to svn_wc_conflict_choice_t and
@@ -378,6 +465,7 @@ resolve_text_conflict(svn_client_conflic
local_abspath = svn_client_conflict_get_local_abspath(conflict);
SVN_ERR(resolve_conflict(id, local_abspath, TRUE, NULL, FALSE,
conflict->ctx, scratch_pool));
+ conflict->resolution = id;
return SVN_NO_ERROR;
}
@@ -394,6 +482,7 @@ resolve_prop_conflict(svn_client_conflic
local_abspath = svn_client_conflict_get_local_abspath(conflict);
SVN_ERR(resolve_conflict(id, local_abspath, FALSE, "", FALSE,
conflict->ctx, scratch_pool));
+ conflict->resolution = id;
return SVN_NO_ERROR;
}
@@ -410,6 +499,7 @@ resolve_tree_conflict(svn_client_conflic
local_abspath = svn_client_conflict_get_local_abspath(conflict);
SVN_ERR(resolve_conflict(id, local_abspath, FALSE, NULL, TRUE,
conflict->ctx, scratch_pool));
+ conflict->resolution = id;
return SVN_NO_ERROR;
}