You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2013/04/21 00:31:14 UTC

svn commit: r1470246 - in /subversion/trunk/subversion/svn: cl-conflicts.c cl-conflicts.h conflict-callbacks.c

Author: julianfoad
Date: Sat Apr 20 22:31:13 2013
New Revision: 1470246

URL: http://svn.apache.org/r1470246
Log:
Improve the interactive resolution of property conflicts.  Similar to
resolving a text conflict, show initially a single line such as

  local delete, incoming edit upon merge

and allow the user to display a 3-way diff with a 'dc - display conflict'
option.  Previously, for each property that is in conflict, we displayed the
entire contents of the property conflict reject file, which includes all of
the property conflicts on the node, and which is not very readable.

* subversion/svn/cl-conflicts.h,
  subversion/svn/cl-conflicts.c
  (svn_cl__get_human_readable_prop_conflict_description): New function.

* subversion/svn/conflict-callbacks.c
  (show_prop_conflict): New function.
  (prop_conflict_options): Add a 'dc - display conflict' option.
  (handle_prop_conflict): Work around a historical mix-up in the provided
    'theirs' and 'merged' and 'conflict-reject file' paths. Display a
    summary of the conflict instead of printing the '.prej' file. Show a
    3-way diff when the 'dc' option is selected.

Modified:
    subversion/trunk/subversion/svn/cl-conflicts.c
    subversion/trunk/subversion/svn/cl-conflicts.h
    subversion/trunk/subversion/svn/conflict-callbacks.c

Modified: subversion/trunk/subversion/svn/cl-conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl-conflicts.c?rev=1470246&r1=1470245&r2=1470246&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl-conflicts.c (original)
+++ subversion/trunk/subversion/svn/cl-conflicts.c Sat Apr 20 22:31:13 2013
@@ -185,6 +185,60 @@ operation_str(svn_wc_operation_t operati
 }
 
 svn_error_t *
