diff options
Diffstat (limited to 'subversion/svn/svn.c')
-rw-r--r-- | subversion/svn/svn.c | 335 |
1 files changed, 58 insertions, 277 deletions
diff --git a/subversion/svn/svn.c b/subversion/svn/svn.c index f83cc08..3c3ac6d 100644 --- a/subversion/svn/svn.c +++ b/subversion/svn/svn.c @@ -52,6 +52,8 @@ #include "svn_hash.h" #include "svn_version.h" #include "cl.h" +#include "shelf2-cmd.h" +#include "shelf-cmd.h" #include "private/svn_opt_private.h" #include "private/svn_cmdline_private.h" @@ -63,95 +65,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. @@ -471,7 +384,9 @@ const apr_getopt_option_t svn_cl__options[] = " " " 'schedule' 'normal','add','delete','replace'\n" " " - " 'depth' checkout depth of TARGET in WC")}, + " 'depth' checkout depth of TARGET in WC\n" + " " + " 'changelist' changelist of TARGET in WC")}, {"adds-as-modification", opt_adds_as_modification, 0, N_("Local additions are merged with incoming additions\n" @@ -530,15 +445,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" @@ -632,7 +540,8 @@ const svn_opt_subcommand_desc3_t svn_cl__cmd_table[] = {'r', opt_ignore_keywords} }, { "changelist", svn_cl__changelist, {"cl"}, {N_( - "Associate (or dissociate) changelist CLNAME with the named files.\n" + "Associate (or dissociate) changelist CLNAME with the named\n" + "files.\n" "usage: 1. changelist CLNAME PATH...\n" " 2. changelist --remove PATH...\n" )}, @@ -668,8 +577,8 @@ const svn_opt_subcommand_desc3_t svn_cl__cmd_table[] = {{'N', N_("obsolete; same as --depth=files")}} }, { "cleanup", svn_cl__cleanup, {0}, {N_( - "Either recover from an interrupted operation that left the working copy locked,\n" - "or remove unwanted files.\n" + "Either recover from an interrupted operation that left the working\n" + "copy locked, or remove unwanted files.\n" "usage: 1. cleanup [WCPATH...]\n" " 2. cleanup --remove-unversioned [WCPATH...]\n" " cleanup --remove-ignored [WCPATH...]\n" @@ -696,9 +605,9 @@ const svn_opt_subcommand_desc3_t svn_cl__cmd_table[] = " referenced by any file in the working copy.\n" )}, { opt_remove_unversioned, opt_remove_ignored, opt_vacuum_pristines, - opt_include_externals, 'q', opt_merge_cmd }, + opt_include_externals, 'q', opt_merge_cmd }, { { opt_merge_cmd, N_("deprecated and ignored") } } }, - + { "commit", svn_cl__commit, {"ci"}, {N_( "Send changes from your working copy to the repository.\n" "usage: commit [PATH...]\n" @@ -1871,7 +1780,8 @@ const svn_opt_subcommand_desc3_t svn_cl__cmd_table[] = {'N', N_("obsolete; same as --depth=immediates")}} }, { "switch", svn_cl__switch, {"sw"}, {N_( - "Update the working copy to a different URL within the same repository.\n" + "Update the working copy to a different URL within the same\n" + "repository.\n" "usage: 1. switch URL[@PEGREV] [PATH]\n" " 2. switch --relocate FROM-PREFIX TO-PREFIX [PATH...]\n" "\n"), N_( @@ -1907,9 +1817,6 @@ const svn_opt_subcommand_desc3_t svn_cl__cmd_table[] = "\n"), N_( " Examples:\n" " svn switch ^/branches/1.x-release\n" - " svn switch --relocate http:// svn://\n" - " svn switch --relocate http://www.example.com/repo/project \\\n" - " svn://svn.example.com/repo/project\n" )}, { 'r', 'N', opt_depth, opt_set_depth, 'q', opt_merge_cmd, opt_ignore_externals, opt_ignore_ancestry, opt_force, opt_accept, @@ -1993,167 +1900,11 @@ const svn_opt_subcommand_desc3_t svn_cl__cmd_table[] = )}, { '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 * @@ -2232,6 +1983,33 @@ viewspec_from_word(enum svn_cl__viewspec_t *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 = (int)(cmd - cmds_old); + for (cmd = cmds_add; cmd->name; cmd++) ; + n_cmds_add = (int)(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. ***/ @@ -2249,6 +2027,7 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool) svn_cl__opt_state_t opt_state = { 0, { 0 } }; svn_client_ctx_t *ctx; apr_array_header_t *received_opts; + const char *exp_cmds; int i; const svn_opt_subcommand_desc3_t *subcommand = NULL; const char *dash_F_arg = NULL; @@ -2289,6 +2068,18 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool) /* Init the temporary buffer. */ svn_membuf__create(&buf, 0, pool); + /* Add experimental commands, if requested. Use the most recent version + * that we know about and that is mentioned in the env. var. */ + exp_cmds = getenv("SVN_EXPERIMENTAL_COMMANDS"); + if (exp_cmds && strstr(exp_cmds, "shelf3")) + { + add_commands(svn_cl__cmd_table_shelf3, pool); + } + else if (exp_cmds && strstr(exp_cmds, "shelf2")) + { + add_commands(svn_cl__cmd_table_shelf2, pool); + } + /* Begin processing arguments. */ opt_state.start_revision.kind = svn_opt_revision_unspecified; opt_state.end_revision.kind = svn_opt_revision_unspecified; @@ -3223,17 +3014,7 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool) 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. */ |