subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject svn commit: r1693592 - in /subversion/trunk/subversion: include/svn_client.h libsvn_client/resolved.c
Date Fri, 31 Jul 2015 13:23:30 GMT
Author: stsp
Date: Fri Jul 31 13:23:29 2015
New Revision: 1693592

URL: http://svn.apache.org/r1693592
Log:
For a given svn_client_conflict_t, keep track of resolution per conflict type
rather than globally.

Replace svn_client_conflict_resolve() and svn_client_conflict_get_resolution()
with functions which operate on a specific type of conflict (text/prop/tree).

This is necessary since an svn_client_conflict_t represents all conflicts
on a working copy node. The former API interface made no sense.

* subversion/include/svn_client.h
  (svn_client_conflict_resolve, svn_client_conflict_get_resolution): Remove.
  (svn_client_conflict_tree_resolve,
   svn_client_conflict_tree_get_resolution,
   svn_client_conflict_prop_resolve
   svn_client_conflict_prop_get_resolution,
   svn_client_conflict_text_resolve
   svn_client_conflict_text_get_resolution) Declare.

* subversion/libsvn_client/resolved.c
  (svn_client_conflict_t): Remove 'resolution' field. Add new fields which
   keep track of resolution of each conflict separately (one text conflict,
   one tree conflict, and one property conflict per property).
  (conflict_get_internal): Initialise new fields.
  (conflict_resolver_func): Make use of the new per-conflict type fields.
  (svn_client_conflict_option_t): Add 'propname' field which indicates
   the specific property to resolve.
  (resolve_postpone): Remove. Treating 'postpone' as a special case no-op
   now gets in the way.
  (resolve_text_conflict, resolve_prop_conflict,
   resolve_tree_conflict): Update the new fields in 'conflict' as appropriate.
  (text_conflict_options, binary_conflict_options, prop_conflict_options,
   tree_conflict_options): Init new svn_client_conflict_option_t field to NULL
    and stop using resolve_postpone.
  (svn_client_conflict_resolve, svn_client_conflict_get_resolution): Remove.
  (svn_client_conflict_tree_resolve,
   svn_client_conflict_tree_get_resolution,
   svn_client_conflict_prop_resolve
   svn_client_conflict_prop_get_resolution,
   svn_client_conflict_text_resolve
   svn_client_conflict_text_get_resolution) 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=1693592&r1=1693591&r2=1693592&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Fri Jul 31 13:23:29 2015
