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. */