You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pr...@apache.org on 2013/06/05 11:22:51 UTC

svn commit: r1489765 [16/22] - in /subversion/branches/verify-keep-going: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/hook-scripts/ contrib/server-side/fsfsfixer/ contrib/server-side/fsfsfixer/fixer/ notes/ subversion...

Modified: subversion/branches/verify-keep-going/subversion/svn/cl-conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svn/cl-conflicts.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svn/cl-conflicts.c (original)
+++ subversion/branches/verify-keep-going/subversion/svn/cl-conflicts.c Wed Jun  5 09:22:43 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,
@@ -230,10 +284,10 @@ svn_cl__get_human_readable_tree_conflict
          an ordinary user-facing string. */
       *desc = apr_psprintf(pool, _("local: %s %s incoming: %s %s %s"),
                            svn_node_kind_to_word(conflict->node_kind),
-                           svn_token__to_word(map_conflict_reason_xml, 
+                           svn_token__to_word(map_conflict_reason_xml,
                                               conflict->reason),
                            svn_node_kind_to_word(incoming_kind),
-                           svn_token__to_word(map_conflict_action_xml, 
+                           svn_token__to_word(map_conflict_action_xml,
                                               conflict->action),
                            operation);
     }

Modified: subversion/branches/verify-keep-going/subversion/svn/cl-conflicts.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svn/cl-conflicts.h?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svn/cl-conflicts.h (original)
+++ subversion/branches/verify-keep-going/subversion/svn/cl-conflicts.h Wed Jun  5 09:22:43 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/branches/verify-keep-going/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svn/cl.h?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svn/cl.h (original)
+++ subversion/branches/verify-keep-going/subversion/svn/cl.h Wed Jun  5 09:22:43 2013
@@ -158,7 +158,7 @@ typedef struct svn_cl__opt_state_t
   /* Was --no-unlock specified? */
   svn_boolean_t no_unlock;
 
-  const char *message;           /* log message */
+  const char *message;           /* log message (not converted to UTF-8) */
   svn_boolean_t force;           /* be more forceful, as in "svn rm -f ..." */
   svn_boolean_t force_log;       /* force validity of a suspect log msg file */
   svn_boolean_t incremental;     /* yield output suitable for concatenation */
@@ -168,19 +168,22 @@ typedef struct svn_cl__opt_state_t
   svn_boolean_t verbose;         /* be verbose */
   svn_boolean_t update;          /* contact the server for the full story */
   svn_boolean_t strict;          /* do strictly what was requested */
-  svn_stringbuf_t *filedata;     /* contents of file used as option data */
-  const char *encoding;          /* the locale/encoding of the data*/
+  svn_stringbuf_t *filedata;     /* contents of file used as option data
+                                    (not converted to UTF-8) */
+  const char *encoding;          /* the locale/encoding of 'message' and of
+                                    'filedata' (not converted to UTF-8) */
   svn_boolean_t help;            /* print usage message */
-  const char *auth_username;     /* auth username */ /* UTF-8! */
-  const char *auth_password;     /* auth password */ /* UTF-8! */
-  const char *extensions;        /* subprocess extension args */ /* UTF-8! */
-  apr_array_header_t *targets;   /* target list from file */ /* UTF-8! */
+  const char *auth_username;     /* auth username */
+  const char *auth_password;     /* auth password */
+  const char *extensions;        /* subprocess extension args */
+  apr_array_header_t *targets;   /* target list from file */
   svn_boolean_t xml;             /* output in xml, e.g., "svn log --xml" */
   svn_boolean_t no_ignore;       /* disregard default ignores & svn:ignore's */
   svn_boolean_t no_auth_cache;   /* do not cache authentication information */
   struct
     {
-  const char *diff_cmd;              /* the external diff command to use */
+  const char *diff_cmd;              /* the external diff command to use
+                                        (not converted to UTF-8) */
   svn_boolean_t internal_diff;       /* override diff_cmd in config file */
   svn_boolean_t no_diff_added;       /* do not show diffs for deleted files */
   svn_boolean_t no_diff_deleted;     /* do not show diffs for deleted files */
@@ -197,8 +200,10 @@ typedef struct svn_cl__opt_state_t
   svn_boolean_t stop_on_copy;    /* don't cross copies during processing */
   svn_boolean_t dry_run;         /* try operation but make no changes */
   svn_boolean_t revprop;         /* operate on a revision property */
-  const char *merge_cmd;         /* the external merge command to use */
-  const char *editor_cmd;        /* the external editor command to use */
+  const char *merge_cmd;         /* the external merge command to use
+                                    (not converted to UTF-8) */
+  const char *editor_cmd;        /* the external editor command to use
+                                    (not converted to UTF-8) */
   svn_boolean_t record_only;     /* whether to record mergeinfo */
   const char *old_target;        /* diff target */
   const char *new_target;        /* diff target */
@@ -210,13 +215,12 @@ typedef struct svn_cl__opt_state_t
   const char *native_eol;        /* override system standard eol marker */
   svn_boolean_t remove;          /* deassociate a changelist */
   apr_array_header_t *changelists; /* changelist filters */
-  const char *changelist;        /* operate on this changelist
-                                    THIS IS TEMPORARY (LAST OF CHANGELISTS) */
   svn_boolean_t keep_changelists;/* don't remove changelists after commit */
   svn_boolean_t keep_local;      /* delete path only from repository */
   svn_boolean_t all_revprops;    /* retrieve all revprops */
   svn_boolean_t no_revprops;     /* retrieve no revprops */
-  apr_hash_t *revprop_table;     /* table of revision properties to get/set */
+  apr_hash_t *revprop_table;     /* table of revision properties to get/set
+                                    (not converted to UTF-8) */
   svn_boolean_t parents;         /* create intermediate directories */
   svn_boolean_t use_merge_history; /* use/display extra merge information */
   svn_cl__accept_t accept_which;   /* how to handle conflicts */
@@ -331,6 +335,31 @@ svn_cl__check_cancel(void *baton);
 typedef struct svn_cl__interactive_conflict_baton_t
   svn_cl__interactive_conflict_baton_t;
 
+/* Conflict stats for operations such as update and merge. */
+typedef struct svn_cl__conflict_stats_t svn_cl__conflict_stats_t;
+
+/* Return a new, initialized, conflict stats structure, allocated in
+ * POOL. */
+svn_cl__conflict_stats_t *
+svn_cl__conflict_stats_create(apr_pool_t *pool);
+
+/* Update CONFLICT_STATS to reflect that a conflict on PATH_LOCAL of kind
+ * CONFLICT_KIND is resolved.  (There is no support for updating the
+ * 'skipped paths' stats, since skips cannot be 'resolved'.) */
+void
+svn_cl__conflict_stats_resolved(svn_cl__conflict_stats_t *conflict_stats,
+                                const char *path_local,
+                                svn_wc_conflict_kind_t conflict_kind);
+
+/* Print the conflict stats accumulated in CONFLICT_STATS.
+ *
+ * Return any error encountered during printing.
+ * See also svn_cl__notifier_print_conflict_stats().
+ */
+svn_error_t *
+svn_cl__print_conflict_stats(svn_cl__conflict_stats_t *conflict_stats,
+                             apr_pool_t *scratch_pool);
+
 /* Create and return an baton for use with svn_cl__conflict_func_interactive
  * in *B, allocated from RESULT_POOL, and initialised with the values
  * ACCEPT_WHICH, CONFIG, EDITOR_CMD, CANCEL_FUNC and CANCEL_BATON. */
@@ -340,6 +369,7 @@ svn_cl__get_conflict_func_interactive_ba
   svn_cl__accept_t accept_which,
   apr_hash_t *config,
   const char *editor_cmd,
+  svn_cl__conflict_stats_t *conflict_stats,
   svn_cancel_func_t cancel_func,
   void *cancel_baton,
   apr_pool_t *result_pool);
@@ -516,6 +546,7 @@ svn_cl__merge_file(const char *base_path
 svn_error_t *
 svn_cl__get_notifier(svn_wc_notify_func2_t *notify_func_p,
                      void **notify_baton_p,
+                     svn_cl__conflict_stats_t *conflict_stats,
                      apr_pool_t *pool);
 
 /* Make the notifier for use with BATON print the appropriate summary
@@ -551,21 +582,17 @@ svn_cl__check_externals_failed_notify_wr
                                               const svn_wc_notify_t *n,
                                               apr_pool_t *pool);
 
-/* Reset to zero the conflict stats accumulated in BATON, which is the
- * notifier baton from svn_cl__get_notifier().
- */
-svn_error_t *
-svn_cl__notifier_reset_conflict_stats(void *baton);
-
-/* Print the conflict stats accumulated in BATON, which is the
- * notifier baton from svn_cl__get_notifier().
+/* Print the conflict stats accumulated in BATON, which is the
+ * notifier baton from svn_cl__get_notifier().  This is just like
+ * calling svn_cl__print_conflict_stats().
+ *
  * Return any error encountered during printing.
  */
 svn_error_t *
 svn_cl__notifier_print_conflict_stats(void *baton, apr_pool_t *scratch_pool);
 
 
-/*** Log message callback stuffs. ***/
+/*** Log message callback stuffs. ***/
 
 /* Allocate in POOL a baton for use with svn_cl__get_log_message().
 
@@ -671,6 +698,17 @@ const char *
 svn_cl__operation_str_human_readable(svn_wc_operation_t operation,
                                      apr_pool_t *pool);
 
+
+/* What use is a property name intended for.
+   Used by svn_cl__check_svn_prop_name to customize error messages. */
+typedef enum svn_cl__prop_use_e
+  {
+    svn_cl__prop_use_set,       /* setting the property */
+    svn_cl__prop_use_edit,      /* editing the property */
+    svn_cl__prop_use_use        /* using the property name */
+  }
+svn_cl__prop_use_t;
+
 /* If PROPNAME looks like but is not identical to one of the svn:
  * poperties, raise an error and suggest a better spelling. Names that
  * raise errors look like this:
@@ -685,7 +723,9 @@ svn_cl__operation_str_human_readable(svn
  * Use SCRATCH_POOL for temporary allocations.
  */
 svn_error_t *
-svn_cl__check_svn_prop_name(const char *propname, svn_boolean_t revprop,
+svn_cl__check_svn_prop_name(const char *propname,
+                            svn_boolean_t revprop,
+                            svn_cl__prop_use_t prop_use,
                             apr_pool_t *scratch_pool);
 
 /* If PROPNAME is one of the svn: properties with a boolean value, and
@@ -809,6 +849,16 @@ svn_cl__propset_print_binary_mime_type_w
                                                const svn_string_t *propval,
                                                apr_pool_t *scratch_pool);
 
+/* A wrapper around the deprecated svn_client_merge_reintegrate. */
+svn_error_t *
+svn_cl__deprecated_merge_reintegrate(const char *source_path_or_url,
+                                     const svn_opt_revision_t *src_peg_revision,
+                                     const char *target_wcpath,
+                                     svn_boolean_t dry_run,
+                                     const apr_array_header_t *merge_options,
+                                     svn_client_ctx_t *ctx,
+                                     apr_pool_t *pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/verify-keep-going/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svn/conflict-callbacks.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/verify-keep-going/subversion/svn/conflict-callbacks.c Wed Jun  5 09:22:43 2013
@@ -34,6 +34,7 @@
 #include "svn_types.h"
 #include "svn_pools.h"
 #include "svn_sorts.h"
+#include "svn_utf.h"
 
 #include "cl.h"
 #include "cl-conflicts.h"
@@ -54,6 +55,8 @@ struct svn_cl__interactive_conflict_bato
   svn_cmdline_prompt_baton_t *pb;
   const char *path_prefix;
   svn_boolean_t quit;
+  svn_cl__conflict_stats_t *conflict_stats;
+  svn_boolean_t printed_summary;
 };
 
 svn_error_t *
@@ -62,6 +65,7 @@ svn_cl__get_conflict_func_interactive_ba
   svn_cl__accept_t accept_which,
   apr_hash_t *config,
   const char *editor_cmd,
+  svn_cl__conflict_stats_t *conflict_stats,
   svn_cancel_func_t cancel_func,
   void *cancel_baton,
   apr_pool_t *result_pool)
@@ -78,6 +82,8 @@ svn_cl__get_conflict_func_interactive_ba
   (*b)->pb = pb;
   SVN_ERR(svn_dirent_get_absolute(&(*b)->path_prefix, "", result_pool));
   (*b)->quit = FALSE;
+  (*b)->conflict_stats = conflict_stats;
+  (*b)->printed_summary = FALSE;
 
   return SVN_NO_ERROR;
 }
@@ -122,9 +128,11 @@ svn_cl__accept_from_word(const char *wor
  * corresponding to the conflict described in DESC. */
 static svn_error_t *
 show_diff(const svn_wc_conflict_description2_t *desc,
+          const char *path_prefix,
           apr_pool_t *pool)
 {
   const char *path1, *path2;
+  const char *label1, *label2;
   svn_diff_t *diff;
   svn_stream_t *output;
   svn_diff_file_options_t *options;
@@ -144,19 +152,35 @@ show_diff(const svn_wc_conflict_descript
        * This way, the diff is always minimal and clearly identifies changes
        * brought into the working copy by the update/switch/merge operation. */
       if (desc->operation == svn_wc_operation_merge)
-        path1 = desc->my_abspath;
+        {
+          path1 = desc->my_abspath;
+          label1 = _("MINE");
+        }
       else
-        path1 = desc->their_abspath;
+        {
+          path1 = desc->their_abspath;
+          label1 = _("THEIRS");
+        }
       path2 = desc->merged_file;
+      label2 = _("MERGED");
     }
   else
     {
       /* There's no merged file, but we can show the
          difference between mine and theirs. */
       path1 = desc->their_abspath;
+      label1 = _("THEIRS");
       path2 = desc->my_abspath;
+      label2 = _("MINE");
     }
 
+  label1 = apr_psprintf(pool, "%s\t- %s",
+                        svn_cl__local_style_skip_ancestor(
+                          path_prefix, path1, pool), label1);
+  label2 = apr_psprintf(pool, "%s\t- %s",
+                        svn_cl__local_style_skip_ancestor(
+                          path_prefix, path2, pool), label2);
+
   options = svn_diff_file_options_create(pool);
   options->ignore_eol_style = TRUE;
   SVN_ERR(svn_stream_for_stdout(&output, pool));
@@ -164,7 +188,7 @@ show_diff(const svn_wc_conflict_descript
                                options, pool));
   return svn_diff_file_output_unified3(output, diff,
                                        path1, path2,
-                                       NULL, NULL,
+                                       label1, label2,
                                        APR_LOCALE_CHARSET,
                                        NULL, FALSE,
                                        pool);
@@ -203,8 +227,85 @@ show_conflicts(const svn_wc_conflict_des
                                      pool);
 }
 
+/* Perform a 3-way merge of the conflicting values of a property,
+ * and write the result to the OUTPUT stream.
+ *
+ * If MERGED_ABSPATH is non-NULL, use it as 'my' version instead of
+ * DESC->MY_ABSPATH.
+ *
+ * Assume the values are printable UTF-8 text.
+ */
+static svn_error_t *
+merge_prop_conflict(svn_stream_t *output,
+                    const svn_wc_conflict_description2_t *desc,
+                    const char *merged_abspath,
+                    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;
+
+  /* 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_diff_file_diff3_2(&diff,
+                                base_abspath,
+                                merged_abspath ? merged_abspath : my_abspath,
+                                their_abspath,
+                                options, pool));
+  SVN_ERR(svn_diff_file_output_merge2(output, diff,
+                                      base_abspath,
+                                      merged_abspath ? merged_abspath
+                                                     : my_abspath,
+                                      their_abspath,
+                                      _("||||||| ORIGINAL"),
+                                      _("<<<<<<< MINE"),
+                                      _(">>>>>>> THEIRS"),
+                                      "=======",
+                                      svn_diff_conflict_display_modified_original_latest,
+                                      pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* Display the conflicting values of a property as a 3-way diff.
+ *
+ * If MERGED_ABSPATH is non-NULL, show it as 'my' version instead of
+ * DESC->MY_ABSPATH.
+ *
+ * Assume the values are printable UTF-8 text.
+ */
+static svn_error_t *
+show_prop_conflict(const svn_wc_conflict_description2_t *desc,
+                   const char *merged_abspath,
+                   apr_pool_t *pool)
+{
+  svn_stream_t *output;
+
+  SVN_ERR(svn_stream_for_stdout(&output, pool));
+  SVN_ERR(merge_prop_conflict(output, desc, merged_abspath, pool));
 
-/* Run an external editor, passing it the 'merged' file in DESC, or, if the
+  return SVN_NO_ERROR;
+}
+
+/* Run an external editor, passing it the MERGED_FILE, or, if the
  * 'merged' file is null, return an error. The tool to use is determined by
  * B->editor_cmd, B->config and environment variables; see
  * svn_cl__edit_file_externally() for details.
@@ -215,15 +316,15 @@ show_conflicts(const svn_wc_conflict_des
  * return that error. */
 static svn_error_t *
 open_editor(svn_boolean_t *performed_edit,
-            const svn_wc_conflict_description2_t *desc,
+            const char *merged_file,
             svn_cl__interactive_conflict_baton_t *b,
             apr_pool_t *pool)
 {
   svn_error_t *err;
 
-  if (desc->merged_file)
+  if (merged_file)
     {
-      err = svn_cmdline__edit_file_externally(desc->merged_file, b->editor_cmd,
+      err = svn_cmdline__edit_file_externally(merged_file, b->editor_cmd,
                                               b->config, pool);
       if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR))
         {
@@ -256,6 +357,34 @@ open_editor(svn_boolean_t *performed_edi
   return SVN_NO_ERROR;
 }
 
+/* Run an external editor, passing it the 'merged' property in DESC.
+ * The tool to use is determined by B->editor_cmd, B->config and
+ * environment variables; see svn_cl__edit_file_externally() for details. */
+static svn_error_t *
+edit_prop_conflict(const char **merged_file_path,
+                   const svn_wc_conflict_description2_t *desc,
+                   svn_cl__interactive_conflict_baton_t *b,
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
+{
+  apr_file_t *file;
+  const char *file_path;
+  svn_boolean_t performed_edit = FALSE;
+  svn_stream_t *merged_prop;
+
+  SVN_ERR(svn_io_open_unique_file3(&file, &file_path, NULL,
+                                   svn_io_file_del_on_pool_cleanup,
+                                   result_pool, scratch_pool));
+  merged_prop = svn_stream_from_aprfile2(file, TRUE /* disown */,
+                                         scratch_pool);
+  SVN_ERR(merge_prop_conflict(merged_prop, desc, NULL, scratch_pool));
+  SVN_ERR(svn_stream_close(merged_prop));
+  SVN_ERR(svn_io_file_flush(file, scratch_pool));
+  SVN_ERR(open_editor(&performed_edit, file_path, b, scratch_pool));
+  *merged_file_path = (performed_edit ? file_path : NULL);
+
+  return SVN_NO_ERROR;
+}
 
 /* Run an external merge tool, passing it the 'base', 'their', 'my' and
  * 'merged' files in DESC. The tool to use is determined by B->config and
@@ -309,7 +438,7 @@ launch_resolver(svn_boolean_t *performed
 typedef struct resolver_option_t
 {
   const char *code;        /* one or two characters */
-  const char *short_desc;  /* short description */
+  const char *short_desc;  /* label in prompt (localized) */
   const char *long_desc;   /* longer description (localized) */
   svn_wc_conflict_choice_t choice;  /* or -1 if not a simple choice */
 } resolver_option_t;
@@ -318,118 +447,146 @@ typedef struct resolver_option_t
 /* (opt->code == "" causes a blank line break in help_string()) */
 static const resolver_option_t text_conflict_options[] =
 {
-  { "e",  "edit",             N_("change merged file in an editor"), -1 },
-  { "df", "diff-full",        N_("show all changes made to merged file"), -1 },
-  { "r",  "resolved",         N_("accept merged version of file"),
-                              svn_wc_conflict_choose_merged },
-  { "",   "",                 "", svn_wc_conflict_choose_unspecified },
-  { "dc", "display-conflict", N_("show all conflicts (ignoring merged version)"), -1 },
-  { "mc", "mine-conflict",    N_("accept my version for all conflicts (same)"),
-                              svn_wc_conflict_choose_mine_conflict },
-  { "tc", "theirs-conflict",  N_("accept their version for all conflicts (same)"),
-                              svn_wc_conflict_choose_theirs_conflict },
-  { "",   "",                 "", svn_wc_conflict_choose_unspecified },
-  { "mf", "mine-full",        N_("accept my version of entire file (even "
-                                 "non-conflicts)"),
-                              svn_wc_conflict_choose_mine_full },
-  { "tf", "theirs-full",      N_("accept their version of entire file (same)"),
-                              svn_wc_conflict_choose_theirs_full },
-  { "",   "",                 "", svn_wc_conflict_choose_unspecified },
-  { "p",  "postpone",         N_("mark the conflict to be resolved later"),
-                              svn_wc_conflict_choose_postpone },
-  { "m",  "merge",            N_("use internal merge tool to resolve conflict"), -1 },
-  { "l",  "launch",           N_("launch external tool to resolve conflict"), -1 },
-  { "q",  "quit",             N_("postpone all remaining conflicts"),
-                              svn_wc_conflict_choose_postpone },
-  { "s",  "show all options", N_("show this list (also 'h', '?')"), -1 },
+  /* Translators: keep long_desc below 70 characters (wrap with a left
+     margin of 9 spaces if needed); don't translate the words within square
+     brackets. */
+  { "e",  N_("edit file"),        N_("change merged file in an editor"
+                                     "  [edit]"),
+                                  -1 },
+  { "df", N_("show diff"),        N_("show all changes made to merged file"),
+                                  -1 },
+  { "r",  N_("resolved"),         N_("accept merged version of file"),
+                                  svn_wc_conflict_choose_merged },
+  { "",   "",                     "", svn_wc_conflict_choose_unspecified },
+  { "dc", N_("display conflict"), N_("show all conflicts "
+                                     "(ignoring merged version)"), -1 },
+  { "mc", N_("my side of conflict"), N_("accept my version for all conflicts "
+                                        "(same)  [mine-conflict]"),
+                                  svn_wc_conflict_choose_mine_conflict },
+  { "tc", N_("their side of conflict"), N_("accept their version for all "
+                                           "conflicts (same)"
+                                           "  [theirs-conflict]"),
+                                  svn_wc_conflict_choose_theirs_conflict },
+  { "",   "",                     "", svn_wc_conflict_choose_unspecified },
+  { "mf", N_("my version"),       N_("accept my version of entire file (even "
+                                     "non-conflicts)  [mine-full]"),
+                                  svn_wc_conflict_choose_mine_full },
+  { "tf", N_("their version"),    N_("accept their version of entire file "
+                                     "(same)  [theirs-full]"),
+                                  svn_wc_conflict_choose_theirs_full },
+  { "",   "",                     "", svn_wc_conflict_choose_unspecified },
+  { "p",  N_("postpone"),         N_("mark the conflict to be resolved later"
+                                     "  [postpone]"),
+                                  svn_wc_conflict_choose_postpone },
+  { "m",  N_("merge"),            N_("use internal merge tool to resolve "
+                                     "conflict"), -1 },
+  { "l",  N_("launch tool"),      N_("launch external tool to resolve "
+                                     "conflict  [launch]"), -1 },
+  { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
+                                  svn_wc_conflict_choose_postpone },
+  { "s",  N_("show all options"), N_("show this list (also 'h', '?')"), -1 },
   { NULL }
 };
 
 /* Resolver options for a property conflict */
 static const resolver_option_t prop_conflict_options[] =
 {
-  { "p",  "postpone",         N_("mark the conflict to be resolved later"),
-                              svn_wc_conflict_choose_postpone },
-  { "mf", "mine-full",        N_("accept my version of entire file (even "
-                                "non-conflicts)"),
-                              svn_wc_conflict_choose_mine_full },
-  { "tf", "theirs-full",      N_("accept their version of entire file (same)"),
-                              svn_wc_conflict_choose_theirs_full },
-  { "q",  "quit",             N_("postpone all remaining conflicts"),
-                              svn_wc_conflict_choose_postpone },
-  { "h",  "help",             N_("show this help (also '?')"), -1 },
+  { "p",  N_("postpone"),         N_("mark the conflict to be resolved later"
+                                     "  [postpone]"),
+                                  svn_wc_conflict_choose_postpone },
+  { "mf", N_("my version"),       N_("accept my version of entire property (even "
+                                     "non-conflicts)  [mine-full]"),
+                                  svn_wc_conflict_choose_mine_full },
+  { "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 },
+  { "e",  N_("edit property"),    N_("change merged property value in an editor"
+                                     "  [edit]"), -1 },
+  { "r",  N_("resolved"),         N_("accept edited version of property"),
+                                  svn_wc_conflict_choose_merged },
+  { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
+                                  svn_wc_conflict_choose_postpone },
+  { "h",  N_("help"),             N_("show this help (also '?')"), -1 },
   { NULL }
 };
 
 /* Resolver options for an obstructued addition */
 static const resolver_option_t obstructed_add_options[] =
 {
-  { "p",  "postpone",         N_("resolve the conflict later"),
-                              svn_wc_conflict_choose_postpone },
-  { "mf", "mine-full",        N_("accept pre-existing item (ignore upstream addition)"),
-                              svn_wc_conflict_choose_mine_full },
-  { "tf", "theirs-full",      N_("accept incoming item (overwrite pre-existing item)"),
-                              svn_wc_conflict_choose_theirs_full },
-  { "q",  "quit",             N_("postpone all remaining conflicts"),
-                              svn_wc_conflict_choose_postpone },
-  { "h",  "help",             N_("show this help (also '?')"), -1 },
+  { "p",  N_("postpone"),         N_("mark the conflict to be resolved later"
+                                     "  [postpone]"),
+                                  svn_wc_conflict_choose_postpone },
+  { "mf", N_("my version"),       N_("accept pre-existing item (ignore "
+                                     "upstream addition)  [mine-full]"),
+                                  svn_wc_conflict_choose_mine_full },
+  { "tf", N_("their version"),    N_("accept incoming item (overwrite "
+                                     "pre-existing item)  [theirs-full]"),
+                                  svn_wc_conflict_choose_theirs_full },
+  { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
+                                  svn_wc_conflict_choose_postpone },
+  { "h",  N_("help"),             N_("show this help (also '?')"), -1 },
   { NULL }
 };
 
 /* Resolver options for a tree conflict */
 static const resolver_option_t tree_conflict_options[] =
 {
-  { "p",  "postpone",         N_("resolve the conflict later"),
-                              svn_wc_conflict_choose_postpone },
-  { "r",  "resolved",         N_("accept current working copy state"),
-                              svn_wc_conflict_choose_merged },
-  { "q",  "quit",             N_("postpone all remaining conflicts"),
-                              svn_wc_conflict_choose_postpone },
-  { "h",  "help",             N_("show this help (also '?')"), -1 },
+  { "p",  N_("postpone"),         N_("resolve the conflict later  [postpone]"),
+                                  svn_wc_conflict_choose_postpone },
+  { "r",  N_("resolved"),         N_("accept current working copy state"),
+                                  svn_wc_conflict_choose_merged },
+  { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
+                                  svn_wc_conflict_choose_postpone },
+  { "h",  N_("help"),             N_("show this help (also '?')"), -1 },
   { NULL }
 };
 
 static const resolver_option_t tree_conflict_options_update_moved_away[] =
 {
-  { "p",  "postpone",         N_("resolve the conflict later"),
-                              svn_wc_conflict_choose_postpone },
-  { "mc", "mine-conflict",    N_("apply update to the move destination"),
-                              svn_wc_conflict_choose_mine_conflict },
-  { "r",  "resolved",         N_("mark resolved (the move will become a copy)"),
-                              svn_wc_conflict_choose_merged },
-  { "q",  "quit",             N_("postpone all remaining conflicts"),
-                              svn_wc_conflict_choose_postpone },
-  { "h",  "help",             N_("show this help (also '?')"), -1 },
+  { "p",  N_("postpone"),         N_("resolve the conflict later  [postpone]"),
+                                  svn_wc_conflict_choose_postpone },
+  { "mc", N_("my side of conflict"), N_("apply update to the move destination"
+                                        "  [mine-conflict]"),
+                                  svn_wc_conflict_choose_mine_conflict },
+  { "r",  N_("resolved"),         N_("mark resolved "
+                                     "(the move will become a copy)"),
+                                  svn_wc_conflict_choose_merged },
+  { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
+                                  svn_wc_conflict_choose_postpone },
+  { "h",  N_("help"),             N_("show this help (also '?')"), -1 },
   { NULL }
 };
 
 static const resolver_option_t tree_conflict_options_update_deleted[] =
 {
-  { "p",  "postpone",         N_("resolve the conflict later"),
-                              svn_wc_conflict_choose_postpone },
-  { "mc", "mine-conflict",    N_("keep any moves affected by this deletion"),
-                              svn_wc_conflict_choose_mine_conflict },
-  { "r",  "resolved",         N_("mark resolved (any affected moves will "
-                                 "become copies)"),
-                              svn_wc_conflict_choose_merged },
-  { "q",  "quit",             N_("postpone all remaining conflicts"),
-                              svn_wc_conflict_choose_postpone },
-  { "h",  "help",             N_("show this help (also '?')"), -1 },
+  { "p",  N_("postpone"),         N_("resolve the conflict later  [postpone]"),
+                                  svn_wc_conflict_choose_postpone },
+  { "mc", N_("my side of conflict"), N_("keep any moves affected "
+                                        "by this deletion  [mine-conflict]"),
+                                  svn_wc_conflict_choose_mine_conflict },
+  { "r",  N_("resolved"),         N_("mark resolved (any affected moves will "
+                                     "become copies)"),
+                                  svn_wc_conflict_choose_merged },
+  { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
+                                  svn_wc_conflict_choose_postpone },
+  { "h",  N_("help"),             N_("show this help (also '?')"), -1 },
   { NULL }
 };
 
 static const resolver_option_t tree_conflict_options_update_replaced[] =
 {
-  { "p",  "postpone",         N_("resolve the conflict later"),
-                              svn_wc_conflict_choose_postpone },
-  { "mc", "mine-conflict",    N_("keep any moves affected by this replacement"),
-                              svn_wc_conflict_choose_mine_conflict },
-  { "r",  "resolved",         N_("mark resolved (any affected moves will "
-                                 "become copies)"),
-                              svn_wc_conflict_choose_merged },
-  { "q",  "quit",             N_("postpone all remaining conflicts"),
-                              svn_wc_conflict_choose_postpone },
-  { "h",  "help",             N_("show this help (also '?')"), -1 },
+  { "p",  N_("postpone"),         N_("resolve the conflict later  [postpone]"),
+                                  svn_wc_conflict_choose_postpone },
+  { "mc", N_("my side of conflict"), N_("keep any moves affected by this "
+                                        "replacement  [mine-conflict]"),
+                                  svn_wc_conflict_choose_mine_conflict },
+  { "r",  N_("resolved"),         N_("mark resolved (any affected moves will "
+                                     "become copies)"),
+                                  svn_wc_conflict_choose_merged },
+  { "q",  N_("quit resolution"),  N_("postpone all remaining conflicts"),
+                                  svn_wc_conflict_choose_postpone },
+  { "h",  N_("help"),             N_("show this help (also '?')"), -1 },
   { NULL }
 };
 
@@ -458,14 +615,17 @@ prompt_string(const resolver_option_t *o
               const char *const *option_codes,
               apr_pool_t *pool)
 {
-  const char *result = "Select:";
-  int this_line_len = strlen(result);
+  const char *result = _("Select:");
+  int left_margin = svn_utf_cstring_utf8_width(result);
+  const char *line_sep = apr_psprintf(pool, "\n%*s", left_margin, "");
+  int this_line_len = left_margin;
   svn_boolean_t first = TRUE;
 
   while (1)
     {
       const resolver_option_t *opt;
       const char *s;
+      int slen;
 
       if (option_codes)
         {
@@ -482,16 +642,17 @@ prompt_string(const resolver_option_t *o
 
       if (! first)
         result = apr_pstrcat(pool, result, ",", (char *)NULL);
+      s = apr_psprintf(pool, _(" (%s) %s"),
+                       opt->code, _(opt->short_desc));
+      slen = svn_utf_cstring_utf8_width(s);
       /* Break the line if adding the next option would make it too long */
-      if ((this_line_len + strlen(opt->short_desc) + 6) > MAX_PROMPT_WIDTH)
+      if (this_line_len + slen > MAX_PROMPT_WIDTH)
         {
-          result = apr_pstrcat(pool, result, "\n       ", (char *)NULL);
-          this_line_len = 7;
+          result = apr_pstrcat(pool, result, line_sep, (char *)NULL);
+          this_line_len = left_margin;
         }
-      s = apr_psprintf(pool, " (%s) %s",
-                       opt->code, opt->short_desc);
       result = apr_pstrcat(pool, result, s, (char *)NULL);
-      this_line_len += strlen(s);
+      this_line_len += slen;
       first = FALSE;
     }
   return apr_pstrcat(pool, result, ": ", (char *)NULL);
@@ -512,14 +673,18 @@ help_string(const resolver_option_t *opt
         {
           const char *s = apr_psprintf(pool, "  (%s)", opt->code);
 
-          result = apr_psprintf(pool, "%s%-6s %-16s - %s\n",
-                                result, s, opt->short_desc, opt->long_desc);
+          result = apr_psprintf(pool, "%s%-6s - %s\n",
+                                result, s, _(opt->long_desc));
         }
       else
         {
           result = apr_pstrcat(pool, result, "\n", (char *)NULL);
         }
     }
+  result = apr_pstrcat(pool, result,
+                       _("Words in square brackets are the corresponding "
+                         "--accept option arguments.\n"),
+                       (char *)NULL);
   return result;
 }
 
@@ -543,20 +708,22 @@ prompt_user(const resolver_option_t **op
   const char *answer;
 
   SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, prompt_baton, scratch_pool));
-  *opt = find_option(conflict_options, answer);
-
-  if (! *opt)
-    {
-      SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
-                                  _("Unrecognized option.\n\n")));
-    }
-  else if (strcmp(answer, "h") == 0 || strcmp(answer, "?") == 0)
+  if (strcmp(answer, "h") == 0 || strcmp(answer, "?") == 0)
     {
       SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "\n%s\n",
                                   help_string(conflict_options,
                                               scratch_pool)));
       *opt = NULL;
     }
+  else
+    {
+      *opt = find_option(conflict_options, answer);
+      if (! *opt)
+        {
+          SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+                                      _("Unrecognized option.\n\n")));
+        }
+    }
   return SVN_NO_ERROR;
 }
 
