subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hwri...@apache.org
Subject svn commit: r1449262 [17/25] - in /subversion/branches/ev2-export: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ build/win32/ contrib/server-side/fsfsfixer/fixer/ contrib/server-side/svncutter/ notes/ note...
Date Sat, 23 Feb 2013 01:25:44 GMT
Modified: subversion/branches/ev2-export/subversion/svn/blame-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/blame-cmd.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/blame-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/blame-cmd.c Sat Feb 23 01:25:38 2013
@@ -375,10 +375,13 @@ svn_cl__blame(apr_getopt_t *os,
             {
               svn_error_clear(err);
               SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
-                                          _("Skipping binary file: '%s'\n"),
+                                          _("Skipping binary file "
+                                            "(use --force to treat as text): "
+                                            "'%s'\n"),
                                           target));
             }
           else if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND ||
+                   err->apr_err == SVN_ERR_ENTRY_NOT_FOUND ||
                    err->apr_err == SVN_ERR_FS_NOT_FILE ||
                    err->apr_err == SVN_ERR_FS_NOT_FOUND)
             {

Modified: subversion/branches/ev2-export/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/cl.h?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/cl.h (original)
+++ subversion/branches/ev2-export/subversion/svn/cl.h Sat Feb 23 01:25:38 2013
@@ -355,13 +355,18 @@ svn_cl__conflict_func_interactive(svn_wc
                                   apr_pool_t *result_pool,
                                   apr_pool_t *scratch_pool);
 
-/* Create an return a baton for use with svn_cl__conflict_func_postpone(),
- * allocated in RESULT_POOL. */
+/* Create and return a baton for use with svn_cl__conflict_func_postpone()
+ * and svn_cl__resolve_postponed_conflicts(), allocated in RESULT_POOL.
+ */
 void *
 svn_cl__get_conflict_func_postpone_baton(apr_pool_t *result_pool);
 
 /* A conflict-resolution callback which postpones all conflicts and
- * remembers conflicted paths in BATON. */
+ * remembers conflicted paths in BATON.  BATON must have been obtained
+ * from svn_cl__get_conflict_func_postpone_baton().
+ *
+ * Implements svn_wc_conflict_resolver_func2_t.
+ */
 svn_error_t *
 svn_cl__conflict_func_postpone(svn_wc_conflict_result_t **result,
                                const svn_wc_conflict_description2_t *desc,
@@ -369,12 +374,20 @@ svn_cl__conflict_func_postpone(svn_wc_co
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool);
 
-/* Run the interactive conflict resolver, obtained internally from
- * svn_cl__get_conflict_func_interactive(), on any conflicted paths
- * stored in the BATON obtained from svn_cl__get_conflict_func_postpone(). */
+/* Perform conflict resolution on any conflicted paths stored in the BATON
+ * which was obtained from svn_cl__get_conflict_func_postpone_baton().
+ *
+ * If CONFLICTS_ALL_RESOLVED is not null, set *CONFLICTS_ALL_RESOLVED to
+ * true if this resolves all the conflicts on the paths that were
+ * recorded (or if none were recorded); or to false if some conflicts
+ * remain.
+ *
+ * The conflict resolution will be interactive if ACCEPT_WHICH is
+ * svn_cl__accept_unspecified.
+ */
 svn_error_t *
-svn_cl__resolve_postponed_conflicts(void *baton,
-                                    svn_depth_t depth,
+svn_cl__resolve_postponed_conflicts(svn_boolean_t *conflicts_all_resolved,
+                                    void *baton,
                                     svn_cl__accept_t accept_which,
                                     const char *editor_cmd,
                                     svn_client_ctx_t *ctx,
@@ -570,13 +583,20 @@ svn_cl__check_externals_failed_notify_wr
                                               const svn_wc_notify_t *n,
                                               apr_pool_t *pool);
 
-/* Print conflict stats accumulated in NOTIFY_BATON.
+/* 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().
  * Return any error encountered during printing.
- * Do all allocations in POOL.*/
+ */
 svn_error_t *
-svn_cl__print_conflict_stats(void *notify_baton, apr_pool_t *pool);
+svn_cl__notifier_print_conflict_stats(void *baton, apr_pool_t *scratch_pool);
+
 
-
 /*** Log message callback stuffs. ***/
 
 /* Allocate in POOL a baton for use with svn_cl__get_log_message().
@@ -809,6 +829,18 @@ svn_cl__check_related_source_and_target(
                                         svn_client_ctx_t *ctx,
                                         apr_pool_t *pool);
 
+/* If the user is setting a mime-type to mark one of the TARGETS as binary,
+ * as determined by property name PROPNAME and value PROPVAL, then check
+ * whether Subversion's own binary-file detection recognizes the target as
+ * a binary file. If Subversion doesn't consider the target to be a binary
+ * file, assume the user is making an error and print a warning to inform
+ * the user that some operations might fail on the file in the future. */
+svn_error_t *
+svn_cl__propset_print_binary_mime_type_warning(apr_array_header_t *targets,
+                                               const char *propname,
+                                               const svn_string_t *propval,
+                                               apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/ev2-export/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/conflict-callbacks.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/ev2-export/subversion/svn/conflict-callbacks.c Sat Feb 23 01:25:38 2013
@@ -24,7 +24,6 @@
 
 #include <apr_xlate.h>  /* for APR_LOCALE_CHARSET */
 
-#define APR_WANT_STDIO
 #define APR_WANT_STRFUNC
 #include <apr_want.h>
 
@@ -53,6 +52,7 @@ struct svn_cl__interactive_conflict_bato
   svn_boolean_t external_failed;
   svn_cmdline_prompt_baton_t *pb;
   const char *path_prefix;
+  svn_boolean_t quit;
 };
 
 svn_error_t *
@@ -76,6 +76,7 @@ svn_cl__get_conflict_func_interactive_ba
   (*b)->external_failed = FALSE;
   (*b)->pb = pb;
   SVN_ERR(svn_dirent_get_absolute(&(*b)->path_prefix, "", result_pool));
+  (*b)->quit = FALSE;
 
   return SVN_NO_ERROR;
 }
@@ -116,8 +117,8 @@ svn_cl__accept_from_word(const char *wor
 }
 
 
-/* Print on stdout a diff between the 'base' and 'merged' files, if both of
- * those are available, else between 'their' and 'my' files, of DESC. */
+/* Print on stdout a diff that shows incoming conflicting changes
+ * corresponding to the conflict described in DESC. */
 static svn_error_t *
 show_diff(const svn_wc_conflict_description2_t *desc,
           apr_pool_t *pool)
@@ -127,15 +128,29 @@ show_diff(const svn_wc_conflict_descript
   svn_stream_t *output;
   svn_diff_file_options_t *options;
 
-  if (desc->merged_file && desc->base_abspath)
+  if (desc->merged_file)
     {
-      /* Show the conflict markers to the user */
-      path1 = desc->base_abspath;
+      /* For conflicts recorded by the 'merge' operation, show a diff between
+       * 'mine' (the working version of the file as it appeared before the
+       * 'merge' operation was run) and 'merged' (the version of the file
+       * as it appears after the merge operation).
+       *
+       * For conflicts recorded by the 'update' and 'switch' operations,
+       * show a diff beween 'theirs' (the new pristine version of the
+       * file) and 'merged' (the version of the file as it appears with
+       * local changes merged with the new pristine version).
+       *
+       * 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;
+      else
+        path1 = desc->their_abspath;
       path2 = desc->merged_file;
     }
   else
     {
-      /* There's no base file, but we can show the
+      /* There's no merged file, but we can show the
          difference between mine and theirs. */
       path1 = desc->their_abspath;
       path2 = desc->my_abspath;
@@ -294,59 +309,101 @@ typedef struct resolver_option_t
 {
   const char *code;        /* one or two characters */
   const char *short_desc;  /* short description */
-  const char *long_desc;   /* longer description */
+  const char *long_desc;   /* longer description (localized) */
+  svn_wc_conflict_choice_t choice;  /* or -1 if not a simple choice */
 } resolver_option_t;
 
 /* Resolver options for a text conflict */
+/* (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") },
-  { "df", "diff-full",        N_("show all changes made to merged file") },
-  { "r",  "resolved",         N_("accept merged version of file") },
+  { "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 },
   { "" },
-  { "dc", "display-conflict", N_("show all conflicts (ignoring merged version)") },
-  { "mc", "mine-conflict",    N_("accept my version for all conflicts (same)") },
-  { "tc", "theirs-conflict",  N_("accept their version for all conflicts (same)") },
+  { "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 },
   { "" },
   { "mf", "mine-full",        N_("accept my version of entire file (even "
-                                 "non-conflicts)") },
-  { "tf", "theirs-full",      N_("accept their version of entire file (same)") },
+                                 "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 },
   { "" },
-  { "p",  "postpone",         N_("mark the conflict to be resolved later") },
-  { "m",  "merge",            N_("use internal merge tool to resolve conflict") },
-  { "l",  "launch",           N_("launch external tool to resolve conflict") },
-  { "s",  "show all options", N_("show this list") },
+  { "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 },
   { 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") },
+  { "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)") },
-  { "tf", "theirs-full",      N_("accept their version of entire file (same)") },
+                                "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 },
   { NULL }
 };
 
 /* Resolver options for an obstructued addition */
 static const resolver_option_t obstructed_add_options[] =
 {
-  { "p",  "postpone",         N_("resolve the conflict later") },
-  { "mf", "mine-full",        N_("accept pre-existing item (ignore upstream addition)") },
-  { "tf", "theirs-full",      N_("accept incoming item (overwrite pre-existing item)") },
-  { "h",  "help",             N_("show this help") },
+  { "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 },
   { NULL }
 };
 
 /* Resolver options for a tree conflict */
 static const resolver_option_t tree_conflict_options[] =
 {
-  { "p",  "postpone",         N_("resolve the conflict later") },
-  { "r",  "resolved",         N_("accept current working copy state") },
-  { "mc", "mine-conflict",    N_("prefer local change") },
-  { "tc", "theirs-conflict",  N_("prefer incoming change") },
-  { "h",  "show help",        N_("show this help") },
+  { "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 },
+  { "mc", "mine-conflict",    N_("prefer local change"),
+                              svn_wc_conflict_choose_mine_conflict },
+  { "tc", "theirs-conflict",  N_("prefer incoming change"),
+                              svn_wc_conflict_choose_theirs_conflict },
+  { "q",  "quit",             N_("postpone all remaining conflicts"),
+                              svn_wc_conflict_choose_postpone },
+  { "h",  "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 the update to the move destination"),
+                              svn_wc_conflict_choose_mine_conflict },
+  { "tc", "theirs-conflict",  N_("break the move, change move destination into "
+                                 "a copy"),
+                              svn_wc_conflict_choose_theirs_conflict },
+  { "q",  "quit",             N_("postpone all remaining conflicts"),
+                              svn_wc_conflict_choose_postpone },
+  { "h",  "help",             N_("show this help (also '?')"), -1 },
   { NULL }
 };
 
@@ -438,6 +495,42 @@ help_string(const resolver_option_t *opt
   return result;
 }
 
+/* Prompt the user with CONFLICT_OPTIONS, restricted to the options listed
+ * in OPTIONS_TO_SHOW if that is non-null.  Set *OPT to point to the chosen
+ * one of CONFLICT_OPTIONS (not necessarily one of OPTIONS_TO_SHOW), or to
+ * NULL if the answer was not one of them.
+ *
+ * If the answer is the (globally recognized) 'help' option, then display
+ * the help (on stderr) and return with *OPT == NULL.
+ */
+static svn_error_t *
+prompt_user(const resolver_option_t **opt,
+            const resolver_option_t *conflict_options,
+            const char *const *options_to_show,
+            void *prompt_baton,
+            apr_pool_t *scratch_pool)
+{
+  const char *prompt
+    = prompt_string(conflict_options, options_to_show, scratch_pool);
+  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)
+    {
+      SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "\n%s\n",
+                                  help_string(conflict_options,
+                                              scratch_pool)));
+      *opt = NULL;
+    }
+  return SVN_NO_ERROR;
+}
 
 /* Ask the user what to do about the text conflict described by DESC.
  * Return the answer in RESULT. B is the conflict baton for this
@@ -478,8 +571,7 @@ handle_text_conflict(svn_wc_conflict_res
     {
       const char *options[ARRAY_LEN(text_conflict_options)];
       const char **next_option = options;
-      const char *prompt;
-      const char *answer;
+      const resolver_option_t *opt;
 
       svn_pool_clear(iterpool);
 
@@ -508,67 +600,26 @@ handle_text_conflict(svn_wc_conflict_res
         }
       *next_option++ = "s";
       *next_option++ = NULL;
-      prompt = prompt_string(text_conflict_options, options, iterpool);
-
-      SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, b->pb, iterpool));
 
-      if (strcmp(answer, "s") == 0)
+      SVN_ERR(prompt_user(&opt, text_conflict_options, options, b->pb,
+                          iterpool));
+      if (! opt)
+        continue;
+
+      if (strcmp(opt->code, "q") == 0)
+        {
+          result->choice = opt->choice;
+          b->accept_which = svn_cl__accept_postpone;
+          b->quit = TRUE;
+          break;
+        }
+      else if (strcmp(opt->code, "s") == 0)
         {
           SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "\n%s\n",
                                       help_string(text_conflict_options,
                                                   iterpool)));
         }
-      else if (strcmp(answer, "p") == 0 || strcmp(answer, ":-P") == 0)
-        {
-          /* Do nothing, let file be marked conflicted. */
-          result->choice = svn_wc_conflict_choose_postpone;
-          break;
-        }
-      else if (strcmp(answer, "mc") == 0 || strcmp(answer, "X-)") == 0)
-        {
-          if (desc->is_binary)
-            {
-              SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
-                                          _("Invalid option; cannot choose "
-                                            "based on conflicts in a "
-                                            "binary file.\n\n")));
-              continue;
-            }
-          result->choice = svn_wc_conflict_choose_mine_conflict;
-          if (performed_edit)
-            result->save_merged = TRUE;
-          break;
-        }
-      else if (strcmp(answer, "tc") == 0 || strcmp(answer, "X-(") == 0)
-        {
-          if (desc->is_binary)
-            {
-              SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
-                                          _("Invalid option; cannot choose "
-                                            "based on conflicts in a "
-                                            "binary file.\n\n")));
-              continue;
-            }
-          result->choice = svn_wc_conflict_choose_theirs_conflict;
-          if (performed_edit)
-            result->save_merged = TRUE;
-          break;
-        }
-      else if (strcmp(answer, "mf") == 0 || strcmp(answer, ":-)") == 0)
-        {
-          result->choice = svn_wc_conflict_choose_mine_full;
-          if (performed_edit)
-            result->save_merged = TRUE;
-          break;
-        }
-      else if (strcmp(answer, "tf") == 0 || strcmp(answer, ":-(") == 0)
-        {
-          result->choice = svn_wc_conflict_choose_theirs_full;
-          if (performed_edit)
-            result->save_merged = TRUE;
-          break;
-        }
-      else if (strcmp(answer, "dc") == 0)
+      else if (strcmp(opt->code, "dc") == 0)
         {
           if (desc->is_binary)
             {
@@ -589,7 +640,7 @@ handle_text_conflict(svn_wc_conflict_res
           SVN_ERR(show_conflicts(desc, iterpool));
           knows_something = TRUE;
         }
-      else if (strcmp(answer, "df") == 0)
+      else if (strcmp(opt->code, "df") == 0)
         {
           if (! diff_allowed)
             {
@@ -602,14 +653,14 @@ handle_text_conflict(svn_wc_conflict_res
           SVN_ERR(show_diff(desc, iterpool));
           knows_something = TRUE;
         }
-      else if (strcmp(answer, "e") == 0 || strcmp(answer, ":-E") == 0)
+      else if (strcmp(opt->code, "e") == 0 || strcmp(opt->code, ":-E") == 0)
         {
           SVN_ERR(open_editor(&performed_edit, desc, b, iterpool));
           if (performed_edit)
             knows_something = TRUE;
         }
-      else if (strcmp(answer, "m") == 0 || strcmp(answer, ":-g") == 0 ||
-               strcmp(answer, "=>-") == 0 || strcmp(answer, ":>.") == 0)
+      else if (strcmp(opt->code, "m") == 0 || strcmp(opt->code, ":-g") == 0 ||
+               strcmp(opt->code, "=>-") == 0 || strcmp(opt->code, ":>.") == 0)
         {
           if (desc->kind != svn_wc_conflict_kind_text)
             {
@@ -642,8 +693,12 @@ handle_text_conflict(svn_wc_conflict_res
             SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                                         _("Invalid option.\n\n")));
         }
-      else if (strcmp(answer, "l") == 0 || strcmp(answer, ":-l") == 0)
+      else if (strcmp(opt->code, "l") == 0 || strcmp(opt->code, ":-l") == 0)
         {
+          /* ### This check should be earlier as it's nasty to offer an option
+           *     and then when the user chooses it say 'Invalid option'. */
+          /* ### 'merged_file' shouldn't be necessary *before* we launch the
+           *     resolver: it should be the *result* of doing so. */
           if (desc->base_abspath && desc->their_abspath &&
               desc->my_abspath && desc->merged_file)
             {
@@ -655,19 +710,36 @@ handle_text_conflict(svn_wc_conflict_res
             SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                                         _("Invalid option.\n\n")));
         }
-      else if (strcmp(answer, "r") == 0)
+      else if (opt->choice != -1)
         {
+          if ((opt->choice == svn_wc_conflict_choose_mine_conflict
+               || opt->choice == svn_wc_conflict_choose_theirs_conflict)
+              && desc->is_binary)
+            {
+              SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
+                                          _("Invalid option; cannot choose "
+                                            "based on conflicts in a "
+                                            "binary file.\n\n")));
+              continue;
+            }
+
           /* We only allow the user accept the merged version of
              the file if they've edited it, or at least looked at
              the diff. */
-          if (knows_something)
+          if (result->choice == svn_wc_conflict_choose_merged
+              && ! knows_something)
             {
-              result->choice = svn_wc_conflict_choose_merged;
-              break;
+              SVN_ERR(svn_cmdline_fprintf(
+                        stderr, iterpool,
+                        _("Invalid option; use diff/edit/merge/launch "
+                          "before choosing 'resolved'.\n\n")));
+              continue;
             }
-          else
-            SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
-                                        _("Invalid option.\n\n")));
+
+          result->choice = opt->choice;
+          if (performed_edit)
+            result->save_merged = TRUE;
+          break;
         }
     }
   svn_pool_destroy(iterpool);
