Author: stsp
Date: Sat Jun 27 10:35:42 2015
New Revision: 1687906
URL: http://svn.apache.org/r1687906
Log:
Add a conflict walker to the new svn_client_conflict API.
Contrary to our current libsvn_wc conflict walker, this walker guarantees
that new conflicts created during conflict resolution (which can happen
when resolving tree conflicts) are visited as well. The libsvn_wc walker
will visit such new conflicts only if they happen to be created in parts
of the working copy which the walker has not yet visited.
* subversion/include/svn_client.h
(svn_client_conflict_walk_func_t, svn_client_conflict_walk): Declare.
* subversion/libsvn_client/resolved.c
(svn_client_conflict_walk): Implement.
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=1687906&r1=1687905&r2=1687906&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Sat Jun 27 10:35:42 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=1687906&r1=1687905&r2=1687906&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/resolved.c (original)
+++ subversion/trunk/subversion/libsvn_client/resolved.c Sat Jun 27 10:35:42
2015
@@ -257,6 +257,77 @@ svn_client_conflict_from_wc_description2
result_pool, scratch_pool));
}
+/* Baton type for conflict_walk_status_func(). */
+typedef struct conflict_walk_status_baton_t {
+
+ svn_client_conflict_walk_func_t *conflict_walk_func;
+ void *conflict_walk_func_baton;
+
+ svn_client_ctx_t *ctx;
+ int conflicts_found;
+
+} conflict_walk_status_baton_t;
+
+/* Implements svn_wc_status_func4_t. */
+static svn_error_t *
+conflict_walk_status_func(void *baton,
+ const char *local_abspath,
+ const svn_wc_status3_t *status,
+ apr_pool_t *scratch_pool)
+{
+ conflict_walk_status_baton_t *b = baton;
+ svn_client_conflict_t *conflict;
+
+ if (!status->conflicted)
+ return SVN_NO_ERROR;
+
+ b->conflicts_found++;
+
+ 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));
+
+ 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)
+{
+ conflict_walk_status_baton_t b;
+
+ b.conflict_walk_func = conflict_walk_func;
+ b.conflict_walk_func_baton = conflict_walk_func_baton;
+ b.ctx = ctx;
+ b.conflicts_found = 0;
+
+ /* ### Re-run the status walk until a walk finds no conflicts at all.
+ * ### This is a crude implementation but provides the guarantees we offer
+ * ### to the caller. To optimize we should check for notifications of new
+ * ### conflicts created during the first status walk and then keep invoking
+ * ### the callback directly on any new conflicts.
+ */
+ do
+ {
+ SVN_ERR(svn_wc_walk_status(ctx->wc_ctx, local_abspath, depth,
+ FALSE, /* get_all */
+ FALSE, /* no_ignore, */
+ TRUE, /* ignore_externals */
+ NULL, /* ignore_patterns */
+ conflict_walk_status_func, &b,
+ ctx->cancel_func, ctx->cancel_baton,
+ scratch_pool));
+ }
+ while (b.conflicts_found > 0);
+
+ return SVN_NO_ERROR;
+}
+
typedef svn_error_t *(*conflict_option_resolve_func_t)(
svn_client_conflict_option_t *option,
svn_client_conflict_t *conflict,