@@ -678,12 +845,12 @@ handle_text_conflict(svn_wc_conflict_res
               continue;
             }
 
-          SVN_ERR(show_diff(desc, iterpool));
+          SVN_ERR(show_diff(desc, b->path_prefix, iterpool));
           knows_something = TRUE;
         }
       else if (strcmp(opt->code, "e") == 0 || strcmp(opt->code, ":-E") == 0)
         {
-          SVN_ERR(open_editor(&performed_edit, desc, b, iterpool));
+          SVN_ERR(open_editor(&performed_edit, desc->merged_file, b, iterpool));
           if (performed_edit)
             knows_something = TRUE;
         }
@@ -783,9 +950,19 @@ static svn_error_t *
 handle_prop_conflict(svn_wc_conflict_result_t *result,
                      const svn_wc_conflict_description2_t *desc,
                      svn_cl__interactive_conflict_baton_t *b,
+                     apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
 {
   apr_pool_t *iterpool;
+  const char *message;
+  const char *merged_file_path = NULL;
+  svn_boolean_t resolved_allowed = FALSE;
+
+  /* ### 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);
 
@@ -797,41 +974,31 @@ 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)
     {
       const resolver_option_t *opt;
+      const char *options[ARRAY_LEN(prop_conflict_options)];
+      const char **next_option = options;
+
+      *next_option++ = "p";
+      *next_option++ = "mf";
+      *next_option++ = "tf";
+      *next_option++ = "dc";
+      *next_option++ = "e";
+      if (resolved_allowed)
+        *next_option++ = "r";
+      *next_option++ = "q";
+      *next_option++ = "h";
+      *next_option++ = NULL;
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(prompt_user(&opt, prop_conflict_options, NULL, b->pb,
+      SVN_ERR(prompt_user(&opt, prop_conflict_options, options, b->pb,
                           iterpool));
       if (! opt)
         continue;
@@ -843,6 +1010,30 @@ handle_prop_conflict(svn_wc_conflict_res
           b->quit = TRUE;
           break;
         }
+      else if (strcmp(opt->code, "dc") == 0)
+        {
+          SVN_ERR(show_prop_conflict(desc, merged_file_path, scratch_pool));
+        }
+      else if (strcmp(opt->code, "e") == 0)
+        {
+          SVN_ERR(edit_prop_conflict(&merged_file_path, desc, b,
+                                     result_pool, scratch_pool));
+          resolved_allowed = (merged_file_path != NULL);
+        }
+      else if (strcmp(opt->code, "r") == 0)
+        {
+          if (! resolved_allowed)
+            {
+              SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
+                             _("Invalid option; please edit the property "
+                               "first.\n\n")));
+              continue;
+            }
+
+          result->merged_file = merged_file_path;
+          result->choice = svn_wc_conflict_choose_merged;
+          break;
+        }
       else if (opt->choice != -1)
         {
           result->choice = opt->choice;
@@ -972,12 +1163,13 @@ handle_obstructed_add(svn_wc_conflict_re
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_cl__conflict_func_interactive(svn_wc_conflict_result_t **result,
-                                  const svn_wc_conflict_description2_t *desc,
-                                  void *baton,
-                                  apr_pool_t *result_pool,
-                                  apr_pool_t *scratch_pool)
+/* The body of svn_cl__conflict_func_interactive(). */
+static svn_error_t *
+conflict_func_interactive(svn_wc_conflict_result_t **result,
+                          const svn_wc_conflict_description2_t *desc,
+                          void *baton,
+                          apr_pool_t *result_pool,
+                          apr_pool_t *scratch_pool)
 {
   svn_cl__interactive_conflict_baton_t *b = baton;
   svn_error_t *err;
@@ -1105,6 +1297,13 @@ svn_cl__conflict_func_interactive(svn_wc
       break;
     }
 
+  /* Print a summary of conflicts before starting interactive resolution */
+  if (! b->printed_summary)
+    {
+      SVN_ERR(svn_cl__print_conflict_stats(b->conflict_stats, scratch_pool));
+      b->printed_summary = TRUE;
+    }
+
   /* We're in interactive mode and either the user gave no --accept
      option or the option did not apply; let's prompt. */
 
@@ -1113,12 +1312,12 @@ svn_cl__conflict_func_interactive(svn_wc
      Conflicting edits on a file's text, or
      Conflicting edits on a property.
   */
-  if (((desc->node_kind == svn_node_file)
+  if (((desc->kind == svn_wc_conflict_kind_text)
        && (desc->action == svn_wc_conflict_action_edit)
        && (desc->reason == svn_wc_conflict_reason_edited)))
     SVN_ERR(handle_text_conflict(*result, desc, b, scratch_pool));
   else if (desc->kind == svn_wc_conflict_kind_property)
-    SVN_ERR(handle_prop_conflict(*result, desc, b, scratch_pool));
+    SVN_ERR(handle_prop_conflict(*result, desc, b, result_pool, scratch_pool));
 
   /*
     Dealing with obstruction of additions can be tricky.  The
@@ -1152,3 +1351,28 @@ svn_cl__conflict_func_interactive(svn_wc
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_cl__conflict_func_interactive(svn_wc_conflict_result_t **result,
+                                  const svn_wc_conflict_description2_t *desc,
+                                  void *baton,
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool)
+{
+  svn_cl__interactive_conflict_baton_t *b = baton;
+
+  SVN_ERR(conflict_func_interactive(result, desc, baton,
+                                    result_pool, scratch_pool));
+
+  /* If we are resolving a conflict, adjust the summary of conflicts. */
+  if ((*result)->choice != svn_wc_conflict_choose_postpone)
+    {
+      const char *local_path
+        = svn_cl__local_style_skip_ancestor(
+            b->path_prefix, desc->local_abspath, scratch_pool);
+
+      svn_cl__conflict_stats_resolved(b->conflict_stats, local_path,
+                                      desc->kind);
+    }
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/verify-keep-going/subversion/svn/copy-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svn/copy-cmd.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svn/copy-cmd.c (original)
+++ subversion/branches/verify-keep-going/subversion/svn/copy-cmd.c Wed Jun  5 09:22:43 2013
@@ -73,7 +73,7 @@ svn_cl__copy(apr_getopt_t *os,
       if (err)
         {
           /* Issue #3606: 'svn cp .@HEAD target' gives
-             svn: '@HEAD' is just a peg revision. Maybe try '@HEAD@' instead? 
+             svn: '@HEAD' is just a peg revision. Maybe try '@HEAD@' instead?
 
              This is caused by a first round of canonicalization in
              svn_cl__args_to_target_array_print_reserved(). Undo that in an

Modified: subversion/branches/verify-keep-going/subversion/svn/diff-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svn/diff-cmd.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svn/diff-cmd.c (original)
+++ subversion/branches/verify-keep-going/subversion/svn/diff-cmd.c Wed Jun  5 09:22:43 2013
@@ -37,6 +37,7 @@
 #include "svn_types.h"
 #include "svn_cmdline.h"
 #include "svn_xml.h"
+#include "svn_hash.h"
 #include "cl.h"
 
 #include "svn_private_config.h"
@@ -179,6 +180,7 @@ svn_cl__diff(apr_getopt_t *os,
   const char *old_target, *new_target;
   apr_pool_t *iterpool;
   svn_boolean_t pegged_diff = FALSE;
+  svn_boolean_t ignore_content_type;
   svn_boolean_t show_copies_as_adds =
     opt_state->diff.patch_compatible || opt_state->diff.show_copies_as_adds;
   svn_boolean_t ignore_properties =
@@ -337,6 +339,21 @@ svn_cl__diff(apr_getopt_t *os,
 
     }
 
+  /* Should we ignore the content-type when deciding what to diff? */
+  if (opt_state->force)
+    {
+      ignore_content_type = TRUE;
+    }
+  else
+    {
+      SVN_ERR(svn_config_get_bool(svn_hash_gets(ctx->config,
+                                                SVN_CONFIG_CATEGORY_CONFIG),
+                                  &ignore_content_type,
+                                  SVN_CONFIG_SECTION_MISCELLANY,
+                                  SVN_CONFIG_OPTION_DIFF_IGNORE_CONTENT_TYPE,
+                                  FALSE));
+    }
+
   svn_opt_push_implicit_dot_target(targets, pool);
 
   iterpool = svn_pool_create(pool);
@@ -399,7 +416,7 @@ svn_cl__diff(apr_getopt_t *os,
                      opt_state->diff.no_diff_added,
                      opt_state->diff.no_diff_deleted,
                      show_copies_as_adds,
-                     opt_state->force,
+                     ignore_content_type,
                      ignore_properties,
                      opt_state->diff.properties_only,
                      opt_state->diff.use_git_diff_format,
@@ -450,7 +467,7 @@ svn_cl__diff(apr_getopt_t *os,
                      opt_state->diff.no_diff_added,
                      opt_state->diff.no_diff_deleted,
                      show_copies_as_adds,
-                     opt_state->force,
+                     ignore_content_type,
                      ignore_properties,
                      opt_state->diff.properties_only,
                      opt_state->diff.use_git_diff_format,

Modified: subversion/branches/verify-keep-going/subversion/svn/file-merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svn/file-merge.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svn/file-merge.c (original)
+++ subversion/branches/verify-keep-going/subversion/svn/file-merge.c Wed Jun  5 09:22:43 2013
@@ -57,7 +57,7 @@ struct file_merge_baton {
   apr_file_t *original_file;
   apr_file_t *modified_file;
   apr_file_t *latest_file;
-  
+
   /* Counters to keep track of the current line in each file. */
   svn_linenum_t current_line_original;
   svn_linenum_t current_line_modified;
@@ -307,7 +307,7 @@ static int
 get_term_width(void)
 {
   char *columns_env;
-#ifdef TIOCGWINSZ	
+#ifdef TIOCGWINSZ
   int fd;
 
   fd = open("/dev/tty", O_RDONLY, 0);
@@ -372,7 +372,7 @@ prepare_line_for_display(const char *lin
 
   /* Trim EOL. */
   if (buf->len >= 2 &&
-      buf->data[buf->len - 2] == '\r' && 
+      buf->data[buf->len - 2] == '\r' &&
       buf->data[buf->len - 1] == '\n')
     svn_stringbuf_chop(buf, 2);
   else if (buf->len >= 1 &&
@@ -490,7 +490,7 @@ edit_chunk(apr_array_header_t **merged_c
         return svn_error_create(SVN_ERR_IO_WRITE_ERROR, NULL,
                                 _("Could not write data to temporary file"));
     }
-  SVN_ERR(svn_io_file_flush_to_disk(temp_file, scratch_pool));
+  SVN_ERR(svn_io_file_flush(temp_file, scratch_pool));
 
   err = svn_cmdline__edit_file_externally(temp_file_name, editor_cmd,
                                           config, scratch_pool);
@@ -591,7 +591,7 @@ merge_chunks(apr_array_header_t **merged
                                                   : chunk2->nelts;
   *abort_merge = FALSE;
 
-  /* 
+  /*
    * Prepare the selection prompt.
    */
 
@@ -645,7 +645,7 @@ merge_chunks(apr_array_header_t **merged
         }
       else
         line2 = prepare_line_for_display("", iterpool);
-        
+
       prompt_line = apr_psprintf(iterpool, "%s|%s\n", line1, line2);
 
       svn_stringbuf_appendcstr(prompt, prompt_line);
@@ -853,13 +853,20 @@ svn_cl__merge_file(const char *base_path
   const char *merged_file_name;
   struct file_merge_baton fmb;
   svn_boolean_t executable;
+  const char *merged_path_local_style;
+  const char *merged_rel_path;
+  const char *wc_path_local_style;
+  const char *wc_rel_path = svn_dirent_skip_ancestor(path_prefix, wc_path);
+
+  /* PATH_PREFIX may not be an ancestor of WC_PATH, just use the
+     full WC_PATH in that case. */
+  if (wc_rel_path)
+    wc_path_local_style = svn_dirent_local_style(wc_rel_path, scratch_pool);
+  else
+    wc_path_local_style = svn_dirent_local_style(wc_path, scratch_pool);
 
-
-  SVN_ERR(svn_cmdline_printf(
-            scratch_pool, _("Merging '%s'.\n"),
-            svn_dirent_local_style(svn_dirent_skip_ancestor(path_prefix,
-                                                            wc_path),
-                                   scratch_pool)));
+  SVN_ERR(svn_cmdline_printf(scratch_pool, _("Merging '%s'.\n"),
+                             wc_path_local_style));
 
   SVN_ERR(svn_io_file_open(&original_file, base_path,
                            APR_READ | APR_BUFFERED,
@@ -905,29 +912,30 @@ svn_cl__merge_file(const char *base_path
   if (fmb.abort_merge)
     {
       SVN_ERR(svn_io_remove_file2(merged_file_name, TRUE, scratch_pool));
-      SVN_ERR(svn_cmdline_printf(
-                scratch_pool, _("Merge of '%s' aborted.\n"),
-                svn_dirent_local_style(svn_dirent_skip_ancestor(path_prefix,
-                                                                wc_path),
-                                       scratch_pool)));
-                
+      SVN_ERR(svn_cmdline_printf(scratch_pool, _("Merge of '%s' aborted.\n"),
+                                 wc_path_local_style));
       return SVN_NO_ERROR;
     }
 
   SVN_ERR(svn_io_is_file_executable(&executable, merged_path, scratch_pool));
+
+  merged_rel_path = svn_dirent_skip_ancestor(path_prefix, merged_path);
+  if (merged_rel_path)
+    merged_path_local_style = svn_dirent_local_style(merged_rel_path,
+                                                     scratch_pool);
+  else
+    merged_path_local_style = svn_dirent_local_style(merged_path,
+                                                     scratch_pool);
+
   SVN_ERR_W(svn_io_copy_file(merged_file_name, merged_path, FALSE,
                              scratch_pool),
             apr_psprintf(scratch_pool,
                          _("Could not write merged result to '%s', saved "
                            "instead at '%s'.\n'%s' remains in conflict.\n"),
-                         svn_dirent_local_style(
-                           svn_dirent_skip_ancestor(path_prefix, merged_path),
-                           scratch_pool),
+                         merged_path_local_style,
                          svn_dirent_local_style(merged_file_name,
                                                 scratch_pool),
-                         svn_dirent_local_style(
-                           svn_dirent_skip_ancestor(path_prefix, wc_path),
-                           scratch_pool)));
+                         wc_path_local_style));
   SVN_ERR(svn_io_set_file_executable(merged_path, executable, FALSE,
                                      scratch_pool));
   SVN_ERR(svn_io_remove_file2(merged_file_name, TRUE, scratch_pool));
@@ -941,15 +949,11 @@ svn_cl__merge_file(const char *base_path
     SVN_ERR(svn_cmdline_printf(
               scratch_pool,
               _("Merge of '%s' completed (remains in conflict).\n"),
-              svn_dirent_local_style(svn_dirent_skip_ancestor(path_prefix,
-                                                              wc_path),
-                                     scratch_pool)));
+              wc_path_local_style));
   else
     SVN_ERR(svn_cmdline_printf(
               scratch_pool, _("Merge of '%s' completed.\n"),
-              svn_dirent_local_style(svn_dirent_skip_ancestor(path_prefix,
-                                                              wc_path),
-                                     scratch_pool)));
-                
+              wc_path_local_style));
+
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/verify-keep-going/subversion/svn/info-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svn/info-cmd.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svn/info-cmd.c (original)
+++ subversion/branches/verify-keep-going/subversion/svn/info-cmd.c Wed Jun  5 09:22:43 2013
@@ -438,6 +438,7 @@ print_info(void *baton,
 
       if (info->wc_info->conflicts)
         {
+          svn_boolean_t printed_prop_conflict_file = FALSE;
           int i;
 
           for (i = 0; i < info->wc_info->conflicts->nelts; i++)
@@ -473,10 +474,12 @@ print_info(void *baton,
                   break;
 
                   case svn_wc_conflict_kind_property:
-                    SVN_ERR(svn_cmdline_printf(pool,
-                              _("Conflict Properties File: %s\n"),
-                              svn_dirent_local_style(conflict->their_abspath,
-                                                     pool)));
+                    if (! printed_prop_conflict_file)
+                      SVN_ERR(svn_cmdline_printf(pool,
+                                _("Conflict Properties File: %s\n"),
+                                svn_dirent_local_style(conflict->their_abspath,
+                                                       pool)));
+                    printed_prop_conflict_file = TRUE;
                   break;
 
                   case svn_wc_conflict_kind_tree:

Modified: subversion/branches/verify-keep-going/subversion/svn/list-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svn/list-cmd.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svn/list-cmd.c (original)
+++ subversion/branches/verify-keep-going/subversion/svn/list-cmd.c Wed Jun  5 09:22:43 2013
@@ -42,7 +42,7 @@
 struct print_baton {
   svn_boolean_t verbose;
   svn_client_ctx_t *ctx;
-  
+
   /* To keep track of last seen external information. */
   const char *last_external_parent_url;
   const char *last_external_target;
@@ -89,17 +89,17 @@ print_dirent(void *baton,
     }
   else
     entryname = path;
-  
+
   if (external_parent_url && external_target)
     {
-      if ((pb->last_external_parent_url == NULL 
-           && pb->last_external_target == NULL) 
+      if ((pb->last_external_parent_url == NULL
+           && pb->last_external_target == NULL)
           || (strcmp(pb->last_external_parent_url, external_parent_url) != 0
               || strcmp(pb->last_external_target, external_target) != 0))
         {
           SVN_ERR(svn_cmdline_printf(scratch_pool,
                                      _("Listing external '%s'"
-                                       " defined on '%s':\n"), 
+                                       " defined on '%s':\n"),
                                      external_target,
                                      external_parent_url));
 
@@ -140,7 +140,7 @@ print_dirent(void *baton,
       /* we need it in UTF-8. */
       SVN_ERR(svn_utf_cstring_to_utf8(&utf8_timestr, timestr, scratch_pool));
 
-      sizestr = apr_psprintf(scratch_pool, "%" SVN_FILESIZE_T_FMT, 
+      sizestr = apr_psprintf(scratch_pool, "%" SVN_FILESIZE_T_FMT,
                              dirent->size);
 
       return svn_cmdline_printf
@@ -177,7 +177,7 @@ print_dirent_xml(void *baton,
   struct print_baton *pb = baton;
   const char *entryname;
   svn_stringbuf_t *sb = svn_stringbuf_create_empty(scratch_pool);
-  
+
   SVN_ERR_ASSERT((external_parent_url == NULL && external_target == NULL) ||
                  (external_parent_url && external_target));
 
@@ -194,10 +194,10 @@ print_dirent_xml(void *baton,
 
   if (pb->ctx->cancel_func)
     SVN_ERR(pb->ctx->cancel_func(pb->ctx->cancel_baton));
-  
+
   if (external_parent_url && external_target)
     {
-      if ((pb->last_external_parent_url == NULL 
+      if ((pb->last_external_parent_url == NULL
            && pb->last_external_target == NULL)
           || (strcmp(pb->last_external_parent_url, external_parent_url) != 0
               || strcmp(pb->last_external_target, external_target) != 0))
@@ -339,8 +339,8 @@ svn_cl__list(apr_getopt_t *os,
       const char *target = APR_ARRAY_IDX(targets, i, const char *);
       const char *truepath;
       svn_opt_revision_t peg_revision;
-      
-      /* Initialize the following variables for 
+
+      /* Initialize the following variables for
          every list target. */
       pb.last_external_parent_url = NULL;
       pb.last_external_target = NULL;
@@ -390,10 +390,10 @@ svn_cl__list(apr_getopt_t *os,
       if (opt_state->xml)
         {
           svn_stringbuf_t *sb = svn_stringbuf_create_empty(pool);
-          
+
           if (pb.in_external)
             {
-              /* close the final external item's tag */ 
+              /* close the final external item's tag */
               svn_xml_make_close_tag(&sb, pool, "external");
               pb.in_external = FALSE;
             }
@@ -404,7 +404,7 @@ svn_cl__list(apr_getopt_t *os,
     }
 
   svn_pool_destroy(subpool);
-  
+
   if (opt_state->include_externals && nwb.had_externals_error)
     {
       externals_err = svn_error_create(SVN_ERR_CL_ERROR_PROCESSING_EXTERNALS,

Modified: subversion/branches/verify-keep-going/subversion/svn/log-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svn/log-cmd.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svn/log-cmd.c (original)
+++ subversion/branches/verify-keep-going/subversion/svn/log-cmd.c Wed Jun  5 09:22:43 2013
@@ -159,7 +159,7 @@ match_search_pattern(const char *search_
 {
   /* Match any substring containing the pattern, like UNIX 'grep' does. */
   const char *pattern = apr_psprintf(pool, "*%s*", search_pattern);
-  int flags = APR_FNM_CASE_BLIND;
+  int flags = 0;
 
   /* Does the author match the search pattern? */
   if (author && apr_fnmatch(pattern, author, flags) == APR_SUCCESS)
@@ -229,7 +229,7 @@ match_search_patterns(apr_array_header_t
           const char *pattern;
 
           svn_pool_clear(iterpool);
-          
+
           pattern = APR_ARRAY_IDX(pattern_group, j, const char *);
           match = match_search_pattern(pattern, author, date, message,
                                        changed_paths, iterpool);

Modified: subversion/branches/verify-keep-going/subversion/svn/merge-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svn/merge-cmd.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svn/merge-cmd.c (original)
+++ subversion/branches/verify-keep-going/subversion/svn/merge-cmd.c Wed Jun  5 09:22:43 2013
@@ -88,7 +88,7 @@ run_merge(svn_boolean_t two_sources_spec
 
   if (opt_state->reintegrate)
     {
-      merge_err = svn_client_merge_reintegrate(
+      merge_err = svn_cl__deprecated_merge_reintegrate(
                     sourcepath1, &peg_revision1, targetpath,
                     opt_state->dry_run, options, ctx, scratch_pool);
     }
@@ -350,7 +350,7 @@ svn_cl__merge(apr_getopt_t *os,
   /* If no targetpath was specified, see if we can infer it from the
      sourcepaths. */
   if (! has_explicit_target
-      && sourcepath1 && sourcepath2 
+      && sourcepath1 && sourcepath2
       && strcmp(targetpath, "") == 0)
     {
       /* If the sourcepath is a URL, it can only refer to a target in

Modified: subversion/branches/verify-keep-going/subversion/svn/mergeinfo-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svn/mergeinfo-cmd.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svn/mergeinfo-cmd.c (original)
+++ subversion/branches/verify-keep-going/subversion/svn/mergeinfo-cmd.c Wed Jun  5 09:22:43 2013
@@ -211,41 +211,28 @@ mergeinfo_summary(
                   svn_client_ctx_t *ctx,
                   apr_pool_t *pool)
 {
-  svn_client_automatic_merge_t *the_merge;
   const char *yca_url, *base_url, *right_url, *target_url;
   svn_revnum_t yca_rev, base_rev, right_rev, target_rev;
   const char *repos_root_url;
-  svn_boolean_t target_is_wc, reintegrate_like;
+  svn_boolean_t target_is_wc, is_reintegration;
 
   target_is_wc = (! svn_path_is_url(target_path_or_url))
                  && (target_revision->kind == svn_opt_revision_unspecified
                      || target_revision->kind == svn_opt_revision_working);
-  if (target_is_wc)
-    SVN_ERR(svn_client_find_automatic_merge(
-              &the_merge,
-              source_path_or_url, source_revision,
-              target_path_or_url,
-              TRUE, TRUE, TRUE,  /* allow_* */
-              ctx, pool, pool));
-  else
-    SVN_ERR(svn_client_find_automatic_merge_no_wc(
-              &the_merge,
-              source_path_or_url, source_revision,
-              target_path_or_url, target_revision,
-              ctx, pool, pool));
-
-  SVN_ERR(svn_client_automatic_merge_get_locations(
+  SVN_ERR(svn_client_get_merging_summary(
+            &is_reintegration,
             &yca_url, &yca_rev,
             &base_url, &base_rev,
             &right_url, &right_rev,
             &target_url, &target_rev,
             &repos_root_url,
-            the_merge, pool));
-  reintegrate_like = svn_client_automatic_merge_is_reintegrate_like(the_merge);
+            source_path_or_url, source_revision,
+            target_path_or_url, target_revision,
+            ctx, pool, pool));
 
   SVN_ERR(mergeinfo_diagram(yca_url, base_url, right_url, target_url,
                             yca_rev, base_rev, right_rev, target_rev,
-                            repos_root_url, target_is_wc, reintegrate_like,
+                            repos_root_url, target_is_wc, is_reintegration,
                             pool));
 
   return SVN_NO_ERROR;
@@ -262,6 +249,7 @@ svn_cl__mergeinfo(apr_getopt_t *os,
   apr_array_header_t *targets;
   const char *source, *target;
   svn_opt_revision_t src_peg_revision, tgt_peg_revision;
+  svn_opt_revision_t *src_start_revision, *src_end_revision;
   /* Default to depth empty. */
   svn_depth_t depth = (opt_state->depth == svn_depth_unknown)
                       ? svn_depth_empty : opt_state->depth;
@@ -314,13 +302,19 @@ svn_cl__mergeinfo(apr_getopt_t *os,
                                                     ctx, pool),
             _("Source and target must be different but related branches"));
 
+  src_start_revision = &(opt_state->start_revision);
+  if (opt_state->end_revision.kind == svn_opt_revision_unspecified)
+    src_end_revision = src_start_revision;
+  else
+    src_end_revision = &(opt_state->end_revision);
+
   /* Do the real work, depending on the requested data flavor. */
   if (opt_state->show_revs == svn_cl__show_revs_merged)
     {
       SVN_ERR(svn_client_mergeinfo_log2(TRUE, target, &tgt_peg_revision,
                                         source, &src_peg_revision,
-                                        &(opt_state->start_revision),
-                                        &(opt_state->end_revision),
+                                        src_start_revision,
+                                        src_end_revision,
                                         print_log_rev, NULL,
                                         TRUE, depth, NULL, ctx,
                                         pool));
@@ -329,14 +323,24 @@ svn_cl__mergeinfo(apr_getopt_t *os,
     {
       SVN_ERR(svn_client_mergeinfo_log2(FALSE, target, &tgt_peg_revision,
                                         source, &src_peg_revision,
-                                        &(opt_state->start_revision),
-                                        &(opt_state->end_revision),
+                                        src_start_revision,
+                                        src_end_revision,
                                         print_log_rev, NULL,
                                         TRUE, depth, NULL, ctx,
                                         pool));
     }
   else
     {
+      if ((opt_state->start_revision.kind != svn_opt_revision_unspecified)
+          || (opt_state->end_revision.kind != svn_opt_revision_unspecified))
+        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                _("--revision (-r) option valid only with "
+                                  "--show-revs option"));
+      if (opt_state->depth != svn_depth_unknown)
+        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                _("Depth specification options valid only "
+                                  "with --show-revs option"));
+
       SVN_ERR(mergeinfo_summary(source, &src_peg_revision,
                                 target, &tgt_peg_revision,
                                 ctx, pool));