Index: subversion/include/svn_opt.h
===================================================================
--- subversion/include/svn_opt.h	(revision 16228)
+++ subversion/include/svn_opt.h	(working copy)
@@ -84,6 +84,13 @@
    */
   int valid_options[SVN_OPT_MAX_OPTIONS];
 
+  /** A list of option descriptors, which overwrite the general descriptors
+   * defined in svn_cl__options.  This list is used to provide
+   * subcommand-specific help messages in the description field.  We have to
+   * ensure that all other fields are in sync with svn_cl__options.
+   */
+  const apr_getopt_option_t options_table[SVN_OPT_MAX_OPTIONS];
+  
 } svn_opt_subcommand_desc_t;
 
 
Index: subversion/libsvn_subr/opt.c
===================================================================
--- subversion/libsvn_subr/opt.c	(revision 16228)
+++ subversion/libsvn_subr/opt.c	(working copy)
@@ -151,7 +151,12 @@
               /* convert each option code into an option */
               option = 
                 svn_opt_get_option_from_code (cmd->valid_options[i],
-                                              options_table);
+                                              cmd->options_table);
+              if (option == NULL)
+                /* no subcommand-specific option */
+                option = 
+                  svn_opt_get_option_from_code (cmd->valid_options[i],
+                                                options_table);
 
               /* print the option's docstring */
               if (option)
