You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2013/01/06 03:33:39 UTC

svn commit: r1429457 [15/21] - in /subversion/branches/tree-read-api: ./ build/ build/ac-macros/ build/generator/templates/ build/win32/ contrib/server-side/svncutter/ doc/ subversion/bindings/cxxhl/include/ subversion/bindings/cxxhl/include/svncxxhl/ ...

Modified: subversion/branches/tree-read-api/subversion/svn/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/props.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/props.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/props.c Sun Jan  6 02:33:34 2013
@@ -83,121 +83,6 @@ svn_cl__revprop_prepare(const svn_opt_re
   return SVN_NO_ERROR;
 }
 
-
-svn_error_t *
-svn_cl__print_prop_hash(svn_stream_t *out,
-                        apr_hash_t *prop_hash,
-                        svn_boolean_t names_only,
-                        apr_pool_t *pool)
-{
-  apr_array_header_t *sorted_props;
-  int i;
-
-  sorted_props = svn_sort__hash(prop_hash, svn_sort_compare_items_lexically,
-                                pool);
-  for (i = 0; i < sorted_props->nelts; i++)
-    {
-      svn_sort__item_t item = APR_ARRAY_IDX(sorted_props, i, svn_sort__item_t);
-      const char *pname = item.key;
-      svn_string_t *propval = item.value;
-      const char *pname_stdout;
-
-      if (svn_prop_needs_translation(pname))
-        SVN_ERR(svn_subst_detranslate_string(&propval, propval,
-                                             TRUE, pool));
-
-      SVN_ERR(svn_cmdline_cstring_from_utf8(&pname_stdout, pname, pool));
-
-      if (out)
-        {
-          pname_stdout = apr_psprintf(pool, "  %s\n", pname_stdout);
-          SVN_ERR(svn_subst_translate_cstring2(pname_stdout, &pname_stdout,
-                                              APR_EOL_STR,  /* 'native' eol */
-                                              FALSE, /* no repair */
-                                              NULL,  /* no keywords */
-                                              FALSE, /* no expansion */
-                                              pool));
-
-          SVN_ERR(svn_stream_puts(out, pname_stdout));
-        }
-      else
-        {
-          /* ### We leave these printfs for now, since if propval wasn't
-             translated above, we don't know anything about its encoding.
-             In fact, it might be binary data... */
-          printf("  %s\n", pname_stdout);
-        }
-
-      if (!names_only)
-        {
-          /* Add an extra newline to the value before indenting, so that
-           * every line of output has the indentation whether the value
-           * already ended in a newline or not. */
-          const char *newval = apr_psprintf(pool, "%s\n", propval->data);
-          const char *indented_newval = svn_cl__indent_string(newval,
-                                                              "    ",
-                                                              pool);
-          if (out)
-            {
-              SVN_ERR(svn_stream_puts(out, indented_newval));
-            }
-          else
-            {
-              printf("%s", indented_newval);
-            }
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_cl__print_xml_prop_hash(svn_stringbuf_t **outstr,
-                            apr_hash_t *prop_hash,
-                            svn_boolean_t names_only,
-                            svn_boolean_t inherited_props,
-                            apr_pool_t *pool)
-{
-  apr_array_header_t *sorted_props;
-  int i;
-
-  if (*outstr == NULL)
-    *outstr = svn_stringbuf_create_empty(pool);
-
-  sorted_props = svn_sort__hash(prop_hash, svn_sort_compare_items_lexically,
-                                pool);
-  for (i = 0; i < sorted_props->nelts; i++)
-    {
-      svn_sort__item_t item = APR_ARRAY_IDX(sorted_props, i, svn_sort__item_t);
-      const char *pname = item.key;
-      svn_string_t *propval = item.value;
-
-      if (names_only)
-        {
-          svn_xml_make_open_tag(
-            outstr, pool, svn_xml_self_closing,
-            inherited_props ? "inherited_property" : "property",
-            "name", pname, NULL);
-        }
-      else
-        {
-          const char *pname_out;
-
-          if (svn_prop_needs_translation(pname))
-            SVN_ERR(svn_subst_detranslate_string(&propval, propval,
-                                                 TRUE, pool));
-
-          SVN_ERR(svn_cmdline_cstring_from_utf8(&pname_out, pname, pool));
-
-          svn_cmdline__print_xml_prop(outstr, pname_out, propval,
-                                      inherited_props, pool);
-        }
-    }
-
-    return SVN_NO_ERROR;
-}
-
-
 void
 svn_cl__check_boolean_prop_val(const char *propname, const char *propval,
                                apr_pool_t *pool)

Modified: subversion/branches/tree-read-api/subversion/svn/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/status.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/status.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/status.c Sun Jan  6 02:33:34 2013
@@ -377,7 +377,7 @@ print_status(const char *cwd_abspath, co
 
           SVN_ERR
             (svn_cmdline_printf(pool,
-                                "%c%c%c%c%c%c%c %c   %6s   %6s %-12s %s%s%s%s\n",
+                                "%c%c%c%c%c%c%c %c %8s %8s %-12s %s%s%s%s\n",
                                 generate_status_code(combined_status(status)),
                                 generate_status_code(prop_status),
                                 status->wc_is_locked ? 'L' : ' ',
@@ -396,7 +396,7 @@ print_status(const char *cwd_abspath, co
         }
       else
         SVN_ERR(
-           svn_cmdline_printf(pool, "%c%c%c%c%c%c%c %c   %6s   %s%s%s%s\n",
+           svn_cmdline_printf(pool, "%c%c%c%c%c%c%c %c %8s   %s%s%s%s\n",
                               generate_status_code(combined_status(status)),
                               generate_status_code(prop_status),
                               status->wc_is_locked ? 'L' : ' ',

Modified: subversion/branches/tree-read-api/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/svn.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/svn.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/svn.c Sun Jan  6 02:33:34 2013
@@ -1,5 +1,5 @@
 /*
- * main.c:  Subversion command line client.
+ * svn.c:  Subversion command line client main file.
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one
@@ -101,6 +101,7 @@ typedef enum svn_cl__longopt_t {
   opt_no_ignore,
   opt_no_unlock,
   opt_non_interactive,
+  opt_force_interactive,
   opt_old_cmd,
   opt_record_only,
   opt_relocate,
@@ -229,7 +230,13 @@ const apr_getopt_option_t svn_cl__option
                        "                             "
                        "with '--non-interactive')") },
   {"non-interactive", opt_non_interactive, 0,
-                    N_("do no interactive prompting")},
+                    N_("do no interactive prompting (default is to prompt\n"
+                       "                             "
+                       "only if standard input is a terminal device)")},
+  {"force-interactive", opt_force_interactive, 0,
+                    N_("do interactive prompting even if standard input\n"
+                       "                             "
+                       "is not a terminal device")},
   {"dry-run",       opt_dry_run, 0,
                     N_("try operation but make no changes")},
   {"ignore-ancestry", opt_ignore_ancestry, 0,
@@ -401,7 +408,8 @@ const apr_getopt_option_t svn_cl__option
    willy-nilly to every invocation of 'svn') . */
 const int svn_cl__global_options[] =
 { opt_auth_username, opt_auth_password, opt_no_auth_cache, opt_non_interactive,
-  opt_trust_server_cert, opt_config_dir, opt_config_options, 0
+  opt_force_interactive, opt_trust_server_cert, opt_config_dir,
+  opt_config_options, 0
 };
 
 /* Options for giving a log message.  (Some of these also have other uses.)
@@ -730,7 +738,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
 "          (the 'automatic' merge)\n"
 "       2. merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [TARGET_WCPATH]\n"
 "          (the 'cherry-pick' merge)\n"
-"       3. merge SOURCE1[@N] SOURCE2[@M] [TARGET_WCPATH]\n"
+"       3. merge SOURCE1[@REV1] SOURCE2[@REV2] [TARGET_WCPATH]\n"
 "          (the '2-URL' merge)\n"
 "\n"
 "  1. This form, with one source path and no revision range, is called\n"
@@ -915,26 +923,27 @@ const svn_opt_subcommand_desc2_t svn_cl_
 "\n"
 "  3. This form is called a '2-URL merge':\n"
 "\n"
-"       svn merge SOURCE1[@N] SOURCE2[@M] [TARGET_WCPATH]\n"
-"\n"
-"     Two source URLs are specified, together with two revisions N and M.\n"
-"     The two sources are compared at the specified revisions, and the\n"
-"     difference is applied to TARGET_WCPATH, which is a path to a working\n"
-"     copy of another branch. The three branches involved can be completely\n"
-"     unrelated.\n"
+"       svn merge SOURCE1[@REV1] SOURCE2[@REV2] [TARGET_WCPATH]\n"
 "\n"
 "     You should use this merge variant only if the other variants do not\n"
 "     apply to your situation, as this variant can be quite complex to\n"
 "     master.\n"
 "\n"
+"     Two source URLs are specified, identifying two trees on the same\n"
+"     branch or on different branches. The trees are compared and the\n"
+"     difference from SOURCE1@REV1 to SOURCE2@REV2 is applied to the\n"
+"     working copy of the target branch at TARGET_WCPATH. The target\n"
+"     branch may be the same as one or both sources, or different again.\n"
+"     The three branches involved can be completely unrelated.\n"
+"\n"
 "     If TARGET_WCPATH is omitted, a default value of '.' is assumed.\n"
 "     However, in the special case where both sources refer to a file node\n"
-"     with the same basename and a similarly named file is also found within\n"
-"     '.', the differences will be applied to that local file.  The source\n"
-"     revisions default to HEAD if omitted.\n"
+"     with the same name and a file with the same name is also found within\n"
+"     '.', the differences will be applied to that local file. The source\n"
+"     revisions REV1 and REV2 default to HEAD if omitted.\n"
 "\n"
-"     The sources can also be specified as working copy paths, in which case\n"
-"     the URLs of the merge sources are derived from the working copies.\n"
+"     SOURCE1 and/or SOURCE2 can also be specified as a working copy path,\n"
+"     in which case the merge source URL is derived from the working copy.\n"
 "\n"
 "       - 2-URL Merge Example -\n"
 "\n"
@@ -1036,7 +1045,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
 "  repositories.\n"),
     {'r', 'c', 'N', opt_depth, 'q', opt_force, opt_dry_run, opt_merge_cmd,
      opt_record_only, 'x', opt_ignore_ancestry, opt_accept, opt_reintegrate,
-     opt_allow_mixed_revisions} },
+     opt_allow_mixed_revisions, 'v'} },
 
   { "mergeinfo", svn_cl__mergeinfo, {0}, N_
     ("Display merge-related information.\n"
@@ -1659,6 +1668,7 @@ sub_main(int argc, const char *argv[], a
   svn_config_t *cfg_config;
   svn_boolean_t descend = TRUE;
   svn_boolean_t interactive_conflicts = FALSE;
+  svn_boolean_t force_interactive = FALSE;
   svn_boolean_t use_notifier = TRUE;
   apr_hash_t *changelists;
   const char *sqlite_exclusive;
@@ -1982,6 +1992,9 @@ sub_main(int argc, const char *argv[], a
       case opt_non_interactive:
         opt_state.non_interactive = TRUE;
         break;
+      case opt_force_interactive:
+        force_interactive = TRUE;
+        break;
       case opt_trust_server_cert:
         opt_state.trust_server_cert = TRUE;
         break;
@@ -2083,6 +2096,12 @@ sub_main(int argc, const char *argv[], a
         break;
       case opt_changelist:
         opt_state.changelist = apr_pstrdup(pool, opt_arg);
+        if (opt_state.changelist[0] == '\0')
+          {
+            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: ");
+          }
         apr_hash_set(changelists, opt_state.changelist,
                      APR_HASH_KEY_STRING, (void *)1);
         break;
@@ -2191,6 +2210,20 @@ sub_main(int argc, const char *argv[], a
       }
     }
 
+  /* The --non-interactive and --force-interactive options are mutually
+   * exclusive. */
+  if (opt_state.non_interactive && force_interactive)
+    {
+      err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                             _("--non-interactive and --force-interactive "
+                               "are mutually exclusive"));
+      return EXIT_ERROR(err);
+    }
+  else
+    opt_state.non_interactive = !svn_cmdline__be_interactive(
+                                  opt_state.non_interactive,
+                                  force_interactive);
+
   /* Turn our hash of changelists into an array of unique ones. */
   SVN_INT_ERR(svn_hash_keys(&(opt_state.changelists), changelists, pool));
 

Modified: subversion/branches/tree-read-api/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svn/util.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svn/util.c (original)
+++ subversion/branches/tree-read-api/subversion/svn/util.c Sun Jan  6 02:33:34 2013
@@ -62,6 +62,7 @@
 #include "private/svn_token.h"
 #include "private/svn_opt_private.h"
 #include "private/svn_client_private.h"
+#include "private/svn_cmdline_private.h"
 #include "private/svn_string_private.h"
 
 
@@ -93,125 +94,6 @@ svn_cl__print_commit_info(const svn_comm
 }
 
 
-/* Helper for the next two functions.  Set *EDITOR to some path to an
-   editor binary.  Sources to search include: the EDITOR_CMD argument
-   (if not NULL), $SVN_EDITOR, the runtime CONFIG variable (if CONFIG
-   is not NULL), $VISUAL, $EDITOR.  Return
-   SVN_ERR_CL_NO_EXTERNAL_EDITOR if no binary can be found. */
-static svn_error_t *
-find_editor_binary(const char **editor,
-                   const char *editor_cmd,
-                   apr_hash_t *config)
-{
-  const char *e;
-  struct svn_config_t *cfg;
-
-  /* Use the editor specified on the command line via --editor-cmd, if any. */
-  e = editor_cmd;
-
-  /* Otherwise look for the Subversion-specific environment variable. */
-  if (! e)
-    e = getenv("SVN_EDITOR");
-
-  /* If not found then fall back on the config file. */
-  if (! e)
-    {
-      cfg = config ? apr_hash_get(config, SVN_CONFIG_CATEGORY_CONFIG,
-                                  APR_HASH_KEY_STRING) : NULL;
-      svn_config_get(cfg, &e, SVN_CONFIG_SECTION_HELPERS,
-                     SVN_CONFIG_OPTION_EDITOR_CMD, NULL);
-    }
-
-  /* If not found yet then try general purpose environment variables. */
-  if (! e)
-    e = getenv("VISUAL");
-  if (! e)
-    e = getenv("EDITOR");
-
-#ifdef SVN_CLIENT_EDITOR
-  /* If still not found then fall back on the hard-coded default. */
-  if (! e)
-    e = SVN_CLIENT_EDITOR;
-#endif
-
-  /* Error if there is no editor specified */
-  if (e)
-    {
-      const char *c;
-
-      for (c = e; *c; c++)
-        if (!svn_ctype_isspace(*c))
-          break;
-
-      if (! *c)
-        return svn_error_create
-          (SVN_ERR_CL_NO_EXTERNAL_EDITOR, NULL,
-           _("The EDITOR, SVN_EDITOR or VISUAL environment variable or "
-             "'editor-cmd' run-time configuration option is empty or "
-             "consists solely of whitespace. Expected a shell command."));
-    }
-  else
-    return svn_error_create
-      (SVN_ERR_CL_NO_EXTERNAL_EDITOR, NULL,
-       _("None of the environment variables SVN_EDITOR, VISUAL or EDITOR are "
-         "set, and no 'editor-cmd' run-time configuration option was found"));
-
-  *editor = e;
-  return SVN_NO_ERROR;
-}
-
-
-/* Use the visual editor to edit files. This requires that the file name itself
-   be shell-safe, although the path to reach that file need not be shell-safe.
- */
-svn_error_t *
-svn_cl__edit_file_externally(const char *path,
-                             const char *editor_cmd,
-                             apr_hash_t *config,
-                             apr_pool_t *pool)
-{
-  const char *editor, *cmd, *base_dir, *file_name, *base_dir_apr;
-  char *old_cwd;
-  int sys_err;
-  apr_status_t apr_err;
-
-  svn_dirent_split(&base_dir, &file_name, path, pool);
-
-  SVN_ERR(find_editor_binary(&editor, editor_cmd, config));
-
-  apr_err = apr_filepath_get(&old_cwd, APR_FILEPATH_NATIVE, pool);
-  if (apr_err)
-    return svn_error_wrap_apr(apr_err, _("Can't get working directory"));
-
-  /* APR doesn't like "" directories */
-  if (base_dir[0] == '\0')
-    base_dir_apr = ".";
-  else
-    SVN_ERR(svn_path_cstring_from_utf8(&base_dir_apr, base_dir, pool));
-
-  apr_err = apr_filepath_set(base_dir_apr, pool);
-  if (apr_err)
-    return svn_error_wrap_apr
-      (apr_err, _("Can't change working directory to '%s'"), base_dir);
-
-  cmd = apr_psprintf(pool, "%s %s", editor, file_name);
-  sys_err = system(cmd);
-
-  apr_err = apr_filepath_set(old_cwd, pool);
-  if (apr_err)
-    svn_handle_error2(svn_error_wrap_apr
-                      (apr_err, _("Can't restore working directory")),
-                      stderr, TRUE /* fatal */, "svn: ");
-
-  if (sys_err)
-    /* Extracting any meaning from sys_err is platform specific, so just
-       use the raw value. */
-    return svn_error_createf(SVN_ERR_EXTERNAL_PROGRAM, NULL,
-                             _("system('%s') returned %d"), cmd, sys_err);
-
-  return SVN_NO_ERROR;
-}
-
 svn_error_t *
 svn_cl__merge_file_externally(const char *base_path,
                               const char *their_path,
@@ -290,248 +172,6 @@ svn_cl__merge_file_externally(const char
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_cl__edit_string_externally(svn_string_t **edited_contents /* UTF-8! */,
-                               const char **tmpfile_left /* UTF-8! */,
-                               const char *editor_cmd,
-                               const char *base_dir /* UTF-8! */,
-                               const svn_string_t *contents /* UTF-8! */,
-                               const char *filename,
-                               apr_hash_t *config,
-                               svn_boolean_t as_text,
-                               const char *encoding,
-                               apr_pool_t *pool)
-{
-  const char *editor;
-  const char *cmd;
-  apr_file_t *tmp_file;
-  const char *tmpfile_name;
-  const char *tmpfile_native;
-  const char *tmpfile_apr, *base_dir_apr;
-  svn_string_t *translated_contents;
-  apr_status_t apr_err, apr_err2;
-  apr_size_t written;
-  apr_finfo_t finfo_before, finfo_after;
-  svn_error_t *err = SVN_NO_ERROR, *err2;
-  char *old_cwd;
-  int sys_err;
-  svn_boolean_t remove_file = TRUE;
-
-  SVN_ERR(find_editor_binary(&editor, editor_cmd, config));
-
-  /* Convert file contents from UTF-8/LF if desired. */
-  if (as_text)
-    {
-      const char *translated;
-      SVN_ERR(svn_subst_translate_cstring2(contents->data, &translated,
-                                           APR_EOL_STR, FALSE,
-                                           NULL, FALSE, pool));
-      translated_contents = svn_string_create_empty(pool);
-      if (encoding)
-        SVN_ERR(svn_utf_cstring_from_utf8_ex2(&translated_contents->data,
-                                              translated, encoding, pool));
-      else
-        SVN_ERR(svn_utf_cstring_from_utf8(&translated_contents->data,
-                                          translated, pool));
-      translated_contents->len = strlen(translated_contents->data);
-    }
-  else
-    translated_contents = svn_string_dup(contents, pool);
-
-  /* Move to BASE_DIR to avoid getting characters that need quoting
-     into tmpfile_name */
-  apr_err = apr_filepath_get(&old_cwd, APR_FILEPATH_NATIVE, pool);
-  if (apr_err)
-    return svn_error_wrap_apr(apr_err, _("Can't get working directory"));
-
-  /* APR doesn't like "" directories */
-  if (base_dir[0] == '\0')
-    base_dir_apr = ".";
-  else
-    SVN_ERR(svn_path_cstring_from_utf8(&base_dir_apr, base_dir, pool));
-  apr_err = apr_filepath_set(base_dir_apr, pool);
-  if (apr_err)
-    {
-      return svn_error_wrap_apr
-        (apr_err, _("Can't change working directory to '%s'"), base_dir);
-    }
-
-  /*** From here on, any problems that occur require us to cd back!! ***/
-
-  /* Ask the working copy for a temporary file named FILENAME-something. */
-  err = svn_io_open_uniquely_named(&tmp_file, &tmpfile_name,
-                                   "" /* dirpath */,
-                                   filename,
-                                   ".tmp",
-                                   svn_io_file_del_none, pool, pool);
-
-  if (err && (APR_STATUS_IS_EACCES(err->apr_err) || err->apr_err == EROFS))
-    {
-      const char *temp_dir_apr;
-
-      svn_error_clear(err);
-
-      SVN_ERR(svn_io_temp_dir(&base_dir, pool));
-
-      SVN_ERR(svn_path_cstring_from_utf8(&temp_dir_apr, base_dir, pool));
-      apr_err = apr_filepath_set(temp_dir_apr, pool);
-      if (apr_err)
-        {
-          return svn_error_wrap_apr
-            (apr_err, _("Can't change working directory to '%s'"), base_dir);
-        }
-
-      err = svn_io_open_uniquely_named(&tmp_file, &tmpfile_name,
-                                       "" /* dirpath */,
-                                       filename,
-                                       ".tmp",
-                                       svn_io_file_del_none, pool, pool);
-    }
-
-  if (err)
-    goto cleanup2;
-
-  /*** From here on, any problems that occur require us to cleanup
-       the file we just created!! ***/
-
-  /* Dump initial CONTENTS to TMP_FILE. */
-  apr_err = apr_file_write_full(tmp_file, translated_contents->data,
-                                translated_contents->len, &written);
-
-  apr_err2 = apr_file_close(tmp_file);
-  if (! apr_err)
-    apr_err = apr_err2;
-
-  /* Make sure the whole CONTENTS were written, else return an error. */
-  if (apr_err)
-    {
-      err = svn_error_wrap_apr(apr_err, _("Can't write to '%s'"),
-                               tmpfile_name);
-      goto cleanup;
-    }
-
-  err = svn_path_cstring_from_utf8(&tmpfile_apr, tmpfile_name, pool);
-  if (err)
-    goto cleanup;
-
-  /* Get information about the temporary file before the user has
-     been allowed to edit its contents. */
-  apr_err = apr_stat(&finfo_before, tmpfile_apr,
-                     APR_FINFO_MTIME, pool);
-  if (apr_err)
-    {
-      err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
-      goto cleanup;
-    }
-
-  /* Backdate the file a little bit in case the editor is very fast
-     and doesn't change the size.  (Use two seconds, since some
-     filesystems have coarse granularity.)  It's OK if this call
-     fails, so we don't check its return value.*/
-  apr_file_mtime_set(tmpfile_apr, finfo_before.mtime - 2000, pool);
-
-  /* Stat it again to get the mtime we actually set. */
-  apr_err = apr_stat(&finfo_before, tmpfile_apr,
-                     APR_FINFO_MTIME | APR_FINFO_SIZE, pool);
-  if (apr_err)
-    {
-      err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
-      goto cleanup;
-    }
-
-  /* Prepare the editor command line.  */
-  err = svn_utf_cstring_from_utf8(&tmpfile_native, tmpfile_name, pool);
-  if (err)
-    goto cleanup;
-  cmd = apr_psprintf(pool, "%s %s", editor, tmpfile_native);
-
-  /* If the caller wants us to leave the file around, return the path
-     of the file we'll use, and make a note not to destroy it.  */
-  if (tmpfile_left)
-    {
-      *tmpfile_left = svn_dirent_join(base_dir, tmpfile_name, pool);
-      remove_file = FALSE;
-    }
-
-  /* Now, run the editor command line.  */
-  sys_err = system(cmd);
-  if (sys_err != 0)
-    {
-      /* Extracting any meaning from sys_err is platform specific, so just
-         use the raw value. */
-      err =  svn_error_createf(SVN_ERR_EXTERNAL_PROGRAM, NULL,
-                               _("system('%s') returned %d"), cmd, sys_err);
-      goto cleanup;
-    }
-
-  /* Get information about the temporary file after the assumed editing. */
-  apr_err = apr_stat(&finfo_after, tmpfile_apr,
-                     APR_FINFO_MTIME | APR_FINFO_SIZE, pool);
-  if (apr_err)
-    {
-      err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
-      goto cleanup;
-    }
-
-  /* If the file looks changed... */
-  if ((finfo_before.mtime != finfo_after.mtime) ||
-      (finfo_before.size != finfo_after.size))
-    {
-      svn_stringbuf_t *edited_contents_s;
-      err = svn_stringbuf_from_file2(&edited_contents_s, tmpfile_name, pool);
-      if (err)
-        goto cleanup;
-
-      *edited_contents = svn_stringbuf__morph_into_string(edited_contents_s);
-
-      /* Translate back to UTF8/LF if desired. */
-      if (as_text)
-        {
-          err = svn_subst_translate_string2(edited_contents, FALSE, FALSE,
-                                            *edited_contents, encoding, FALSE,
-                                            pool, pool);
-          if (err)
-            {
-              err = svn_error_quick_wrap
-                (err,
-                 _("Error normalizing edited contents to internal format"));
-              goto cleanup;
-            }
-        }
-    }
-  else
-    {
-      /* No edits seem to have been made */
-      *edited_contents = NULL;
-    }
-
- cleanup:
-  if (remove_file)
-    {
-      /* Remove the file from disk.  */
-      err2 = svn_io_remove_file2(tmpfile_name, FALSE, pool);
-
-      /* Only report remove error if there was no previous error. */
-      if (! err && err2)
-        err = err2;
-      else
-        svn_error_clear(err2);
-    }
-
- cleanup2:
-  /* If we against all probability can't cd back, all further relative
-     file references would be screwed up, so we have to abort. */
-  apr_err = apr_filepath_set(old_cwd, pool);
-  if (apr_err)
-    {
-      svn_handle_error2(svn_error_wrap_apr
-                        (apr_err, _("Can't restore working directory")),
-                        stderr, TRUE /* fatal */, "svn: ");
-    }
-
-  return svn_error_trace(err);
-}
-
 
 /* A svn_client_ctx_t's log_msg_baton3, for use with
    svn_cl__make_log_msg_baton(). */
@@ -732,8 +372,8 @@ svn_cl__get_log_message(const char **log
   while (! message)
     {
       /* We still don't have a valid commit message.  Use $EDITOR to
-         get one.  Note that svn_cl__edit_externally will still return
-         a UTF-8'ized log message. */
+         get one.  Note that svn_cl__edit_string_externally will still
+         return a UTF-8'ized log message. */
       int i;
       svn_stringbuf_t *tmp_message = svn_stringbuf_dup(default_msg, pool);
       svn_error_t *err = SVN_NO_ERROR;
@@ -793,12 +433,12 @@ svn_cl__get_log_message(const char **log
       /* Use the external edit to get a log message. */
       if (! lmb->non_interactive)
         {
-          err = svn_cl__edit_string_externally(&msg_string, &lmb->tmpfile_left,
-                                               lmb->editor_cmd, lmb->base_dir,
-                                               msg_string, "svn-commit",
-                                               lmb->config, TRUE,
-                                               lmb->message_encoding,
-                                               pool);
+          err = svn_cmdline__edit_string_externally(&msg_string, &lmb->tmpfile_left,
+                                                    lmb->editor_cmd, lmb->base_dir,
+                                                    msg_string, "svn-commit",
+                                                    lmb->config, TRUE,
+                                                    lmb->message_encoding,
+                                                    pool);
         }
       else /* non_interactive flag says we can't pop up an editor, so error */
         {
@@ -1264,56 +904,6 @@ svn_cl__time_cstring_to_human_cstring(co
   return SVN_NO_ERROR;
 }
 
-
-/* Return a copy, allocated in POOL, of the next line of text from *STR
- * up to and including a CR and/or an LF. Change *STR to point to the
- * remainder of the string after the returned part. If there are no
- * characters to be returned, return NULL; never return an empty string.
- */
-static const char *
-next_line(const char **str, apr_pool_t *pool)
-{
-  const char *start = *str;
-  const char *p = *str;
-
-  /* n.b. Throughout this fn, we never read any character after a '\0'. */
-  /* Skip over all non-EOL characters, if any. */
-  while (*p != '\r' && *p != '\n' && *p != '\0')
-    p++;
-  /* Skip over \r\n or \n\r or \r or \n, if any. */
-  if (*p == '\r' || *p == '\n')
-    {
-      char c = *p++;
-
-      if ((c == '\r' && *p == '\n') || (c == '\n' && *p == '\r'))
-        p++;
-    }
-
-  /* Now p points after at most one '\n' and/or '\r'. */
-  *str = p;
-
-  if (p == start)
-    return NULL;
-
-  return svn_string_ncreate(start, p - start, pool)->data;
-}
-
-const char *
-svn_cl__indent_string(const char *str,
-                      const char *indent,
-                      apr_pool_t *pool)
-{
-  svn_stringbuf_t *out = svn_stringbuf_create_empty(pool);
-  const char *line;
-
-  while ((line = next_line(&str, pool)))
-    {
-      svn_stringbuf_appendcstr(out, indent);
-      svn_stringbuf_appendcstr(out, line);
-    }
-  return out->data;
-}
-
 const char *
 svn_cl__node_description(const svn_wc_conflict_version_t *node,
                          const char *wc_repos_root_URL,

Modified: subversion/branches/tree-read-api/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svnadmin/svnadmin.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/tree-read-api/subversion/svnadmin/svnadmin.c Sun Jan  6 02:33:34 2013
@@ -1,5 +1,5 @@
 /*
- * main.c: Subversion server administration tool.
+ * svnadmin.c: Subversion server administration tool main file.
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one

Modified: subversion/branches/tree-read-api/subversion/svndumpfilter/svndumpfilter.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svndumpfilter/svndumpfilter.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svndumpfilter/svndumpfilter.c (original)
+++ subversion/branches/tree-read-api/subversion/svndumpfilter/svndumpfilter.c Sun Jan  6 02:33:34 2013
@@ -1,5 +1,5 @@
 /*
- * main.c: Subversion dump stream filtering tool.
+ * svndumpfilter.c: Subversion dump stream filtering tool main file.
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one

Modified: subversion/branches/tree-read-api/subversion/svnlook/svnlook.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svnlook/svnlook.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svnlook/svnlook.c (original)
+++ subversion/branches/tree-read-api/subversion/svnlook/svnlook.c Sun Jan  6 02:33:34 2013
@@ -1,5 +1,5 @@
 /*
- * main.c: Subversion server inspection tool.
+ * svnlook.c: Subversion server inspection tool main file.
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one
@@ -97,7 +97,8 @@ enum
     svnlook__xml_opt,
     svnlook__ignore_properties,
     svnlook__properties_only,
-    svnlook__diff_cmd
+    svnlook__diff_cmd,
+    svnlook__show_inherited_props
   };
 
 /*
@@ -150,6 +151,9 @@ static const apr_getopt_option_t options
   {"show-ids",          svnlook__show_ids, 0,
    N_("show node revision ids for each path")},
 
+  {"show-inherited-props", svnlook__show_inherited_props, 0,
+   N_("show path's inherited properties")},
+
   {"transaction",       't', 1,
    N_("specify transaction name ARG")},
 
@@ -265,7 +269,7 @@ static const svn_opt_subcommand_desc2_t 
       "       2. svnlook propget --revprop REPOS_PATH PROPNAME\n\n"
       "Print the raw value of a property on a path in the repository.\n"
       "With --revprop, print the raw value of a revision property.\n"),
-   {'r', 't', svnlook__revprop_opt} },
+   {'r', 't', 'v', svnlook__revprop_opt, svnlook__show_inherited_props} },
 
   {"proplist", subcommand_plist, {"plist", "pl"},
    N_("usage: 1. svnlook proplist REPOS_PATH PATH_IN_REPOS\n"
@@ -275,7 +279,8 @@ static const svn_opt_subcommand_desc2_t 
       "List the properties of a path in the repository, or\n"
       "with the --revprop option, revision properties.\n"
       "With -v, show the property values too.\n"),
-   {'r', 't', 'v', svnlook__revprop_opt, svnlook__xml_opt} },
+   {'r', 't', 'v', svnlook__revprop_opt, svnlook__xml_opt,
+    svnlook__show_inherited_props} },
 
   {"tree", subcommand_tree, {0},
    N_("usage: svnlook tree REPOS_PATH [PATH_IN_REPOS]\n\n"
@@ -323,6 +328,7 @@ struct svnlook_opt_state
   svn_boolean_t ignore_properties;  /* --ignore_properties */
   svn_boolean_t properties_only;    /* --properties-only */
   const char *diff_cmd;           /* --diff-cmd */
+  svn_boolean_t show_inherited_props; /*  --show-inherited-props */
 };
 
 
@@ -1628,13 +1634,23 @@ do_history(svnlook_ctxt_t *c,
 
 
 /* Print the value of property PROPNAME on PATH in the repository.
-   Error with SVN_ERR_FS_NOT_FOUND if PATH does not exist, or with
-   SVN_ERR_PROPERTY_NOT_FOUND if no such property on PATH.
+
+   If VERBOSE, print their values too.  If SHOW_INHERITED_PROPS, print
+   PATH's inherited props too.
+
+   Error with SVN_ERR_FS_NOT_FOUND if PATH does not exist. If
+   SHOW_INHERITED_PROPS is FALSE,then error with SVN_ERR_PROPERTY_NOT_FOUND
+   if there is no such property on PATH.  If SHOW_INHERITED_PROPS is TRUE,
+   then error with SVN_ERR_PROPERTY_NOT_FOUND only if there is no such
+   property on PATH nor inherited by path.
+
    If PATH is NULL, operate on a revision property. */
 static svn_error_t *
 do_pget(svnlook_ctxt_t *c,
         const char *propname,
         const char *path,
+        svn_boolean_t verbose,
+        svn_boolean_t show_inherited_props,
         apr_pool_t *pool)
 {
   svn_fs_root_t *root;
@@ -1642,17 +1658,30 @@ do_pget(svnlook_ctxt_t *c,
   svn_node_kind_t kind;
   svn_stream_t *stdout_stream;
   apr_size_t len;
+  apr_array_header_t *inherited_props = NULL;
 
   SVN_ERR(get_root(&root, c, pool));
   if (path != NULL)
     {
+      path = svn_fspath__canonicalize(path, pool);
       SVN_ERR(verify_path(&kind, root, path, pool));
       SVN_ERR(svn_fs_node_prop(&prop, root, path, propname, pool));
+
+      if (show_inherited_props)
+        {
+          SVN_ERR(svn_repos_fs_get_inherited_props(&inherited_props, root,
+                                                   path, propname, NULL,
+                                                   NULL, pool, pool));
+        }
+    }
+  else /* --revprop */
+    {
+      SVN_ERR(get_property(&prop, c, propname, pool));
     }
-  else
-    SVN_ERR(get_property(&prop, c, propname, pool));
 
-  if (prop == NULL)
+  /* Did we find nothing? */
+  if (prop == NULL
+      && (!show_inherited_props || inherited_props->nelts == 0))
     {
        const char *err_msg;
        if (path == NULL)
@@ -1665,61 +1694,162 @@ do_pget(svnlook_ctxt_t *c,
        else
          {
            if (SVN_IS_VALID_REVNUM(c->rev_id))
-             err_msg = apr_psprintf(pool,
-                                    _("Property '%s' not found on path '%s' "
-                                      "in revision %ld"),
-                                    propname, path, c->rev_id);
+             {
+               if (show_inherited_props)
+                 err_msg = apr_psprintf(pool,
+                                        _("Property '%s' not found on path '%s' "
+                                          "or inherited from a parent "
+                                          "in revision %ld"),
+                                        propname, path, c->rev_id);
+               else
+                 err_msg = apr_psprintf(pool,
+                                        _("Property '%s' not found on path '%s' "
+                                          "in revision %ld"),
+                                        propname, path, c->rev_id);
+             }
            else
-             err_msg = apr_psprintf(pool,
-                                    _("Property '%s' not found on path '%s' "
-                                      "in transaction %s"),
-                                    propname, path, c->txn_name);
+             {
+               if (show_inherited_props)
+                 err_msg = apr_psprintf(pool,
+                                        _("Property '%s' not found on path '%s' "
+                                          "or inherited from a parent "
+                                          "in transaction %s"),
+                                        propname, path, c->txn_name);
+               else
+                 err_msg = apr_psprintf(pool,
+                                        _("Property '%s' not found on path '%s' "
+                                          "in transaction %s"),
+                                        propname, path, c->txn_name);
+             }
          }
        return svn_error_create(SVN_ERR_PROPERTY_NOT_FOUND, NULL, err_msg);
     }
 
-  /* Else. */
-
   SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
 
-  /* Unlike the command line client, we don't translate the property
-     value or print a trailing newline here.  We just output the raw
-     bytes of whatever's in the repository, as svnlook is more likely
-     to be used for automated inspections. */
-  len = prop->len;
-  SVN_ERR(svn_stream_write(stdout_stream, prop->data, &len));
+  if (verbose || show_inherited_props)
+    {
+      if (inherited_props)
+        {
+          int i;
+
+          for (i = 0; i < inherited_props->nelts; i++)
+            {
+              svn_prop_inherited_item_t *elt =
+                APR_ARRAY_IDX(inherited_props, i,
+                              svn_prop_inherited_item_t *);
+
+              if (verbose)
+                {
+                  SVN_ERR(svn_stream_printf(stdout_stream, pool,
+                          _("Inherited properties on '%s',\nfrom '%s':\n"),
+                          path, svn_fspath__canonicalize(elt->path_or_url,
+                                                         pool)));
+                  SVN_ERR(svn_cmdline__print_prop_hash(stdout_stream,
+                                                       elt->prop_hash,
+                                                       !verbose, pool));
+                }
+              else
+                {
+                  svn_string_t *propval =
+                    svn__apr_hash_index_val(apr_hash_first(pool,
+                                                           elt->prop_hash));
+
+                  SVN_ERR(svn_stream_printf(
+                    stdout_stream, pool, "%s - ",
+                    svn_fspath__canonicalize(elt->path_or_url, pool)));
+                  len = propval->len;
+                  SVN_ERR(svn_stream_write(stdout_stream, propval->data, &len));
+                  /* If we have more than one property to write, then add a newline*/
+                  if (inherited_props->nelts > 1 || prop)
+                    {
+                      len = strlen(APR_EOL_STR);
+                      SVN_ERR(svn_stream_write(stdout_stream, APR_EOL_STR, &len));
+                    }
+                }
+            }
+        }
+
+      if (prop)
+        {
+          if (verbose)
+            {
+              apr_hash_t *hash = apr_hash_make(pool);
+
+              apr_hash_set(hash, propname, APR_HASH_KEY_STRING, prop);
+              SVN_ERR(svn_stream_printf(stdout_stream, pool,
+                      _("Properties on '%s':\n"), path));
+              SVN_ERR(svn_cmdline__print_prop_hash(stdout_stream, hash,
+                                                   FALSE, pool));
+            }
+          else
+            {
+              SVN_ERR(svn_stream_printf(stdout_stream, pool, "%s - ", path));
+              len = prop->len;
+              SVN_ERR(svn_stream_write(stdout_stream, prop->data, &len));
+            }
+        }
+    }
+  else /* Raw single prop output, i.e. non-verbose output with no
+          inherited props. */
+    {
+      /* Unlike the command line client, we don't translate the property
+         value or print a trailing newline here.  We just output the raw
+         bytes of whatever's in the repository, as svnlook is more likely
+         to be used for automated inspections. */
+      len = prop->len;
+      SVN_ERR(svn_stream_write(stdout_stream, prop->data, &len));
+    }
 
   return SVN_NO_ERROR;
 }
 
 
 /* Print the property names of all properties on PATH in the repository.
-   If VERBOSE, print their values too.
-   If XML, print as XML rather than as plain text.
-   Error with SVN_ERR_FS_NOT_FOUND if PATH does not exist, or with
-   SVN_ERR_PROPERTY_NOT_FOUND if no such property on PATH.
+
+   If VERBOSE, print their values too.  If XML, print as XML rather than as
+   plain text.  If SHOW_INHERITED_PROPS, print PATH's inherited props too.
+
+   Error with SVN_ERR_FS_NOT_FOUND if PATH does not exist.
+
    If PATH is NULL, operate on a revision properties. */
 static svn_error_t *
 do_plist(svnlook_ctxt_t *c,
          const char *path,
          svn_boolean_t verbose,
          svn_boolean_t xml,
+         svn_boolean_t show_inherited_props,
          apr_pool_t *pool)
 {
-  svn_stream_t *stdout_stream;
   svn_fs_root_t *root;
   apr_hash_t *props;
   apr_hash_index_t *hi;
   svn_node_kind_t kind;
   svn_stringbuf_t *sb = NULL;
   svn_boolean_t revprop = FALSE;
+  apr_array_header_t *inherited_props = NULL;
 
-  SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
   if (path != NULL)
     {
+      /* PATH might be the root of the repsository and we accept both
+         "" and "/".  But to avoid the somewhat cryptic output like this:
+
+           >svnlook pl repos-path ""
+           Properties on '':
+             svn:auto-props
+             svn:global-ignores
+
+         We canonicalize PATH so that is has a leading slash. */
+      path = svn_fspath__canonicalize(path, pool);
+
       SVN_ERR(get_root(&root, c, pool));
       SVN_ERR(verify_path(&kind, root, path, pool));
       SVN_ERR(svn_fs_node_proplist(&props, root, path, pool));
+
+      if (show_inherited_props)
+        SVN_ERR(svn_repos_fs_get_inherited_props(&inherited_props, root,
+                                                 path, NULL, NULL, NULL,
+                                                 pool, pool));
     }
   else if (c->is_revision)
     {
@@ -1734,18 +1864,55 @@ do_plist(svnlook_ctxt_t *c,
 
   if (xml)
     {
-      char *revstr = apr_psprintf(pool, "%ld", c->rev_id);
       /* <?xml version="1.0" encoding="UTF-8"?> */
       svn_xml_make_header2(&sb, "UTF-8", pool);
 
       /* "<properties>" */
       svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "properties", NULL);
+    }
 
+  if (inherited_props)
+    {
+      int i;
+
+      for (i = 0; i < inherited_props->nelts; i++)
+        {
+          svn_prop_inherited_item_t *elt =
+            APR_ARRAY_IDX(inherited_props, i, svn_prop_inherited_item_t *);
+
+          /* Canonicalize the inherited parent paths for consistency
+             with PATH. */
+          if (xml)
+            {
+              svn_xml_make_open_tag(
+                &sb, pool, svn_xml_normal, "target", "path",
+                svn_fspath__canonicalize(elt->path_or_url, pool),
+                NULL);
+              SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, elt->prop_hash,
+                                                       !verbose, TRUE,
+                                                       pool));
+              svn_xml_make_close_tag(&sb, pool, "target");
+            }
+          else
+            {
+              SVN_ERR(svn_cmdline_printf(
+                pool, _("Inherited properties on '%s',\nfrom '%s':\n"),
+                path, svn_fspath__canonicalize(elt->path_or_url, pool)));
+               SVN_ERR(svn_cmdline__print_prop_hash(NULL, elt->prop_hash,
+                                                    !verbose, pool));
+            }
+        }
+    }
+
+  if (xml)
+    {
       if (revprop)
         {
           /* "<revprops ...>" */
           if (c->is_revision)
             {
+              char *revstr = apr_psprintf(pool, "%ld", c->rev_id);
+
               svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "revprops",
                                     "rev", revstr, NULL);
             }
@@ -1763,6 +1930,9 @@ do_plist(svnlook_ctxt_t *c,
         }
     }
 
+  if (!xml && path /* Not a --revprop */)
+    SVN_ERR(svn_cmdline_printf(pool, _("Properties on '%s':\n"), path));
+
   for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
     {
       const char *pname = svn__apr_hash_index_key(hi);
@@ -1786,10 +1956,19 @@ do_plist(svnlook_ctxt_t *c,
           else
             {
               const char *pname_stdout;
+              const char *indented_newval;
 
               SVN_ERR(svn_cmdline_cstring_from_utf8(&pname_stdout, pname,
                                                     pool));
-              printf("  %s : %s\n", pname_stdout, propval->data);
+              printf("  %s\n", pname_stdout);
+              /* Add an extra newline to the value before indenting, so that
+                 every line of output has the indentation whether the value
+                 already ended in a newline or not. */
+              indented_newval =
+                svn_cmdline__indent_string(apr_psprintf(pool, "%s\n",
+                                                        propval->data),
+                                           "    ", pool);
+              printf("%s", indented_newval);
             }
         }
       else if (xml)
@@ -2171,7 +2350,9 @@ subcommand_pget(apr_getopt_t *os, void *
 
   SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
   SVN_ERR(do_pget(c, opt_state->arg1,
-                  opt_state->revprop ? NULL : opt_state->arg2, pool));
+                  opt_state->revprop ? NULL : opt_state->arg2,
+                  opt_state->verbose, opt_state->show_inherited_props,
+                  pool));
   return SVN_NO_ERROR;
 }
 
@@ -2186,7 +2367,8 @@ subcommand_plist(apr_getopt_t *os, void 
 
   SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
   SVN_ERR(do_plist(c, opt_state->revprop ? NULL : opt_state->arg1,
-                   opt_state->verbose, opt_state->xml, pool));
+                   opt_state->verbose, opt_state->xml,
+                   opt_state->show_inherited_props, pool));
   return SVN_NO_ERROR;
 }
 
@@ -2419,6 +2601,10 @@ main(int argc, const char *argv[])
           opt_state.diff_cmd = opt_arg;
           break;
 
+        case svnlook__show_inherited_props:
+          opt_state.show_inherited_props = TRUE;
+          break;
+
         default:
           SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
           svn_pool_destroy(pool);
@@ -2434,6 +2620,13 @@ main(int argc, const char *argv[])
                  _("The '--transaction' (-t) and '--revision' (-r) arguments "
                    "cannot co-exist")));
 
+  /* The --show-inherited-props and --revprop options may not co-exist. */
+  if (opt_state.show_inherited_props && opt_state.revprop)
+    SVN_INT_ERR(svn_error_create
+                (SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
+                 _("Cannot use the '--show-inherited-props' option with the "
+                   "'--revprop' option")));
+
   /* If the user asked for help, then the rest of the arguments are
      the names of subcommands to get help on (if any), or else they're
      just typos/mistakes.  Whatever the case, the subcommand to

Modified: subversion/branches/tree-read-api/subversion/svnmucc/svnmucc.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/svnmucc/svnmucc.c?rev=1429457&r1=1429456&r2=1429457&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/svnmucc/svnmucc.c (original)
+++ subversion/branches/tree-read-api/subversion/svnmucc/svnmucc.c Sun Jan  6 02:33:34 2013
@@ -55,6 +55,9 @@
 
 #include "private/svn_cmdline_private.h"
 #include "private/svn_ra_private.h"
+#include "private/svn_string_private.h"
+
+#include "svn_private_config.h"
 
 static void handle_error(svn_error_t *err, apr_pool_t *pool)
 {
@@ -750,6 +753,29 @@ execute(const apr_array_header_t *action
                                             "svnmucc: ", "--config-option"));
   cfg_config = apr_hash_get(config, SVN_CONFIG_CATEGORY_CONFIG,
                             APR_HASH_KEY_STRING);
+
+  if (! apr_hash_get(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING))
+    {
+      svn_string_t *msg = svn_string_create("", pool);
+
+      /* If we can do so, try to pop up $EDITOR to fetch a log message. */
+      if (non_interactive)
+        {
+          return svn_error_create
+            (SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
+             _("Cannot invoke editor to get log message "
+               "when non-interactive"));
+        }
+      else
+        {
+          SVN_ERR(svn_cmdline__edit_string_externally(
+                      &msg, NULL, NULL, "", msg, "svnmucc-commit", config,
+                      TRUE, NULL, apr_hash_pool_get(revprops)));
+        }
+
+      apr_hash_set(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING, msg);
+    }
+
   SVN_ERR(create_ra_callbacks(&ra_callbacks, username, password, config_dir,
                               cfg_config, non_interactive, no_auth_cache,
                               pool));
@@ -899,38 +925,43 @@ static void
 usage(apr_pool_t *pool, int exit_val)
 {
   FILE *stream = exit_val == EXIT_SUCCESS ? stdout : stderr;
-  static const char *msg =
-    "Multiple URL Command Client (for Subversion)\n"
-    "\nUsage: svnmucc [OPTION]... [ACTION]...\n"
-    "\nActions:\n"
-    "  cp REV URL1 URL2      copy URL1@REV to URL2\n"
-    "  mkdir URL             create new directory URL\n"
-    "  mv URL1 URL2          move URL1 to URL2\n"
-    "  rm URL                delete URL\n"
-    "  put SRC-FILE URL      add or modify file URL with contents copied from\n"
-    "                        SRC-FILE (use \"-\" to read from standard input)\n"
-    "  propset NAME VAL URL  set property NAME on URL to value VAL\n"
-    "  propsetf NAME VAL URL set property NAME on URL to value from file VAL\n"
-    "  propdel NAME URL      delete property NAME from URL\n"
-    "\nOptions:\n"
-    "  -h, --help, -?        display this text\n"
-    "  -m, --message ARG     use ARG as a log message\n"
-    "  -F, --file ARG        read log message from file ARG\n"
-    "  -u, --username ARG    commit the changes as username ARG\n"
-    "  -p, --password ARG    use ARG as the password\n"
-    "  -U, --root-url ARG    interpret all action URLs are relative to ARG\n"
-    "  -r, --revision ARG    use revision ARG as baseline for changes\n"
-    "  --with-revprop A[=B]  set revision property A in new revision to B\n"
-    "                        if specified, else to the empty string\n"
-    "  -n, --non-interactive don't prompt the user about anything\n"
-    "  -X, --extra-args ARG  append arguments from file ARG (one per line;\n"
-    "                        use \"-\" to read from standard input)\n"
-    "  --config-dir ARG      use ARG to override the config directory\n"
-    "  --config-option ARG   use ARG to override a configuration option\n"
-    "  --no-auth-cache       do not cache authentication tokens\n"
-    "  --version             print version information\n";
-  svn_error_clear(svn_cmdline_fputs(msg, stream, pool));
-  apr_pool_destroy(pool);
+  svn_error_clear(svn_cmdline_fputs(
+    _("Subversion multiple URL command client\n"
+      "usage: svnmucc [OPTION]... [ACTION]...\n"
+      "\n"
+      "  Perform one or more Subversion repository URL-based ACTIONs, committing\n"
+      "  the result as a (single) new revision.\n"
+      "\n"
+      "Actions:\n"
+      "  cp REV URL1 URL2       : copy URL1@REV to URL2\n"
+      "  mkdir URL              : create new directory URL\n"
+      "  mv URL1 URL2           : move URL1 to URL2\n"
+      "  rm URL                 : delete URL\n"
+      "  put SRC-FILE URL       : add or modify file URL with contents copied from\n"
+      "                           SRC-FILE (use \"-\" to read from standard input)\n"
+      "  propset NAME VAL URL   : set property NAME on URL to value VAL\n"
+      "  propsetf NAME VAL URL  : set property NAME on URL to value from file VAL\n"
+      "  propdel NAME URL       : delete property NAME from URL\n"
+      "\n"
+      "Valid options:\n"
+      "  -h, -? [--help]        : display this text\n"
+      "  -m [--message] ARG     : use ARG as a log message\n"
+      "  -F [--file] ARG        : read log message from file ARG\n"
+      "  -u [--username] ARG    : commit the changes as username ARG\n"
+      "  -p [--password] ARG    : use ARG as the password\n"
+      "  -U [--root-url] ARG    : interpret all action URLs relative to ARG\n"
+      "  -r [--revision] ARG    : use revision ARG as baseline for changes\n"
+      "  --with-revprop ARG     : set revision property in the following format:\n"
+      "                               NAME[=VALUE]\n"
+      "  -n [--non-interactive] : don't prompt the user about anything\n"
+      "  -X [--extra-args] ARG  : append arguments from file ARG (one per line;\n"
+      "                         : use \"-\" to read from standard input)\n"
+      "  --config-dir ARG       : use ARG to override the config directory\n"
+      "  --config-option ARG    : use ARG to override a configuration option\n"
+      "  --no-auth-cache        : do not cache authentication tokens\n"
+      "  --version              : print version information\n"),
+                  stream, pool));
+  svn_pool_destroy(pool);
   exit(exit_val);
 }
 
@@ -959,6 +990,53 @@ display_version(apr_getopt_t *os, apr_po
   return SVN_NO_ERROR;
 }
 
+/* Return an error about the mutual exclusivity of the -m, -F, and
+   --with-revprop=svn:log command-line options. */
+static svn_error_t *
+mutually_exclusive_logs_error(void)
+{
+  return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                          _("--message (-m), --file (-F), and "
+                            "--with-revprop=svn:log are mutually "
+                            "exclusive"));
+}
+
+/* Ensure that the REVPROPS hash contains a command-line-provided log
+   message, if any, and that there was but one source of such a thing
+   provided on that command-line.  */
+static svn_error_t *
+sanitize_log_sources(apr_hash_t *revprops,
+                     const char *message,
+                     svn_stringbuf_t *filedata)
+{
+  apr_pool_t *hash_pool = apr_hash_pool_get(revprops);
+
+  /* If we already have a log message in the revprop hash, then just
+     make sure the user didn't try to also use -m or -F.  Otherwise,
+     we need to consult -m or -F to find a log message, if any. */
+  if (apr_hash_get(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING))
+    {
+      if (filedata || message)
+        return mutually_exclusive_logs_error();
+    }
+  else if (filedata)
+    {
+      if (message)
+        return mutually_exclusive_logs_error();
+
+      SVN_ERR(svn_utf_cstring_to_utf8(&message, filedata->data, hash_pool));
+      apr_hash_set(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING,
+                   svn_stringbuf__morph_into_string(filedata));
+    }
+  else if (message)
+    {
+      apr_hash_set(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING,
+                   svn_string_create(message, hash_pool));
+    }
+  
+  return SVN_NO_ERROR;
+}
+
 int
 main(int argc, const char **argv)
 {
@@ -994,6 +1072,7 @@ main(int argc, const char **argv)
     {NULL, 0, 0, NULL}
   };
   const char *message = NULL;
+  svn_stringbuf_t *filedata = NULL;
   const char *username = NULL, *password = NULL;
   const char *root_url = NULL, *extra_args_file = NULL;
   const char *config_dir = NULL;
@@ -1031,12 +1110,9 @@ main(int argc, const char **argv)
         case 'F':
           {
             const char *arg_utf8;
-            svn_stringbuf_t *contents;
             err = svn_utf_cstring_to_utf8(&arg_utf8, arg, pool);
             if (! err)
-              err = svn_stringbuf_from_file2(&contents, arg, pool);
-            if (! err)
-              err = svn_utf_cstring_to_utf8(&message, contents->data, pool);
+              err = svn_stringbuf_from_file2(&filedata, arg, pool);
             if (err)
               handle_error(err, pool);
           }
@@ -1109,6 +1185,11 @@ main(int argc, const char **argv)
         }
     }
 
+  /* Make sure we have a log message to use. */
+  err = sanitize_log_sources(revprops, message, filedata);
+  if (err)
+    handle_error(err, pool);
+
   /* Copy the rest of our command-line arguments to an array,
      UTF-8-ing them along the way. */
   action_args = apr_array_make(pool, opts->argc, sizeof(const char *));
@@ -1324,21 +1405,6 @@ main(int argc, const char **argv)
   if (! actions->nelts)
     usage(pool, EXIT_FAILURE);
 
-  if (message == NULL)
-    {
-      if (apr_hash_get(revprops, SVN_PROP_REVISION_LOG,
-                       APR_HASH_KEY_STRING) == NULL)
-        /* None of -F, -m, or --with-revprop=svn:log specified; default. */
-        apr_hash_set(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING,
-                     svn_string_create("committed using svnmucc", pool));
-    }
-  else
-    {
-      /* -F or -m specified; use that even if --with-revprop=svn:log. */
-      apr_hash_set(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING,
-                   svn_string_create(message, pool));
-    }
-
   if ((err = execute(actions, anchor, revprops, username, password,
                      config_dir, config_options, non_interactive,
                      no_auth_cache, base_revision, pool)))