@@ -4535,16 +4535,6 @@ svn_client_conflict_option_describe(cons
                                     apr_pool_t *scratch_pool);
 
 /**
- * Resolve @a conflict using resolution option @a option.
- *
- * @since New in 1.10.
- */
-svn_error_t *
-svn_client_conflict_resolve(svn_client_conflict_t *conflict,
-                            svn_client_conflict_option_t *option,
-                            apr_pool_t *scratch_pool);
-
-/**
  * Return the kind of conflict (text conflict, property conflict,
  * or tree conflict) represented by @a conflict.
  *
@@ -4661,16 +4651,6 @@ svn_client_conflict_get_incoming_new_rep
   apr_pool_t *scratch_pool);
 
 /**
- * Return the ID of the option this conflict has been resolved to.
- * If the conflict has not been resolved yet, then return
- * @c svn_client_conflict_option_undefined.
- *
- * @since New in 1.10.
- */
-svn_client_conflict_option_id_t
-svn_client_conflict_get_resolution(const svn_client_conflict_t *conflict);
-
-/**
  * Return the node kind of the tree conflict victim described by @a conflict.
  * The victim is the local node in the working copy which was affected by the
  * tree conflict at the time the conflict was raised.
@@ -4682,6 +4662,27 @@ svn_client_conflict_tree_get_victim_node
   const svn_client_conflict_t *conflict);
 
 /**
+ * Resolve a tree @a conflict using resolution option @a option.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_tree_resolve(svn_client_conflict_t *conflict,
+                                 svn_client_conflict_option_t *option,
+                                 apr_pool_t *scratch_pool);
+
+/**
+ * Return the ID of the option this tree @a conflict has been resolved to.
+ * If the conflict has not been resolved yet, then return
+ * @c svn_client_conflict_option_undefined.
+ *
+ * @since New in 1.10.
+ */
+svn_client_conflict_option_id_t
+svn_client_conflict_tree_get_resolution(const svn_client_conflict_t *conflict);
+
+
+/**
  * Return the name of the conflicted property represented by @a conflict.
  *
  * @since New in 1.10.
@@ -4722,6 +4723,31 @@ svn_client_conflict_prop_get_propvals(co
                                       apr_pool_t *result_pool);
 
 /**
+ * Resolve a property @a conflict in property @a propname using resolution
+ * option @a option. To resolve all properties to the same option at once,
+ * set @a propname to the empty string "".
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_prop_resolve(svn_client_conflict_t *conflict,
+                                 const char *propname,
+                                 svn_client_conflict_option_t *option,
+                                 apr_pool_t *scratch_pool);
+
+/**
+ * Return the ID of the option this property @a conflict in property
+ * @a propname has been resolved to.
+ * If the conflict has not been resolved yet, then return
+ * @c svn_client_conflict_option_undefined.
+ *
+ * @since New in 1.10.
+ */
+svn_client_conflict_option_id_t
+svn_client_conflict_prop_get_resolution(const svn_client_conflict_t *conflict,
+                                        const char *propname);
+
+/**
  * Return the MIME-type of the working version of the text-conflicted file
  * described by @a conflict.
  *
@@ -4749,6 +4775,26 @@ svn_client_conflict_text_get_contents(co
                                       apr_pool_t *result_pool,
                                       apr_pool_t *scratch_pool);
 
+/**
+ * Resolve a text @a conflict using resolution option @a option.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_text_resolve(svn_client_conflict_t *conflict,
+                                 svn_client_conflict_option_t *option,
+                                 apr_pool_t *scratch_pool);
+
+/**
+ * Return the ID of the option this text @a conflict has been resolved to.
+ * If the conflict has not been resolved yet, then return
+ * @c svn_client_conflict_option_undefined.
+ *
+ * @since New in 1.10.
+ */
+svn_client_conflict_option_id_t
+svn_client_conflict_text_get_resolution(const svn_client_conflict_t *conflict);
+
 /** @} */
 
 /**

Modified: subversion/trunk/subversion/libsvn_client/resolved.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/resolved.c?rev=1693592&r1=1693591&r2=1693592&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/resolved.c (original)
+++ subversion/trunk/subversion/libsvn_client/resolved.c Fri Jul 31 13:23:29 2015
@@ -157,8 +157,16 @@ 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;
+  /* Indicate which options were chosen to resolve a text or tree conflict
+   * on the conflited node. */
+  svn_client_conflict_option_id_t resolution_text;
+  svn_client_conflict_option_id_t resolution_tree;
+
+  /* A mapping from const char* property name to pointers to
+   * svn_client_conflict_option_t for all properties which had their
+   * conflicts resolved. Indicates which options were chosen to resolve
+   * the property conflicts. */
+  apr_hash_t *resolved_props;
 
   /* For backwards compat. */
   const svn_wc_conflict_description2_t *legacy_text_conflict;
@@ -255,14 +263,18 @@ 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;
+      (*conflict)->resolution_text = svn_client_conflict_option_undefined;
+      (*conflict)->resolution_tree = svn_client_conflict_option_undefined;
+      (*conflict)->resolved_props = apr_hash_make(result_pool);
       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)->resolution_text = svn_client_conflict_option_undefined;
