subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From g..@apache.org
Subject svn commit: r1526487 [9/10] - in /subversion/branches/invoke-diff-cmd-feature: ./ build/ac-macros/ build/generator/ build/generator/templates/ contrib/client-side/emacs/ notes/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apach...
Date Thu, 26 Sep 2013 13:47:26 GMT
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svn/conflict-callbacks.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svn/conflict-callbacks.c Thu Sep 26 13:47:21 2013
@@ -399,31 +399,11 @@ launch_resolver(svn_boolean_t *performed
                 svn_cl__interactive_conflict_baton_t *b,
                 apr_pool_t *pool)
 {
-  svn_error_t *err;
-
-  err = svn_cl__merge_file_externally(desc->base_abspath, desc->their_abspath,
-                                      desc->my_abspath, desc->merged_file,
-                                      desc->local_abspath, b->config, NULL,
-                                      pool);
-  if (err && err->apr_err == SVN_ERR_CL_NO_EXTERNAL_MERGE_TOOL)
-    {
-      SVN_ERR(svn_cmdline_fprintf(stderr, pool, "%s\n",
-                                  err->message ? err->message :
-                                  _("No merge tool found, "
-                                    "try '(m) merge' instead.\n")));
-      svn_error_clear(err);
-    }
-  else if (err && err->apr_err == SVN_ERR_EXTERNAL_PROGRAM)
-    {
-      SVN_ERR(svn_cmdline_fprintf(stderr, pool, "%s\n",
-                                  err->message ? err->message :
-                             _("Error running merge tool, "
-                               "try '(m) merge' instead.")));
-      svn_error_clear(err);
-    }
-  else if (err)
-    return svn_error_trace(err);
-  else if (performed_edit)
+  SVN_ERR(svn_cl__merge_file_externally(desc->base_abspath, desc->their_abspath,
+                                        desc->my_abspath, desc->merged_file,
+                                        desc->local_abspath, b->config, NULL,
+                                        pool));
+  if (performed_edit)
     *performed_edit = TRUE;
 
   return SVN_NO_ERROR;
@@ -474,8 +454,8 @@ static const resolver_option_t text_conf
                                      "(same)  [theirs-full]"),
                                   svn_wc_conflict_choose_theirs_full },
   { "",   "",                     "", svn_wc_conflict_choose_unspecified },
-  { "m",  N_("merge"),            N_("use internal merge tool to resolve "
-                                     "conflict"), -1 },
+  { "m",  N_("merge"),            N_("use merge tool to resolve conflict"),
+                                     -1 },
   { "l",  N_("launch tool"),      N_("launch external tool to resolve "
                                      "conflict  [launch]"), -1 },
   { "p",  N_("postpone"),         N_("mark the conflict to be resolved later"
@@ -835,20 +815,35 @@ handle_text_conflict(svn_wc_conflict_res
       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)
+          svn_boolean_t remains_in_conflict;
+          svn_error_t *err;
+
+          err = launch_resolver(&performed_edit, desc, b, iterpool);
+          if (err)
             {
-              SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
-                                          _("Invalid option; can only "
-                                            "resolve text conflicts with "
-                                            "the internal merge tool."
-                                            "\n\n")));
-              continue;
+              if (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_MERGE_TOOL ||
+                  err->apr_err == SVN_ERR_EXTERNAL_PROGRAM)
+                {
+                  /* Try the internal merge tool. */
+                  svn_error_clear(err);
+                }
+              else
+                return svn_error_trace(err);
             }
 
-          if (desc->base_abspath && desc->their_abspath &&
+          if (!performed_edit &&
+              desc->base_abspath && desc->their_abspath &&
               desc->my_abspath && desc->merged_file)
             {
-              svn_boolean_t remains_in_conflict;
+              if (desc->kind != svn_wc_conflict_kind_text)
+                {
+                  SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
+                                              _("Invalid option; can only "
+                                                "resolve text conflicts with "
+                                                "the internal merge tool."
+                                                "\n\n")));
+                  continue;
+                }
 
               SVN_ERR(svn_cl__merge_file(desc->base_abspath,
                                          desc->their_abspath,
@@ -860,11 +855,13 @@ handle_text_conflict(svn_wc_conflict_res
                                          b->config,
                                          &remains_in_conflict,
                                          iterpool));
-              knows_something = !remains_in_conflict;
             }
           else
             SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                                         _("Invalid option.\n\n")));
