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 2020/02/28 21:09:13 UTC

svn commit: r1874631 - in /subversion/branches/decouple-shelving-cli/subversion/svn: cl.h shelf-cmd.c shelf-cmd.h svn.c

Author: julianfoad
Date: Fri Feb 28 21:09:13 2020
New Revision: 1874631

URL: http://svn.apache.org/viewvc?rev=1874631&view=rev
Log:
Initialize the 'svn x-shelf-*' commands programmatically at run time,
instead of hard-coding them in svn's main command table.

A step towards decoupling the experimental shelving CLI from the main CLI.

* subversion/svn/cl.h
  (svn_cl__longopt_t,
   SVN_CL__LOG_MSG_OPTIONS): Move to here from svn.c.
  (svn_cl__shelf_*,
   svn_cl__wc_copy_mods): Remove these declarations.
  (svn_cl__cmd_table): Change to a pointer.

* subversion/svn/shelf-cmd.c
  (svn_cl__shelf_*,
   svn_cl__wc_copy_mods): New 'static', no longer external.
  (svn_cl__cmd_table_shelf3): New command table, with contents moved to here
    from svn_cl__cmd_table.

* subversion/svn/shelf-cmd.h
  New.

* subversion/svn/svn.c
  (svn_cl__cmd_table_main): Renamed from 'svn_cl__cmd_table'. Move
    shelf-related entries to svn_cl__cmd_table_shelf3 in shelf-cmd.c.
  (svn_cl__cmd_table): Change to a pointer.
  (add_commands): New.
  (sub_main): Call add_commands(). Rewrite a check because the shelving
    command functions are no longer externally visible.

Added:
    subversion/branches/decouple-shelving-cli/subversion/svn/shelf-cmd.h   (with props)
Modified:
    subversion/branches/decouple-shelving-cli/subversion/svn/cl.h
    subversion/branches/decouple-shelving-cli/subversion/svn/shelf-cmd.c
    subversion/branches/decouple-shelving-cli/subversion/svn/svn.c

Modified: subversion/branches/decouple-shelving-cli/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/decouple-shelving-cli/subversion/svn/cl.h?rev=1874631&r1=1874630&r2=1874631&view=diff
==============================================================================
--- subversion/branches/decouple-shelving-cli/subversion/svn/cl.h (original)
+++ subversion/branches/decouple-shelving-cli/subversion/svn/cl.h Fri Feb 28 21:09:13 2020
@@ -288,6 +288,103 @@ typedef struct svn_cl__cmd_baton_t
 } svn_cl__cmd_baton_t;
 
 
+/* Add an identifier here for long options that don't have a short
+   option. Options that have both long and short options should just
+   use the short option letter as identifier.  */
+typedef enum svn_cl__longopt_t {
+  opt_auth_password = SVN_OPT_FIRST_LONGOPT_ID,
+  opt_auth_password_from_stdin,
+  opt_auth_username,
+  opt_autoprops,
+  opt_changelist,
+  opt_config_dir,
+  opt_config_options,
+  /* diff options */
+  opt_diff_cmd,
+  opt_internal_diff,
+  opt_no_diff_added,
+  opt_no_diff_deleted,
+  opt_show_copies_as_adds,
+  opt_notice_ancestry,
+  opt_summarize,
+  opt_use_git_diff_format,
+  opt_ignore_properties,
+  opt_properties_only,
+  opt_patch_compatible,
+  /* end of diff options */
+  opt_dry_run,
+  opt_editor_cmd,
+  opt_encoding,
+  opt_force_log,
+  opt_force,
+  opt_keep_changelists,
+  opt_ignore_ancestry,
+  opt_ignore_externals,
+  opt_incremental,
+  opt_merge_cmd,
+  opt_native_eol,
+  opt_new_cmd,
+  opt_no_auth_cache,
+  opt_no_autoprops,
+  opt_no_ignore,
+  opt_no_unlock,
+  opt_non_interactive,
+  opt_force_interactive,
+  opt_old_cmd,
+  opt_record_only,
+  opt_relocate,
+  opt_remove,
+  opt_revprop,
+  opt_stop_on_copy,
+  opt_strict,                   /* ### DEPRECATED */
+  opt_targets,
+  opt_depth,
+  opt_set_depth,
+  opt_version,
+  opt_xml,
+  opt_keep_local,
+  opt_with_revprop,
+  opt_with_all_revprops,
+  opt_with_no_revprops,
+  opt_parents,
+  opt_accept,
+  opt_show_revs,
+  opt_reintegrate,
+  opt_trust_server_cert,
+  opt_trust_server_cert_failures,
+  opt_strip,
+  opt_ignore_keywords,
+  opt_reverse_diff,
+  opt_ignore_whitespace,
+  opt_diff,
+  opt_allow_mixed_revisions,
+  opt_include_externals,
+  opt_show_inherited_props,
+  opt_search,
+  opt_search_and,
+  opt_mergeinfo_log,
+  opt_remove_unversioned,
+  opt_remove_ignored,
+  opt_remove_added,
+  opt_no_newline,
+  opt_show_passwords,
+  opt_pin_externals,
+  opt_show_item,
+  opt_adds_as_modification,
+  opt_vacuum_pristines,
+  opt_drop,
+  opt_viewspec,
+} svn_cl__longopt_t;
+
+/* Options for giving a log message.  (Some of these also have other uses.)
+ */
+#define SVN_CL__LOG_MSG_OPTIONS 'm', 'F', \
+                                opt_force_log, \
+                                opt_editor_cmd, \
+                                opt_encoding, \
+                                opt_with_revprop
+
+
 /* Declare all the command procedures */
 svn_opt_subcommand_t
   svn_cl__add,