Index: subversion/clients/cmdline/main.c
===================================================================
--- subversion/clients/cmdline/main.c	(revision 16228)
+++ subversion/clients/cmdline/main.c	(working copy)
@@ -194,7 +194,8 @@
        "usage: add PATH...\n"),
     {svn_cl__targets_opt, 'N', 'q', svn_cl__config_dir_opt,
      svn_cl__force_opt, svn_cl__no_ignore_opt, svn_cl__autoprops_opt, 
-     svn_cl__no_autoprops_opt} },
+     svn_cl__no_autoprops_opt},
+    {{0, 0, 0, 0}} },
 
   { "blame", svn_cl__blame, {"praise", "annotate", "ann"},
     N_("Output the content of specified files or\n"
@@ -204,7 +205,8 @@
        "  If specified, REV determines in which revision the target is first\n"
        "  looked up.\n"),
     {'r', 'v', svn_cl__incremental_opt, svn_cl__xml_opt, SVN_CL__AUTH_OPTIONS,
-     svn_cl__config_dir_opt} },
+     svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
 
   { "cat", svn_cl__cat, {0},
     N_("Output the content of specified files or URLs.\n"
@@ -212,7 +214,8 @@
        "\n"
        "  If specified, REV determines in which revision the target is first\n"
        "  looked up.\n"),
-    {'r', SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },
+    {'r', SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
 
   { "checkout", svn_cl__checkout, {"co"}, N_
     ("Check out a working copy from a repository.\n"
@@ -226,13 +229,15 @@
      "  out into a sub-directory of PATH, with the name of the sub-directory\n"
      "  being the basename of the URL.\n"),
     {'r', 'q', 'N', SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt,
-     svn_cl__ignore_externals_opt} },
+     svn_cl__ignore_externals_opt},
+    {{0, 0, 0, 0}} },
 
   { "cleanup", svn_cl__cleanup, {0},
     N_("Recursively clean up the working copy, removing locks, resuming\n"
        "unfinished operations, etc.\n"
        "usage: cleanup [PATH...]\n"),
-    {svn_cl__merge_cmd_opt, svn_cl__config_dir_opt} },
+    {svn_cl__merge_cmd_opt, svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
   
   { "commit", svn_cl__commit, {"ci"},
     N_("Send changes from your working copy to the repository.\n"
@@ -243,7 +248,9 @@
        "  If any targets are (or contain) locked items, those will be\n"
        "  unlocked after a successful commit.\n"),
     {'q', 'N', svn_cl__targets_opt, svn_cl__no_unlock_opt,
-     SVN_CL__LOG_MSG_OPTIONS, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },
+     SVN_CL__LOG_MSG_OPTIONS, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt},
+    {{"file", 'F', 1, N_("read commit message from file ARG")},
+     {0, 0, 0, 0}} },
   
   { "copy", svn_cl__copy, {"cp"},
     N_("Duplicate something in working copy or repository, remembering "
@@ -256,7 +263,9 @@
        "    URL -> WC:   check out URL into WC, schedule for addition\n"
        "    URL -> URL:  complete server-side copy;  used to branch & tag\n"),
     {'r', 'q',
-     SVN_CL__LOG_MSG_OPTIONS, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },
+     SVN_CL__LOG_MSG_OPTIONS, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt},
+    {{"file", 'F', 1, N_("read commit message from file ARG")},
+     {0, 0, 0, 0}} },
   
   { "delete", svn_cl__delete, {"del", "remove", "rm"},
     N_("Remove files and directories from version control.\n"
@@ -272,7 +281,9 @@
        "  2. Each item specified by a URL is deleted from the repository\n"
        "    via an immediate commit.\n"),
     {svn_cl__force_opt, 'q', svn_cl__targets_opt,
-     SVN_CL__LOG_MSG_OPTIONS, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },
+     SVN_CL__LOG_MSG_OPTIONS, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt},
+    {{"file", 'F', 1, N_("read commit message from file ARG")},
+     {0, 0, 0, 0}} },
   
   { "diff", svn_cl__diff, {"di"},
     N_("Display the differences between two paths.\n"
@@ -312,7 +323,8 @@
     {'r', svn_cl__old_cmd_opt, svn_cl__new_cmd_opt, 'N',
      svn_cl__diff_cmd_opt, 'x', svn_cl__no_diff_deleted,
      svn_cl__notice_ancestry_opt, svn_cl__force_opt, SVN_CL__AUTH_OPTIONS,
-     svn_cl__config_dir_opt} },
+     svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
 
   { "export", svn_cl__export, {0},
     N_("Create an unversioned copy of a tree.\n"
@@ -341,12 +353,14 @@
        "  looked up.\n"),
     {'r', 'q', 'N', svn_cl__force_opt, SVN_CL__AUTH_OPTIONS,
      svn_cl__config_dir_opt, svn_cl__native_eol_opt, 
-     svn_cl__ignore_externals_opt} },
+     svn_cl__ignore_externals_opt},
+    {{0, 0, 0, 0}} },
 
   { "help", svn_cl__help, {"?", "h"},
     N_("Describe the usage of this program or its subcommands.\n"
        "usage: help [SUBCOMMAND...]\n"),
-    {svn_cl__version_opt, 'q', svn_cl__config_dir_opt} },
+    {svn_cl__version_opt, 'q', svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
   /* We need to support "--help", "-?", and all that good stuff, of
      course.  But those options, since unknown, will result in the
      help message being printed out anyway, so there's no need to
@@ -363,7 +377,9 @@
        "  directly under URL.\n"),
     {'q', 'N', svn_cl__autoprops_opt, svn_cl__no_autoprops_opt,
      SVN_CL__LOG_MSG_OPTIONS, svn_cl__no_ignore_opt, SVN_CL__AUTH_OPTIONS, 
-     svn_cl__config_dir_opt} },
+     svn_cl__config_dir_opt},
+    {{"file", 'F', 1, N_("read commit message from file ARG")},
+     {0, 0, 0, 0}} },
  
   { "info", svn_cl__info, {0},
     N_("Display information about a local or remote item.\n"
@@ -372,7 +388,8 @@
        "  Print information about each TARGET (default: '.')\n"
        "  TARGET may be either a working-copy path or URL.\n"),
     {'r', 'R', svn_cl__targets_opt, svn_cl__incremental_opt, svn_cl__xml_opt,
-     SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },
+     SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
  
   { "list", svn_cl__ls, {"ls"},
     N_("List directory entries in the repository.\n"
@@ -397,7 +414,8 @@
        "    Size (in bytes)\n"
        "    Date and time of the last commit\n"),
     {'r', 'v', 'R', svn_cl__incremental_opt, svn_cl__xml_opt,
-     SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },
+     SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
   
   { "lock", svn_cl__lock, {0},
     N_("Lock working copy paths or URLs in the repository, so that\n"
@@ -407,7 +425,11 @@
        "  Use --force to steal the lock from another user or working copy.\n"),
     { svn_cl__targets_opt, 'm', 'F', svn_cl__force_log_opt,
       svn_cl__encoding_opt, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt,
-      svn_cl__force_opt } },
+      svn_cl__force_opt},
+    {{"file", 'F', 1, N_("read lock message from file ARG")},
+     {"message", 'm', 1, N_("specify lock message ARG")},
+     {0, 0, 0, 0}} },
+
   { "log", svn_cl__log, {0},
     N_("Show the log messages for a set of revision(s) and/or file(s).\n"
        "usage: 1. log [PATH]\n"
@@ -438,7 +460,8 @@
        "    svn log http://www.example.com/repo/project foo.c bar.c\n"),
     {'r', 'q', 'v', svn_cl__targets_opt, svn_cl__stop_on_copy_opt,
      svn_cl__incremental_opt, svn_cl__xml_opt, SVN_CL__AUTH_OPTIONS, 
-     svn_cl__config_dir_opt, svn_cl__limit_opt} },
+     svn_cl__config_dir_opt, svn_cl__limit_opt},
+    {{0, 0, 0, 0}} },
 
   { "merge", svn_cl__merge, {0},
     N_("Apply the differences between two sources to a working copy path.\n"
@@ -468,7 +491,8 @@
        "  in which case, the differences will be applied to that file.\n"),
     {'r', 'N', 'q', svn_cl__force_opt, svn_cl__dry_run_opt,
      svn_cl__merge_cmd_opt, svn_cl__ignore_ancestry_opt, 
-     SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },
+     SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
   
   { "mkdir", svn_cl__mkdir, {0},
     N_("Create a new directory under version control.\n"
@@ -488,7 +512,9 @@
        "  In both cases, all the intermediate directories must already "
        "exist.\n"),
     {'q',
-     SVN_CL__LOG_MSG_OPTIONS, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },
+     SVN_CL__LOG_MSG_OPTIONS, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt},
+    {{"file", 'F', 1, N_("read commit message from file ARG")},
+     {0, 0, 0, 0}} },
 
   { "move", svn_cl__move, {"mv", "rename", "ren"},
     N_("Move and/or rename something in working copy or repository.\n"
@@ -500,7 +526,9 @@
        "    WC  -> WC:   move and schedule for addition (with history)\n"
        "    URL -> URL:  complete server-side rename.\n"),    
     {'r', 'q', svn_cl__force_opt,
-     SVN_CL__LOG_MSG_OPTIONS, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },
+     SVN_CL__LOG_MSG_OPTIONS, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt},
+    {{"file", 'F', 1, N_("read commit message from file ARG")},
+     {0, 0, 0, 0}} },
   
   { "propdel", svn_cl__propdel, {"pdel", "pd"},
     N_("Remove PROPNAME from files, dirs, or revisions.\n"
@@ -510,7 +538,8 @@
        "  1. Removes versioned props in working copy.\n"
        "  2. Removes unversioned remote prop on repos revision.\n"),
     {'q', 'R', 'r', svn_cl__revprop_opt, SVN_CL__AUTH_OPTIONS,
-     svn_cl__config_dir_opt} },
+     svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
   
   { "propedit", svn_cl__propedit, {"pedit", "pe"},
     N_("Edit property PROPNAME with an external editor on targets.\n"
@@ -521,7 +550,8 @@
        "  2. Edits unversioned remote prop on repos revision.\n"),
     {'r', svn_cl__revprop_opt, SVN_CL__AUTH_OPTIONS,
      svn_cl__encoding_opt, svn_cl__editor_cmd_opt, svn_cl__force_opt,
-     svn_cl__config_dir_opt} },
+     svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
   
   { "propget", svn_cl__propget, {"pget", "pg"},
     N_("Print value of PROPNAME on files, dirs, or revisions.\n"
@@ -539,7 +569,8 @@
        "  the --strict option to disable these beautifications (useful,\n"
        "  for example, when redirecting binary property values to a file).\n"),
     {'R', 'r', svn_cl__revprop_opt, svn_cl__strict_opt, 
-     SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },
+     SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
 
   { "proplist", svn_cl__proplist, {"plist", "pl"},
     N_("List all properties on files, dirs, or revisions.\n"
@@ -550,7 +581,8 @@
        "     revision the target is first looked up.\n"
        "  2. Lists unversioned remote props on repos revision.\n"),
     {'v', 'R', 'r', 'q', svn_cl__revprop_opt, SVN_CL__AUTH_OPTIONS,
-     svn_cl__config_dir_opt} },
+     svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
 
   { "propset", svn_cl__propset, {"pset", "ps"},
     N_("Set PROPNAME to PROPVAL on files, dirs, or revisions.\n"
@@ -600,7 +632,9 @@
        "  only on the file children of the directory.\n"),
     {'F', svn_cl__encoding_opt, 'q', 'r', svn_cl__targets_opt, 'R',
      svn_cl__revprop_opt, SVN_CL__AUTH_OPTIONS, svn_cl__force_opt,
-     svn_cl__config_dir_opt} },
+     svn_cl__config_dir_opt},
+    {{"file", 'F', 1, N_("read property value from file ARG")},
+     {0, 0, 0, 0}} },
   
   { "resolved", svn_cl__resolved, {0},
     N_("Remove 'conflicted' state on working copy files or directories.\n"
@@ -609,7 +643,8 @@
        "  Note:  this subcommand does not semantically resolve conflicts or\n"
        "  remove conflict markers; it merely removes the conflict-related\n"
        "  artifact files and allows PATH to be committed again.\n"),
-    {svn_cl__targets_opt, 'R', 'q', svn_cl__config_dir_opt} },
+    {svn_cl__targets_opt, 'R', 'q', svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
  
   { "revert", svn_cl__revert, {0},
     N_("Restore pristine working copy file (undo most local edits).\n"
@@ -619,7 +654,8 @@
        "resolves\n"
        "  any conflicted states.  However, it does not restore removed "
        "directories.\n"),
-    {svn_cl__targets_opt, 'R', 'q', svn_cl__config_dir_opt} },
+    {svn_cl__targets_opt, 'R', 'q', svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
 
   { "status", svn_cl__status, {"stat", "st"}, N_
     ("Print the status of working copy files and directories.\n"
@@ -696,7 +732,8 @@
      "    Status against revision:   981\n"),
     { 'u', 'v', 'N', 'q', svn_cl__no_ignore_opt, svn_cl__incremental_opt,
       svn_cl__xml_opt, SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt,
-      svn_cl__ignore_externals_opt} },
+      svn_cl__ignore_externals_opt},
+    {{0, 0, 0, 0}} },
   
   { "switch", svn_cl__switch, {"sw"},
     N_("Update the working copy to a different URL.\n"
@@ -717,7 +754,8 @@
        "same\n"
        "     directory within the same repository.\n"),
     { 'r', 'N', 'q', svn_cl__merge_cmd_opt, svn_cl__relocate_opt,
-      SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt} },
+      SVN_CL__AUTH_OPTIONS, svn_cl__config_dir_opt},
+    {{0, 0, 0, 0}} },
  
   { "unlock", svn_cl__unlock, {0},
     N_("Unlock working copy paths or URLs.\n"
@@ -725,7 +763,8 @@
        "\n"
        "  Use --force to break the lock.\n"),
     { svn_cl__targets_opt, SVN_CL__AUTH_OPTIONS,
-      svn_cl__config_dir_opt, svn_cl__force_opt } },
+      svn_cl__config_dir_opt, svn_cl__force_opt },
+    {{0, 0, 0, 0}} },
 
   { "update", svn_cl__update, {"up"}, 
     N_("Bring changes from the repository into the working copy.\n"
@@ -752,7 +791,8 @@
        "  been broken or stolen.\n"
        ),
     {'r', 'N', 'q', svn_cl__merge_cmd_opt, SVN_CL__AUTH_OPTIONS, 
-     svn_cl__config_dir_opt, svn_cl__ignore_externals_opt} },
+     svn_cl__config_dir_opt, svn_cl__ignore_externals_opt},
+    {{0, 0, 0, 0}} },
 
   { NULL, NULL, {0}, NULL, {0} }
 };