+svn_cl__get_human_readable_prop_conflict_description(
+  const char **desc,
+  const svn_wc_conflict_description2_t *conflict,
+  apr_pool_t *pool)
+{
+  const char *reason_str, *action_str;
+
+  /* We provide separately translatable strings for the values that we
+   * know about, and a fall-back in case any other values occur. */
+  switch (conflict->reason)
+    {
+      case svn_wc_conflict_reason_edited:
+        reason_str = _("local edit");
+        break;
+      case svn_wc_conflict_reason_added:
+        reason_str = _("local add");
+        break;
+      case svn_wc_conflict_reason_deleted:
+        reason_str = _("local delete");
+        break;
+      case svn_wc_conflict_reason_obstructed:
+        reason_str = _("local obstruction");
+        break;
+      default:
+        reason_str = apr_psprintf(pool, _("local %s"),
+                                  svn_token__to_word(map_conflict_reason_xml,
+                                                     conflict->reason));
+        break;
+    }
+  switch (conflict->action)
+    {
+      case svn_wc_conflict_action_edit:
+        action_str = _("incoming edit");
+        break;
+      case svn_wc_conflict_action_add:
+        action_str = _("incoming add");
+        break;
+      case svn_wc_conflict_action_delete:
+        action_str = _("incoming delete");
+        break;
+      default:
+        action_str = apr_psprintf(pool, _("incoming %s"),
+                                  svn_token__to_word(map_conflict_action_xml,
+                                                     conflict->action));
+        break;
+    }
+  SVN_ERR_ASSERT(reason_str && action_str);
+  *desc = apr_psprintf(pool, _("%s, %s %s"),
+                       reason_str, action_str,
+                       operation_str(conflict->operation));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_cl__get_human_readable_tree_conflict_description(
   const char **desc,
   const svn_wc_conflict_description2_t *conflict,

Modified: subversion/trunk/subversion/svn/cl-conflicts.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl-conflicts.h?rev=1470246&r1=1470245&r2=1470246&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl-conflicts.h (original)
+++ subversion/trunk/subversion/svn/cl-conflicts.h Sat Apr 20 22:31:13 2013
@@ -41,6 +41,18 @@ extern "C" {
 
 /**
  * Return in @a desc a possibly localized human readable
+ * description of a property conflict described by @a conflict.
+ *
+ * Allocate the result in @a pool.
+ */
+svn_error_t *
+svn_cl__get_human_readable_prop_conflict_description(
+  const char **desc,
+  const svn_wc_conflict_description2_t *conflict,
+  apr_pool_t *pool);
+
+/**
+ * Return in @a desc a possibly localized human readable
  * description of a tree conflict described by @a conflict.
  *
  * Allocate the result in @a pool.

Modified: subversion/trunk/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/conflict-callbacks.c?rev=1470246&r1=1470245&r2=1470246&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/conflict-callbacks.c (original)
+++ subversion/trunk/subversion/svn/conflict-callbacks.c Sat Apr 20 22:31:13 2013
@@ -225,6 +225,57 @@ show_conflicts(const svn_wc_conflict_des
                                      pool);
 }
 
+/* Display the conflicting values of a property as a 3-way diff.
+ *
+ * Assume the values are printable UTF-8 text.
+ */
+static svn_error_t *
+show_prop_conflict(const svn_wc_conflict_description2_t *desc,
+                   apr_pool_t *pool)
+{
+  const char *base_abspath = desc->base_abspath;
+  const char *my_abspath = desc->my_abspath;
+  const char *their_abspath = desc->their_abspath;
+  svn_diff_file_options_t *options = svn_diff_file_options_create(pool);
+  svn_diff_t *diff;
+  svn_stream_t *output;
+
+  /* If any of the property values is missing, use an empty file instead
+   * for the purpose of showing a diff. */
+  if (! base_abspath || ! my_abspath || ! their_abspath)
+    {
+      const char *empty_file;
+
+      SVN_ERR(svn_io_open_unique_file3(NULL, &empty_file,
+                                       NULL, svn_io_file_del_on_pool_cleanup,
+                                       pool, pool));
+      if (! base_abspath)
+        base_abspath = empty_file;
+      if (! my_abspath)
+        my_abspath = empty_file;
+      if (! their_abspath)
+        their_abspath = empty_file;
+    }
+
+  options->ignore_eol_style = TRUE;
+  SVN_ERR(svn_stream_for_stdout(&output, pool));
+  SVN_ERR(svn_diff_file_diff3_2(&diff,
+                                base_abspath, my_abspath, their_abspath,
+                                options, pool));
+  SVN_ERR(svn_diff_file_output_merge2(output, diff,
+                                      base_abspath,
+                                      my_abspath,
+                                      their_abspath,
+                                      _("||||||| ORIGINAL"),
+                                      _("<<<<<<< MINE"),
+                                      _(">>>>>>> THEIRS"),
+                                      "=======",
+                                      svn_diff_conflict_display_modified_original_latest,
+                                      pool));
+
+  return SVN_NO_ERROR;
+}
+
 
 /* Run an external editor, passing it the 'merged' file in DESC, or, if the
  * 'merged' file is null, return an error. The tool to use is determined by
@@ -393,6 +444,7 @@ static const resolver_option_t prop_conf
   { "tf", N_("their version"),    N_("accept their version of entire property "
                                      "(same)  [theirs-full]"),
                                   svn_wc_conflict_choose_theirs_full },
+  { "dc", N_("display conflict"), N_("show conflicts in this property"), -1 },
   { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
                                   svn_wc_conflict_choose_postpone },
   { "h",  N_("help"),             N_("show this help (also '?')"), -1 },
@@ -841,6 +893,13 @@ handle_prop_conflict(svn_wc_conflict_res
                      apr_pool_t *scratch_pool)
 {
   apr_pool_t *iterpool;
+  const char *message;
+
+  /* ### Work around a historical bug in the provider: the path to the
+   *     conflict description file was put in the 'theirs' field, and
+   *     'theirs' was put in the 'merged' field. */
+  ((svn_wc_conflict_description2_t *)desc)->their_abspath = desc->merged_file;
+  ((svn_wc_conflict_description2_t *)desc)->merged_file = NULL;
 
   SVN_ERR_ASSERT(desc->kind == svn_wc_conflict_kind_property);
 
@@ -852,32 +911,9 @@ handle_prop_conflict(svn_wc_conflict_res
                                 b->path_prefix, desc->local_abspath,
                                 scratch_pool)));
 
-  /* ### Currently, the only useful information in a prop conflict
-   * ### description is the .prej file path, which, possibly due to
-   * ### deceitful interference from outer space, is stored in the
-   * ### 'their_abspath' field of the description.
-   * ### This needs to be fixed so we can present better options here. */
-  if (desc->their_abspath)
-    {
-      svn_stringbuf_t *prop_reject;
-
-      /* ### The library dumps an svn_string_t into a temp file, and
-       * ### we read it back from the file into an svn_stringbuf_t here.
-       * ### That's rather silly. We should be passed svn_string_t's
-       * ### containing the old/mine/theirs values instead. */
-      SVN_ERR(svn_stringbuf_from_file2(&prop_reject,
-                                       desc->their_abspath,
-                                       scratch_pool));
-      /* Print reject file contents. */
-      SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
-                                  "%s\n", prop_reject->data));
-    }
-  else
-    {
-      /* Nothing much we can do without a prej file... */
-      result->choice = svn_wc_conflict_choose_postpone;
-      return SVN_NO_ERROR;
-    }
+  SVN_ERR(svn_cl__get_human_readable_prop_conflict_description(&message, desc,
+                                                               scratch_pool));
+  SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n", message));
 
   iterpool = svn_pool_create(scratch_pool);
   while (TRUE)