+
+          if (performed_edit || !remains_in_conflict)
+            knows_something = TRUE;
         }
       else if (strcmp(opt->code, "l") == 0 || strcmp(opt->code, ":-l") == 0)
         {
@@ -875,7 +872,28 @@ handle_text_conflict(svn_wc_conflict_res
           if (desc->base_abspath && desc->their_abspath &&
               desc->my_abspath && desc->merged_file)
             {
-              SVN_ERR(launch_resolver(&performed_edit, desc, b, iterpool));
+              svn_error_t *err;
+
+              err = launch_resolver(&performed_edit, desc, b, iterpool);
+              if (err && err->apr_err == SVN_ERR_CL_NO_EXTERNAL_MERGE_TOOL)
+                {
+                  SVN_ERR(svn_cmdline_fprintf(stderr, iterpool, "%s\n",
+                                              err->message ? err->message :
+                                              _("No merge tool found, "
+                                                "try '(m) merge' instead.\n")));
+                  svn_error_clear(err);
+                }
+              else if (err && err->apr_err == SVN_ERR_EXTERNAL_PROGRAM)
+                {
+                  SVN_ERR(svn_cmdline_fprintf(stderr, iterpool, "%s\n",
+                                              err->message ? err->message :
+                                         _("Error running merge tool, "
+                                           "try '(m) merge' instead.")));
+                  svn_error_clear(err);
+                }
+              else if (err)
+                return svn_error_trace(err);
+
               if (performed_edit)
                 knows_something = TRUE;
             }

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svn/help-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svn/help-cmd.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svn/help-cmd.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svn/help-cmd.c Thu Sep 26 13:47:21 2013
@@ -32,7 +32,6 @@
 #include "svn_string.h"
 #include "svn_config.h"
 #include "svn_error.h"
-#include "svn_version.h"
 #include "cl.h"
 
 
@@ -47,10 +46,9 @@ svn_cl__help(apr_getopt_t *os,
   svn_cl__opt_state_t *opt_state = NULL;
   svn_stringbuf_t *version_footer = NULL;
 
-  /* xgettext: the %s is for SVN_VER_NUMBER. */
-  char help_header_template[] =
+  char help_header[] =
   N_("usage: svn <subcommand> [options] [args]\n"
-     "Subversion command-line client, version %s.\n"
+     "Subversion command-line client.\n"
      "Type 'svn help <subcommand>' for help on a specific subcommand.\n"
      "Type 'svn --version' to see the program version and RA modules\n"
      "  or 'svn --version --quiet' to see just the version number.\n"
@@ -65,9 +63,6 @@ svn_cl__help(apr_getopt_t *os,
   N_("Subversion is a tool for version control.\n"
      "For additional information, see http://subversion.apache.org/\n");
 
-  char *help_header =
-    apr_psprintf(pool, _(help_header_template), SVN_VER_NUMBER);
-
   const char *ra_desc_start
     = _("The following repository access (RA) modules are available:\n\n");
 

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svn/log-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svn/log-cmd.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svn/log-cmd.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svn/log-cmd.c Thu Sep 26 13:47:21 2013
@@ -687,6 +687,9 @@ svn_cl__log(apr_getopt_t *os,
   const char *target;
   int i;
   apr_array_header_t *revprops;
+  svn_move_behavior_t move_behavior = opt_state->auto_moves
+                                    ? svn_move_behavior_auto_moves
+                                    : svn_move_behavior_explicit_moves;
 
   if (!opt_state->xml)
     {
@@ -851,13 +854,14 @@ svn_cl__log(apr_getopt_t *os,
           if (!opt_state->quiet)
             APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_LOG;
         }
-      SVN_ERR(svn_client_log5(targets,
+      SVN_ERR(svn_client_log6(targets,
                               &lb.target_peg_revision,
                               opt_state->revision_ranges,
                               opt_state->limit,
                               opt_state->verbose,
                               opt_state->stop_on_copy,
                               opt_state->use_merge_history,
+                              move_behavior,
                               revprops,
                               log_entry_receiver_xml,
                               &lb,
@@ -874,13 +878,14 @@ svn_cl__log(apr_getopt_t *os,
       APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_DATE;
       if (!opt_state->quiet)
         APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_LOG;
-      SVN_ERR(svn_client_log5(targets,
+      SVN_ERR(svn_client_log6(targets,
                               &lb.target_peg_revision,
                               opt_state->revision_ranges,
                               opt_state->limit,
                               opt_state->verbose,
                               opt_state->stop_on_copy,
                               opt_state->use_merge_history,
+                              move_behavior,
                               revprops,
                               log_entry_receiver,
                               &lb,

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svn/svn.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svn/svn.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svn/svn.c Thu Sep 26 13:47:21 2013
@@ -119,6 +119,7 @@ typedef enum svn_cl__longopt_t {
   opt_with_revprop,
   opt_with_all_revprops,
   opt_with_no_revprops,
+  opt_auto_moves,
   opt_parents,
   opt_accept,
   opt_show_revs,
@@ -293,6 +294,10 @@ const apr_getopt_option_t svn_cl__option
                     N_("set revision property ARG in new revision\n"
                        "                             "
                        "using the name[=value] format")},
+  {"auto-moves",    opt_auto_moves, 0,
+                    N_("attempt to interpret matching unique DEL+ADD\n"
+                       "                             "
+                       "pairs as moves")},
   {"parents",       opt_parents, 0, N_("make intermediate directories")},
   {"use-merge-history", 'g', 0,
                     N_("use/display additional information from merge\n"
@@ -798,9 +803,9 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "    was created:\n"
      "      svn log --stop-on-copy --limit 1 -r0:HEAD ^/branches/foo\n"),
     {'r', 'q', 'v', 'g', 'c', opt_targets, opt_stop_on_copy, opt_incremental,
-     opt_xml, 'l', opt_with_all_revprops, opt_with_no_revprops, opt_with_revprop,
-     opt_depth, opt_diff, opt_diff_cmd, opt_internal_diff, 'x', opt_search,
-     opt_search_and, opt_invoke_diff_cmd },
+     opt_xml, 'l', opt_with_all_revprops, opt_with_no_revprops,
+     opt_with_revprop, opt_auto_moves, opt_depth, opt_diff, opt_diff_cmd,
+     opt_internal_diff, 'x', opt_search, opt_search_and },
     {{opt_with_revprop, N_("retrieve revision property ARG")},
      {'c', N_("the change made in revision ARG")}} },
 
@@ -2268,6 +2273,9 @@ sub_main(int argc, const char *argv[], a
       case 'g':
         opt_state.use_merge_history = TRUE;
         break;
+      case opt_auto_moves:
+        opt_state.auto_moves = TRUE;
+        break;
       case opt_accept:
         SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         opt_state.accept_which = svn_cl__accept_from_word(utf8_opt_arg);

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svnadmin/svnadmin.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svnadmin/svnadmin.c Thu Sep 26 13:47:21 2013
@@ -1180,6 +1180,7 @@ subcommand_help(apr_getopt_t *os, void *
   struct svnadmin_opt_state *opt_state = baton;
   const char *header =
     _("general usage: svnadmin SUBCOMMAND REPOS_PATH  [ARGS & OPTIONS ...]\n"
+      "Subversion repository administration tool.\n"
       "Type 'svnadmin help <subcommand>' for help on a specific subcommand.\n"
       "Type 'svnadmin --version' to see the program version and FS modules.\n"
       "\n"

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svnauth/svnauth.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svnauth/svnauth.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svnauth/svnauth.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svnauth/svnauth.c Thu Sep 26 13:47:21 2013
@@ -67,7 +67,8 @@ typedef enum svnauth__longopt_t {
 /** Subcommands. **/
 static svn_opt_subcommand_t
   subcommand_help,
-  subcommand_list;
+  subcommand_list,
+  subcommand_delete;
 
 /* Array of available subcommands.
  * The entire list must be terminated with an entry of nulls.
@@ -86,16 +87,36 @@ static const svn_opt_subcommand_desc2_t 
     "\n"
     "  If PATTERN is specified, only list credentials with attributes matching\n"
     "  the pattern. All attributes except passwords can be matched. If more than\n"
-    "  one pattern is specified, credentials are shown if their attributes match\n"
-    "  any of the patterns. Patterns are matched case-sensitively, and may\n"
-    "  contain glob wildcards:\n"
+    "  one pattern is specified credentials are shown if their attributes match\n"
+    "  all patterns. Patterns are matched case-sensitively and may contain\n"
+    "  glob wildcards:\n"
     "    ?      matches any single character\n"
     "    *      matches a sequence of arbitrary characters\n"
     "    [abc]  matches any of the characters listed inside the brackets\n"
+    "  Note that wildcards will usually need to be quoted or escaped on the\n"
+    "  command line because many command shells will interfere by trying to\n"
+    "  expand them.\n"
     "\n"
     "  If no pattern is specified, all cached credentials are shown.\n"),
    {opt_config_dir, opt_show_passwords} },
 
+  {"delete", subcommand_delete, {"del", "remove", "rm"}, N_
+   ("usage: svnauth delete PATTERN ...\n"
+    "\n"
+    "  Delete cached authentication credentials matching a pattern.\n"
+    "\n"
+    "  All credential attributes except passwords can be matched. If more than \n"
+    "  one pattern is specified credentials are deleted only if their attributes\n"
+    "  match all patterns. Patterns are matched case-sensitively and may contain\n"
+    "  glob wildcards:\n"
+    "    ?      matches any single character\n"
+    "    *      matches a sequence of arbitrary characters\n"
+    "    [abc]  matches any of the characters listed inside the brackets\n"
+    "  Note that wildcards will usually need to be quoted or escaped on the\n"
+    "  command line because many command shells will interfere by trying to\n"
+    "  expand them.\n"),
+   {opt_config_dir} },
+
   {NULL}
 };
 
@@ -140,11 +161,10 @@ parse_args(apr_array_header_t **args,
     SVN_ERR_ASSERT(args);
 
   if ((min_expected >= 0) && (num_args < min_expected))
-    return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0,
-                            "Not enough arguments");
+    return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
   if ((max_expected >= 0) && (num_args > max_expected))
     return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0,
-                            "Too many arguments");
+                            _("Too many arguments provided"));
   if (args)
     {
       *args = apr_array_make(pool, num_args, sizeof(const char *));
@@ -165,6 +185,7 @@ subcommand_help(apr_getopt_t *os, void *
   struct svnauth_opt_state *opt_state = baton;
   const char *header =
     _("general usage: svnauth SUBCOMMAND [ARGS & OPTIONS ...]\n"
+      "Subversion authentication credentials management tool.\n"
       "Type 'svnauth help <subcommand>' for help on a specific subcommand.\n"
       "Type 'svnauth --version' to see the program version and available\n"
       "authentication credential caches.\n"
@@ -515,7 +536,9 @@ show_cert_failures(const char *failure_s
 
 struct walk_credentials_baton_t
 {
+  int matches;
   svn_boolean_t list;
+  svn_boolean_t delete;
   svn_boolean_t show_passwords;
   apr_array_header_t *patterns;
 };
@@ -747,9 +770,18 @@ walk_credentials(svn_boolean_t *delete_c
         return SVN_NO_ERROR;
     }
 
+  b->matches++;
+
   if (b->list)
     SVN_ERR(list_credential(cred_kind, realmstring, sorted_cred_items,
                             b->show_passwords, scratch_pool));
+  if (b->delete)
+    {
+      *delete_cred = TRUE;
+      SVN_ERR(svn_cmdline_printf(scratch_pool,
+                                 _("Deleting %s credential for realm '%s'\n"),
+                                 cred_kind, realmstring));
+    }
 
   return SVN_NO_ERROR;
 }
@@ -763,8 +795,10 @@ subcommand_list(apr_getopt_t *os, void *
   const char *config_path;
   struct walk_credentials_baton_t b;
 
+  b.matches = 0;
   b.show_passwords = opt_state->show_passwords;
   b.list = TRUE;
+  b.delete = FALSE;
   SVN_ERR(parse_args(&b.patterns, os, 0, -1, pool));
 
   SVN_ERR(svn_config_get_user_config_path(&config_path,
@@ -773,6 +807,67 @@ subcommand_list(apr_getopt_t *os, void *
 
   SVN_ERR(svn_config_walk_auth_data(config_path, walk_credentials, &b,
                                     pool));
+
+  if (b.matches == 0)
+    {
+      if (b.patterns->nelts == 0)
+        SVN_ERR(svn_cmdline_printf(pool,
+                                   _("Credentials cache in '%s' is empty\n"),
+                                   svn_dirent_local_style(config_path, pool)));
+      else 
+        return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, 0,
+                                 _("Credentials cache in '%s' contains "
+                                   "no matching credentials"),
+                                 svn_dirent_local_style(config_path, pool));
+    }
+  else
+    {
+      if (b.patterns->nelts == 0)
+        SVN_ERR(svn_cmdline_printf(pool,
+                                   _("Credentials cache in '%s' contains %d "
+                                     "credentials\n"),
+                                   svn_dirent_local_style(config_path, pool),
+                                   b.matches));
+      else
+        SVN_ERR(svn_cmdline_printf(pool,
+                                   _("Credentials cache in '%s' contains %d "
+                                     "matching credentials\n"),
+                                   svn_dirent_local_style(config_path, pool),
+                                   b.matches));
+    }
+  return SVN_NO_ERROR;
+}
+
+/* This implements `svn_opt_subcommand_t'. */
+static svn_error_t *
+subcommand_delete(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+  struct svnauth_opt_state *opt_state = baton;
+  const char *config_path;
+  struct walk_credentials_baton_t b;
+
+  b.matches = 0;
+  b.show_passwords = opt_state->show_passwords;
+  b.list = FALSE;
+  b.delete = TRUE;
+  SVN_ERR(parse_args(&b.patterns, os, 1, -1, pool));
+
+  SVN_ERR(svn_config_get_user_config_path(&config_path,
+                                          opt_state->config_dir, NULL,
+                                          pool));
+
+  SVN_ERR(svn_config_walk_auth_data(config_path, walk_credentials, &b, pool));
+
+  if (b.matches == 0)
+    return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, 0,
+                             _("Credentials cache in '%s' contains "
+                               "no matching credentials"),
+                             svn_dirent_local_style(config_path, pool));
+  else
+    SVN_ERR(svn_cmdline_printf(pool, _("Deleted %d matching credentials "
+                               "from '%s'\n"), b.matches,
+                               svn_dirent_local_style(config_path, pool)));
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svndumpfilter/svndumpfilter.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svndumpfilter/svndumpfilter.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svndumpfilter/svndumpfilter.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svndumpfilter/svndumpfilter.c Thu Sep 26 13:47:21 2013
@@ -1146,6 +1146,7 @@ subcommand_help(apr_getopt_t *os, void *
   struct svndumpfilter_opt_state *opt_state = baton;
   const char *header =
     _("general usage: svndumpfilter SUBCOMMAND [ARGS & OPTIONS ...]\n"
+      "Subversion repository dump filtering tool.\n"
       "Type 'svndumpfilter help <subcommand>' for help on a "
       "specific subcommand.\n"
       "Type 'svndumpfilter --version' to see the program version.\n"

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svnlook/svnlook.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svnlook/svnlook.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svnlook/svnlook.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svnlook/svnlook.c Thu Sep 26 13:47:21 2013
@@ -2237,11 +2237,12 @@ subcommand_help(apr_getopt_t *os, void *
   struct svnlook_opt_state *opt_state = baton;
   const char *header =
     _("general usage: svnlook SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]\n"
+      "Subversion repository inspection tool.\n"
+      "Type 'svnlook help <subcommand>' for help on a specific subcommand.\n"
+      "Type 'svnlook --version' to see the program version and FS modules.\n"
       "Note: any subcommand which takes the '--revision' and '--transaction'\n"
       "      options will, if invoked without one of those options, act on\n"
       "      the repository's youngest revision.\n"
-      "Type 'svnlook help <subcommand>' for help on a specific subcommand.\n"
-      "Type 'svnlook --version' to see the program version and FS modules.\n"
       "\n"
       "Available subcommands:\n");
 

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svnmucc/svnmucc.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svnmucc/svnmucc.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svnmucc/svnmucc.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svnmucc/svnmucc.c Thu Sep 26 13:47:21 2013
@@ -922,8 +922,9 @@ usage(apr_pool_t *pool, int exit_val)
 {
   FILE *stream = exit_val == EXIT_SUCCESS ? stdout : stderr;
   svn_error_clear(svn_cmdline_fputs(
-    _("Subversion multiple URL command client\n"
-      "usage: svnmucc ACTION...\n"
+    _("usage: svnmucc ACTION...\n"
+      "Subversion multiple URL command client.\n"
+      "Type 'svnmucc --version' to see the program version.\n"
       "\n"
       "  Perform one or more Subversion repository URL-based ACTIONs, committing\n"
       "  the result as a (single) new revision.\n"

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svnrdump/svnrdump.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svnrdump/svnrdump.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svnrdump/svnrdump.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svnrdump/svnrdump.c Thu Sep 26 13:47:21 2013
@@ -666,22 +666,20 @@ version(const char *progname,
 }
 
 
-/* A statement macro, similar to @c SVN_ERR, but returns an integer.
- * Evaluate @a expr. If it yields an error, handle that error and
- * return @c EXIT_FAILURE.
- */
-#define SVNRDUMP_ERR(expr)                                               \
-  do                                                                     \
-    {                                                                    \
-      svn_error_t *svn_err__temp = (expr);                               \
-      if (svn_err__temp)                                                 \
-        {                                                                \
-          svn_handle_error2(svn_err__temp, stderr, FALSE, "svnrdump: "); \
-          svn_error_clear(svn_err__temp);                                \
-          return EXIT_FAILURE;                                           \
-        }                                                                \
-    }                                                                    \
-  while (0)
+/* Report and clear the error ERR, and return EXIT_FAILURE. */
+#define EXIT_ERROR(err)                                                 \
+  svn_cmdline_handle_exit_error(err, NULL, "svnrdump: ")
+
+/* A redefinition of the public SVN_INT_ERR macro, that suppresses the
+ * error message if it is SVN_ERR_IO_PIPE_WRITE_ERROR, and with the
+ * program name 'svnrdump' instead of 'svn'. */
+#undef SVN_INT_ERR
+#define SVN_INT_ERR(expr)                                        \
+  do {                                                           \
+    svn_error_t *svn_err__temp = (expr);                         \
+    if (svn_err__temp)                                           \
+      return EXIT_ERROR(svn_err__temp);                          \
+  } while (0)
 
 /* Handle the "dump" subcommand.  Implements `svn_opt_subcommand_t'.  */
 static svn_error_t *
@@ -728,6 +726,7 @@ help_cmd(apr_getopt_t *os,
 {
   const char *header =
     _("general usage: svnrdump SUBCOMMAND URL [-r LOWER[:UPPER]]\n"
+      "Subversion remote repository dump and load tool.\n"
       "Type 'svnrdump help <subcommand>' for help on a specific subcommand.\n"
       "Type 'svnrdump --version' to see the program version and RA modules.\n"
       "\n"
@@ -830,14 +829,13 @@ validate_and_resolve_revisions(opt_baton
   return SVN_NO_ERROR;
 }
 
-int
-main(int argc, const char **argv)
+static int
+sub_main(int argc, const char *argv[], apr_pool_t *pool)
 {
   svn_error_t *err = SVN_NO_ERROR;
   const svn_opt_subcommand_desc2_t *subcommand = NULL;
   opt_baton_t *opt_baton;
   svn_revnum_t latest_revision = SVN_INVALID_REVNUM;
-  apr_pool_t *pool = NULL;
   const char *config_dir = NULL;
   const char *username = NULL;
   const char *password = NULL;
@@ -851,20 +849,12 @@ main(int argc, const char **argv)
   apr_array_header_t *received_opts;
   int i;
 
-  if (svn_cmdline_init ("svnrdump", stderr) != EXIT_SUCCESS)
-    return EXIT_FAILURE;
-
-  /* Create our top-level pool.  Use a separate mutexless allocator,
-   * given this application is single threaded.
-   */
-  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
-
   opt_baton = apr_pcalloc(pool, sizeof(*opt_baton));
   opt_baton->start_revision.kind = svn_opt_revision_unspecified;
   opt_baton->end_revision.kind = svn_opt_revision_unspecified;
   opt_baton->url = NULL;
 
-  SVNRDUMP_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
+  SVN_INT_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
 
   os->interleave = TRUE; /* Options and arguments can be interleaved */
 
@@ -904,8 +894,8 @@ main(int argc, const char **argv)
         break;
       if (status != APR_SUCCESS)
         {
-          SVNRDUMP_ERR(usage(argv[0], pool));
-          exit(EXIT_FAILURE);
+          SVN_INT_ERR(usage(argv[0], pool));
+          return EXIT_FAILURE;
         }
 
       /* Stash the option code in an array before parsing it. */
@@ -922,7 +912,7 @@ main(int argc, const char **argv)
                                        _("Multiple revision arguments "
                                          "encountered; try '-r N:M' instead "
                                          "of '-r N -r M'"));
-                return svn_cmdline_handle_exit_error(err, pool, "svnrdump: ");
+                return EXIT_ERROR(err);
               }
             /* Parse the -r argument. */
             if (svn_opt_parse_revision(&(opt_baton->start_revision),
@@ -935,7 +925,7 @@ main(int argc, const char **argv)
                   err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                           _("Syntax error in revision "
                                             "argument '%s'"), utf8_opt_arg);
-                return svn_cmdline_handle_exit_error(err, pool, "svnrdump: ");
+                return EXIT_ERROR(err);
               }
           }
           break;
@@ -952,10 +942,10 @@ main(int argc, const char **argv)
           opt_baton->help = TRUE;
           break;
         case opt_auth_username:
-          SVNRDUMP_ERR(svn_utf_cstring_to_utf8(&username, opt_arg, pool));
+          SVN_INT_ERR(svn_utf_cstring_to_utf8(&username, opt_arg, pool));
           break;
         case opt_auth_password:
-          SVNRDUMP_ERR(svn_utf_cstring_to_utf8(&password, opt_arg, pool));
+          SVN_INT_ERR(svn_utf_cstring_to_utf8(&password, opt_arg, pool));
           break;
         case opt_auth_nocache:
           no_auth_cache = TRUE;
@@ -978,9 +968,9 @@ main(int argc, const char **argv)
                     apr_array_make(pool, 1,
                                    sizeof(svn_cmdline__config_argument_t*));
 
-            SVNRDUMP_ERR(svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool));
-            SVNRDUMP_ERR(svn_cmdline__parse_config_option(config_options,
-                                                          opt_arg, pool));
+            SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool));
+            SVN_INT_ERR(svn_cmdline__parse_config_option(config_options,
+                                                         opt_arg, pool));
         }
     }
 
@@ -991,7 +981,7 @@ main(int argc, const char **argv)
       err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                              _("--non-interactive and --force-interactive "
                                "are mutually exclusive"));
-      return svn_cmdline_handle_exit_error(err, pool, "svnrdump: ");
+      return EXIT_ERROR(err);
     }
 
   if (opt_baton->help)
@@ -1016,9 +1006,8 @@ main(int argc, const char **argv)
 
           else
             {
-              SVNRDUMP_ERR(help_cmd(NULL, NULL, pool));
-              svn_pool_destroy(pool);
-              exit(EXIT_FAILURE);
+              SVN_INT_ERR(help_cmd(NULL, NULL, pool));
+              return EXIT_FAILURE;
             }
         }
       else
@@ -1032,14 +1021,13 @@ main(int argc, const char **argv)
               const char *first_arg_utf8;
               err = svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg, pool);
               if (err)
-                return svn_cmdline_handle_exit_error(err, pool, "svnrdump: ");
+                return EXIT_ERROR(err);
               svn_error_clear(
                 svn_cmdline_fprintf(stderr, pool,
                                     _("Unknown subcommand: '%s'\n"),
                                     first_arg_utf8));
-              SVNRDUMP_ERR(help_cmd(NULL, NULL, pool));
-              svn_pool_destroy(pool);
-              exit(EXIT_FAILURE);
+              SVN_INT_ERR(help_cmd(NULL, NULL, pool));
+              return EXIT_FAILURE;
             }
         }
     }
@@ -1071,23 +1059,20 @@ main(int argc, const char **argv)
                                 _("Subcommand '%s' doesn't accept option '%s'\n"
                                   "Type 'svnrdump help %s' for usage.\n"),
                                 subcommand->name, optstr, subcommand->name));
-          svn_pool_destroy(pool);
           return EXIT_FAILURE;
         }
     }
 
   if (strcmp(subcommand->name, "--version") == 0)
     {
-      SVNRDUMP_ERR(version(argv[0], opt_baton->quiet, pool));
-      svn_pool_destroy(pool);
-      exit(EXIT_SUCCESS);
+      SVN_INT_ERR(version(argv[0], opt_baton->quiet, pool));
+      return EXIT_SUCCESS;
     }
 
   if (strcmp(subcommand->name, "help") == 0)
     {
-      SVNRDUMP_ERR(help_cmd(os, opt_baton, pool));
-      svn_pool_destroy(pool);
-      exit(EXIT_SUCCESS);
+      SVN_INT_ERR(help_cmd(os, opt_baton, pool));
+      return EXIT_SUCCESS;
     }
 
   /* --trust-server-cert can only be used with --non-interactive */
@@ -1096,30 +1081,27 @@ main(int argc, const char **argv)
       err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                              _("--trust-server-cert requires "
                                "--non-interactive"));
-      return svn_cmdline_handle_exit_error(err, pool, "svnrdump: ");
+      return EXIT_ERROR(err);
     }
 
   /* Expect one more non-option argument:  the repository URL. */
   if (os->ind != os->argc - 1)
     {
-      SVNRDUMP_ERR(usage(argv[0], pool));
-      svn_pool_destroy(pool);
-      exit(EXIT_FAILURE);
+      SVN_INT_ERR(usage(argv[0], pool));
+      return EXIT_FAILURE;
     }
   else
     {
       const char *repos_url;
 
-      SVNRDUMP_ERR(svn_utf_cstring_to_utf8(&repos_url,
-                                           os->argv[os->ind], pool));
+      SVN_INT_ERR(svn_utf_cstring_to_utf8(&repos_url,
+                                          os->argv[os->ind], pool));
       if (! svn_path_is_url(repos_url))
         {
           err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, 0,
                                   "Target '%s' is not a URL",
                                   repos_url);
-          SVNRDUMP_ERR(err);
-          svn_pool_destroy(pool);
-          exit(EXIT_FAILURE);
+          return EXIT_ERROR(err);
         }
       opt_baton->url = svn_uri_canonicalize(repos_url, pool);
     }
@@ -1140,16 +1122,16 @@ main(int argc, const char **argv)
   non_interactive = !svn_cmdline__be_interactive(non_interactive,
                                                  force_interactive);
 
-  SVNRDUMP_ERR(init_client_context(&(opt_baton->ctx),
-                                   non_interactive,
-                                   username,
-                                   password,
-                                   config_dir,
-                                   opt_baton->url,
-                                   no_auth_cache,
-                                   trust_server_cert,
-                                   config_options,
-                                   pool));
+  SVN_INT_ERR(init_client_context(&(opt_baton->ctx),
+                                  non_interactive,
+                                  username,
+                                  password,
+                                  config_dir,
+                                  opt_baton->url,
+                                  no_auth_cache,
+                                  trust_server_cert,
+                                  config_options,
+                                  pool));
 
   err = svn_client_open_ra_session2(&(opt_baton->session),
                                     opt_baton->url, NULL,
@@ -1174,11 +1156,31 @@ main(int argc, const char **argv)
                                  _("Authentication failed and interactive"
                                    " prompting is disabled; see the"
                                    " --force-interactive option"));
+      return EXIT_ERROR(err);
     }
+  else if (err)
+    return EXIT_ERROR(err);
+  else
+    return EXIT_SUCCESS;
+}
 
-  SVNRDUMP_ERR(err);
+int
+main(int argc, const char *argv[])
+{
+  apr_pool_t *pool;
+  int exit_code;
 
-  svn_pool_destroy(pool);
+  /* Initialize the app. */
+  if (svn_cmdline_init("svnrdump", stderr) != EXIT_SUCCESS)
+    return EXIT_FAILURE;
 
-  return EXIT_SUCCESS;
+  /* Create our top-level pool.  Use a separate mutexless allocator,
+   * given this application is single threaded.
+   */
+  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
+
+  exit_code = sub_main(argc, argv, pool);
+
+  svn_pool_destroy(pool);
+  return exit_code;
 }

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/serve.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/serve.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/serve.c Thu Sep 26 13:47:21 2013
@@ -112,21 +112,16 @@ log_write(apr_file_t *log_file, const ch
   return svn_io_file_write(log_file, errstr, &len, pool);
 }
 
-void
-log_error(svn_error_t *err, apr_file_t *log_file, const char *remote_host,
-          const char *user, const char *repos, apr_pool_t *pool)
+static void
+log_error_internal(svn_error_t *err, apr_file_t *log_file,
+                   const char *remote_host, const char *user,
+                   const char *repos, apr_pool_t *pool)
 {
   const char *timestr, *continuation;
   char errbuf[256];
   /* 8192 from MAX_STRING_LEN in from httpd-2.2.4/include/httpd.h */
   char errstr[8192];
 
-  if (err == SVN_NO_ERROR)
-    return;
-
-  if (log_file == NULL)
-    return;
-
   timestr = svn_time_to_cstring(apr_time_now(), pool);
   remote_host = (remote_host ? remote_host : "-");
   user = (user ? user : "-");
@@ -160,13 +155,41 @@ log_error(svn_error_t *err, apr_file_t *
     }
 }
 
+
+void
+log_error(svn_error_t *err, apr_file_t *log_file,
+          svn_mutex__t *log_file_mutex, const char *remote_host,
+          const char *user, const char *repos, apr_pool_t *pool)
+{
+  if (err == SVN_NO_ERROR)
+    return;
+
+  if (log_file == NULL)
+    return;
+
+  if (log_file_mutex)
+    {
+      /* if the mutex functions fail, things look pretty grim.
+       * 
+       * Our best hope is to try to get some info into the log before
+       * everything breaks apart.  Therefore, ignore any mutex errors.
+       */
+      svn_error_clear(svn_mutex__lock(log_file_mutex));
+      log_error_internal(err, log_file, remote_host, user, repos, pool);
+      svn_error_clear(svn_mutex__unlock(log_file_mutex, SVN_NO_ERROR));
+    }
+  else
+    log_error_internal(err, log_file, remote_host, user, repos, pool);
+}
+
 /* Call log_error with log_file, remote_host, user, and repos
    arguments from SERVER and CONN. */
 static void
 log_server_error(svn_error_t *err, server_baton_t *server,
                  svn_ra_svn_conn_t *conn, apr_pool_t *pool)
 {
-  log_error(err, server->log_file, svn_ra_svn_conn_remote_host(conn),
+  log_error(err, server->log_file, server->log_file_mutex,
+            svn_ra_svn_conn_remote_host(conn),
             server->user, server->repos_name, pool);
 }
 
@@ -2184,18 +2207,20 @@ static svn_error_t *log_cmd(svn_ra_svn_c
   char *revprop_word;
   svn_ra_svn_item_t *elt;
   int i;
-  apr_uint64_t limit, include_merged_revs_param;
+  apr_uint64_t limit, include_merged_revs_param, move_behavior_param;
+  svn_move_behavior_t move_behavior;
   log_baton_t lb;
   authz_baton_t ab;
 
   ab.server = b;
   ab.conn = conn;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "l(?r)(?r)bb?n?Bwl", &paths,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "l(?r)(?r)bb?n?Bwl?n", &paths,
                                   &start_rev, &end_rev, &send_changed_paths,
                                   &strict_node, &limit,
                                   &include_merged_revs_param,
-                                  &revprop_word, &revprop_items));
+                                  &revprop_word, &revprop_items,
+                                  &move_behavior_param));
 
   if (include_merged_revs_param == SVN_RA_SVN_UNSPECIFIED_NUMBER)
     include_merged_revisions = FALSE;
@@ -2227,6 +2252,16 @@ static svn_error_t *log_cmd(svn_ra_svn_c
                              _("Unknown revprop word '%s' in log command"),
                              revprop_word);
 
+  if (move_behavior_param == SVN_RA_SVN_UNSPECIFIED_NUMBER)
+    move_behavior = svn_move_behavior_no_moves;
+  else if (move_behavior_param <= svn_move_behavior_auto_moves)
+    move_behavior = (svn_move_behavior_t) move_behavior_param;
+  else
+    return svn_error_createf(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+                             _("Invalid move_behavior value %"
+                               APR_UINT64_T_FMT " in log command"),
+                             move_behavior_param);
+
   /* If we got an unspecified number then the user didn't send us anything,
      so we assume no limit.  If it's larger than INT_MAX then someone is
      messing with us, since we know the svn client libraries will never send
@@ -2257,11 +2292,11 @@ static svn_error_t *log_cmd(svn_ra_svn_c
   lb.fs_path = b->fs_path->data;
   lb.conn = conn;
   lb.stack_depth = 0;
-  err = svn_repos_get_logs4(b->repos, full_paths, start_rev, end_rev,
+  err = svn_repos_get_logs5(b->repos, full_paths, start_rev, end_rev,
                             (int) limit, send_changed_paths, strict_node,
-                            include_merged_revisions, revprops,
-                            authz_check_access_cb_func(b), &ab, log_receiver,
-                            &lb, pool);
+                            include_merged_revisions, move_behavior,
+                            revprops, authz_check_access_cb_func(b),
+                            &ab, log_receiver, &lb, pool);
 
   write_err = svn_ra_svn__write_word(conn, pool, "done");
   if (write_err)
@@ -3531,6 +3566,7 @@ svn_error_t *serve(svn_ra_svn_conn_t *co
   b.authzdb = NULL;
   b.realm = NULL;
   b.log_file = params->log_file;
+  b.log_file_mutex = params->log_file_mutex;
   b.pool = pool;
   b.use_sasl = FALSE;
   b.vhost = params->vhost;
@@ -3635,8 +3671,8 @@ svn_error_t *serve(svn_ra_svn_conn_t *co
     }
   if (err)
     {
-      log_error(err, b.log_file, svn_ra_svn_conn_remote_host(conn),
-                b.user, NULL, pool);
+      log_error(err, b.log_file, b.log_file_mutex,
+                svn_ra_svn_conn_remote_host(conn), b.user, NULL, pool);
       io_err = svn_ra_svn__write_cmd_failure(conn, pool, err);
       svn_error_clear(err);
       SVN_ERR(io_err);

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/server.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/server.h?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/server.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/server.h Thu Sep 26 13:47:21 2013
@@ -36,6 +36,8 @@ extern "C" {
 #include "svn_repos.h"
 #include "svn_ra_svn.h"
 
+#include "private/svn_mutex.h"
+
 enum username_case_type { CASE_FORCE_UPPER, CASE_FORCE_LOWER, CASE_ASIS };
 
 typedef struct server_baton_t {
@@ -60,6 +62,8 @@ typedef struct server_baton_t {
   svn_boolean_t use_sasl;  /* Use Cyrus SASL for authentication;
                               always false if SVN_HAVE_SASL not defined */
   apr_file_t *log_file;    /* Log filehandle. */
+  svn_mutex__t *log_file_mutex; /* Serializes access to log_file.
+                              May be NULL even if log_file is not. */
   svn_boolean_t vhost;     /* Use virtual-host-based path to repo. */
   apr_pool_t *pool;
 } server_baton_t;
@@ -100,6 +104,9 @@ typedef struct serve_params_t {
   /* A filehandle open for writing logs to; possibly NULL. */
   apr_file_t *log_file;
 
+  /* Mutex to serialize access to log_file; possibly NULL. */
+  svn_mutex__t *log_file_mutex;
+
   /* Username case normalization style. */
   enum username_case_type username_case;
 
@@ -162,11 +169,14 @@ svn_error_t *cyrus_auth_request(svn_ra_s
 apr_size_t escape_errorlog_item(char *dest, const char *source,
                                 apr_size_t buflen);
 
-/* Log ERR to LOG_FILE if LOG_FILE is not NULL.  Include REMOTE_HOST,
-   USER, and REPOS in the log if they are not NULL.  Allocate temporary
-   char buffers in POOL (which caller can then clear or dispose of). */
+/* Log ERR to LOG_FILE if LOG_FILE is not NULL.  In multi-threaded
+   servers, you should also provide a LOG_FILE_MUTEX object to serialize
+   access to the log file.   Include REMOTE_HOST, USER, and REPOS in the
+   log if they are not NULL.  Allocate temporary char buffers in POOL
+   (which caller can then clear or dispose of). */
 void
-log_error(svn_error_t *err, apr_file_t *log_file, const char *remote_host,
+log_error(svn_error_t *err, apr_file_t *log_file,
+          svn_mutex__t *log_file_mutex, const char *remote_host,
           const char *user, const char *repos, apr_pool_t *pool);
 
 #ifdef __cplusplus

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/svnserve.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/svnserve.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/svnserve.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svnserve/svnserve.c Thu Sep 26 13:47:21 2013
@@ -54,6 +54,21 @@
 #include "private/svn_dep_compat.h"
 #include "private/svn_cmdline_private.h"
 #include "private/svn_atomic.h"
+#include "private/svn_mutex.h"
+
+/* Alas! old APR-Utils don't provide thread pools */
+#if APR_HAS_THREADS
+#  if APR_VERSION_AT_LEAST(1,3,0)
+#    include <apr_thread_pool.h>
+#    define HAVE_THREADPOOLS 1
+#    define THREAD_ERROR_MSG _("Can't push task")
+#  else
+#    define HAVE_THREADPOOLS 0
+#    define THREAD_ERROR_MSG _("Can't create thread")
+#  endif
+#else
+#  define HAVE_THREADPOOLS 0
+#endif
 
 #include "winservice.h"
 
@@ -102,6 +117,50 @@ enum run_mode {
 
 #endif
 
+/* Parameters for the worker thread pool used in threaded mode. */
+
+/* Have at least this many worker threads (even if there are no requests
+ * to handle).
+ *
+ * A 0 value is legal but increases the latency for the next incoming
+ * request.  Higher values may be useful for servers that experience short
+ * bursts of concurrent requests followed by longer idle periods.
+ */
+#define THREADPOOL_MIN_SIZE 1
+
+/* Maximum number of worker threads.  If there are more concurrent requests
+ * than worker threads, the extra requests get queued.
+ *
+ * Since very slow connections will hog a full thread for a potentially
+ * long time before timing out, be sure to not set this limit too low.
+ * 
+ * On the other hand, keep in mind that every thread will allocate up to
+ * 4MB of unused RAM in the APR allocator of its root pool.  32 bit servers
+ * must hence do with fewer threads.
+ */
+#if (APR_SIZEOF_VOIDP <= 4)
+#define THREADPOOL_MAX_SIZE 64
+#else
+#define THREADPOOL_MAX_SIZE 256
+#endif
+
+/* Number of microseconds that an unused thread remains in the pool before
+ * being terminated.
+ *
+ * Higher values are useful if clients frequently send small requests and
+ * you want to minimize the latency for those.
+ */
+#define THREADPOOL_THREAD_IDLE_LIMIT 1000000
+
+/* Number of client to server connections that may concurrently in the
+ * TCP 3-way handshake state, i.e. are in the process of being created.
+ *
+ * Larger values improve scalability with lots of small requests comming
+ * on over long latency networks.
+ * 
+ * The OS may actually use a lower limit than specified here.
+ */
+#define ACCEPT_BACKLOG 128
 
 #ifdef WIN32
 static apr_os_sock_t winservice_svnserve_accept_socket = INVALID_SOCKET;
@@ -224,7 +283,7 @@ static const apr_getopt_option_t svnserv
         "                             "
         "revisions.\n"
         "                             "
-        "Default is no.\n"
+        "Default is yes.\n"
         "                             "
         "[used for FSFS repositories only]")},
     {"cache-fulltexts", SVNSERVE_OPT_CACHE_FULLTEXTS, 1,
@@ -291,6 +350,13 @@ static const apr_getopt_option_t svnserv
     {0,                  0,   0, 0}
   };
 
+/* unused connection pools.
+ * Use CONNECTION_POOLS_MUTEX to serialize access to this collection.
+ */
+apr_array_header_t *connection_pools = NULL;
+
+/* Mutex to serialize access to connection_pools */
+svn_mutex__t *connection_pools_mutex = NULL;
 
 static void usage(const char *progname, apr_pool_t *pool)
 {
@@ -310,15 +376,21 @@ static void help(apr_pool_t *pool)
 #ifdef WIN32
   svn_error_clear(svn_cmdline_fputs(_("usage: svnserve [-d | -i | -t | -X "
                                       "| --service] [options]\n"
+                                      "Subversion repository server.\n"
+                                      "Type 'svnserve --version' to see the "
+                                      "program version.\n"
                                       "\n"
                                       "Valid options:\n"),
-                                    stdout, pool));
+                                      stdout, pool));
 #else
   svn_error_clear(svn_cmdline_fputs(_("usage: svnserve [-d | -i | -t | -X] "
                                       "[options]\n"
+                                      "Subversion repository server.\n"
+                                      "Type 'svnserve --version' to see the "
+                                      "program version.\n"
                                       "\n"
                                       "Valid options:\n"),
-                                    stdout, pool));
+                                      stdout, pool));
 #endif
   for (i = 0; svnserve__options[i].name && svnserve__options[i].optch; i++)
     {
@@ -379,6 +451,74 @@ static apr_status_t redirect_stdout(void
   return apr_file_dup2(out_file, err_file, pool);
 }
 
+/* Create the global collection object for unused connection pools plus
+ * the necessary mutex.  Their lifetime will be bound to POOL.
+ */
+static svn_error_t *
+initialize_connection_pools(apr_pool_t *pool)
+{
+  SVN_ERR(svn_mutex__init(&connection_pools_mutex, TRUE, pool));
+  connection_pools = apr_array_make(pool, 16, sizeof(apr_pool_t *));
+
+  return SVN_NO_ERROR;
+}
+
+/* Return a currently unused connection pool in *POOL. If no such pool
+ * exists, create a new root pool and return that in *POOL.
+ */
+static svn_error_t *
+acquire_connection_pool_internal(apr_pool_t **pool)
+{
+  SVN_ERR(svn_mutex__lock(connection_pools_mutex));
+  *pool = connection_pools->nelts
+        ? *(apr_pool_t **)apr_array_pop(connection_pools)
+        : apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
+  SVN_ERR(svn_mutex__unlock(connection_pools_mutex, SVN_NO_ERROR));
+    
+  return SVN_NO_ERROR;
+}
+
+/* Return a currently unused connection pool. If no such pool exists,
+ * create a new root pool and return that.
+ */
+static apr_pool_t *
+acquire_connection_pool(void)
+{
+  apr_pool_t *pool;
+  svn_error_t *err = acquire_connection_pool_internal(&pool);
+  if (err)
+    {
+      /* Mutex failure?!  Well, try to continue with unrecycled data. */
+      svn_error_clear(err);
+      pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
+    }
+
+  return pool;
+}
+
+/* Clear and release the given connection POOL.
+ */
+static void
+release_connection_pool(apr_pool_t *pool)
+{
+  svn_error_t *err;
+
+  svn_pool_clear(pool);
+
+  err = svn_mutex__lock(connection_pools_mutex);
+  if (err)
+    {
+      svn_error_clear(err);
+      svn_pool_destroy(pool);
+    }
+  else
+    {
+      APR_ARRAY_PUSH(connection_pools, apr_pool_t *) = pool;
+      svn_error_clear(svn_mutex__unlock(connection_pools_mutex,
+                                        SVN_NO_ERROR));
+    }
+}
+
 #if APR_HAS_THREADS
 /* The pool passed to apr_thread_create can only be released when both
 
@@ -408,13 +548,55 @@ static void
 release_shared_pool(struct shared_pool_t *shared)
 {
   if (svn_atomic_dec(&shared->count) == 0)
-    svn_pool_destroy(shared->pool);
+    release_connection_pool(shared->pool);
 }
 #endif
 
+/* Wrapper around serve() that takes a socket instead of a connection.
+ * This is to off-load work from the main thread in threaded and fork modes.
+ */
+static svn_error_t *
+serve_socket(apr_socket_t *usock,
+             serve_params_t *params,
+             apr_pool_t *pool)
+{
+  apr_status_t status;
+  svn_ra_svn_conn_t *conn;
+  svn_error_t *err;
+  
+  /* Enable TCP keep-alives on the socket so we time out when
+   * the connection breaks due to network-layer problems.
+   * If the peer has dropped the connection due to a network partition
+   * or a crash, or if the peer no longer considers the connection
+   * valid because we are behind a NAT and our public IP has changed,
+   * it will respond to the keep-alive probe with a RST instead of an
+   * acknowledgment segment, which will cause svn to abort the session
+   * even while it is currently blocked waiting for data from the peer. */
+  status = apr_socket_opt_set(usock, APR_SO_KEEPALIVE, 1);
+  if (status)
+    {
+      /* It's not a fatal error if we cannot enable keep-alives. */
+    }
+
+  /* create the connection, configure ports etc. */
+  conn = svn_ra_svn_create_conn3(usock, NULL, NULL,
+                                 params->compression_level,
+                                 params->zero_copy_limit,
+                                 params->error_check_interval,
+                                 pool);
+
+  /* process the actual request and log errors */
+  err = serve(conn, params, pool);
+  if (err)
+    log_error(err, params->log_file, params->log_file_mutex,
+              svn_ra_svn_conn_remote_host(conn), NULL, NULL, pool);
+
+  return svn_error_trace(err);
+}
+
 /* "Arguments" passed from the main thread to the connection thread */
 struct serve_thread_t {
-  svn_ra_svn_conn_t *conn;
+  apr_socket_t *usock;
   serve_params_t *params;
   struct shared_pool_t *shared_pool;
 };
@@ -424,7 +606,7 @@ static void * APR_THREAD_FUNC serve_thre
 {
   struct serve_thread_t *d = data;
 
-  svn_error_clear(serve(d->conn, d->params, d->shared_pool->pool));
+  svn_error_clear(serve_socket(d->usock, d->params, d->shared_pool->pool));
   release_shared_pool(d->shared_pool);
 
   return NULL;
@@ -439,8 +621,9 @@ static svn_error_t *write_pid_file(const
   const char *contents = apr_psprintf(pool, "%" APR_PID_T_FMT "\n",
                                              getpid());
 
+  SVN_ERR(svn_io_remove_file2(filename, TRUE, pool));
   SVN_ERR(svn_io_file_open(&file, filename,
-                           APR_WRITE | APR_CREATE | APR_TRUNCATE,
+                           APR_WRITE | APR_CREATE | APR_EXCL,
                            APR_OS_DEFAULT, pool));
   SVN_ERR(svn_io_file_write_full(file, contents, strlen(contents), NULL,
                                  pool));
@@ -484,14 +667,16 @@ int main(int argc, const char *argv[])
   serve_params_t params;
   const char *arg;
   apr_status_t status;
-  svn_ra_svn_conn_t *conn;
   apr_proc_t proc;
 #if APR_HAS_THREADS
-  apr_threadattr_t *tattr;
-  apr_thread_t *tid;
   struct shared_pool_t *shared_pool;
-
   struct serve_thread_t *thread_data;
+#if HAVE_THREADPOOLS
+  apr_thread_pool_t *threads;
+#else
+  apr_threadattr_t *tattr;
+  apr_thread_t *tid;
+#endif
 #endif
   enum connection_handling_mode handling_mode = CONNECTION_DEFAULT;
   apr_uint16_t port = SVN_RA_SVN_PORT;
@@ -543,11 +728,12 @@ int main(int argc, const char *argv[])
   params.cfg = NULL;
   params.compression_level = SVN_DELTA_COMPRESSION_LEVEL_DEFAULT;
   params.log_file = NULL;
+  params.log_file_mutex = NULL;
   params.vhost = FALSE;
   params.username_case = CASE_ASIS;
   params.memory_cache_size = (apr_uint64_t)-1;
   params.cache_fulltexts = TRUE;
-  params.cache_txdeltas = FALSE;
+  params.cache_txdeltas = TRUE;
   params.cache_revprops = FALSE;
   params.zero_copy_limit = 0;
   params.error_check_interval = 4096;
@@ -798,9 +984,12 @@ int main(int argc, const char *argv[])
     }
 
   if (log_filename)
-    SVN_INT_ERR(svn_io_file_open(&params.log_file, log_filename,
-                                 APR_WRITE | APR_CREATE | APR_APPEND,
-                                 APR_OS_DEFAULT, pool));
+    {
+      SVN_INT_ERR(svn_io_file_open(&params.log_file, log_filename,
+                                  APR_WRITE | APR_CREATE | APR_APPEND,
+                                  APR_OS_DEFAULT, pool));
+      SVN_INT_ERR(svn_mutex__init(&params.log_file_mutex, TRUE, pool));
+    }
 
   if (params.tunnel_user && run_mode != run_mode_tunnel)
     {
@@ -813,6 +1002,8 @@ int main(int argc, const char *argv[])
 
   if (run_mode == run_mode_inetd || run_mode == run_mode_tunnel)
     {
+      svn_ra_svn_conn_t *conn;
+
       params.tunnel = (run_mode == run_mode_tunnel);
       apr_pool_cleanup_register(pool, pool, apr_pool_cleanup_null,
                                 redirect_stdout);
@@ -959,7 +1150,7 @@ int main(int argc, const char *argv[])
       return svn_cmdline_handle_exit_error(err, pool, "svnserve: ");
     }
 
-  apr_socket_listen(sock, 7);
+  apr_socket_listen(sock, ACCEPT_BACKLOG);
 
 #if APR_HAS_FORK
   if (run_mode != run_mode_listen_once && !foreground)
@@ -1021,6 +1212,33 @@ int main(int argc, const char *argv[])
     svn_cache_config_set(&settings);
   }
 
+  err = initialize_connection_pools(pool);
+  if (err)
+    return svn_cmdline_handle_exit_error(err, pool, "svnserve: ");
+
+#if HAVE_THREADPOOLS
+  if (handling_mode == connection_mode_thread)
+    {
+      /* create the thread pool */
+      status = apr_thread_pool_create(&threads,
+                                      THREADPOOL_MIN_SIZE,
+                                      THREADPOOL_MAX_SIZE,
+                                      pool);
+      if (status)
+        {
+          err = svn_error_wrap_apr (status, _("Can't create thread pool"));
+          return svn_cmdline_handle_exit_error(err, pool, "svnserve: ");
+        }
+
+      /* let idle threads linger for a while in case more requests are
+         coming in */
+      apr_thread_pool_idle_wait_set(threads, THREADPOOL_THREAD_IDLE_LIMIT);
+
+      /* don't queue requests unless we reached the worker thread limit */
+      apr_thread_pool_threshold_set(threads, 0);
+    }
+#endif
+
   while (1)
     {
 #ifdef WIN32
@@ -1032,8 +1250,7 @@ int main(int argc, const char *argv[])
          the connection threads so it cannot clean up after each one.  So
          separate pools that can be cleared at thread exit are used. */
 
-      connection_pool
-          = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
+      connection_pool = acquire_connection_pool();
 
       status = apr_socket_accept(&usock, sock, connection_pool);
       if (handling_mode == connection_mode_fork)
@@ -1047,7 +1264,7 @@ int main(int argc, const char *argv[])
           || APR_STATUS_IS_ECONNABORTED(status)
           || APR_STATUS_IS_ECONNRESET(status))
         {
-          svn_pool_destroy(connection_pool);
+          release_connection_pool(connection_pool);
           continue;
         }
       if (status)
@@ -1057,29 +1274,9 @@ int main(int argc, const char *argv[])
           return svn_cmdline_handle_exit_error(err, pool, "svnserve: ");
         }
 
-      /* Enable TCP keep-alives on the socket so we time out when
-       * the connection breaks due to network-layer problems.
-       * If the peer has dropped the connection due to a network partition
-       * or a crash, or if the peer no longer considers the connection
-       * valid because we are behind a NAT and our public IP has changed,
-       * it will respond to the keep-alive probe with a RST instead of an
-       * acknowledgment segment, which will cause svn to abort the session
-       * even while it is currently blocked waiting for data from the peer. */
-      status = apr_socket_opt_set(usock, APR_SO_KEEPALIVE, 1);
-      if (status)
-        {
-          /* It's not a fatal error if we cannot enable keep-alives. */
-        }
-
-      conn = svn_ra_svn_create_conn3(usock, NULL, NULL,
-                                     params.compression_level,
-                                     params.zero_copy_limit,
-                                     params.error_check_interval,
-                                     connection_pool);
-
       if (run_mode == run_mode_listen_once)
         {
-          err = serve(conn, &params, connection_pool);
+          err = serve_socket(usock, &params, connection_pool);
 
           if (err)
             svn_handle_error2(err, stdout, FALSE, "svnserve: ");
@@ -1098,12 +1295,7 @@ int main(int argc, const char *argv[])
           if (status == APR_INCHILD)
             {
               apr_socket_close(sock);
-              err = serve(conn, &params, connection_pool);
-              log_error(err, params.log_file,
-                        svn_ra_svn_conn_remote_host(conn),
-                        NULL, NULL, /* user, repos */
-                        connection_pool);
-              svn_error_clear(err);
+              svn_error_clear(serve_socket(usock, &params, connection_pool));
               apr_socket_close(usock);
               exit(0);
             }
@@ -1114,14 +1306,13 @@ int main(int argc, const char *argv[])
           else
             {
               err = svn_error_wrap_apr(status, "apr_proc_fork");
-              log_error(err, params.log_file,
-                        svn_ra_svn_conn_remote_host(conn),
-                        NULL, NULL, /* user, repos */
+              log_error(err, params.log_file, params.log_file_mutex,
+                        NULL, NULL, NULL, /* ip, user, repos */
                         connection_pool);
               svn_error_clear(err);
               apr_socket_close(usock);
             }
-          svn_pool_destroy(connection_pool);
+          release_connection_pool(connection_pool);
 #endif
           break;
 
@@ -1131,6 +1322,15 @@ int main(int argc, const char *argv[])
              little different from forking one process per connection. */
 #if APR_HAS_THREADS
           shared_pool = attach_shared_pool(connection_pool);
+
+          thread_data = apr_palloc(connection_pool, sizeof(*thread_data));
+          thread_data->usock = usock;
+          thread_data->params = &params;
+          thread_data->shared_pool = shared_pool;
+#if HAVE_THREADPOOLS
+          status = apr_thread_pool_push(threads, serve_thread, thread_data,
+                                        0, NULL);
+#else
           status = apr_threadattr_create(&tattr, connection_pool);
           if (status)
             {
@@ -1147,15 +1347,12 @@ int main(int argc, const char *argv[])
               svn_error_clear(err);
               exit(1);
             }
-          thread_data = apr_palloc(connection_pool, sizeof(*thread_data));
-          thread_data->conn = conn;
-          thread_data->params = &params;
-          thread_data->shared_pool = shared_pool;
           status = apr_thread_create(&tid, tattr, serve_thread, thread_data,
                                      shared_pool->pool);
+#endif
           if (status)
             {
-              err = svn_error_wrap_apr(status, _("Can't create thread"));
+              err = svn_error_wrap_apr(status, THREAD_ERROR_MSG);
               svn_handle_error2(err, stderr, FALSE, "svnserve: ");
               svn_error_clear(err);
               exit(1);
@@ -1166,8 +1363,8 @@ int main(int argc, const char *argv[])
 
         case connection_mode_single:
           /* Serve one connection at a time. */
-          svn_error_clear(serve(conn, &params, connection_pool));
-          svn_pool_destroy(connection_pool);
+          svn_error_clear(serve_socket(usock, &params, connection_pool));
+          release_connection_pool(connection_pool);
         }
     }
 

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svnsync/svnsync.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svnsync/svnsync.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svnsync/svnsync.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svnsync/svnsync.c Thu Sep 26 13:47:21 2013
@@ -1846,6 +1846,7 @@ help_cmd(apr_getopt_t *os, void *baton, 
 
   const char *header =
     _("general usage: svnsync SUBCOMMAND DEST_URL  [ARGS & OPTIONS ...]\n"
+      "Subversion repository replication tool.\n"
       "Type 'svnsync help <subcommand>' for help on a specific subcommand.\n"
       "Type 'svnsync --version' to see the program version and RA modules.\n"
       "\n"

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svnversion/svnversion.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svnversion/svnversion.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svnversion/svnversion.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svnversion/svnversion.c Thu Sep 26 13:47:21 2013
@@ -57,7 +57,10 @@ help(const apr_getopt_option_t *options,
   svn_error_clear
     (svn_cmdline_fprintf
      (stdout, pool,
-      _("usage: svnversion [OPTIONS] [WC_PATH [TRAIL_URL]]\n\n"
+      _("usage: svnversion [OPTIONS] [WC_PATH [TRAIL_URL]]\n"
+        "Subversion working copy identification tool.\n"
+        "Type 'svnversion --version' to see the program version.\n"
+        "\n"
         "  Produce a compact version identifier for the working copy path\n"
         "  WC_PATH.  TRAIL_URL is the trailing portion of the URL used to\n"
         "  determine if WC_PATH itself is switched (detection of switches\n"

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/authz_tests.py?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/authz_tests.py Thu Sep 26 13:47:21 2013
@@ -1551,6 +1551,44 @@ def log_diff_dontdothat(sbox):
                                       'log', ddt_url,
                                       '-c', 1, '--diff')
 
+@Issue(4422)
+@Skip(svntest.main.is_ra_type_file)
+def authz_file_external_to_authz(sbox):
+  "replace file external with authz node"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  repo_url = sbox.repo_url
+
+  write_authz_file(sbox, {"/": "* = rw"})
+  write_restrictive_svnserve_conf(sbox.repo_dir)
+
+  sbox.simple_propset('svn:externals', 'Z ' + repo_url + '/iota', '')
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('', status=' M')
+  expected_status.add({
+    'Z' : Item(status='  ', wc_rev='1', switched='X'),
+  })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        None, None, expected_status)
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'cp', repo_url + '/A',
+                                           repo_url + '/Z',
+                                      '-m', 'Add Z')
+
+  write_authz_file(sbox, {"/": "* = rw", "/Z": "* = "})
+
+  expected_status.tweak(wc_rev=2)
+
+  # ### This used to assert with
+  # ### svn: E235000: In file 'update_editor.c' line 3043: assertion failed
+  # ###               (status != svn_wc__db_status_normal)
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        None, None, expected_status)
+
 
 ########################################################################
 # Run the tests
@@ -1585,6 +1623,7 @@ test_list = [ None,
               authz_svnserve_groups,
               authz_del_from_subdir,
               log_diff_dontdothat,
+              authz_file_external_to_authz,
              ]
 serial_only = True
 

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/checkout_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/checkout_tests.py?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/checkout_tests.py (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/checkout_tests.py Thu Sep 26 13:47:21 2013
@@ -1057,7 +1057,7 @@ def checkout_wc_from_drive(sbox):
   svntest.main.safe_rmtree(sbox.wc_dir)
   os.mkdir(sbox.wc_dir)
 
-  # create a virtual drive to the working copy folder
+  # create a virtual drive to the repository folder
   drive = find_the_next_available_drive_letter()
   if drive is None:
     raise svntest.Skip
@@ -1093,8 +1093,49 @@ def checkout_wc_from_drive(sbox):
     })
     svntest.actions.run_and_verify_checkout(repo_url, wc_dir,
                                             expected_output, expected_wc,
-                                            None, None, None, None,
-                                            '--force')
+                                            None, None, None, None)
+
+    wc2_dir = sbox.add_wc_path('2')
+    expected_output = wc.State(wc2_dir, {
+      'D'                 : Item(status='A '),
+      'D/H'               : Item(status='A '),
+      'D/H/psi'           : Item(status='A '),
+      'D/H/chi'           : Item(status='A '),
+      'D/H/omega'         : Item(status='A '),
+      'D/G'               : Item(status='A '),
+      'D/G/tau'           : Item(status='A '),
+      'D/G/pi'            : Item(status='A '),
+      'D/G/rho'           : Item(status='A '),
+      'D/gamma'           : Item(status='A '),
+      'C'                 : Item(status='A '),
+      'mu'                : Item(status='A '),
+      'B'                 : Item(status='A '),
+      'B/E'               : Item(status='A '),
+      'B/E/alpha'         : Item(status='A '),
+      'B/E/beta'          : Item(status='A '),
+      'B/F'               : Item(status='A '),
+      'B/lambda'          : Item(status='A '),
+    })
+    svntest.actions.run_and_verify_checkout(repo_url + '/A', wc2_dir,
+                                            expected_output, None,
+                                            None, None, None, None)
+
+    wc3_dir = sbox.add_wc_path('3')
+    expected_output = wc.State(wc3_dir, {
+      'H'                 : Item(status='A '),
+      'H/psi'             : Item(status='A '),
+      'H/chi'             : Item(status='A '),
+      'H/omega'           : Item(status='A '),
+      'G'                 : Item(status='A '),
+      'G/tau'             : Item(status='A '),
+      'G/pi'              : Item(status='A '),
+      'G/rho'             : Item(status='A '),
+      'gamma'             : Item(status='A '),
+    })
+
+    svntest.actions.run_and_verify_checkout(repo_url + '/A/D', wc3_dir,
+                                            expected_output, None,
+                                            None, None, None, None)
 
   finally:
     os.chdir(was_cwd)

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/commit_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/commit_tests.py?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/commit_tests.py (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/commit_tests.py Thu Sep 26 13:47:21 2013
@@ -1250,7 +1250,7 @@ def commit_add_file_twice(sbox):
   svntest.actions.run_and_verify_commit(wc_dir,
                                         None,
                                         None,
-                                        "already exists",
+                                        "E160020: File.*already exists",
                                         wc_dir)
 
 #----------------------------------------------------------------------

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/externals_tests.py?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/externals_tests.py Thu Sep 26 13:47:21 2013
@@ -3264,6 +3264,89 @@ def switch_parent_relative_file_external
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'update', branch_wc)
 
+@Issue(4420)
+def file_external_unversioned_obstruction(sbox):
+  """file externals unversioned obstruction"""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  expected_output = verify.RegexOutput('r2 committed .*')
+  svntest.actions.run_and_verify_svnmucc(None, expected_output, [],
+                           '-U', sbox.repo_url, '-m', 'r2: set external',
+                           'propset', 'svn:externals', '^/A/mu mu-ext', 'A')
+
+  sbox.simple_append('A/mu-ext', 'unversioned obstruction')
+
+  # Update reports a tree-conflict but status doesn't show any such
+  # conflict.  I'm no sure whether this is correct.
+  expected_output = svntest.wc.State(wc_dir, {
+      'A'        : Item(status=' U'),
+      'A/mu-ext' : Item(status='  ', treeconflict='A'),
+      })
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.add({
+      'A/mu-ext' : Item('unversioned obstruction'),
+      })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.add({
+      'A/mu-ext' : Item(status='M ', wc_rev='2', switched='X'),
+      })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output, expected_disk,
+                                        expected_status)
+
+@Issue(4001)
+@XFail()
+def file_external_versioned_obstruction(sbox):
+  """file externals versioned obstruction"""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  expected_output = verify.RegexOutput('r2 committed .*')
+  svntest.actions.run_and_verify_svnmucc(None, expected_output, [],
+                           '-U', sbox.repo_url, '-m', 'r2: set external',
+                           'propset', 'svn:externals', '^/A/mu mu-ext', 'A')
+
+  expected_output = svntest.wc.State(wc_dir, {
+      'A'        : Item(status=' U'),
+      'A/mu-ext' : Item(status='A '),
+      })
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.add({
+      'A/mu-ext' : Item('This is the file \'mu\'.\n'),
+      })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.add({
+      'A/mu-ext' : Item(status='  ', wc_rev='2', switched='X'),
+      })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output, expected_disk,
+                                        expected_status)
+
+  # Update skips adding the versioned node because of the file
+  # external obstruction then when the external is deleted the
+  # versioned node is missing from disk and wc.db.  Not really sure
+  # what should happen, perhaps a not-present node?
+  expected_output = verify.RegexOutput('r3 committed .*')
+  svntest.actions.run_and_verify_svnmucc(None, expected_output, [],
+                           '-U', sbox.repo_url, '-m', 'r3: copy file',
+                           'cp', 'head', 'A/mu', 'A/mu-ext',
+                           'propdel', 'svn:externals', 'A')
+
+  expected_output = svntest.wc.State(wc_dir, {
+      'A'        : Item(status=' U'),
+      'A/mu-ext' : Item(verb='Removed external', prev_verb='Skipped'),
+      })
+  expected_disk.tweak('A/mu-ext', content='This is the file \'mu\'.\n')
+  expected_status.tweak(wc_rev=3)
+  expected_status.tweak('A/mu-ext', switched=None)
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output, expected_disk,
+                                        expected_status)
+
+
 ########################################################################
 # Run the tests
 
@@ -3317,6 +3400,8 @@ test_list = [ None,
               pinned_externals,
               update_dir_external_shallow,
               switch_parent_relative_file_external,
+              file_external_unversioned_obstruction,
+              file_external_versioned_obstruction,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests.py?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests.py (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests.py Thu Sep 26 13:47:21 2013
@@ -90,13 +90,6 @@ rep_lines_res = [
                  # In 'svn --version --quiet', we print only the version
                  # number in a single line.
                  (re.compile(r'^\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?$'), 'X.Y.Z\n'),
-                 # 'svn --help' has a line with the version number.
-                 # It can vary, for example:
-                 # "Subversion command-line client, version 1.1.0."
-                 # "Subversion command-line client, version 1.1.0-dev."
-                 (re.compile(r'Subversion command-line client, '
-                             'version \d+\.\d+\.\d+(.|-[a-zA-Z0-9]+\.)$'),
-                  'Subversion command-line client, version X.Y.Z.'),
                 ]
 
 # This is a trigger pattern that selects the secondary set of

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout Thu Sep 26 13:47:21 2013
@@ -1,5 +1,5 @@
 usage: svn <subcommand> [options] [args]
-Subversion command-line client, version X.Y.Z.
+Subversion command-line client.
 Type 'svn help <subcommand>' for help on a specific subcommand.
 Type 'svn --version' to see the program version and RA modules
   or 'svn --version --quiet' to see just the version number.

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout Thu Sep 26 13:47:21 2013
@@ -95,6 +95,8 @@ Valid options:
   --with-all-revprops      : retrieve all revision properties
   --with-no-revprops       : retrieve no revision properties
   --with-revprop ARG       : retrieve revision property ARG
+  --auto-moves             : attempt to interpret matching unique DEL+ADD
+                             pairs as moves
   --depth ARG              : limit operation by depth ARG ('empty', 'files',
                              'immediates', or 'infinity')
   --diff                   : produce diff output

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout Thu Sep 26 13:47:21 2013
@@ -1,5 +1,5 @@
 usage: svn <subcommand> [options] [args]
-Subversion command-line client, version X.Y.Z.
+Subversion command-line client.
 Type 'svn help <subcommand>' for help on a specific subcommand.
 Type 'svn --version' to see the program version and RA modules
   or 'svn --version --quiet' to see just the version number.

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/lock_tests.py?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/lock_tests.py Thu Sep 26 13:47:21 2013
@@ -1889,6 +1889,36 @@ def drop_locks_on_parent_deletion(sbox):
                                         None,
                                         wc_dir)
 	
+
+def copy_with_lock(sbox):
+  """copy with lock on source"""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  lock_url = sbox.repo_url + '/A/B/E/alpha'
+
+  svntest.actions.run_and_validate_lock(lock_url, svntest.main.wc_author)
+  sbox.simple_copy('A/B/E', 'A/B/E2')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B/E2' : Item(verb='Adding'),
+    })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/B/E/alpha', writelocked='O')
+  expected_status.add({
+    'A/B/E2'       : Item(status='  ', wc_rev=2),
+    'A/B/E2/alpha' : Item(status='  ', wc_rev=2),
+    'A/B/E2/beta'  : Item(status='  ', wc_rev=2),
+    })
+
+  # This is really a regression test for httpd: 2.2.25 and 2.4.6 have
+  # a bug that causes mod_dav to check for locks on the copy source
+  # and so the commit fails.
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        expected_output,
+                                        expected_status,
+                                        None,
+                                        wc_dir)
 										
 ########################################################################
 # Run the tests
@@ -1943,6 +1973,7 @@ test_list = [ None,
               lock_unlock_deleted,
               commit_stolen_lock,
               drop_locks_on_parent_deletion,
+              copy_with_lock,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/log_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/log_tests.py?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/log_tests.py Thu Sep 26 13:47:21 2013
@@ -2184,6 +2184,7 @@ def log_diff(sbox):
   compare_diff_output(r9diff, log_chain[1]['diff_lines'])
   compare_diff_output(r8diff, log_chain[2]['diff_lines'])
 
+@Skip(svntest.main.is_fs_type_fsx)
 def log_xml_old(sbox):
   "log --xml shows kind for old style repository"
 



Mime
View raw message