@@ -685,8 +757,6 @@ handle_prop_conflict(svn_wc_conflict_res
                      svn_cl__interactive_conflict_baton_t *b,
                      apr_pool_t *scratch_pool)
 {
-  const char *prompt
-    = prompt_string(prop_conflict_options, NULL, scratch_pool);
   apr_pool_t *iterpool;
 
   SVN_ERR_ASSERT(desc->kind == svn_wc_conflict_kind_property);
@@ -729,26 +799,25 @@ handle_prop_conflict(svn_wc_conflict_res
   iterpool = svn_pool_create(scratch_pool);
   while (TRUE)
     {
-      const char *answer;
+      const resolver_option_t *opt;
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, b->pb, iterpool));
-
-      if (strcmp(answer, "p") == 0 || strcmp(answer, ":-P") == 0)
-        {
-          /* Do nothing, let property be marked conflicted. */
-          result->choice = svn_wc_conflict_choose_postpone;
+      SVN_ERR(prompt_user(&opt, prop_conflict_options, NULL, b->pb,
+                          iterpool));
+      if (! opt)
+        continue;
+
+      if (strcmp(opt->code, "q") == 0)
+        {
+          result->choice = opt->choice;
+          b->accept_which = svn_cl__accept_postpone;
+          b->quit = TRUE;
           break;
         }
-      else if (strcmp(answer, "mf") == 0 || strcmp(answer, ":-)") == 0)
+      else if (opt->choice != -1)
         {
-          result->choice = svn_wc_conflict_choose_mine_full;
-          break;
-        }
-      else if (strcmp(answer, "tf") == 0 || strcmp(answer, ":-(") == 0)
-        {
-          result->choice = svn_wc_conflict_choose_theirs_full;
+          result->choice = opt->choice;
           break;
         }
     }
@@ -767,8 +836,6 @@ handle_tree_conflict(svn_wc_conflict_res
                      svn_cl__interactive_conflict_baton_t *b,
                      apr_pool_t *scratch_pool)
 {
-  const char *prompt
-    = prompt_string(tree_conflict_options, NULL, scratch_pool);
   const char *readable_desc;
   apr_pool_t *iterpool;
 
@@ -785,36 +852,34 @@ handle_tree_conflict(svn_wc_conflict_res
   iterpool = svn_pool_create(scratch_pool);
   while (1)
     {
-      const char *answer;
+      const resolver_option_t *opt;
+      const resolver_option_t *tc_opts;
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, b->pb, iterpool));
-
-      if (strcmp(answer, "h") == 0 || strcmp(answer, "?") == 0)
-        {
-          SVN_ERR(svn_cmdline_fprintf(stderr, iterpool, "%s",
-                                      help_string(tree_conflict_options,
-                                                  iterpool)));
-        }
-      if (strcmp(answer, "p") == 0 || strcmp(answer, ":-p") == 0)
+      if ((desc->operation == svn_wc_operation_update ||
+           desc->operation == svn_wc_operation_switch) &&
+          desc->reason == svn_wc_conflict_reason_moved_away)
         {
-          result->choice = svn_wc_conflict_choose_postpone;
-          break;
+          tc_opts = tree_conflict_options_update_moved_away;
         }
-      else if (strcmp(answer, "r") == 0)
-        {
-          result->choice = svn_wc_conflict_choose_merged;
-          break;
-        }
-      else if (strcmp(answer, "mc") == 0)
+      else
+        tc_opts = tree_conflict_options;
+
+      SVN_ERR(prompt_user(&opt, tc_opts, NULL, b->pb, iterpool));
+      if (! opt)
+        continue;
+
+      if (strcmp(opt->code, "q") == 0)
         {
-          result->choice = svn_wc_conflict_choose_mine_conflict;
+          result->choice = opt->choice;
+          b->accept_which = svn_cl__accept_postpone;
+          b->quit = TRUE;
           break;
         }
-      else if (strcmp(answer, "tc") == 0)
+      else if (opt->choice != -1)
         {
-          result->choice = svn_wc_conflict_choose_theirs_conflict;
+          result->choice = opt->choice;
           break;
         }
     }
@@ -833,8 +898,6 @@ handle_obstructed_add(svn_wc_conflict_re
                       svn_cl__interactive_conflict_baton_t *b,
                       apr_pool_t *scratch_pool)
 {
-  const char *prompt
-    = prompt_string(obstructed_add_options, NULL, scratch_pool);
   apr_pool_t *iterpool;
 
   SVN_ERR(svn_cmdline_fprintf(
@@ -848,31 +911,25 @@ handle_obstructed_add(svn_wc_conflict_re
   iterpool = svn_pool_create(scratch_pool);
   while (1)
     {
-      const char *answer;
+      const resolver_option_t *opt;
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, b->pb, iterpool));
-
-      if (strcmp(answer, "h") == 0 || strcmp(answer, "?") == 0)
-        {
-          SVN_ERR(svn_cmdline_fprintf(stderr, iterpool, "%s\n",
-                                      help_string(obstructed_add_options,
-                                                  iterpool)));
-        }
-      if (strcmp(answer, "p") == 0 || strcmp(answer, ":-P") == 0)
-        {
-          result->choice = svn_wc_conflict_choose_postpone;
-          break;
-        }
-      if (strcmp(answer, "mf") == 0 || strcmp(answer, ":-)") == 0)
-        {
-          result->choice = svn_wc_conflict_choose_mine_full;
+      SVN_ERR(prompt_user(&opt, obstructed_add_options, NULL, b->pb,
+                          iterpool));
+      if (! opt)
+        continue;
+
+      if (strcmp(opt->code, "q") == 0)
+        {
+          result->choice = opt->choice;
+          b->accept_which = svn_cl__accept_postpone;
+          b->quit = TRUE;
           break;
         }
-      if (strcmp(answer, "tf") == 0 || strcmp(answer, ":-(") == 0)
+      else if (opt->choice != -1)
         {
-          result->choice = svn_wc_conflict_choose_theirs_full;
+          result->choice = opt->choice;
           break;
         }
     }
@@ -910,6 +967,10 @@ svn_cl__conflict_func_interactive(svn_wc
       (*result)->choice = svn_wc_conflict_choose_base;
       return SVN_NO_ERROR;
     case svn_cl__accept_working:
+      /* If the caller didn't merge the property values, then I guess
+       * 'choose working' means 'choose mine'... */
+      if (! desc->merged_file)
+        (*result)->merged_file = desc->my_abspath;
       (*result)->choice = svn_wc_conflict_choose_merged;
       return SVN_NO_ERROR;
     case svn_cl__accept_mine_conflict:
@@ -1060,8 +1121,6 @@ svn_cl__conflict_func_interactive(svn_wc
   return SVN_NO_ERROR;
 }
 
-/* Implement svn_wc_conflict_resolver_func2_t; postpones all conflicts
- * and remembers conflicted paths in BATON. */
 svn_error_t *
 svn_cl__conflict_func_postpone(svn_wc_conflict_result_t **result,
                                const svn_wc_conflict_description2_t *desc,
@@ -1095,9 +1154,6 @@ get_postponed_conflicted_paths(void *bat
   apr_array_header_t *result_array;
   int i;
 
-  if (apr_hash_count(conflicted_paths) == 0)
-    return NULL;
-
   sorted_array = svn_sort__hash(conflicted_paths,
                                 svn_sort_compare_items_as_paths,
                                 apr_hash_pool_get(conflicted_paths));
@@ -1116,8 +1172,8 @@ get_postponed_conflicted_paths(void *bat
 }
 
 svn_error_t *
-svn_cl__resolve_postponed_conflicts(void *baton,
-                                    svn_depth_t depth,
+svn_cl__resolve_postponed_conflicts(svn_boolean_t *conflicts_all_resolved,
+                                    void *baton,
                                     svn_cl__accept_t accept_which,
                                     const char *editor_cmd,
                                     svn_client_ctx_t *ctx,
@@ -1128,8 +1184,9 @@ svn_cl__resolve_postponed_conflicts(void
   apr_pool_t *iterpool;
 
   targets = get_postponed_conflicted_paths(baton, scratch_pool);
-  if (targets == NULL)
-    return SVN_NO_ERROR;
+
+  if (conflicts_all_resolved != NULL)
+    *conflicts_all_resolved = TRUE;
 
   iterpool = svn_pool_create(scratch_pool);
   for (i = 0; i < targets->nelts; i++)
@@ -1140,6 +1197,7 @@ svn_cl__resolve_postponed_conflicts(void
       svn_wc_conflict_resolver_func2_t conflict_func2;
       void *conflict_baton2;
       svn_cl__interactive_conflict_baton_t *b;
+      svn_boolean_t text_c, prop_c, tree_c;
 
       svn_pool_clear(iterpool);
 
@@ -1159,7 +1217,7 @@ svn_cl__resolve_postponed_conflicts(void
                                                           scratch_pool));
       ctx->conflict_baton2 = b;
 
-      err = svn_client_resolve(local_abspath, depth,
+      err = svn_client_resolve(local_abspath, svn_depth_empty,
                                svn_wc_conflict_choose_unspecified,
                                ctx, iterpool);
 
@@ -1175,6 +1233,19 @@ svn_cl__resolve_postponed_conflicts(void
 
           svn_error_clear(err);
         }
+
+      /* Report if we left any of the conflicts unresolved */
+      if (conflicts_all_resolved != NULL)
+        {
+          SVN_ERR(svn_wc_conflicted_p3(&text_c, &prop_c, &tree_c,
+                                       ctx->wc_ctx, local_abspath,
+                                       scratch_pool));
+          if (text_c || prop_c || tree_c)
+            *conflicts_all_resolved = FALSE;
+        }
+
+      if (b->quit)
+        break;
     }
   svn_pool_destroy(iterpool);
 

Modified: subversion/branches/ev2-export/subversion/svn/diff-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/diff-cmd.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/diff-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/diff-cmd.c Sat Feb 23 01:25:38 2013
@@ -221,12 +221,13 @@ svn_cl__diff(apr_getopt_t *os,
 
   if (! opt_state->old_target && ! opt_state->new_target
       && (targets->nelts == 2)
-      && svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *))
-      && svn_path_is_url(APR_ARRAY_IDX(targets, 1, const char *))
+      && (svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *))
+          || svn_path_is_url(APR_ARRAY_IDX(targets, 1, const char *)))
       && opt_state->start_revision.kind == svn_opt_revision_unspecified
       && opt_state->end_revision.kind == svn_opt_revision_unspecified)
     {
-      /* The 'svn diff OLD_URL[@OLDREV] NEW_URL[@NEWREV]' case matches. */
+      /* A 2-target diff where one or both targets are URLs. These are
+       * shorthands for some 'svn diff --old X --new Y' invocations. */
 
       SVN_ERR(svn_opt_parse_path(&opt_state->start_revision, &old_target,
                                  APR_ARRAY_IDX(targets, 0, const char *),
@@ -236,10 +237,16 @@ svn_cl__diff(apr_getopt_t *os,
                                  pool));
       targets->nelts = 0;
 
+      /* Set default start/end revisions based on target types, in the same
+       * manner as done for the corresponding '--old X --new Y' cases,
+       * (note that we have an explicit --new target) */
       if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
-        opt_state->start_revision.kind = svn_opt_revision_head;
+        opt_state->start_revision.kind = svn_path_is_url(old_target)
+            ? svn_opt_revision_head : svn_opt_revision_working;
+
       if (opt_state->end_revision.kind == svn_opt_revision_unspecified)
-        opt_state->end_revision.kind = svn_opt_revision_head;
+        opt_state->end_revision.kind = svn_path_is_url(new_target)
+            ? svn_opt_revision_head : svn_opt_revision_working;
     }
   else if (opt_state->old_target)
     {
@@ -252,9 +259,8 @@ svn_cl__diff(apr_getopt_t *os,
       tmp = apr_array_make(pool, 2, sizeof(const char *));
       APR_ARRAY_PUSH(tmp, const char *) = (opt_state->old_target);
       APR_ARRAY_PUSH(tmp, const char *) = (opt_state->new_target
-                                            ? opt_state->new_target
-                                           : APR_ARRAY_IDX(tmp, 0,
-                                                           const char *));
+                                           ? opt_state->new_target
+                                           : opt_state->old_target);
 
       SVN_ERR(svn_cl__args_to_target_array_print_reserved(&tmp2, os, tmp,
                                                           ctx, FALSE, pool));
@@ -275,21 +281,14 @@ svn_cl__diff(apr_getopt_t *os,
       if (new_rev.kind != svn_opt_revision_unspecified)
         opt_state->end_revision = new_rev;
 
-      if (opt_state->new_target
-          && opt_state->start_revision.kind == svn_opt_revision_unspecified
-          && opt_state->end_revision.kind == svn_opt_revision_unspecified
-          && ! svn_path_is_url(old_target)
-          && ! svn_path_is_url(new_target))
-        {
-          /* We want the arbitrary_nodes_diff instead of just working nodes */
-          opt_state->start_revision.kind = svn_opt_revision_working;
-          opt_state->end_revision.kind = svn_opt_revision_working;
-        }
-
+      /* For URLs, default to HEAD. For WC paths, default to WORKING if
+       * new target is explicit; if new target is implicitly the same as
+       * old target, then default the old to BASE and new to WORKING. */
       if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
         opt_state->start_revision.kind = svn_path_is_url(old_target)
-          ? svn_opt_revision_head : svn_opt_revision_base;
-
+          ? svn_opt_revision_head
+          : (opt_state->new_target
+             ? svn_opt_revision_working : svn_opt_revision_base);
       if (opt_state->end_revision.kind == svn_opt_revision_unspecified)
         opt_state->end_revision.kind = svn_path_is_url(new_target)
           ? svn_opt_revision_head : svn_opt_revision_working;
@@ -314,7 +313,10 @@ svn_cl__diff(apr_getopt_t *os,
       old_target = "";
       new_target = "";
 
-      SVN_ERR(svn_cl__assert_homogeneous_target_type(targets));
+      SVN_ERR_W(svn_cl__assert_homogeneous_target_type(targets),
+        _("'svn diff [-r N[:M]] [TARGET[@REV]...]' does not support mixed "
+          "target types. Try using the --old and --new options or one of "
+          "the shorthand invocations listed in 'svn help diff'."));
 
       working_copy_present = ! svn_path_is_url(APR_ARRAY_IDX(targets, 0,
                                                              const char *));

Modified: subversion/branches/ev2-export/subversion/svn/info-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/info-cmd.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/info-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/info-cmd.c Sat Feb 23 01:25:38 2013
@@ -105,7 +105,7 @@ print_info_xml(void *baton,
   /* "<url> xx </url>" */
   svn_cl__xml_tagged_cdata(&sb, pool, "url", info->URL);
 
-  if (info->repos_root_URL)
+  if (info->repos_root_URL && info->URL)
     {
       /* "<relative-url> xx </relative-url>" */
       svn_cl__xml_tagged_cdata(&sb, pool, "relative-url",

Modified: subversion/branches/ev2-export/subversion/svn/merge-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/merge-cmd.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/merge-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/merge-cmd.c Sat Feb 23 01:25:38 2013
@@ -44,64 +44,6 @@ static const svn_opt_revision_t unspecif
 
 /*** Code. ***/
 
-/* Do a reintegrate merge from SOURCE_PATH_OR_URL@SOURCE_PEG_REVISION into
- * TARGET_WCPATH.  Do it with a WC write lock unless DRY_RUN is true. */
-static svn_error_t *
-merge_reintegrate(const char *source_path_or_url,
-                  const svn_opt_revision_t *source_peg_revision,
-                  const char *target_wcpath,
-                  svn_boolean_t dry_run,
-                  svn_boolean_t verbose,
-                  const apr_array_header_t *merge_options,
-                  svn_client_ctx_t *ctx,
-                  apr_pool_t *scratch_pool)
-{
-  const char *url1, *url2;
-  svn_revnum_t rev1, rev2;
-
-  if (verbose)
-    SVN_ERR(svn_cmdline_printf(scratch_pool, _("checking branch relationship...\n")));
-  SVN_ERR_W(svn_cl__check_related_source_and_target(
-              source_path_or_url, source_peg_revision,
-              target_wcpath, &unspecified_revision, ctx, scratch_pool),
-            _("Source and target must be different but related branches"));
-
-  if (verbose)
-    SVN_ERR(svn_cmdline_printf(scratch_pool, _("calculating reintegrate merge...\n")));
-  SVN_ERR(svn_client_find_reintegrate_merge(
-            &url1, &rev1, &url2, &rev2,
-            source_path_or_url, source_peg_revision, target_wcpath,
-            ctx, scratch_pool, scratch_pool));
-
-  if (url1)
-    {
-      svn_opt_revision_t revision1;
-      svn_opt_revision_t revision2;
-
-      revision1.kind = svn_opt_revision_number;
-      revision1.value.number = rev1;
-
-      revision2.kind = svn_opt_revision_number;
-      revision2.value.number = rev2;
-
-      if (verbose)
-        SVN_ERR(svn_cmdline_printf(scratch_pool, _("merging...\n")));
-
-      /* Do the merge.  Set 'allow_mixed_rev' to true, not because we want
-       * to allow a mixed-rev WC but simply to bypass the check, as it was
-       * already checked in svn_client_find_reintegrate_merge(). */
-      SVN_ERR(svn_client_merge4(url1, &revision1, url2, &revision2,
-                                target_wcpath, svn_depth_infinity,
-                                FALSE /* ignore_ancestry */,
-                                FALSE /* force_delete */,
-                                FALSE /* record_only */,
-                                dry_run, TRUE /* allow_mixed_rev */,
-                                merge_options, ctx, scratch_pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
 /* Throw an error if PATH_OR_URL is a path and REVISION isn't a repository
  * revision. */
 static svn_error_t *
@@ -127,6 +69,7 @@ automatic_merge(const char *source_path_
                 const svn_opt_revision_t *source_revision,
                 const char *target_wcpath,
                 svn_depth_t depth,
+                svn_boolean_t diff_ignore_ancestry,
                 svn_boolean_t force_delete,
                 svn_boolean_t record_only,
                 svn_boolean_t dry_run,
@@ -141,14 +84,14 @@ automatic_merge(const char *source_path_
   svn_client_automatic_merge_t *merge;
 
   if (verbose)
-    SVN_ERR(svn_cmdline_printf(scratch_pool, _("checking branch relationship...\n")));
+    SVN_ERR(svn_cmdline_printf(scratch_pool, _("--- Checking branch relationship\n")));
   SVN_ERR_W(svn_cl__check_related_source_and_target(
               source_path_or_url, source_revision,
               target_wcpath, &unspecified_revision, ctx, scratch_pool),
             _("Source and target must be different but related branches"));
 
   if (verbose)
-    SVN_ERR(svn_cmdline_printf(scratch_pool, _("calculating automatic merge...\n")));
+    SVN_ERR(svn_cmdline_printf(scratch_pool, _("--- Calculating automatic merge\n")));
 
   /* Find the 3-way merges needed (and check suitability of the WC). */
   SVN_ERR(svn_client_find_automatic_merge(&merge,
@@ -185,10 +128,11 @@ automatic_merge(const char *source_path_
     }
 
   if (verbose)
-    SVN_ERR(svn_cmdline_printf(scratch_pool, _("merging...\n")));
+    SVN_ERR(svn_cmdline_printf(scratch_pool, _("--- Merging\n")));
 
   /* Perform the 3-way merges */
   SVN_ERR(svn_client_do_automatic_merge(merge, target_wcpath, depth,
+                                        diff_ignore_ancestry,
                                         force_delete, record_only,
                                         dry_run, merge_options,
                                         ctx, scratch_pool));
@@ -196,6 +140,127 @@ automatic_merge(const char *source_path_
   return SVN_NO_ERROR;
 }
 
+/* Run a merge.
+ *
+ * (No docs yet, as this code was just hoisted out of svn_cl__merge().)
+ *
+ * Having FIRST_RANGE_START/_END params is ugly -- we should be able to use
+ * PEG_REVISION1/2 and/or RANGES_TO_MERGE instead, maybe adjusting the caller.
+ */
+static svn_error_t *
+run_merge(svn_boolean_t two_sources_specified,
+          const char *sourcepath1,
+          svn_opt_revision_t peg_revision1,
+          const char *sourcepath2,
+          svn_opt_revision_t peg_revision2,
+          const char *targetpath,
+          apr_array_header_t *ranges_to_merge,
+          svn_opt_revision_t first_range_start,
+          svn_opt_revision_t first_range_end,
+          svn_cl__opt_state_t *opt_state,
+          apr_array_header_t *options,
+          svn_client_ctx_t *ctx,
+          apr_pool_t *scratch_pool)
+{
+  svn_error_t *merge_err;
+
+  /* Do an automatic merge if just one source and no revisions. */
+  if ((! two_sources_specified)
+      && (! opt_state->reintegrate)
+      && (! opt_state->ignore_ancestry)
+      && first_range_start.kind == svn_opt_revision_unspecified
+      && first_range_end.kind == svn_opt_revision_unspecified)
+    {
+      merge_err = automatic_merge(sourcepath1, &peg_revision1, targetpath,
+                                  opt_state->depth,
+                                  FALSE /*diff_ignore_ancestry*/,
+                                  opt_state->force, /* force_delete */
+                                  opt_state->record_only,
+                                  opt_state->dry_run,
+                                  opt_state->allow_mixed_rev,
+                                  TRUE /*allow_local_mods*/,
+                                  TRUE /*allow_switched_subtrees*/,
+                                  opt_state->verbose,
+                                  options, ctx, scratch_pool);
+    }
+  else if (opt_state->reintegrate)
+    {
+      merge_err = svn_client_merge_reintegrate(
+                    sourcepath1, &peg_revision1, targetpath,
+                    opt_state->dry_run, options, ctx, scratch_pool);
+    }
+  else if (! two_sources_specified)
+    {
+      /* If we don't have at least one valid revision range, pick a
+         good one that spans the entire set of revisions on our
+         source. */
+      if ((first_range_start.kind == svn_opt_revision_unspecified)
+          && (first_range_end.kind == svn_opt_revision_unspecified))
+        {
+          svn_opt_revision_range_t *range = apr_pcalloc(scratch_pool,
+                                                        sizeof(*range));
+          ranges_to_merge = apr_array_make(scratch_pool, 1, sizeof(range));
+          range->start.kind = svn_opt_revision_number;
+          range->start.value.number = 1;
+          range->end = peg_revision1;
+          APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *) = range;
+
+          /* This must be a 'sync' merge so check branch relationship. */
+          if (opt_state->verbose)
+            SVN_ERR(svn_cmdline_printf(
+                      scratch_pool, _("--- Checking branch relationship\n")));
+          SVN_ERR_W(svn_cl__check_related_source_and_target(
+                      sourcepath1, &peg_revision1,
+                      targetpath, &unspecified_revision, ctx, scratch_pool),
+                _("Source and target must be different but related branches"));
+        }
+
+      if (opt_state->verbose)
+        SVN_ERR(svn_cmdline_printf(scratch_pool, _("--- Merging\n")));
+      merge_err = svn_client_merge_peg5(sourcepath1,
+                                        ranges_to_merge,
+                                        &peg_revision1,
+                                        targetpath,
+                                        opt_state->depth,
+                                        opt_state->ignore_ancestry,
+                                        opt_state->ignore_ancestry,
+                                        opt_state->force, /* force_delete */
+                                        opt_state->record_only,
+                                        opt_state->dry_run,
+                                        opt_state->allow_mixed_rev,
+                                        options,
+                                        ctx,
+                                        scratch_pool);
+    }
+  else
+    {
+      if (svn_path_is_url(sourcepath1) != svn_path_is_url(sourcepath2))
+        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                _("Merge sources must both be "
+                                  "either paths or URLs"));
+
+      if (opt_state->verbose)
+        SVN_ERR(svn_cmdline_printf(scratch_pool, _("--- Merging\n")));
+      merge_err = svn_client_merge5(sourcepath1,
+                                    &first_range_start,
+                                    sourcepath2,
+                                    &first_range_end,
+                                    targetpath,
+                                    opt_state->depth,
+                                    opt_state->ignore_ancestry,
+                                    opt_state->ignore_ancestry,
+                                    opt_state->force, /* force_delete */
+                                    opt_state->record_only,
+                                    opt_state->dry_run,
+                                    opt_state->allow_mixed_rev,
+                                    options,
+                                    ctx,
+                                    scratch_pool);
+    }
+
+  return merge_err;
+}
+
 /* This implements the `svn_opt_subcommand_t' interface. */
 svn_error_t *
 svn_cl__merge(apr_getopt_t *os,
@@ -207,8 +272,7 @@ svn_cl__merge(apr_getopt_t *os,
   apr_array_header_t *targets;
   const char *sourcepath1 = NULL, *sourcepath2 = NULL, *targetpath = "";
   svn_boolean_t two_sources_specified = TRUE;
-  svn_error_t *err = SVN_NO_ERROR;
-  svn_error_t *merge_err = SVN_NO_ERROR;
+  svn_error_t *merge_err;
   svn_opt_revision_t first_range_start, first_range_end, peg_revision1,
     peg_revision2;
   apr_array_header_t *options, *ranges_to_merge = opt_state->revision_ranges;
@@ -479,123 +543,62 @@ svn_cl__merge(apr_getopt_t *os,
                                   "with --reintegrate"));
     }
 
-  /* Postpone conflict resolution during the merge operation.
-   * If any conflicts occur we'll run the conflict resolver later. */
-
-  /* Do an automatic merge if just one source and no revisions. */
-  if ((! two_sources_specified)
-      && (! opt_state->reintegrate)
-      && (! opt_state->ignore_ancestry)
-      && first_range_start.kind == svn_opt_revision_unspecified
-      && first_range_end.kind == svn_opt_revision_unspecified)
+  /* Decide how to handle conflicts.  If the user wants interactive
+   * conflict resolution, postpone conflict resolution during the merge
+   * and if any conflicts occur we'll run the conflict resolver later.
+   * Otherwise install the appropriate resolver now. */
+  if (opt_state->accept_which == svn_cl__accept_unspecified
+      || opt_state->accept_which == svn_cl__accept_postpone
+      || opt_state->accept_which == svn_cl__accept_edit
+      || opt_state->accept_which == svn_cl__accept_launch)
     {
-      merge_err = automatic_merge(sourcepath1, &peg_revision1, targetpath,
-                                  opt_state->depth,
-                                  opt_state->force, /* force_delete */
-                                  opt_state->record_only,
-                                  opt_state->dry_run,
-                                  opt_state->allow_mixed_rev,
-                                  TRUE /*allow_local_mods*/,
-                                  TRUE /*allow_switched_subtrees*/,
-                                  opt_state->verbose,
-                                  options, ctx, pool);
-    }
-  else if (opt_state->reintegrate)
-    {
-      merge_err = merge_reintegrate(sourcepath1, &peg_revision1, targetpath,
-                                    opt_state->dry_run, opt_state->verbose,
-                                    options, ctx, pool);
-    }
-  else if (! two_sources_specified)
-    {
-      /* If we don't have at least one valid revision range, pick a
-         good one that spans the entire set of revisions on our
-         source. */
-      if ((first_range_start.kind == svn_opt_revision_unspecified)
-          && (first_range_end.kind == svn_opt_revision_unspecified))
-        {
-          svn_opt_revision_range_t *range = apr_pcalloc(pool, sizeof(*range));
-          ranges_to_merge = apr_array_make(pool, 1, sizeof(range));
-          range->start.kind = svn_opt_revision_number;
-          range->start.value.number = 1;
-          range->end = peg_revision1;
-          APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *) = range;
-
-          /* This must be a 'sync' merge so check branch relationship. */
-          if (opt_state->verbose)
-            SVN_ERR(svn_cmdline_printf(pool, _("checking branch relationship...\n")));
-          SVN_ERR_W(svn_cl__check_related_source_and_target(
-                      sourcepath1, &peg_revision1,
-                      targetpath, &unspecified_revision, ctx, pool),
-                _("Source and target must be different but related branches"));
-        }
-
-      if (opt_state->verbose)
-        SVN_ERR(svn_cmdline_printf(pool, _("merging...\n")));
-      merge_err = svn_client_merge_peg4(sourcepath1,
-                                        ranges_to_merge,
-                                        &peg_revision1,
-                                        targetpath,
-                                        opt_state->depth,
-                                        opt_state->ignore_ancestry,
-                                        opt_state->force, /* force_delete */
-                                        opt_state->record_only,
-                                        opt_state->dry_run,
-                                        opt_state->allow_mixed_rev,
-                                        options,
-                                        ctx,
-                                        pool);
+      /* 'svn.c' has already installed the 'postpone' handler for us. */
     }
   else
     {
-      if (svn_path_is_url(sourcepath1) != svn_path_is_url(sourcepath2))
-        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                _("Merge sources must both be "
-                                  "either paths or URLs"));
+      svn_cl__interactive_conflict_baton_t *b;
 
-      if (opt_state->verbose)
-        SVN_ERR(svn_cmdline_printf(pool, _("merging...\n")));
-      merge_err = svn_client_merge4(sourcepath1,
-                                    &first_range_start,
-                                    sourcepath2,
-                                    &first_range_end,
-                                    targetpath,
-                                    opt_state->depth,
-                                    opt_state->ignore_ancestry,
-                                    opt_state->force, /* force_delete */
-                                    opt_state->record_only,
-                                    opt_state->dry_run,
-                                    opt_state->allow_mixed_rev,
-                                    options,
-                                    ctx,
-                                    pool);
-    }
-
-  if (! opt_state->quiet)
-    err = svn_cl__print_conflict_stats(ctx->notify_baton2, pool);
-
-  if (!err)
-    err = svn_cl__resolve_postponed_conflicts(ctx->conflict_baton2,
-                                              opt_state->depth,
-                                              opt_state->accept_which,
-                                              opt_state->editor_cmd,
-                                              ctx, pool);
-  if (merge_err)
-    {
-      if (merge_err->apr_err ==
-          SVN_ERR_CLIENT_INVALID_MERGEINFO_NO_MERGETRACKING)
-        {
-          err = svn_error_quick_wrap(
-            svn_error_compose_create(merge_err, err),
-            _("Merge tracking not possible, use --ignore-ancestry or\n"
-              "fix invalid mergeinfo in target with 'svn propset'"));
-        }
-      else
-        {
-          err = svn_error_compose_create(merge_err, err);
-          return svn_cl__may_need_force(err);
-        }
+      ctx->conflict_func2 = svn_cl__conflict_func_interactive;
+      SVN_ERR(svn_cl__get_conflict_func_interactive_baton(
+                &b,
+                opt_state->accept_which,
+                ctx->config, opt_state->editor_cmd,
+                ctx->cancel_func, ctx->cancel_baton, pool));
+      ctx->conflict_baton2 = b;
+    }
+
+  merge_err = run_merge(two_sources_specified,
+                        sourcepath1, peg_revision1,
+                        sourcepath2, peg_revision2,
+                        targetpath,
+                        ranges_to_merge, first_range_start, first_range_end,
+                        opt_state, options, ctx, pool);
+  if (merge_err && merge_err->apr_err
+                   == SVN_ERR_CLIENT_INVALID_MERGEINFO_NO_MERGETRACKING)
+    {
+      return svn_error_quick_wrap(
+               merge_err,
+               _("Merge tracking not possible, use --ignore-ancestry or\n"
+                 "fix invalid mergeinfo in target with 'svn propset'"));
+    }
+  if (! merge_err || merge_err->apr_err == SVN_ERR_WC_FOUND_CONFLICT)
+    {
+      svn_error_t *err = SVN_NO_ERROR;
+
+      if (! opt_state->quiet)
+        err = svn_cl__notifier_print_conflict_stats(ctx->notify_baton2,
+                                                        pool);
+
+      /* Resolve any postponed conflicts.  (Only if we've been using the
+       * default 'postpone' resolver which remembers what was postponed.) */
+      if (!err && ctx->conflict_func2 == svn_cl__conflict_func_postpone)
+        err = svn_cl__resolve_postponed_conflicts(NULL,
+                                                  ctx->conflict_baton2,
+                                                  opt_state->accept_which,
+                                                  opt_state->editor_cmd,
+                                                  ctx, pool);
+      merge_err = svn_error_compose_create(merge_err, err);
     }
 
-  return svn_error_trace(err);
+  return svn_cl__may_need_force(merge_err);
 }

Modified: subversion/branches/ev2-export/subversion/svn/mergeinfo-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/mergeinfo-cmd.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/mergeinfo-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/mergeinfo-cmd.c Sat Feb 23 01:25:38 2013
@@ -162,12 +162,14 @@ mergeinfo_diagram(const char *yca_url,
     }
 
   /* Column headings */
-  SVN_ERR(svn_cmdline_fputs(
-            _("    youngest  last               repos.\n"
-              "    common    full     tip of    path of\n"
-              "    ancestor  merge    branch    branch\n"
-              "\n"),
-            stdout, pool));
+  SVN_ERR(svn_cmdline_printf(pool,
+            "    %s\n"
+            "    |         %s\n"
+            "    |         |        %s\n"
+            "    |         |        |         %s\n"
+            "\n",
+            _("youngest common ancestor"), _("last full merge"),
+            _("tip of branch"), _("repository path")));
 
   /* Print the diagram, row by row */
   for (row = 0; row < ROWS; row++)

Modified: subversion/branches/ev2-export/subversion/svn/notify.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/notify.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/notify.c (original)
+++ subversion/branches/ev2-export/subversion/svn/notify.c Sat Feb 23 01:25:38 2013
@@ -54,10 +54,10 @@ struct notify_baton
                                     when we've already had one print error. */
 
   /* Conflict stats for update and merge. */
-  unsigned int text_conflicts;
-  unsigned int prop_conflicts;
-  unsigned int tree_conflicts;
-  unsigned int skipped_paths;
+  int text_conflicts;
+  int prop_conflicts;
+  int tree_conflicts;
+  int skipped_paths;
 
   /* The cwd, for use in decomposing absolute paths. */
   const char *path_prefix;
@@ -65,38 +65,43 @@ struct notify_baton
 
 
 svn_error_t *
-svn_cl__print_conflict_stats(void *notify_baton, apr_pool_t *pool)
+svn_cl__notifier_reset_conflict_stats(void *baton)
 {
-  struct notify_baton *nb = notify_baton;
-  unsigned int text_conflicts;
-  unsigned int prop_conflicts;
-  unsigned int tree_conflicts;
-  unsigned int skipped_paths;
-
-  text_conflicts = nb->text_conflicts;
-  prop_conflicts = nb->prop_conflicts;
-  tree_conflicts = nb->tree_conflicts;
-  skipped_paths = nb->skipped_paths;
-
-  if (text_conflicts > 0 || prop_conflicts > 0
-    || tree_conflicts > 0 || skipped_paths > 0)
-      SVN_ERR(svn_cmdline_printf(pool, "%s", _("Summary of conflicts:\n")));
-
-  if (text_conflicts > 0)
-    SVN_ERR(svn_cmdline_printf
-      (pool, _("  Text conflicts: %u\n"), text_conflicts));
-
-  if (prop_conflicts > 0)
-    SVN_ERR(svn_cmdline_printf
-      (pool, _("  Property conflicts: %u\n"), prop_conflicts));
-
-  if (tree_conflicts > 0)
-    SVN_ERR(svn_cmdline_printf
-      (pool, _("  Tree conflicts: %u\n"), tree_conflicts));
-
-  if (skipped_paths > 0)
-    SVN_ERR(svn_cmdline_printf
-      (pool, _("  Skipped paths: %u\n"), skipped_paths));
+  struct notify_baton *nb = baton;
+
+  nb->text_conflicts = 0;
+  nb->prop_conflicts = 0;
+  nb->tree_conflicts = 0;
+  nb->skipped_paths = 0;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_cl__notifier_print_conflict_stats(void *baton, apr_pool_t *scratch_pool)
+{
+  struct notify_baton *nb = baton;
+
+  if (nb->text_conflicts > 0 || nb->prop_conflicts > 0
+      || nb->tree_conflicts > 0 || nb->skipped_paths > 0)
+    SVN_ERR(svn_cmdline_printf(scratch_pool,
+                               _("Summary of conflicts:\n")));
+
+  if (nb->text_conflicts > 0)
+    SVN_ERR(svn_cmdline_printf(scratch_pool,
+                               _("  Text conflicts: %d\n"),
+                               nb->text_conflicts));
+  if (nb->prop_conflicts > 0)
+    SVN_ERR(svn_cmdline_printf(scratch_pool,
+                               _("  Property conflicts: %d\n"),
+                               nb->prop_conflicts));
+  if (nb->tree_conflicts > 0)
+    SVN_ERR(svn_cmdline_printf(scratch_pool,
+                               _("  Tree conflicts: %d\n"),
+                               nb->tree_conflicts));
+  if (nb->skipped_paths > 0)
+    SVN_ERR(svn_cmdline_printf(scratch_pool,
+                               _("  Skipped paths: %d\n"),
+                               nb->skipped_paths));
 
   return SVN_NO_ERROR;
 }
@@ -997,12 +1002,21 @@ notify(void *baton, const svn_wc_notify_
 
     case svn_wc_notify_conflict_resolver_starting:
       /* Once all operations invoke the interactive conflict resolution after
-       * they've completed, we can run svn_cl__print_conflict_stats() here. */
+       * they've completed, we can run svn_cl__notifier_print_conflict_stats()
+       * here. */
       break;
 
     case svn_wc_notify_conflict_resolver_done:
       break;
 
+    case svn_wc_notify_foreign_copy_begin:
+      if (n->merge_range == NULL)
+        err = svn_cmdline_printf(pool,
+                                 _("--- Copying from foreign repository URL '%s':\n"),
+                                 n->url);
+      if (err)
+        goto print_error;
+
     default:
       break;
     }

Modified: subversion/branches/ev2-export/subversion/svn/patch-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/patch-cmd.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/patch-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/patch-cmd.c Sat Feb 23 01:25:38 2013
@@ -92,7 +92,7 @@ svn_cl__patch(apr_getopt_t *os,
 
 
   if (! opt_state->quiet)
-    SVN_ERR(svn_cl__print_conflict_stats(ctx->notify_baton2, pool));
+    SVN_ERR(svn_cl__notifier_print_conflict_stats(ctx->notify_baton2, pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ev2-export/subversion/svn/propedit-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/propedit-cmd.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/propedit-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/propedit-cmd.c Sat Feb 23 01:25:38 2013
@@ -315,6 +315,10 @@ svn_cl__propedit(apr_getopt_t *os,
                                                     sizeof(const char *));
 
                   APR_ARRAY_PUSH(targs, const char *) = target;
+
+                  SVN_ERR(svn_cl__propset_print_binary_mime_type_warning(
+                      targs, pname_utf8, propval, subpool));
+
                   err = svn_client_propset_local(pname_utf8, edited_propval,
                                                  targs, svn_depth_empty,
                                                  opt_state->force, NULL,

Modified: subversion/branches/ev2-export/subversion/svn/propset-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/propset-cmd.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/propset-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/propset-cmd.c Sat Feb 23 01:25:38 2013
@@ -173,6 +173,11 @@ svn_cl__propset(apr_getopt_t *os,
             }
         }
 
+      SVN_ERR(svn_cl__propset_print_binary_mime_type_warning(targets,
+                                                             pname_utf8,
+                                                             propval,
+                                                             scratch_pool));
+
       SVN_ERR(svn_client_propset_local(pname_utf8, propval, targets,
                                        opt_state->depth, opt_state->force,
                                        opt_state->changelists, ctx,

Modified: subversion/branches/ev2-export/subversion/svn/resolve-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/resolve-cmd.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/resolve-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/resolve-cmd.c Sat Feb 23 01:25:38 2013
@@ -26,9 +26,6 @@
 
 
 /*** Includes. ***/
-#define APR_WANT_STDIO
-#include <apr_want.h>
-
 #include "svn_path.h"
 #include "svn_client.h"
 #include "svn_error.h"

Modified: subversion/branches/ev2-export/subversion/svn/resolved-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/resolved-cmd.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/resolved-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/resolved-cmd.c Sat Feb 23 01:25:38 2013
@@ -26,9 +26,6 @@
 
 
 /*** Includes. ***/
-#define APR_WANT_STDIO
-#include <apr_want.h>
-
 #include "svn_path.h"
 #include "svn_client.h"
 #include "svn_error.h"

Modified: subversion/branches/ev2-export/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/svn.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/svn.c (original)
+++ subversion/branches/ev2-export/subversion/svn/svn.c Sat Feb 23 01:25:38 2013
@@ -536,29 +536,41 @@ const svn_opt_subcommand_desc2_t svn_cl_
     {opt_force, 'q', opt_targets, SVN_CL__LOG_MSG_OPTIONS, opt_keep_local} },
 
   { "diff", svn_cl__diff, {"di"}, N_
-    ("Display the differences between two revisions or paths.\n"
-     "usage: 1. diff [-c M | -r N[:M]] [TARGET[@REV]...]\n"
-     "       2. diff [-r N[:M]] --old=OLD-TGT[@OLDREV] [--new=NEW-TGT[@NEWREV]] \\\n"
+    ("Display local changes or differences between two revisions or paths.\n"
+     "usage: 1. diff\n"
+     "       2. diff [-c M | -r N[:M]] [TARGET[@REV]...]\n"
+     "       3. diff [-r N[:M]] --old=OLD-TGT[@OLDREV] [--new=NEW-TGT[@NEWREV]] \\\n"
      "               [PATH...]\n"
-     "       3. diff OLD-URL[@OLDREV] NEW-URL[@NEWREV]\n"
+     "       4. diff OLD-URL[@OLDREV] NEW-URL[@NEWREV]\n"
+     "       5. diff OLD-URL[@OLDREV] NEW-PATH[@NEWREV]\n"
+     "       6. diff OLD-PATH[@OLDREV] NEW-URL[@NEWREV]\n"
      "\n"
-     "  1. Display the changes made to TARGETs as they are seen in REV between\n"
+     "  1. Use just 'svn diff' to display local modifications in a working copy.\n"
+     "\n"
+     "  2. Display the changes made to TARGETs as they are seen in REV between\n"
      "     two revisions.  TARGETs may be all working copy paths or all URLs.\n"
      "     If TARGETs are working copy paths, N defaults to BASE and M to the\n"
      "     working copy; if URLs, N must be specified and M defaults to HEAD.\n"
      "     The '-c M' option is equivalent to '-r N:M' where N = M-1.\n"
      "     Using '-c -M' does the reverse: '-r M:N' where N = M-1.\n"
      "\n"
-     "  2. Display the differences between OLD-TGT as it was seen in OLDREV and\n"
+     "  3. Display the differences between OLD-TGT as it was seen in OLDREV and\n"
      "     NEW-TGT as it was seen in NEWREV.  PATHs, if given, are relative to\n"
      "     OLD-TGT and NEW-TGT and restrict the output to differences for those\n"
      "     paths.  OLD-TGT and NEW-TGT may be working copy paths or URL[@REV].\n"
      "     NEW-TGT defaults to OLD-TGT if not specified.  -r N makes OLDREV default\n"
      "     to N, -r N:M makes OLDREV default to N and NEWREV default to M.\n"
+     "     If OLDREV or NEWREV are not specified, they default to WORKING for\n"
+     "     working copy targets and to HEAD for URL targets.\n"
      "\n"
-     "  3. Shorthand for 'svn diff --old=OLD-URL[@OLDREV] --new=NEW-URL[@NEWREV]'\n"
-     "\n"
-     "  Use just 'svn diff' to display local modifications in a working copy.\n"),
+     "     Either or both OLD-TGT and NEW-TGT may also be paths to unversioned\n"
+     "     targets. Revisions cannot be specified for unversioned targets.\n"
+     "     Both targets must be of the same node kind (file or directory).\n"
+     "     Diffing unversioned targets against URL targets is not supported.\n"
+     "\n"
+     "  4. Shorthand for 'svn diff --old=OLD-URL[@OLDREV] --new=NEW-URL[@NEWREV]'\n"
+     "  5. Shorthand for 'svn diff --old=OLD-URL[@OLDREV] --new=NEW-PATH[@NEWREV]'\n"
+     "  6. Shorthand for 'svn diff --old=OLD-PATH[@OLDREV] --new=NEW-URL[@NEWREV]'\n"),
     {'r', 'c', opt_old_cmd, opt_new_cmd, 'N', opt_depth, opt_diff_cmd,
      opt_internal_diff, 'x', opt_no_diff_added, opt_no_diff_deleted,
      opt_ignore_properties, opt_properties_only,
@@ -1321,10 +1333,12 @@ const svn_opt_subcommand_desc2_t svn_cl_
     ("Resolve conflicts on working copy files or directories.\n"
      "usage: resolve [PATH...]\n"
      "\n"
-     "  If no arguments are given, perform interactive conflict resolution for\n"
-     "  all conflicted paths in the working copy, with default depth 'infinity'.\n"
-     "  The --accept=ARG option prevents prompting and forces conflicts on PATH\n"
-     "  to resolved in the manner specified by ARG, with default depth 'empty'.\n"),
+     "  By default, perform interactive conflict resolution on PATH.\n"
+     "  In this mode, the command is recursive by default (depth 'infinity').\n"
+     "\n"
+     "  The --accept=ARG option prevents interactive prompting and forces\n"
+     "  conflicts on PATH to be resolved in the manner specified by ARG.\n"
+     "  In this mode, the command is not recursive by default (depth 'empty').\n"),
     {opt_targets, 'R', opt_depth, 'q', opt_accept},
     {{opt_accept, N_("specify automatic conflict resolution source\n"
                      "                             "
@@ -1677,7 +1691,6 @@ sub_main(int argc, const char *argv[], a
   svn_boolean_t force_interactive = FALSE;
   svn_boolean_t use_notifier = TRUE;
   apr_hash_t *changelists;
-  const char *sqlite_exclusive;
   apr_hash_t *cfg_hash;
 
   received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
@@ -2109,7 +2122,7 @@ sub_main(int argc, const char *argv[], a
           {
             err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                    _("Changelist names must not be empty"));
-            return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+            return EXIT_ERROR(err);
           }
         apr_hash_set(changelists, opt_state.changelist,
                      APR_HASH_KEY_STRING, (void *)1);
@@ -2442,11 +2455,6 @@ sub_main(int argc, const char *argv[], a
         return EXIT_ERROR(err);
     }
 
-  /* Create a client context object. */
-  command_baton.opt_state = &opt_state;
-  SVN_INT_ERR(svn_client_create_context2(&ctx, cfg_hash, pool));
-  command_baton.ctx = ctx;
-
   /* Relocation is infinite-depth only. */
   if (opt_state.relocate)
     {
@@ -2505,27 +2513,49 @@ sub_main(int argc, const char *argv[], a
         }
     }
 
-  cfg_config = apr_hash_get(ctx->config, SVN_CONFIG_CATEGORY_CONFIG,
+  cfg_config = apr_hash_get(cfg_hash, SVN_CONFIG_CATEGORY_CONFIG,
                             APR_HASH_KEY_STRING);
 
   /* Update the options in the config */
   if (opt_state.config_options)
     {
       svn_error_clear(
-          svn_cmdline__apply_config_options(ctx->config,
+          svn_cmdline__apply_config_options(cfg_hash,
                                             opt_state.config_options,
                                             "svn: ", "--config-option"));
     }
 
-  svn_config_get(cfg_config, &sqlite_exclusive,
-                 SVN_CONFIG_SECTION_WORKING_COPY,
-                 SVN_CONFIG_OPTION_SQLITE_EXCLUSIVE,
-                 NULL);
-  if (!sqlite_exclusive)
-    svn_config_set(cfg_config,
+#if !defined(SVN_CL_NO_EXCLUSIVE_LOCK)
+  {
+    const char *exclusive_clients_option;
+    apr_array_header_t *exclusive_clients;
+
+    svn_config_get(cfg_config, &exclusive_clients_option,
                    SVN_CONFIG_SECTION_WORKING_COPY,
-                   SVN_CONFIG_OPTION_SQLITE_EXCLUSIVE,
-                   "true");
+                   SVN_CONFIG_OPTION_SQLITE_EXCLUSIVE_CLIENTS,
+                   NULL);
+    exclusive_clients = svn_cstring_split(exclusive_clients_option,
+                                          " ,", TRUE, pool);
+    for (i = 0; i < exclusive_clients->nelts; ++i)
+      {
+        const char *exclusive_client = APR_ARRAY_IDX(exclusive_clients, i,
+                                                     const char *);
+
+        /* This blocks other clients from accessing the wc.db so it must
+           be explicitly enabled.*/
+        if (!strcmp(exclusive_client, "svn"))
+          svn_config_set(cfg_config,
+                         SVN_CONFIG_SECTION_WORKING_COPY,
+                         SVN_CONFIG_OPTION_SQLITE_EXCLUSIVE,
+                         "true");
+      }
+  }
+#endif
+
+  /* Create a client context object. */
+  command_baton.opt_state = &opt_state;
+  SVN_INT_ERR(svn_client_create_context2(&ctx, cfg_hash, pool));
+  command_baton.ctx = ctx;
 
   /* If we're running a command that could result in a commit, verify
      that any log message we were given on the command line makes

Modified: subversion/branches/ev2-export/subversion/svn/switch-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/switch-cmd.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/switch-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/switch-cmd.c Sat Feb 23 01:25:38 2013
@@ -193,13 +193,13 @@ svn_cl__switch(apr_getopt_t *os,
 
   if (! opt_state->quiet)
     {
-      err = svn_cl__print_conflict_stats(nwb.wrapped_baton, scratch_pool);
+      err = svn_cl__notifier_print_conflict_stats(nwb.wrapped_baton, scratch_pool);
       if (err)
         return svn_error_compose_create(externals_err, err);
     }
 
-  err = svn_cl__resolve_postponed_conflicts(ctx->conflict_baton2,
-                                            opt_state->depth,
+  err = svn_cl__resolve_postponed_conflicts(NULL,
+                                            ctx->conflict_baton2,
                                             opt_state->accept_which,
                                             opt_state->editor_cmd,
                                             ctx, scratch_pool);

Modified: subversion/branches/ev2-export/subversion/svn/update-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/update-cmd.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/update-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/update-cmd.c Sat Feb 23 01:25:38 2013
@@ -51,12 +51,12 @@ print_update_summary(apr_array_header_t 
   int i;
   const char *path_prefix;
   apr_pool_t *iterpool;
+  svn_boolean_t printed_header = FALSE;
 
   if (targets->nelts < 2)
     return SVN_NO_ERROR;
 
   SVN_ERR(svn_dirent_get_absolute(&path_prefix, "", scratch_pool));
-  SVN_ERR(svn_cmdline_printf(scratch_pool, _("Summary of updates:\n")));
 
   iterpool = svn_pool_create(scratch_pool);
 
@@ -87,6 +87,13 @@ print_update_summary(apr_array_header_t 
       /* Print an update summary for this target, removing the current
          working directory prefix from PATH (if PATH is at or under
          $CWD), and converting the path to local style for display. */
+      if (! printed_header)
+        {
+          SVN_ERR(svn_cmdline_printf(scratch_pool,
+                                     _("Summary of updates:\n")));
+          printed_header = TRUE;
+        }
+
       SVN_ERR(svn_cmdline_printf(iterpool, _("  Updated '%s' to r%ld.\n"),
                                  svn_cl__local_style_skip_ancestor(
                                    path_prefix, path, iterpool),
@@ -182,13 +189,14 @@ svn_cl__update(apr_getopt_t *os,
       /* ### Layering problem: This call assumes that the baton we're
        * passing is the one that was originally provided by
        * svn_cl__get_notifier(), but that isn't promised. */
-      err = svn_cl__print_conflict_stats(nwb.wrapped_baton, scratch_pool);
+      err = svn_cl__notifier_print_conflict_stats(nwb.wrapped_baton,
+                                                  scratch_pool);
       if (err)
         return svn_error_compose_create(externals_err, err);
     }
 
-  err = svn_cl__resolve_postponed_conflicts(ctx->conflict_baton2,
-                                            opt_state->depth,
+  err = svn_cl__resolve_postponed_conflicts(NULL,
+                                            ctx->conflict_baton2,
                                             opt_state->accept_which,
                                             opt_state->editor_cmd,
                                             ctx, scratch_pool);

Modified: subversion/branches/ev2-export/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/util.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/util.c (original)
+++ subversion/branches/ev2-export/subversion/svn/util.c Sat Feb 23 01:25:38 2013
@@ -54,8 +54,10 @@
 #include "svn_utf.h"
 #include "svn_subst.h"
 #include "svn_config.h"
+#include "svn_wc.h"
 #include "svn_xml.h"
 #include "svn_time.h"
+#include "svn_props.h"
 #include "svn_private_config.h"
 #include "cl.h"
 
@@ -972,9 +974,7 @@ svn_cl__assert_homogeneous_target_type(c
 
   err = svn_client__assert_homogeneous_target_type(targets);
   if (err && err->apr_err == SVN_ERR_ILLEGAL_TARGET)
-    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
-                             _("Cannot mix repository and working copy "
-                               "targets"));
+    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, err, NULL);
   return err;
 }
 
@@ -1053,3 +1053,59 @@ svn_cl__check_related_source_and_target(
     }
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_cl__propset_print_binary_mime_type_warning(apr_array_header_t *targets,
+                                               const char *propname,
+                                               const svn_string_t *propval,
+                                               apr_pool_t *scratch_pool)
+{
+  if (strcmp(propname, SVN_PROP_MIME_TYPE) == 0)
+    {
+      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+      int i;
+
+      for (i = 0; i < targets->nelts; i++)
+        {
+          const char *detected_mimetype;
+          const char *target = APR_ARRAY_IDX(targets, i, const char *);
+          const char *local_abspath;
+          const svn_string_t *canon_propval;
+          svn_node_kind_t node_kind;
+
+          svn_pool_clear(iterpool);
+
+          SVN_ERR(svn_dirent_get_absolute(&local_abspath, target, iterpool));
+          SVN_ERR(svn_io_check_path(local_abspath, &node_kind, iterpool));
+          if (node_kind != svn_node_file)
+            continue;
+
+          SVN_ERR(svn_wc_canonicalize_svn_prop(&canon_propval,
+                                               propname, propval,
+                                               local_abspath,
+                                               svn_node_file,
+                                               FALSE, NULL, NULL,
+                                               iterpool));
+
+          if (svn_mime_type_is_binary(canon_propval->data))
+            {
+              SVN_ERR(svn_io_detect_mimetype2(&detected_mimetype,
+                                              local_abspath, NULL,
+                                              iterpool));
+              if (detected_mimetype == NULL ||
+                  !svn_mime_type_is_binary(detected_mimetype))
+                svn_error_clear(svn_cmdline_fprintf(stderr, iterpool,
+                  _("svn: warning: '%s' is a binary mime-type but file '%s' "
+                    "looks like text; diff, merge, blame, and other "
+                    "operations will stop working on this file\n"),
+                    canon_propval->data,
+                    svn_dirent_local_style(local_abspath, iterpool)));
+                    
+            }
+        }
+      svn_pool_destroy(iterpool);
+    }
+
+  return SVN_NO_ERROR;
+}
+

Modified: subversion/branches/ev2-export/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svnadmin/svnadmin.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/ev2-export/subversion/svnadmin/svnadmin.c Sat Feb 23 01:25:38 2013
@@ -289,6 +289,8 @@ static const apr_getopt_option_t options
      N_("use repository format compatible with Subversion\n"
         "                             version ARG (\"1.5.5\", \"1.7\", etc.)")},
 
+    {"file", 'F', 1, N_("read repository paths from file ARG")},
+
     {NULL}
   };
 
@@ -336,9 +338,14 @@ static const svn_opt_subcommand_desc2_t 
   {'r', svnadmin__incremental, svnadmin__deltas, 'q', 'M'} },
 
   {"freeze", subcommand_freeze, {0}, N_
-   ("usage: svnadmin freeze REPOS_PATH PROGRAM [ARG...]\n\n"
-    "Run PROGRAM passing ARGS while holding a write-lock on REPOS_PATH.\n"),
-   {0} },
+   ("usage: 1. svnadmin freeze REPOS_PATH PROGRAM [ARG...]\n"
+    "               2. svnadmin freeze -F FILE PROGRAM [ARG...]\n\n"
+    "1. Run PROGRAM passing ARGS while holding a write-lock on REPOS_PATH.\n"
+    "\n"
+    "2. Like 1 except all repositories listed in FILE are locked. The file\n"
+    "   format is repository paths separated by newlines.  Repositories are\n"
+    "   locked in the same order as they are listed in the file.\n"),
+   {'F'} },
 
   {"help", subcommand_help, {"?", "h"}, N_
    ("usage: svnadmin help [SUBCOMMAND...]\n\n"
@@ -506,6 +513,7 @@ struct svnadmin_opt_state
                                                        --force-uuid */
   apr_uint64_t memory_cache_size;                   /* --memory-cache-size M */
   const char *parent_dir;
+  svn_stringbuf_t *filedata;                        /* --file */
 
   const char *config_dir;    /* Overriding Configuration Directory */
 };
@@ -759,10 +767,10 @@ repos_notify_handler(void *baton,
     case  svn_repos_notify_verify_struc_rev:
       if (notify->revision == SVN_INVALID_REVNUM)
         svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                                _("* Verifying global structure ...\n")));
+                                _("* Verifying repository metadata ...\n")));
       else
         svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                        _("* Verifying structure at revision %ld ...\n"),
+                        _("* Verifying metadata at revision %ld ...\n"),
                         notify->revision));
       return;
 
@@ -1028,6 +1036,7 @@ static svn_error_t *
 subcommand_freeze(apr_getopt_t *os, void *baton, apr_pool_t *pool)
 {
   struct svnadmin_opt_state *opt_state = baton;
+  apr_array_header_t *paths;
   apr_array_header_t *args;
   int i;
   struct freeze_baton_t b;
@@ -1038,13 +1047,25 @@ subcommand_freeze(apr_getopt_t *os, void
     return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0,
                             _("No program provided"));
 
+  if (!opt_state->filedata)
+    {
+      /* One repository on the command line. */
+      paths = apr_array_make(pool, 1, sizeof(const char *));
+      APR_ARRAY_PUSH(paths, const char *) = opt_state->repository_path;
+    }
+  else
+    {
+      /* All repositories in filedata. */
+      paths = svn_cstring_split(opt_state->filedata->data, "\n", FALSE, pool);
+    }
+
   b.command = APR_ARRAY_IDX(args, 0, const char *);
   b.args = apr_palloc(pool, sizeof(char *) * args->nelts + 1);
   for (i = 0; i < args->nelts; ++i)
     b.args[i] = APR_ARRAY_IDX(args, i, const char *);
   b.args[args->nelts] = NULL;
 
-  SVN_ERR(svn_repos_freeze(opt_state->repository_path, freeze_body, &b, pool));
+  SVN_ERR(svn_repos_freeze(paths, freeze_body, &b, pool));
 
   /* Make any non-zero status visible to the user. */
   if (b.status)
@@ -1902,6 +1923,7 @@ sub_main(int argc, const char *argv[], a
   int opt_id;
   apr_array_header_t *received_opts;
   int i;
+  svn_boolean_t dash_F_arg = FALSE;
 
   received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
 
@@ -1981,6 +2003,11 @@ sub_main(int argc, const char *argv[], a
         opt_state.memory_cache_size
             = 0x100000 * apr_strtoi64(opt_arg, NULL, 0);
         break;
+      case 'F':
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_INT_ERR(svn_stringbuf_from_file2(&(opt_state.filedata),
+                                             utf8_opt_arg, pool));
+        dash_F_arg = TRUE;
       case svnadmin__version:
         opt_state.version = TRUE;
         break;
@@ -2146,9 +2173,11 @@ sub_main(int argc, const char *argv[], a
         }
     }
 
-  /* Every subcommand except `help' requires a second argument -- the
-     repository path.  Parse it out here and store it in opt_state. */
-  if (subcommand->cmd_func != subcommand_help)
+  /* Every subcommand except `help' and `freeze' with '-F' require a
+     second argument -- the repository path.  Parse it out here and
+     store it in opt_state. */
+  if (!(subcommand->cmd_func == subcommand_help
+        || (subcommand->cmd_func == subcommand_freeze && dash_F_arg)))
     {
       const char *repos_path = NULL;
 



Mime
View raw message