@@ -898,6 +934,10 @@ handle_prop_conflict(svn_wc_conflict_res
           b->quit = TRUE;
           break;
         }
+      else if (strcmp(opt->code, "dc") == 0)
+        {
+          SVN_ERR(show_prop_conflict(desc, scratch_pool));
+        }
       else if (opt->choice != -1)
         {
           result->choice = opt->choice;



RE: svn commit: r1470246 - in /subversion/trunk/subversion/svn: cl-conflicts.c cl-conflicts.h conflict-callbacks.c

Posted by Bert Huijben <be...@qqmail.nl>.

> -----Original Message-----
> From: julianfoad@apache.org [mailto:julianfoad@apache.org]
> Sent: zondag 21 april 2013 0:31
> To: commits@subversion.apache.org
> Subject: svn commit: r1470246 - in /subversion/trunk/subversion/svn: cl-
> conflicts.c cl-conflicts.h conflict-callbacks.c
> 
> Author: julianfoad
> Date: Sat Apr 20 22:31:13 2013
> New Revision: 1470246
> 
> URL: http://svn.apache.org/r1470246
> Log:
> Improve the interactive resolution of property conflicts.  Similar to
> resolving a text conflict, show initially a single line such as
> 
>   local delete, incoming edit upon merge
> 
> and allow the user to display a 3-way diff with a 'dc - display conflict'
> option.  Previously, for each property that is in conflict, we displayed the
> entire contents of the property conflict reject file, which includes all of
> the property conflicts on the node, and which is not very readable.
> 
> * subversion/svn/cl-conflicts.h,
>   subversion/svn/cl-conflicts.c
>   (svn_cl__get_human_readable_prop_conflict_description): New function.
> 
> * subversion/svn/conflict-callbacks.c
>   (show_prop_conflict): New function.
>   (prop_conflict_options): Add a 'dc - display conflict' option.
>   (handle_prop_conflict): Work around a historical mix-up in the provided
>     'theirs' and 'merged' and 'conflict-reject file' paths. Display a
>     summary of the conflict instead of printing the '.prej' file. Show a
>     3-way diff when the 'dc' option is selected.
> 
> Modified:
>     subversion/trunk/subversion/svn/cl-conflicts.c
>     subversion/trunk/subversion/svn/cl-conflicts.h
>     subversion/trunk/subversion/svn/conflict-callbacks.c
> 
> Modified: subversion/trunk/subversion/svn/cl-conflicts.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl-
> conflicts.c?rev=1470246&r1=1470245&r2=1470246&view=diff
> ==========================================================
> ====================
> --- subversion/trunk/subversion/svn/cl-conflicts.c (original)
> +++ subversion/trunk/subversion/svn/cl-conflicts.c Sat Apr 20 22:31:13 2013
> @@ -185,6 +185,60 @@ operation_str(svn_wc_operation_t operati
>  }
> 
>  svn_error_t *
> +svn_cl__get_human_readable_prop_conflict_description(
> +  const char **desc,
> +  const svn_wc_conflict_description2_t *conflict,
> +  apr_pool_t *pool)
> +{
> +  const char *reason_str, *action_str;
> +
> +  /* We provide separately translatable strings for the values that we
> +   * know about, and a fall-back in case any other values occur. */
> +  switch (conflict->reason)
> +    {
> +      case svn_wc_conflict_reason_edited:
> +        reason_str = _("local edit");
> +        break;
> +      case svn_wc_conflict_reason_added:
> +        reason_str = _("local add");
> +        break;
> +      case svn_wc_conflict_reason_deleted:
> +        reason_str = _("local delete");
> +        break;
> +      case svn_wc_conflict_reason_obstructed:
> +        reason_str = _("local obstruction");
> +        break;
> +      default:
> +        reason_str = apr_psprintf(pool, _("local %s"),
> +                                  svn_token__to_word(map_conflict_reason_xml,
> +                                                     conflict->reason));
> +        break;
> +    }
> +  switch (conflict->action)
> +    {
> +      case svn_wc_conflict_action_edit:
> +        action_str = _("incoming edit");
> +        break;
> +      case svn_wc_conflict_action_add:
> +        action_str = _("incoming add");
> +        break;
> +      case svn_wc_conflict_action_delete:
> +        action_str = _("incoming delete");
> +        break;
> +      default:
> +        action_str = apr_psprintf(pool, _("incoming %s"),
> +                                  svn_token__to_word(map_conflict_action_xml,
> +                                                     conflict->action));
> +        break;
> +    }
> +  SVN_ERR_ASSERT(reason_str && action_str);
> +  *desc = apr_psprintf(pool, _("%s, %s %s"),
> +                       reason_str, action_str,
> +                       operation_str(conflict->operation));
> +  return SVN_NO_ERROR;
> +}
> +
> +svn_error_t *
>  svn_cl__get_human_readable_tree_conflict_description(
>    const char **desc,
>    const svn_wc_conflict_description2_t *conflict,
> 
> Modified: subversion/trunk/subversion/svn/cl-conflicts.h
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl-
> conflicts.h?rev=1470246&r1=1470245&r2=1470246&view=diff
> ==========================================================
> ====================
> --- subversion/trunk/subversion/svn/cl-conflicts.h (original)
> +++ subversion/trunk/subversion/svn/cl-conflicts.h Sat Apr 20 22:31:13 2013
> @@ -41,6 +41,18 @@ extern "C" {
> 
>  /**
>   * Return in @a desc a possibly localized human readable
> + * description of a property conflict described by @a conflict.
> + *
> + * Allocate the result in @a pool.
> + */
> +svn_error_t *
> +svn_cl__get_human_readable_prop_conflict_description(
> +  const char **desc,
> +  const svn_wc_conflict_description2_t *conflict,
> +  apr_pool_t *pool);
> +
> +/**
> + * Return in @a desc a possibly localized human readable
>   * description of a tree conflict described by @a conflict.
>   *
>   * Allocate the result in @a pool.
> 
> Modified: subversion/trunk/subversion/svn/conflict-callbacks.c
> URL:
> http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/conflict-
> callbacks.c?rev=1470246&r1=1470245&r2=1470246&view=diff
> ==========================================================
> ====================
> --- subversion/trunk/subversion/svn/conflict-callbacks.c (original)
> +++ subversion/trunk/subversion/svn/conflict-callbacks.c Sat Apr 20 22:31:13
> 2013
> @@ -225,6 +225,57 @@ show_conflicts(const svn_wc_conflict_des
>                                       pool);
>  }
> 
> +/* Display the conflicting values of a property as a 3-way diff.
> + *
> + * Assume the values are printable UTF-8 text.
> + */
> +static svn_error_t *
> +show_prop_conflict(const svn_wc_conflict_description2_t *desc,
> +                   apr_pool_t *pool)
> +{
> +  const char *base_abspath = desc->base_abspath;
> +  const char *my_abspath = desc->my_abspath;
> +  const char *their_abspath = desc->their_abspath;
> +  svn_diff_file_options_t *options = svn_diff_file_options_create(pool);
> +  svn_diff_t *diff;
> +  svn_stream_t *output;
> +
> +  /* If any of the property values is missing, use an empty file instead
> +   * for the purpose of showing a diff. */
> +  if (! base_abspath || ! my_abspath || ! their_abspath)
> +    {
> +      const char *empty_file;
> +
> +      SVN_ERR(svn_io_open_unique_file3(NULL, &empty_file,
> +                                       NULL, svn_io_file_del_on_pool_cleanup,
> +                                       pool, pool));
> +      if (! base_abspath)
> +        base_abspath = empty_file;
> +      if (! my_abspath)
> +        my_abspath = empty_file;
> +      if (! their_abspath)
> +        their_abspath = empty_file;
> +    }
> +
> +  options->ignore_eol_style = TRUE;
> +  SVN_ERR(svn_stream_for_stdout(&output, pool));
> +  SVN_ERR(svn_diff_file_diff3_2(&diff,
> +                                base_abspath, my_abspath, their_abspath,
> +                                options, pool));
> +  SVN_ERR(svn_diff_file_output_merge2(output, diff,
> +                                      base_abspath,
> +                                      my_abspath,
> +                                      their_abspath,
> +                                      _("||||||| ORIGINAL"),
> +                                      _("<<<<<<< MINE"),
> +                                      _(">>>>>>> THEIRS"),
> +                                      "=======",
> +                                      svn_diff_conflict_display_modified_original_latest,
> +                                      pool));
> +
> +  return SVN_NO_ERROR;
> +}
> +
> 
>  /* Run an external editor, passing it the 'merged' file in DESC, or, if the
>   * 'merged' file is null, return an error. The tool to use is determined by
> @@ -393,6 +444,7 @@ static const resolver_option_t prop_conf
>    { "tf", N_("their version"),    N_("accept their version of entire property "
>                                       "(same)  [theirs-full]"),
>                                    svn_wc_conflict_choose_theirs_full },
> +  { "dc", N_("display conflict"), N_("show conflicts in this property"), -1 },
>    { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
>                                    svn_wc_conflict_choose_postpone },
>    { "h",  N_("help"),             N_("show this help (also '?')"), -1 },
> @@ -841,6 +893,13 @@ handle_prop_conflict(svn_wc_conflict_res
>                       apr_pool_t *scratch_pool)
>  {
>    apr_pool_t *iterpool;
> +  const char *message;
> +
> +  /* ### Work around a historical bug in the provider: the path to the
> +   *     conflict description file was put in the 'theirs' field, and
> +   *     'theirs' was put in the 'merged' field. */

Note that this was true when handling a conflict after installing it. The interactive resolver as called from the property merge code in libsvn_wc didn't put the .prej file here, as that wasn't written at the time of invocation.

Since 1.8 we store all information first and only then we start the resolving phase.

But since we now run the resolver later we see different results depending on how/where we fill the conflict description struct. If we get instances via 'svn_client_infoX' we get one instance with a reference to the .prej file (just like in 1.7), while we see multiple instances in the resolver.

	Bert 



RE: svn commit: r1470246 - in /subversion/trunk/subversion/svn: cl-conflicts.c cl-conflicts.h conflict-callbacks.c

Posted by Bert Huijben <be...@qqmail.nl>.

> -----Original Message-----
> From: julianfoad@apache.org [mailto:julianfoad@apache.org]
> Sent: zondag 21 april 2013 0:31
> To: commits@subversion.apache.org
> Subject: svn commit: r1470246 - in /subversion/trunk/subversion/svn: cl-
> conflicts.c cl-conflicts.h conflict-callbacks.c
> 
> Author: julianfoad
> Date: Sat Apr 20 22:31:13 2013
> New Revision: 1470246
> 
> URL: http://svn.apache.org/r1470246
> Log:
> Improve the interactive resolution of property conflicts.  Similar to
> resolving a text conflict, show initially a single line such as
> 
>   local delete, incoming edit upon merge
> 
> and allow the user to display a 3-way diff with a 'dc - display conflict'
> option.  Previously, for each property that is in conflict, we displayed the
> entire contents of the property conflict reject file, which includes all of
> the property conflicts on the node, and which is not very readable.
> 
> * subversion/svn/cl-conflicts.h,
>   subversion/svn/cl-conflicts.c
>   (svn_cl__get_human_readable_prop_conflict_description): New function.
> 
> * subversion/svn/conflict-callbacks.c
>   (show_prop_conflict): New function.
>   (prop_conflict_options): Add a 'dc - display conflict' option.
>   (handle_prop_conflict): Work around a historical mix-up in the provided
>     'theirs' and 'merged' and 'conflict-reject file' paths. Display a
>     summary of the conflict instead of printing the '.prej' file. Show a
>     3-way diff when the 'dc' option is selected.
> 
> Modified:
>     subversion/trunk/subversion/svn/cl-conflicts.c
>     subversion/trunk/subversion/svn/cl-conflicts.h
>     subversion/trunk/subversion/svn/conflict-callbacks.c
> 
> Modified: subversion/trunk/subversion/svn/cl-conflicts.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl-
> conflicts.c?rev=1470246&r1=1470245&r2=1470246&view=diff
> ==========================================================
> ====================
> --- subversion/trunk/subversion/svn/cl-conflicts.c (original)
> +++ subversion/trunk/subversion/svn/cl-conflicts.c Sat Apr 20 22:31:13 2013
> @@ -185,6 +185,60 @@ operation_str(svn_wc_operation_t operati
>  }
> 
>  svn_error_t *
> +svn_cl__get_human_readable_prop_conflict_description(
> +  const char **desc,
> +  const svn_wc_conflict_description2_t *conflict,
> +  apr_pool_t *pool)
> +{
> +  const char *reason_str, *action_str;
> +
> +  /* We provide separately translatable strings for the values that we
> +   * know about, and a fall-back in case any other values occur. */
> +  switch (conflict->reason)
> +    {
> +      case svn_wc_conflict_reason_edited:
> +        reason_str = _("local edit");
> +        break;
> +      case svn_wc_conflict_reason_added:
> +        reason_str = _("local add");
> +        break;
> +      case svn_wc_conflict_reason_deleted:
> +        reason_str = _("local delete");
> +        break;
> +      case svn_wc_conflict_reason_obstructed:
> +        reason_str = _("local obstruction");
> +        break;
> +      default:
> +        reason_str = apr_psprintf(pool, _("local %s"),
> +                                  svn_token__to_word(map_conflict_reason_xml,
> +                                                     conflict->reason));
> +        break;
> +    }
> +  switch (conflict->action)
> +    {
> +      case svn_wc_conflict_action_edit:
> +        action_str = _("incoming edit");
> +        break;
> +      case svn_wc_conflict_action_add:
> +        action_str = _("incoming add");
> +        break;
> +      case svn_wc_conflict_action_delete:
> +        action_str = _("incoming delete");
> +        break;
> +      default:
> +        action_str = apr_psprintf(pool, _("incoming %s"),
> +                                  svn_token__to_word(map_conflict_action_xml,
> +                                                     conflict->action));
> +        break;
> +    }
> +  SVN_ERR_ASSERT(reason_str && action_str);
> +  *desc = apr_psprintf(pool, _("%s, %s %s"),
> +                       reason_str, action_str,
> +                       operation_str(conflict->operation));
> +  return SVN_NO_ERROR;
> +}
> +
> +svn_error_t *
>  svn_cl__get_human_readable_tree_conflict_description(
>    const char **desc,
>    const svn_wc_conflict_description2_t *conflict,
> 
> Modified: subversion/trunk/subversion/svn/cl-conflicts.h
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl-
> conflicts.h?rev=1470246&r1=1470245&r2=1470246&view=diff
> ==========================================================
> ====================
> --- subversion/trunk/subversion/svn/cl-conflicts.h (original)
> +++ subversion/trunk/subversion/svn/cl-conflicts.h Sat Apr 20 22:31:13 2013
> @@ -41,6 +41,18 @@ extern "C" {
> 
>  /**
>   * Return in @a desc a possibly localized human readable
> + * description of a property conflict described by @a conflict.
> + *
> + * Allocate the result in @a pool.
> + */
> +svn_error_t *
> +svn_cl__get_human_readable_prop_conflict_description(
> +  const char **desc,
> +  const svn_wc_conflict_description2_t *conflict,
> +  apr_pool_t *pool);
> +
> +/**
> + * Return in @a desc a possibly localized human readable
>   * description of a tree conflict described by @a conflict.
>   *
>   * Allocate the result in @a pool.
> 
> Modified: subversion/trunk/subversion/svn/conflict-callbacks.c
> URL:
> http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/conflict-
> callbacks.c?rev=1470246&r1=1470245&r2=1470246&view=diff
> ==========================================================
> ====================
> --- subversion/trunk/subversion/svn/conflict-callbacks.c (original)
> +++ subversion/trunk/subversion/svn/conflict-callbacks.c Sat Apr 20 22:31:13
> 2013
> @@ -225,6 +225,57 @@ show_conflicts(const svn_wc_conflict_des
>                                       pool);
>  }
> 
> +/* Display the conflicting values of a property as a 3-way diff.
> + *
> + * Assume the values are printable UTF-8 text.
> + */
> +static svn_error_t *
> +show_prop_conflict(const svn_wc_conflict_description2_t *desc,
> +                   apr_pool_t *pool)
> +{
> +  const char *base_abspath = desc->base_abspath;
> +  const char *my_abspath = desc->my_abspath;
> +  const char *their_abspath = desc->their_abspath;
> +  svn_diff_file_options_t *options = svn_diff_file_options_create(pool);
> +  svn_diff_t *diff;
> +  svn_stream_t *output;
> +
> +  /* If any of the property values is missing, use an empty file instead
> +   * for the purpose of showing a diff. */
> +  if (! base_abspath || ! my_abspath || ! their_abspath)
> +    {
> +      const char *empty_file;
> +
> +      SVN_ERR(svn_io_open_unique_file3(NULL, &empty_file,
> +                                       NULL, svn_io_file_del_on_pool_cleanup,
> +                                       pool, pool));
> +      if (! base_abspath)
> +        base_abspath = empty_file;
> +      if (! my_abspath)
> +        my_abspath = empty_file;
> +      if (! their_abspath)
> +        their_abspath = empty_file;
> +    }
> +
> +  options->ignore_eol_style = TRUE;
> +  SVN_ERR(svn_stream_for_stdout(&output, pool));
> +  SVN_ERR(svn_diff_file_diff3_2(&diff,
> +                                base_abspath, my_abspath, their_abspath,
> +                                options, pool));
> +  SVN_ERR(svn_diff_file_output_merge2(output, diff,
> +                                      base_abspath,
> +                                      my_abspath,
> +                                      their_abspath,
> +                                      _("||||||| ORIGINAL"),
> +                                      _("<<<<<<< MINE"),
> +                                      _(">>>>>>> THEIRS"),
> +                                      "=======",
> +                                      svn_diff_conflict_display_modified_original_latest,
> +                                      pool));
> +
> +  return SVN_NO_ERROR;
> +}
> +
> 
>  /* Run an external editor, passing it the 'merged' file in DESC, or, if the
>   * 'merged' file is null, return an error. The tool to use is determined by
> @@ -393,6 +444,7 @@ static const resolver_option_t prop_conf
>    { "tf", N_("their version"),    N_("accept their version of entire property "
>                                       "(same)  [theirs-full]"),
>                                    svn_wc_conflict_choose_theirs_full },
> +  { "dc", N_("display conflict"), N_("show conflicts in this property"), -1 },
>    { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
>                                    svn_wc_conflict_choose_postpone },
>    { "h",  N_("help"),             N_("show this help (also '?')"), -1 },
> @@ -841,6 +893,13 @@ handle_prop_conflict(svn_wc_conflict_res
>                       apr_pool_t *scratch_pool)
>  {
>    apr_pool_t *iterpool;
> +  const char *message;
> +
> +  /* ### Work around a historical bug in the provider: the path to the
> +   *     conflict description file was put in the 'theirs' field, and
> +   *     'theirs' was put in the 'merged' field. */

Note that this was true when handling a conflict after installing it. The interactive resolver as called from the property merge code in libsvn_wc didn't put the .prej file here, as that wasn't written at the time of invocation.

Since 1.8 we store all information first and only then we start the resolving phase.

But since we now run the resolver later we see different results depending on how/where we fill the conflict description struct. If we get instances via 'svn_client_infoX' we get one instance with a reference to the .prej file (just like in 1.7), while we see multiple instances in the resolver.

	Bert