@@ -322,15 +419,6 @@ svn_opt_subcommand_t
   svn_cl__revert,
   svn_cl__resolve,
   svn_cl__resolved,
-  svn_cl__shelf_diff,
-  svn_cl__shelf_drop,
-  svn_cl__shelf_list,
-  svn_cl__shelf_list_by_paths,
-  svn_cl__shelf_log,
-  svn_cl__shelf_save,
-  svn_cl__shelf_shelve,
-  svn_cl__shelf_unshelve,
-  svn_cl__wc_copy_mods,
   svn_cl__status,
   svn_cl__switch,
   svn_cl__unlock,
@@ -339,7 +427,7 @@ svn_opt_subcommand_t
 
 
 /* See definition in svn.c for documentation. */
-extern const svn_opt_subcommand_desc3_t svn_cl__cmd_table[];
+extern const svn_opt_subcommand_desc3_t *svn_cl__cmd_table;
 
 /* See definition in svn.c for documentation. */
 extern const int svn_cl__global_options[];

Modified: subversion/branches/decouple-shelving-cli/subversion/svn/shelf-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/decouple-shelving-cli/subversion/svn/shelf-cmd.c?rev=1874631&r1=1874630&r2=1874631&view=diff
==============================================================================
--- subversion/branches/decouple-shelving-cli/subversion/svn/shelf-cmd.c (original)
+++ subversion/branches/decouple-shelving-cli/subversion/svn/shelf-cmd.c Fri Feb 28 21:09:13 2020
@@ -34,6 +34,7 @@
 #include "svn_pools.h"
 #include "svn_utf.h"
 
+#include "shelf-cmd.h"
 #include "cl.h"
 
 #include "svn_private_config.h"