+  (*conflict)->resolution_tree = svn_client_conflict_option_undefined;
+  (*conflict)->resolved_props = apr_hash_make(result_pool);
   (*conflict)->ctx = ctx;
 
   /* Add all legacy conflict descriptors we can find. Eventually, this code
@@ -329,6 +341,7 @@ conflict_resolver_func(svn_wc_conflict_r
   struct conflict_resolver_baton_t *b = baton;
   svn_client_conflict_t *conflict;
   const char *local_abspath;
+  svn_client_conflict_option_id_t resolution;
   svn_wc_conflict_choice_t conflict_choice;
 
   local_abspath = description->local_abspath;
@@ -338,10 +351,42 @@ conflict_resolver_func(svn_wc_conflict_r
   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);
+  /* Evaluate the conflict callback result based on which kind
+   * of conflict libsvn_wc has given us. */
+  resolution = svn_client_conflict_option_undefined;
+  if (description->kind == svn_wc_conflict_kind_text)
+    resolution = conflict->resolution_text;
+  else if (description->kind == svn_wc_conflict_kind_tree)
+    resolution = conflict->resolution_tree;
+  else if (description->kind == svn_wc_conflict_kind_property)
+    {
+      svn_client_conflict_option_t *option;
+
+      option = svn_hash_gets(conflict->resolved_props,
+                             description->property_name);
+      if (option == NULL)
+        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                                 _("No resolution provided for conflicted "
+                                   "property '%s' on path '%s'"),
+                                 description->property_name,
+                                 svn_dirent_local_style(local_abspath,
+                                                        scratch_pool));
+
+      resolution = svn_client_conflict_option_get_id(option);
+    }
+  else
+    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                             _("Unknown legacy conflict kind '%d'"),
+                             description->kind);
+
+  if (resolution == svn_client_conflict_option_undefined)
+    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                             _("No resolution for conflicted path '%s'"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+    
+  conflict_choice = conflict_option_id_to_wc_conflict_choice(resolution);
+  *result = svn_wc_create_conflict_result(conflict_choice, NULL, result_pool);
 
   return SVN_NO_ERROR;
 }
@@ -399,20 +444,14 @@ struct svn_client_conflict_option_t
   svn_client_conflict_option_id_t id;
   const char *description;
 
+  /* Indicates the property to resolve in case of a property conflict.
+   * If set to "", all properties are resolved to this option. */
+  const char *propname;
+
   svn_client_conflict_t *conflict;
   conflict_option_resolve_func_t do_resolve_func;
 };
 
