You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2012/05/13 01:11:19 UTC
svn commit: r1337725 - /subversion/trunk/subversion/libsvn_wc/conflicts.c
Author: rhuijben
Date: Sat May 12 23:11:18 2012
New Revision: 1337725
URL: http://svn.apache.org/viewvc?rev=1337725&view=rev
Log:
Use a status walker with text-modification checks disabled to find out
which conflicted nodes to resolve in the conflict resolver.
As walking the existing nodes, with the addition of actual-only nodes is not
easy, using the most optimized implementation we have reduces the number of
db transactions considerable over the current code.
* subversion/libsvn_wc/conflicts.c
(conflict_status_walker_baton): New baton.
(resolve_one_conflict): Rename to ...
(conflict_status_walker): ... this and implement svn_wc_status4_t using
conflict_status_walker_baton.
(svn_wc__resolve_conflicts): Directly call into conflict_status_walker using
a standard status walker.
Modified:
subversion/trunk/subversion/libsvn_wc/conflicts.c
Modified: subversion/trunk/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/conflicts.c?rev=1337725&r1=1337724&r2=1337725&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_wc/conflicts.c Sat May 12 23:11:18 2012
@@ -330,27 +330,41 @@ svn_wc__resolve_text_conflict(svn_wc__db
}
-/* */
+/* Baton for conflict_status_walker */
+struct conflict_status_walker_baton
+{
+ svn_wc__db_t *db;
+ svn_boolean_t resolve_text;
+ const char *resolve_prop;
+ svn_boolean_t resolve_tree;
+ svn_wc_conflict_choice_t conflict_choice;
+ svn_wc_conflict_resolver_func2_t conflict_func;
+ void *conflict_baton;
+ svn_cancel_func_t cancel_func;
+ void *cancel_baton;
+ svn_wc_notify_func2_t notify_func;
+ void *notify_baton;
+};
+
+/* Implements svn_wc_status4_t to walk all conflicts to resolve */
static svn_error_t *
-resolve_one_conflict(svn_wc__db_t *db,
- const char *local_abspath,
- svn_boolean_t resolve_text,
- const char *resolve_prop,
- svn_boolean_t resolve_tree,
- svn_wc_conflict_choice_t conflict_choice,
- svn_wc_conflict_resolver_func2_t conflict_func,
- void *conflict_baton,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
- svn_wc_notify_func2_t notify_func,
- void *notify_baton,
- apr_pool_t *scratch_pool)
+conflict_status_walker(void *baton,
+ const char *local_abspath,
+ const svn_wc_status3_t *status,
+ apr_pool_t *scratch_pool)
{
+ struct conflict_status_walker_baton *cswb = baton;
+ svn_wc__db_t *db = cswb->db;
+
const apr_array_header_t *conflicts;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
int i;
svn_boolean_t resolved = FALSE;
+ if (!status->conflicted)
+ return SVN_NO_ERROR;
+
+
SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
scratch_pool, iterpool));
@@ -358,7 +372,7 @@ resolve_one_conflict(svn_wc__db_t *db,
{
const svn_wc_conflict_description2_t *cd;
svn_boolean_t did_resolve;
- svn_wc_conflict_choice_t my_choice = conflict_choice;
+ svn_wc_conflict_choice_t my_choice = cswb->conflict_choice;
cd = APR_ARRAY_IDX(conflicts, i, const svn_wc_conflict_description2_t *);
@@ -368,13 +382,13 @@ resolve_one_conflict(svn_wc__db_t *db,
{
svn_wc_conflict_result_t *result;
- if (conflict_func == NULL)
+ if (!cswb->conflict_func)
return svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
_("No conflict-callback and no "
"pre-defined conflict-choice provided"));
-
- SVN_ERR(conflict_func(&result, cd, conflict_baton, iterpool,
- iterpool));
+
+ SVN_ERR(cswb->conflict_func(&result, cd, cswb->conflict_baton,
+ iterpool, iterpool));
my_choice = result->choice;
}
@@ -386,7 +400,7 @@ resolve_one_conflict(svn_wc__db_t *db,
switch (cd->kind)
{
case svn_wc_conflict_kind_tree:
- if (!resolve_tree)
+ if (!cswb->resolve_tree)
break;
/* For now, we only clear tree conflict information and resolve
@@ -411,14 +425,15 @@ resolve_one_conflict(svn_wc__db_t *db,
FALSE /* resolve_props */,
TRUE /* resolve_tree */,
my_choice,
- cancel_func, cancel_baton,
+ cswb->cancel_func,
+ cswb->cancel_baton,
iterpool));
resolved = TRUE;
break;
case svn_wc_conflict_kind_text:
- if (!resolve_text)
+ if (!cswb->resolve_text)
break;
SVN_ERR(resolve_conflict_on_node(&did_resolve,
@@ -428,7 +443,8 @@ resolve_one_conflict(svn_wc__db_t *db,
FALSE /* resolve_props */,
FALSE /* resolve_tree */,
my_choice,
- cancel_func, cancel_baton,
+ cswb->cancel_func,
+ cswb->cancel_baton,
iterpool));
if (did_resolve)
@@ -436,13 +452,13 @@ resolve_one_conflict(svn_wc__db_t *db,
break;
case svn_wc_conflict_kind_property:
- if (!resolve_prop)
+ if (!cswb->resolve_prop)
break;
/* ### this is bogus. resolve_conflict_on_node() does not handle
### individual property resolution. */
- if (*resolve_prop != '\0' &&
- strcmp(resolve_prop, cd->property_name) != 0)
+ if (*cswb->resolve_prop != '\0' &&
+ strcmp(cswb->resolve_prop, cd->property_name) != 0)
{
break; /* Skip this property conflict */
}
@@ -456,7 +472,8 @@ resolve_one_conflict(svn_wc__db_t *db,
TRUE /* resolve_props */,
FALSE /* resolve_tree */,
my_choice,
- cancel_func, cancel_baton,
+ cswb->cancel_func,
+ cswb->cancel_baton,
iterpool));
if (did_resolve)
@@ -470,162 +487,18 @@ resolve_one_conflict(svn_wc__db_t *db,
}
/* Notify */
- if (notify_func && resolved)
- notify_func(notify_baton,
- svn_wc_create_notify(local_abspath, svn_wc_notify_resolved,
- iterpool),
- iterpool);
+ if (cswb->notify_func && resolved)
+ cswb->notify_func(cswb->notify_baton,
+ svn_wc_create_notify(local_abspath,
+ svn_wc_notify_resolved,
+ iterpool),
+ iterpool);
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
-/* */
-static svn_error_t *
-recursive_resolve_conflict(svn_wc__db_t *db,
- const char *local_abspath,
- svn_boolean_t this_is_conflicted,
- svn_depth_t depth,
- svn_boolean_t resolve_text,
- const char *resolve_prop,
- svn_boolean_t resolve_tree,
- svn_wc_conflict_choice_t conflict_choice,
- svn_wc_conflict_resolver_func2_t conflict_func,
- void *conflict_baton,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
- svn_wc_notify_func2_t notify_func,
- void *notify_baton,
- apr_pool_t *scratch_pool)
-{
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- const apr_array_header_t *children;
- apr_hash_t *visited = apr_hash_make(scratch_pool);
- svn_depth_t child_depth;
- int i;
-
- if (cancel_func)
- SVN_ERR(cancel_func(cancel_baton));
-
- if (this_is_conflicted)
- {
- SVN_ERR(resolve_one_conflict(db,
- local_abspath,
- resolve_text,
- resolve_prop,
- resolve_tree,
- conflict_choice,
- conflict_func, conflict_baton,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- iterpool));
- }
-
- if (depth < svn_depth_files)
- return SVN_NO_ERROR;
-
- child_depth = (depth < svn_depth_infinity) ? svn_depth_empty : depth;
-
- SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath,
- scratch_pool, iterpool));
-
- for (i = 0; i < children->nelts; i++)
- {
- const char *name = APR_ARRAY_IDX(children, i, const char *);
- const char *child_abspath;
- svn_wc__db_status_t status;
- svn_kind_t kind;
- svn_boolean_t conflicted;
-
- svn_pool_clear(iterpool);
-
- if (cancel_func)
- SVN_ERR(cancel_func(cancel_baton));
-
- child_abspath = svn_dirent_join(local_abspath, name, iterpool);
-
- SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- &conflicted, NULL, NULL, NULL, NULL, NULL,
- NULL,
- db, child_abspath, iterpool, iterpool));
-
- if (status == svn_wc__db_status_not_present
- || status == svn_wc__db_status_excluded
- || status == svn_wc__db_status_server_excluded)
- continue;
-
- apr_hash_set(visited, name, APR_HASH_KEY_STRING, name);
- if (kind == svn_kind_dir && depth < svn_depth_immediates)
- continue;
-
- if (kind == svn_kind_dir)
- SVN_ERR(recursive_resolve_conflict(db,
- child_abspath,
- conflicted,
- child_depth,
- resolve_text,
- resolve_prop,
- resolve_tree,
- conflict_choice,
- conflict_func, conflict_baton,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- iterpool));
- else if (conflicted)
- SVN_ERR(resolve_one_conflict(db,
- child_abspath,
- resolve_text,
- resolve_prop,
- resolve_tree,
- conflict_choice,
- conflict_func, conflict_baton,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- iterpool));
- }
-
- SVN_ERR(svn_wc__db_read_conflict_victims(&children, db, local_abspath,
- scratch_pool, iterpool));
-
- for (i = 0; i < children->nelts; i++)
- {
- const char *name = APR_ARRAY_IDX(children, i, const char *);
- const char *child_abspath;
-
- svn_pool_clear(iterpool);
-
- if (apr_hash_get(visited, name, APR_HASH_KEY_STRING) != NULL)
- continue; /* Already visited */
-
- if (cancel_func)
- SVN_ERR(cancel_func(cancel_baton));
-
- child_abspath = svn_dirent_join(local_abspath, name, iterpool);
-
- /* We only have to resolve one level of tree conflicts. All other
- conflicts are resolved in the other loop */
- SVN_ERR(resolve_one_conflict(db,
- child_abspath,
- FALSE /*resolve_text*/,
- FALSE /*resolve_prop*/,
- resolve_tree,
- conflict_choice,
- conflict_func, conflict_baton,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- iterpool));
- }
-
-
- svn_pool_destroy(iterpool);
-
- return SVN_NO_ERROR;
-}
-
-
svn_error_t *
svn_wc__resolve_conflicts(svn_wc_context_t *wc_ctx,
const char *local_abspath,
@@ -644,6 +517,8 @@ svn_wc__resolve_conflicts(svn_wc_context
{
svn_kind_t kind;
svn_boolean_t conflicted;
+ struct conflict_status_walker_baton cswb;
+
/* ### the underlying code does NOT support resolving individual
### properties. bail out if the caller tries it. */
if (resolve_prop != NULL && *resolve_prop != '\0')
@@ -651,6 +526,8 @@ svn_wc__resolve_conflicts(svn_wc_context
U_("Resolving a single property is not (yet) "
"supported."));
+ /* ### Just a versioned check? */
+ /* Conflicted is set to allow invoking on actual only nodes */
SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, &conflicted,
@@ -665,21 +542,28 @@ svn_wc__resolve_conflicts(svn_wc_context
else if (depth == svn_depth_unknown)
depth = svn_depth_infinity;
- return svn_error_trace(recursive_resolve_conflict(
- wc_ctx->db,
- local_abspath,
- conflicted,
- depth,
- resolve_text,
- resolve_prop,
- resolve_tree,
- conflict_choice,
- conflict_func, conflict_baton,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- scratch_pool));
-}
+ cswb.db = wc_ctx->db;
+ cswb.resolve_text = resolve_text;
+ cswb.resolve_prop = resolve_prop;
+ cswb.resolve_tree = resolve_tree;
+ cswb.conflict_choice = conflict_choice;
+
+ cswb.conflict_func = conflict_func;
+ cswb.conflict_baton = conflict_baton;
+
+ cswb.cancel_func = cancel_func;
+ cswb.cancel_baton = cancel_baton;
+
+ cswb.notify_func = notify_func;
+ cswb.notify_baton = notify_baton;
+
+ SVN_ERR(svn_wc_walk_status(wc_ctx, local_abspath, depth, FALSE, FALSE, TRUE,
+ NULL, conflict_status_walker, &cswb,
+ cancel_func, cancel_baton,
+ scratch_pool));
+ return SVN_NO_ERROR;
+}
svn_error_t *
svn_wc_resolved_conflict5(svn_wc_context_t *wc_ctx,
Re: svn commit: r1337725 - /subversion/trunk/subversion/libsvn_wc/conflicts.c
Posted by Greg Stein <gs...@gmail.com>.
On Sat, May 12, 2012 at 7:11 PM, <rh...@apache.org> wrote:
>...
> +++ subversion/trunk/subversion/libsvn_wc/conflicts.c Sat May 12 23:11:18 2012
>...
> +conflict_status_walker(void *baton,
> + const char *local_abspath,
> + const svn_wc_status3_t *status,
> + apr_pool_t *scratch_pool)
> {
> + struct conflict_status_walker_baton *cswb = baton;
> + svn_wc__db_t *db = cswb->db;
> +
> const apr_array_header_t *conflicts;
> apr_pool_t *iterpool = svn_pool_create(scratch_pool);
> int i;
> svn_boolean_t resolved = FALSE;
>
> + if (!status->conflicted)
> + return SVN_NO_ERROR;
iterpool is created before the fast-path exit. I'd suggest delaying
it. (possibly along with those other assignments)
>...
> + SVN_ERR(svn_wc_walk_status(wc_ctx, local_abspath, depth, FALSE, FALSE, TRUE,
> + NULL, conflict_status_walker, &cswb,
> + cancel_func, cancel_baton,
> + scratch_pool));
Some comments on those arguments? I can't tell what they're doing, and
as you noted in the log message, it is important that this is not
performing text mod checks.
>...
Cheers,
-g