@@ -838,8 +839,13 @@ shelf_shelve(int *new_version,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+svn_cl__shelf_shelve(apr_getopt_t *os,
+                     void *baton,
+                     apr_pool_t *pool);
+
 /* This implements the `svn_opt_subcommand_t' interface. */
-svn_error_t *
+static svn_error_t *
 svn_cl__shelf_save(apr_getopt_t *os,
                    void *baton,
                    apr_pool_t *pool)
@@ -852,7 +858,7 @@ svn_cl__shelf_save(apr_getopt_t *os,
 }
 
 /* This implements the `svn_opt_subcommand_t' interface. */
-svn_error_t *
+static svn_error_t *
 svn_cl__shelf_shelve(apr_getopt_t *os,
                      void *baton,
                      apr_pool_t *pool)
@@ -907,7 +913,7 @@ svn_cl__shelf_shelve(apr_getopt_t *os,
 }
 
 /* This implements the `svn_opt_subcommand_t' interface. */
-svn_error_t *
+static svn_error_t *
 svn_cl__shelf_unshelve(apr_getopt_t *os,
                        void *baton,
                        apr_pool_t *scratch_pool)
@@ -959,7 +965,7 @@ svn_cl__shelf_unshelve(apr_getopt_t *os,
 }
 
 /* This implements the `svn_opt_subcommand_t' interface. */
-svn_error_t *
+static svn_error_t *
 svn_cl__shelf_list(apr_getopt_t *os,
                    void *baton,
                    apr_pool_t *pool)
@@ -1083,7 +1089,7 @@ shelf_list_by_paths(apr_array_header_t *
 }
 
 /* This implements the `svn_opt_subcommand_t' interface. */
-svn_error_t *
+static svn_error_t *
 svn_cl__shelf_list_by_paths(apr_getopt_t *os,
                             void *baton,
                             apr_pool_t *pool)
@@ -1103,7 +1109,7 @@ svn_cl__shelf_list_by_paths(apr_getopt_t
 }
 
 /* This implements the `svn_opt_subcommand_t' interface. */
-svn_error_t *
+static svn_error_t *
 svn_cl__shelf_diff(apr_getopt_t *os,
                    void *baton,
                    apr_pool_t *pool)
@@ -1135,7 +1141,7 @@ svn_cl__shelf_diff(apr_getopt_t *os,
 }
 
 /* This implements the `svn_opt_subcommand_t' interface. */
-svn_error_t *
+static svn_error_t *
 svn_cl__shelf_drop(apr_getopt_t *os,
                    void *baton,
                    apr_pool_t *pool)
@@ -1173,7 +1179,7 @@ svn_cl__shelf_drop(apr_getopt_t *os,
 }
 
 /* This implements the `svn_opt_subcommand_t' interface. */
-svn_error_t *
+static svn_error_t *
 svn_cl__shelf_log(apr_getopt_t *os,
                   void *baton,
                   apr_pool_t *pool)
@@ -1211,7 +1217,7 @@ svn_cl__shelf_log(apr_getopt_t *os,
 /**************************************************************************/
 
 /* This implements the `svn_opt_subcommand_t' interface. */
-svn_error_t *
+static svn_error_t *
 svn_cl__wc_copy_mods(apr_getopt_t *os,
                      void *baton,
                      apr_pool_t *pool)
@@ -1231,3 +1237,168 @@ svn_cl__wc_copy_mods(apr_getopt_t *os,
 
   return SVN_NO_ERROR;
 }
+
+const svn_opt_subcommand_desc3_t
+svn_cl__cmd_table_shelf3[] =
+{
+  { "x-shelf-diff", svn_cl__shelf_diff, {0}, {N_(
+     "Show shelved changes as a diff.\n"
+     "usage: x-shelf-diff SHELF [VERSION]\n"
+     "\n"), N_(
+     "  Show the changes in SHELF:VERSION (default: latest) as a diff.\n"
+     "\n"), N_(
+     "  See also: 'svn diff --cl=svn:shelf:SHELF' which supports most options of\n"
+     "  'svn diff'.\n"
+     "\n"), N_(
+     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
+     "  in the next release, and there is no promise of backward compatibility.\n"
+    )},
+    {opt_summarize},
+  },
+
+  { "x-shelf-drop", svn_cl__shelf_drop, {0}, {N_(
+     "Delete a shelf.\n"
+     "usage: x-shelf-drop SHELF [PATH ...]\n"
+     "\n"), N_(
+     "  Delete the shelves named SHELF from the working copies containing PATH\n"
+     "  (default PATH is '.')\n"
+     "\n"), N_(
+     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
+     "  in the next release, and there is no promise of backward compatibility.\n"
+    )},
+  },
+
+  { "x-shelf-list", svn_cl__shelf_list, {"x-shelves"}, {N_(
+     "List shelves.\n"
+     "usage: x-shelf-list [PATH ...]\n"
+     "\n"), N_(
+     "  List shelves for each working copy containing PATH (default is '.')\n"
+     "  Include the first line of any log message and some details about the\n"
+     "  contents of the shelf, unless '-q' is given.\n"
+     "\n"), N_(
+     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
+     "  in the next release, and there is no promise of backward compatibility.\n"
+    )},
+    {'q', 'v'}
+  },
+
+  { "x-shelf-list-by-paths", svn_cl__shelf_list_by_paths, {0}, {N_(
+     "List which shelf affects each path.\n"
+     "usage: x-shelf-list-by-paths [PATH...]\n"
+     "\n"), N_(
+     "  List which shelf most recently affects each path below the given PATHs.\n"
+     "\n"), N_(
+     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
+     "  in the next release, and there is no promise of backward compatibility.\n"
+    )},
+  },
+
+  { "x-shelf-log", svn_cl__shelf_log, {0}, {N_(
+     "Show the versions of a shelf.\n"
+     "usage: x-shelf-log SHELF [PATH...]\n"
+     "\n"), N_(
+     "  Show all versions of SHELF for each working copy containing PATH (the\n"
+     "  default PATH is '.').\n"
+     "\n"), N_(
+     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
+     "  in the next release, and there is no promise of backward compatibility.\n"
+    )},
+    {'q', 'v'}
+  },
+
+  { "x-shelf-save", svn_cl__shelf_save, {0}, {N_(
+     "Copy local changes onto a new version of a shelf.\n"
+     "usage: x-shelf-save SHELF [PATH...]\n"
+     "\n"), N_(
+     "  Save local changes in the given PATHs as a new version of SHELF.\n"
+     "  The shelf's log message can be set with -m, -F, etc.\n"
+     "\n"), N_(
+     "  The same as 'svn shelve --keep-local'.\n"
+     "\n"), N_(
+     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
+     "  in the next release, and there is no promise of backward compatibility.\n"
+    )},
+    {'q', opt_dry_run,
+     opt_depth, opt_targets, opt_changelist,
+     SVN_CL__LOG_MSG_OPTIONS,
+    }
+  },
+
+  { "x-shelve", svn_cl__shelf_shelve, {0}, {N_(
+     "Move local changes onto a shelf.\n"
+     "usage: x-shelve [--keep-local] SHELF [PATH...]\n"
+     "\n"), N_(
+     "  Save the local changes in the given PATHs to a new or existing SHELF.\n"
+     "  Revert those changes from the WC unless '--keep-local' is given.\n"
+     "  The shelf's log message can be set with -m, -F, etc.\n"
+     "\n"), N_(
+     "  'svn shelve --keep-local' is the same as 'svn shelf-save'.\n"
+     "\n"), N_(
+     "  The kinds of change you can shelve are committable changes to files and\n"
+     "  properties, except the following kinds which are not yet supported:\n"
+     "     * copies and moves\n"
+     "     * mkdir and rmdir\n"
+     "  Uncommittable states such as conflicts, unversioned and missing cannot\n"
+     "  be shelved.\n"
+     "\n"), N_(
+     "  To bring back shelved changes, use 'svn unshelve SHELF'.\n"
+     "\n"), N_(
+     "  Shelves are currently stored under <WC>/.svn/experimental/shelves/ .\n"
+     "  (In Subversion 1.10, shelves were stored under <WC>/.svn/shelves/ as\n"
+     "  patch files. To recover a shelf created by 1.10, either use a 1.10\n"
+     "  client to find and unshelve it, or find the patch file and use any\n"
+     "  1.10 or later 'svn patch' to apply it.)\n"
+     "\n"), N_(
+     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
+     "  in the next release, and there is no promise of backward compatibility.\n"
+    )},
+    {'q', opt_dry_run, opt_keep_local,
+     opt_depth, opt_targets, opt_changelist,
+     SVN_CL__LOG_MSG_OPTIONS,
+    } },
+
+  { "x-unshelve", svn_cl__shelf_unshelve, {0}, {N_(
+     "Copy shelved changes back into the WC.\n"
+     "usage: x-unshelve [--drop] [SHELF [VERSION]]\n"
+     "\n"), N_(
+     "  Apply the changes stored in SHELF to the working copy.\n"
+     "  SHELF defaults to the newest shelf.\n"
+     "\n"), N_(
+     "  Apply the newest version of the shelf, by default. If VERSION is\n"
+     "  specified, apply that version and discard all versions newer than that.\n"
+     "  In any case, retain the unshelved version and versions older than that\n"
+     "  (unless --drop is specified).\n"
+     "\n"), N_(
+     "  With --drop, delete the entire shelf (like 'svn shelf-drop') after\n"
+     "  successfully unshelving with no conflicts.\n"
+     "\n"), N_(
+     "  The working files involved should be in a clean, unmodified state\n"
+     "  before using this command. To roll back to an older version of the\n"
+     "  shelf, first ensure any current working changes are removed, such as\n"
+     "  by shelving or reverting them, and then unshelve the desired version.\n"
+     "\n"), N_(
+     "  Unshelve normally refuses to apply any changes if any path involved is\n"
+     "  already modified (or has any other abnormal status) in the WC. With\n"
+     "  --force, it does not check and may error out and/or produce partial or\n"
+     "  unexpected results.\n"
+     "\n"), N_(
+     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
+     "  in the next release, and there is no promise of backward compatibility.\n"
+    )},
+    {opt_drop, 'q', opt_dry_run, opt_force} },
+
+  { "x-wc-copy-mods", svn_cl__wc_copy_mods, {0}, {N_(
+     "Copy local modifications from one WC to another.\n"
+     "usage: x-wc-copy-mods SRC_WC_PATH DST_WC_PATH\n"
+     "\n"), N_(
+     "  The source and destination WC paths may be in the same WC or in different"
+     "  WCs.\n"
+     "\n"), N_(
+     "  This feature is EXPERIMENTAL. This command is likely to change\n"
+     "  in the next release, and there is no promise of backward compatibility.\n"
+    )},
+  },
+
+  { NULL, NULL, {0}, {NULL}, {0} }
+};
+

Added: subversion/branches/decouple-shelving-cli/subversion/svn/shelf-cmd.h
URL: http://svn.apache.org/viewvc/subversion/branches/decouple-shelving-cli/subversion/svn/shelf-cmd.h?rev=1874631&view=auto
==============================================================================
--- subversion/branches/decouple-shelving-cli/subversion/svn/shelf-cmd.h (added)
+++ subversion/branches/decouple-shelving-cli/subversion/svn/shelf-cmd.h Fri Feb 28 21:09:13 2020
@@ -0,0 +1,49 @@
+/*
+ * shelf-cmd.h:  experimental shelving v3
+ *
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ */
+
+/* ==================================================================== */
+
+
+
+#ifndef SVN_SHELF_CMD_H
+#define SVN_SHELF_CMD_H
+
+/*** Includes. ***/
+#include <apr_getopt.h>
+
+#include "svn_opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+extern const svn_opt_subcommand_desc3_t svn_cl__cmd_table_shelf3[];
+/*extern const apr_getopt_option_t svn_cl__options_shelving3[];*/
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SVN_SHELF_CMD_H */

Propchange: subversion/branches/decouple-shelving-cli/subversion/svn/shelf-cmd.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: subversion/branches/decouple-shelving-cli/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/decouple-shelving-cli/subversion/svn/svn.c?rev=1874631&r1=1874630&r2=1874631&view=diff
==============================================================================
--- subversion/branches/decouple-shelving-cli/subversion/svn/svn.c (original)
+++ subversion/branches/decouple-shelving-cli/subversion/svn/svn.c Fri Feb 28 21:09:13 2020
@@ -52,6 +52,7 @@
 #include "svn_hash.h"
 #include "svn_version.h"
 #include "cl.h"
+#include "shelf-cmd.h"
 
 #include "private/svn_opt_private.h"
 #include "private/svn_cmdline_private.h"
@@ -63,95 +64,6 @@
 
 /*** Option Processing ***/
 
-/* Add an identifier here for long options that don't have a short
-   option. Options that have both long and short options should just
-   use the short option letter as identifier.  */
-typedef enum svn_cl__longopt_t {
-  opt_auth_password = SVN_OPT_FIRST_LONGOPT_ID,
-  opt_auth_password_from_stdin,
-  opt_auth_username,
-  opt_autoprops,
-  opt_changelist,
-  opt_config_dir,
-  opt_config_options,
-  /* diff options */
-  opt_diff_cmd,
-  opt_internal_diff,
-  opt_no_diff_added,
-  opt_no_diff_deleted,
-  opt_show_copies_as_adds,
-  opt_notice_ancestry,
-  opt_summarize,
-  opt_use_git_diff_format,
-  opt_ignore_properties,
-  opt_properties_only,
-  opt_patch_compatible,
-  /* end of diff options */
-  opt_dry_run,
-  opt_editor_cmd,
-  opt_encoding,
-  opt_force_log,
-  opt_force,
-  opt_keep_changelists,
-  opt_ignore_ancestry,
-  opt_ignore_externals,
-  opt_incremental,
-  opt_merge_cmd,
-  opt_native_eol,
-  opt_new_cmd,
-  opt_no_auth_cache,
-  opt_no_autoprops,
-  opt_no_ignore,
-  opt_no_unlock,
-  opt_non_interactive,
-  opt_force_interactive,
-  opt_old_cmd,
-  opt_record_only,
-  opt_relocate,
-  opt_remove,
-  opt_revprop,
-  opt_stop_on_copy,
-  opt_strict,                   /* ### DEPRECATED */
-  opt_targets,
-  opt_depth,
-  opt_set_depth,
-  opt_version,
-  opt_xml,
-  opt_keep_local,
-  opt_with_revprop,
-  opt_with_all_revprops,
-  opt_with_no_revprops,
-  opt_parents,
-  opt_accept,
-  opt_show_revs,
-  opt_reintegrate,
-  opt_trust_server_cert,
-  opt_trust_server_cert_failures,
-  opt_strip,
-  opt_ignore_keywords,
-  opt_reverse_diff,
-  opt_ignore_whitespace,
-  opt_diff,
-  opt_allow_mixed_revisions,
-  opt_include_externals,
-  opt_show_inherited_props,
-  opt_search,
-  opt_search_and,
-  opt_mergeinfo_log,
-  opt_remove_unversioned,
-  opt_remove_ignored,
-  opt_remove_added,
-  opt_no_newline,
-  opt_show_passwords,
-  opt_pin_externals,
-  opt_show_item,
-  opt_adds_as_modification,
-  opt_vacuum_pristines,
-  opt_drop,
-  opt_viewspec,
-} svn_cl__longopt_t;
-
-
 /* Option codes and descriptions for the command line client.
  *
  * The entire list must be terminated with an entry of nulls.
@@ -532,15 +444,8 @@ const int svn_cl__global_options[] =
   opt_config_dir, opt_config_options, 0
 };
 
-/* Options for giving a log message.  (Some of these also have other uses.)
- */
-#define SVN_CL__LOG_MSG_OPTIONS 'm', 'F', \
-                                opt_force_log, \
-                                opt_editor_cmd, \
-                                opt_encoding, \
-                                opt_with_revprop
-
-const svn_opt_subcommand_desc3_t svn_cl__cmd_table[] =
+static const svn_opt_subcommand_desc3_t
+svn_cl__cmd_table_main[] =
 {
   { "add", svn_cl__add, {0}, {N_(
      "Put new files and directories under version control.\n"
@@ -1994,167 +1899,11 @@ const svn_opt_subcommand_desc3_t svn_cl_
     )},
     { 'q' } },
 
-  { "x-shelf-diff", svn_cl__shelf_diff, {0}, {N_(
-     "Show shelved changes as a diff.\n"
-     "usage: x-shelf-diff SHELF [VERSION]\n"
-     "\n"), N_(
-     "  Show the changes in SHELF:VERSION (default: latest) as a diff.\n"
-     "\n"), N_(
-     "  See also: 'svn diff --cl=svn:shelf:SHELF' which supports most options of\n"
-     "  'svn diff'.\n"
-     "\n"), N_(
-     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
-     "  in the next release, and there is no promise of backward compatibility.\n"
-    )},
-    {opt_summarize},
-  },
-
-  { "x-shelf-drop", svn_cl__shelf_drop, {0}, {N_(
-     "Delete a shelf.\n"
-     "usage: x-shelf-drop SHELF [PATH ...]\n"
-     "\n"), N_(
-     "  Delete the shelves named SHELF from the working copies containing PATH\n"
-     "  (default PATH is '.')\n"
-     "\n"), N_(
-     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
-     "  in the next release, and there is no promise of backward compatibility.\n"
-    )},
-  },
-
-  { "x-shelf-list", svn_cl__shelf_list, {"x-shelves"}, {N_(
-     "List shelves.\n"
-     "usage: x-shelf-list [PATH ...]\n"
-     "\n"), N_(
-     "  List shelves for each working copy containing PATH (default is '.')\n"
-     "  Include the first line of any log message and some details about the\n"
-     "  contents of the shelf, unless '-q' is given.\n"
-     "\n"), N_(
-     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
-     "  in the next release, and there is no promise of backward compatibility.\n"
-    )},
-    {'q', 'v'}
-  },
-
-  { "x-shelf-list-by-paths", svn_cl__shelf_list_by_paths, {0}, {N_(
-     "List which shelf affects each path.\n"
-     "usage: x-shelf-list-by-paths [PATH...]\n"
-     "\n"), N_(
-     "  List which shelf most recently affects each path below the given PATHs.\n"
-     "\n"), N_(
-     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
-     "  in the next release, and there is no promise of backward compatibility.\n"
-    )},
-  },
-
-  { "x-shelf-log", svn_cl__shelf_log, {0}, {N_(
-     "Show the versions of a shelf.\n"
-     "usage: x-shelf-log SHELF [PATH...]\n"
-     "\n"), N_(
-     "  Show all versions of SHELF for each working copy containing PATH (the\n"
-     "  default PATH is '.').\n"
-     "\n"), N_(
-     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
-     "  in the next release, and there is no promise of backward compatibility.\n"
-    )},
-    {'q', 'v'}
-  },
-
-  { "x-shelf-save", svn_cl__shelf_save, {0}, {N_(
-     "Copy local changes onto a new version of a shelf.\n"
-     "usage: x-shelf-save SHELF [PATH...]\n"
-     "\n"), N_(
-     "  Save local changes in the given PATHs as a new version of SHELF.\n"
-     "  The shelf's log message can be set with -m, -F, etc.\n"
-     "\n"), N_(
-     "  The same as 'svn shelve --keep-local'.\n"
-     "\n"), N_(
-     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
-     "  in the next release, and there is no promise of backward compatibility.\n"
-    )},
-    {'q', opt_dry_run,
-     opt_depth, opt_targets, opt_changelist,
-     SVN_CL__LOG_MSG_OPTIONS,
-    }
-  },
-
-  { "x-shelve", svn_cl__shelf_shelve, {0}, {N_(
-     "Move local changes onto a shelf.\n"
-     "usage: x-shelve [--keep-local] SHELF [PATH...]\n"
-     "\n"), N_(
-     "  Save the local changes in the given PATHs to a new or existing SHELF.\n"
-     "  Revert those changes from the WC unless '--keep-local' is given.\n"
-     "  The shelf's log message can be set with -m, -F, etc.\n"
-     "\n"), N_(
-     "  'svn shelve --keep-local' is the same as 'svn shelf-save'.\n"
-     "\n"), N_(
-     "  The kinds of change you can shelve are committable changes to files and\n"
-     "  properties, except the following kinds which are not yet supported:\n"
-     "     * copies and moves\n"
-     "     * mkdir and rmdir\n"
-     "  Uncommittable states such as conflicts, unversioned and missing cannot\n"
-     "  be shelved.\n"
-     "\n"), N_(
-     "  To bring back shelved changes, use 'svn unshelve SHELF'.\n"
-     "\n"), N_(
-     "  Shelves are currently stored under <WC>/.svn/experimental/shelves/ .\n"
-     "  (In Subversion 1.10, shelves were stored under <WC>/.svn/shelves/ as\n"
-     "  patch files. To recover a shelf created by 1.10, either use a 1.10\n"
-     "  client to find and unshelve it, or find the patch file and use any\n"
-     "  1.10 or later 'svn patch' to apply it.)\n"
-     "\n"), N_(
-     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
-     "  in the next release, and there is no promise of backward compatibility.\n"
-    )},
-    {'q', opt_dry_run, opt_keep_local,
-     opt_depth, opt_targets, opt_changelist,
-     SVN_CL__LOG_MSG_OPTIONS,
-    } },
-
-  { "x-unshelve", svn_cl__shelf_unshelve, {0}, {N_(
-     "Copy shelved changes back into the WC.\n"
-     "usage: x-unshelve [--drop] [SHELF [VERSION]]\n"
-     "\n"), N_(
-     "  Apply the changes stored in SHELF to the working copy.\n"
-     "  SHELF defaults to the newest shelf.\n"
-     "\n"), N_(
-     "  Apply the newest version of the shelf, by default. If VERSION is\n"
-     "  specified, apply that version and discard all versions newer than that.\n"
-     "  In any case, retain the unshelved version and versions older than that\n"
-     "  (unless --drop is specified).\n"
-     "\n"), N_(
-     "  With --drop, delete the entire shelf (like 'svn shelf-drop') after\n"
-     "  successfully unshelving with no conflicts.\n"
-     "\n"), N_(
-     "  The working files involved should be in a clean, unmodified state\n"
-     "  before using this command. To roll back to an older version of the\n"
-     "  shelf, first ensure any current working changes are removed, such as\n"
-     "  by shelving or reverting them, and then unshelve the desired version.\n"
-     "\n"), N_(
-     "  Unshelve normally refuses to apply any changes if any path involved is\n"
-     "  already modified (or has any other abnormal status) in the WC. With\n"
-     "  --force, it does not check and may error out and/or produce partial or\n"
-     "  unexpected results.\n"
-     "\n"), N_(
-     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
-     "  in the next release, and there is no promise of backward compatibility.\n"
-    )},
-    {opt_drop, 'q', opt_dry_run, opt_force} },
-
-  { "x-wc-copy-mods", svn_cl__wc_copy_mods, {0}, {N_(
-     "Copy local modifications from one WC to another.\n"
-     "usage: x-wc-copy-mods SRC_WC_PATH DST_WC_PATH\n"
-     "\n"), N_(
-     "  The source and destination WC paths may be in the same WC or in different"
-     "  WCs.\n"
-     "\n"), N_(
-     "  This feature is EXPERIMENTAL. This command is likely to change\n"
-     "  in the next release, and there is no promise of backward compatibility.\n"
-    )},
-  },
-
   { NULL, NULL, {0}, {NULL}, {0} }
 };
 
+const svn_opt_subcommand_desc3_t *svn_cl__cmd_table = svn_cl__cmd_table_main;
+
 
 /* Version compatibility check */
 static svn_error_t *
@@ -2233,6 +1982,33 @@ viewspec_from_word(enum svn_cl__viewspec
   return SVN_NO_ERROR;
 }
 
+/* Re-initialize the command table SVN_CL__CMD_TABLE,
+ * adding additional commands from CMDS_ADD.
+ * (TODO: and the options table) */
+static void
+add_commands(const svn_opt_subcommand_desc3_t *cmds_add,
+             apr_pool_t *pool)
+{
+  int elt_size = sizeof(svn_opt_subcommand_desc3_t);
+  const svn_opt_subcommand_desc3_t *cmds_old = svn_cl__cmd_table;
+  const svn_opt_subcommand_desc3_t *cmd;
+  int n_cmds_old, n_cmds_add, n_cmds_new;
+  svn_opt_subcommand_desc3_t *cmds_new;
+
+  for (cmd = cmds_old; cmd->name; cmd++) ;
+  n_cmds_old = cmd - cmds_old;
+  for (cmd = cmds_add; cmd->name; cmd++) ;
+  n_cmds_add = cmd - cmds_add;
+  n_cmds_new = n_cmds_old + n_cmds_add;
+
+  /* copy CMDS_OLD and CMDS_ADD, plus an all-zeros terminator entry */
+  cmds_new = apr_pcalloc(pool, (n_cmds_new + 1) * elt_size);
+  memcpy(cmds_new, cmds_old, n_cmds_old * elt_size);
+  memcpy(&cmds_new[n_cmds_old], cmds_add, n_cmds_add * elt_size);
+
+  svn_cl__cmd_table = cmds_new;
+}
+
 
 /*** Main. ***/
 
@@ -2290,6 +2066,9 @@ sub_main(int *exit_code, int argc, const
   /* Init the temporary buffer. */
   svn_membuf__create(&buf, 0, pool);
 
+  /* Add externally defined commands */
+  add_commands(svn_cl__cmd_table_shelf3, pool);
+
   /* Begin processing arguments. */
   opt_state.start_revision.kind = svn_opt_revision_unspecified;
   opt_state.end_revision.kind = svn_opt_revision_unspecified;
@@ -3224,17 +3003,7 @@ sub_main(int *exit_code, int argc, const
      sense (unless we've also been instructed not to care).  This may
      access the working copy so do it after setting the locking mode. */
   if ((! opt_state.force_log)
-      && (subcommand->cmd_func == svn_cl__commit
-          || subcommand->cmd_func == svn_cl__copy
-          || subcommand->cmd_func == svn_cl__delete
-          || subcommand->cmd_func == svn_cl__import
-          || subcommand->cmd_func == svn_cl__mkdir
-          || subcommand->cmd_func == svn_cl__move
-          || subcommand->cmd_func == svn_cl__lock
-          || subcommand->cmd_func == svn_cl__propedit
-          || subcommand->cmd_func == svn_cl__shelf_save
-          || subcommand->cmd_func == svn_cl__shelf_shelve
-         ))
+      && subcommand->cmd_func != svn_cl__propset)
     {
       /* If the -F argument is a file that's under revision control,
          that's probably not what the user intended. */



Re: svn commit: r1874631 - in /subversion/branches/decouple-shelving-cli/subversion/svn: cl.h shelf-cmd.c shelf-cmd.h svn.c

Posted by Julian Foad <ju...@apache.org>.
Daniel Shahaf wrote:
> Not sure what the grand plan here, but as a request: Could we continue
> to have a programmatic way to get all subcommands, --options, etc, that
> exist and are enabled?  That exists currently («svn help -v» and «svn
> help $subcommand»)

Yes.  I'm not changing that.

- Julian

Re: svn commit: r1874631 - in /subversion/branches/decouple-shelving-cli/subversion/svn: cl.h shelf-cmd.c shelf-cmd.h svn.c

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
Good morning Julian,

julianfoad@apache.org wrote on Fri, 28 Feb 2020 21:09 -0000:
> Initialize the 'svn x-shelf-*' commands programmatically at run time,
> instead of hard-coding them in svn's main command table.
> 
> A step towards decoupling the experimental shelving CLI from the main CLI.

Not sure what the grand plan here, but as a request: Could we continue
to have a programmatic way to get all subcommands, --options, etc, that
exist and are enabled?  That exists currently («svn help -v» and «svn
help $subcommand») and it's a _de facto_ API — there are scripts out
there that rely on it — so it'd be nice to keep that functionality
available, under some name or another.

Cheers,

Daniel

Re: svn commit: r1874631 - in /subversion/branches/decouple-shelving-cli/subversion/svn: cl.h shelf-cmd.c shelf-cmd.h svn.c

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
Good morning Julian,

julianfoad@apache.org wrote on Fri, 28 Feb 2020 21:09 -0000:
> Initialize the 'svn x-shelf-*' commands programmatically at run time,
> instead of hard-coding them in svn's main command table.
> 
> A step towards decoupling the experimental shelving CLI from the main CLI.

Not sure what the grand plan here, but as a request: Could we continue
to have a programmatic way to get all subcommands, --options, etc, that
exist and are enabled?  That exists currently («svn help -v» and «svn
help $subcommand») and it's a _de facto_ API — there are scripts out
there that rely on it — so it'd be nice to keep that functionality
available, under some name or another.

Cheers,

Daniel