-static svn_error_t *
-resolve_postpone(svn_client_conflict_option_t *option,
-                 svn_client_conflict_t *conflict,
-                 apr_pool_t *scratch_pool)
-{
-  /* Nothing to do. */
-  conflict->resolution = svn_client_conflict_option_postpone;
-  return SVN_NO_ERROR;
-}
-
 /* 
  * Resolve the conflict at LOCAL_ABSPATH. Currently only supports
  * an OPTION_ID which can be mapped to svn_wc_conflict_choice_t and
@@ -453,6 +492,7 @@ resolve_conflict(svn_client_conflict_opt
   return SVN_NO_ERROR;
 }
 
+/* Implements conflict_option_resolve_func_t. */
 static svn_error_t *
 resolve_text_conflict(svn_client_conflict_option_t *option,
                       svn_client_conflict_t *conflict,
@@ -465,11 +505,12 @@ resolve_text_conflict(svn_client_conflic
   local_abspath = svn_client_conflict_get_local_abspath(conflict);
   SVN_ERR(resolve_conflict(option_id, local_abspath, TRUE, NULL, FALSE,
                            conflict->ctx, scratch_pool));
-  conflict->resolution = option_id;
+  conflict->resolution_text = option_id;
 
   return SVN_NO_ERROR;
 }
 
+/* Implements conflict_option_resolve_func_t. */
 static svn_error_t *
 resolve_prop_conflict(svn_client_conflict_option_t *option,
                       svn_client_conflict_t *conflict,
@@ -480,14 +521,42 @@ resolve_prop_conflict(svn_client_conflic
 
   option_id = svn_client_conflict_option_get_id(option);
   local_abspath = svn_client_conflict_get_local_abspath(conflict);
-  SVN_ERR(resolve_conflict(option_id, local_abspath, FALSE, "", FALSE,
+  SVN_ERR(resolve_conflict(option_id, local_abspath,
+                           FALSE, option->propname, FALSE,
                            conflict->ctx, scratch_pool));
-  conflict->resolution = option_id;
+
+  if (option->propname[0] == '\0')
+    {
+      apr_hash_index_t *hi;
+
+      /* All properties have been resolved to the same option. */
+      for (hi = apr_hash_first(scratch_pool, conflict->prop_conflicts);
+           hi;
+           hi = apr_hash_next(hi))
+        {
+          const char *propname = apr_hash_this_key(hi);
+
+          svn_hash_sets(conflict->resolved_props,
+                        apr_pstrdup(apr_hash_pool_get(conflict->resolved_props),
+                                    propname),
+                        option);
+          svn_hash_sets(conflict->prop_conflicts, propname, NULL);
+        }
+    }
+  else
+    {
+      svn_hash_sets(conflict->resolved_props,
+                    apr_pstrdup(apr_hash_pool_get(conflict->resolved_props),
+                                option->propname),
+                   option);
+      svn_hash_sets(conflict->prop_conflicts, option->propname, NULL);
+    }
 
   return SVN_NO_ERROR;
 }
 
 static svn_error_t *
+/* Implements conflict_option_resolve_func_t. */
 resolve_tree_conflict(svn_client_conflict_option_t *option,
                       svn_client_conflict_t *conflict,
                       apr_pool_t *scratch_pool)
@@ -499,7 +568,7 @@ resolve_tree_conflict(svn_client_conflic
   local_abspath = svn_client_conflict_get_local_abspath(conflict);
   SVN_ERR(resolve_conflict(option_id, local_abspath, FALSE, NULL, TRUE,
                            conflict->ctx, scratch_pool));
-  conflict->resolution = option_id;
+  conflict->resolution_tree = option_id;
 
   return SVN_NO_ERROR;
 }
@@ -511,13 +580,15 @@ static const svn_client_conflict_option_
     svn_client_conflict_option_postpone,
     N_("mark the conflict to be resolved later"),
     NULL,
-    resolve_postpone
+    NULL,
+    resolve_text_conflict
   },
 
   {
     svn_client_conflict_option_incoming_new_text,
     N_("accept incoming version of entire file"),
     NULL,
+    NULL,
     resolve_text_conflict
   },
 
@@ -525,6 +596,7 @@ static const svn_client_conflict_option_
     svn_client_conflict_option_working_text,
     N_("accept working copy version of entire file"),
     NULL,
+    NULL,
     resolve_text_conflict
   },
 
@@ -532,6 +604,7 @@ static const svn_client_conflict_option_
     svn_client_conflict_option_incoming_new_text_for_conflicted_hunks_only,
     N_("accept incoming version of all text conflicts in file"),
     NULL,
+    NULL,
     resolve_text_conflict
   },
 
@@ -539,6 +612,7 @@ static const svn_client_conflict_option_
     svn_client_conflict_option_working_text_for_conflicted_hunks_only,
     N_("accept working copy version of all text conflicts in file"),
     NULL,
+    NULL,
     resolve_text_conflict
   },
 
@@ -551,13 +625,15 @@ static const svn_client_conflict_option_
     svn_client_conflict_option_postpone,
     N_("mark the conflict to be resolved later"),
     NULL,
-    resolve_postpone
+    NULL,
+    resolve_text_conflict,
   },
 
   {
     svn_client_conflict_option_incoming_new_text,
     N_("accept incoming version of binary file"),
     NULL,
+    NULL,
     resolve_text_conflict
   },
 
@@ -565,6 +641,7 @@ static const svn_client_conflict_option_
     svn_client_conflict_option_working_text,
     N_("accept working copy version of binary file"),
     NULL,
+    NULL,
     resolve_text_conflict
   },
 
@@ -577,13 +654,15 @@ static const svn_client_conflict_option_
     svn_client_conflict_option_postpone,
     N_("mark the conflict to be resolved later"),
     NULL,
-    resolve_postpone
+    NULL,
+    resolve_prop_conflict
   },
 
   {
     svn_client_conflict_option_incoming_new_text,
     N_("accept incoming version of entire property value"),
     NULL,
+    NULL,
     resolve_prop_conflict
   },
 
@@ -591,6 +670,7 @@ static const svn_client_conflict_option_
     svn_client_conflict_option_working_text,
     N_("accept working copy version of entire property value"),
     NULL,
+    NULL,
     resolve_prop_conflict
   },
 
@@ -603,7 +683,8 @@ static const svn_client_conflict_option_
     svn_client_conflict_option_postpone,
     N_("mark the conflict to be resolved later"),
     NULL,
-    resolve_postpone
+    NULL,
+    resolve_tree_conflict
   },
 
   {
@@ -612,6 +693,7 @@ static const svn_client_conflict_option_
     svn_client_conflict_option_working_text,
     N_("accept current working copy state"),
     NULL,
+    NULL,
     resolve_tree_conflict
   },
 
@@ -755,15 +837,65 @@ svn_client_conflict_option_describe(cons
 }
 
 svn_error_t *
-svn_client_conflict_resolve(svn_client_conflict_t *conflict,
-                            svn_client_conflict_option_t *option,
-                            apr_pool_t *scratch_pool)
+svn_client_conflict_text_resolve(svn_client_conflict_t *conflict,
+                                 svn_client_conflict_option_t *option,
+                                 apr_pool_t *scratch_pool)
+{
+  SVN_ERR(assert_text_conflict(conflict, scratch_pool));
+  SVN_ERR(option->do_resolve_func(option, conflict, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_client_conflict_option_id_t
+svn_client_conflict_text_get_resolution(const svn_client_conflict_t *conflict)
+{
+  return conflict->resolution_text;
+}
+
+svn_error_t *
+svn_client_conflict_prop_resolve(svn_client_conflict_t *conflict,
+                                 const char *propname,
+                                 svn_client_conflict_option_t *option,
+                                 apr_pool_t *scratch_pool)
+{
+  SVN_ERR(assert_prop_conflict(conflict, scratch_pool));
+  option->propname = propname;
+  SVN_ERR(option->do_resolve_func(option, conflict, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_client_conflict_option_id_t
+svn_client_conflict_prop_get_resolution(const svn_client_conflict_t *conflict,
+                                        const char *propname)
+{
+  svn_client_conflict_option_t *option;
+
+  option = svn_hash_gets(conflict->resolved_props, propname);
+  if (option == NULL)
+    return svn_client_conflict_option_undefined;
+
+  return svn_client_conflict_option_get_id(option);
+}
+
+svn_error_t *
+svn_client_conflict_tree_resolve(svn_client_conflict_t *conflict,
+                                 svn_client_conflict_option_t *option,
+                                 apr_pool_t *scratch_pool)
 {
+  SVN_ERR(assert_tree_conflict(conflict, scratch_pool));
   SVN_ERR(option->do_resolve_func(option, conflict, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
+svn_client_conflict_option_id_t
+svn_client_conflict_tree_get_resolution(const svn_client_conflict_t *conflict)
+{
+  return conflict->resolution_tree;
+}
+
 /* Return the legacy conflict descriptor which is wrapped by CONFLICT. */
 static const svn_wc_conflict_description2_t *
 get_conflict_desc2_t(const svn_client_conflict_t *conflict)
@@ -953,12 +1085,6 @@ svn_client_conflict_get_incoming_new_rep
   return SVN_NO_ERROR;
 }
 
-svn_client_conflict_option_id_t
-svn_client_conflict_get_resolution(const svn_client_conflict_t *conflict)
-{
-  return conflict->resolution;
-}
-
 svn_node_kind_t
 svn_client_conflict_tree_get_victim_node_kind(
   const svn_client_conflict_t *conflict)



Mime
View raw message