aboutsummaryrefslogtreecommitdiff
path: root/subversion/svn/svn.c
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2018-05-08 03:44:38 +0000
committerPeter Wemm <peter@FreeBSD.org>2018-05-08 03:44:38 +0000
commit3faf8d6bffc5d0fb2525ba37bb504c53366caf9d (patch)
tree7e47911263e75034b767fe34b2f8d3d17e91f66d /subversion/svn/svn.c
parenta55fb3c0d5eca7d887798125d5b95942b1f01d4b (diff)
Import Subversion-1.10.0vendor/subversion/subversion-1.10.0
Notes
Notes: svn path=/vendor/subversion/dist/; revision=333347 svn path=/vendor/subversion/subversion-1.10.0/; revision=333348; tag=vendor/subversion/subversion-1.10.0
Diffstat (limited to 'subversion/svn/svn.c')
-rw-r--r--subversion/svn/svn.c499
1 files changed, 354 insertions, 145 deletions
diff --git a/subversion/svn/svn.c b/subversion/svn/svn.c
index 058be707d074..48b894f49983 100644
--- a/subversion/svn/svn.c
+++ b/subversion/svn/svn.c
@@ -33,7 +33,6 @@
#include <apr_strings.h>
#include <apr_tables.h>
#include <apr_general.h>
-#include <apr_signal.h>
#include "svn_cmdline.h"
#include "svn_pools.h"
@@ -57,6 +56,7 @@
#include "private/svn_opt_private.h"
#include "private/svn_cmdline_private.h"
#include "private/svn_subr_private.h"
+#include "private/svn_utf_private.h"
#include "svn_private_config.h"
@@ -68,6 +68,7 @@
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,
@@ -143,6 +144,11 @@ typedef enum svn_cl__longopt_t {
opt_show_passwords,
opt_pin_externals,
opt_show_item,
+ opt_adds_as_modification,
+ opt_vacuum_pristines,
+ opt_delete,
+ opt_keep_shelved,
+ opt_list
} svn_cl__longopt_t;
@@ -198,6 +204,9 @@ const apr_getopt_option_t svn_cl__options[] =
N_("specify a password ARG (caution: on many operating\n"
" "
"systems, other users will be able to see this)")},
+ {"password-from-stdin",
+ opt_auth_password_from_stdin, 0,
+ N_("read password from stdin")},
{"extensions", 'x', 1,
N_("Specify differencing options for external diff or\n"
" "
@@ -327,9 +336,9 @@ const apr_getopt_option_t svn_cl__options[] =
" "
"'theirs-conflict', 'mine-full', 'theirs-full',\n"
" "
- "'edit', 'launch')\n"
+ "'edit', 'launch', 'recommended') (shorthand:\n"
" "
- "(shorthand: 'p', 'mc', 'tc', 'mf', 'tf', 'e', 'l')"
+ "'p', 'mc', 'tc', 'mf', 'tf', 'e', 'l', 'r')"
)},
{"show-revs", opt_show_revs, 1,
N_("specify which collection of revisions to display\n"
@@ -400,7 +409,11 @@ const apr_getopt_option_t svn_cl__options[] =
{"show-inherited-props", opt_show_inherited_props, 0,
N_("retrieve properties set on parents of the target")},
{"search", opt_search, 1,
- N_("use ARG as search pattern (glob syntax)")},
+ N_("use ARG as search pattern (glob syntax, case-\n"
+ " "
+ "and accent-insensitive, may require quotation marks\n"
+ " "
+ "to prevent shell expansion)")},
{"search-and", opt_search_and, 1,
N_("combine ARG with the previous search pattern")},
{"log", opt_mergeinfo_log, 0,
@@ -415,15 +428,55 @@ const apr_getopt_option_t svn_cl__options[] =
" "
"current revision (recommended when tagging)")},
{"show-item", opt_show_item, 1,
- N_("print only the item identified by ARG ('kind',\n"
- " "
- "'url', 'relative-url', 'repos-root-url',\n"
+ N_("print only the item identified by ARG:\n"
+ " "
+ " 'kind' node kind of TARGET\n"
+ " "
+ " 'url' URL of TARGET in the repository\n"
+ " "
+ " 'relative-url'\n"
+ " "
+ " repository-relative URL of TARGET\n"
+ " "
+ " 'repos-root-url'\n"
+ " "
+ " root URL of repository\n"
+ " "
+ " 'repos-uuid' UUID of repository\n"
+ " "
+ " 'revision' specified or implied revision\n"
+ " "
+ " 'last-changed-revision'\n"
+ " "
+ " last change of TARGET at or before\n"
+ " "
+ " 'revision'\n"
+ " "
+ " 'last-changed-date'\n"
+ " "
+ " date of 'last-changed-revision'\n"
+ " "
+ " 'last-changed-author'\n"
+ " "
+ " author of 'last-changed-revision'\n"
+ " "
+ " 'wc-root' root of TARGET's working copy")},
+
+ {"adds-as-modification", opt_adds_as_modification, 0,
+ N_("Local additions are merged with incoming additions\n"
" "
- "'repos-uuid', 'revision', 'last-changed-revision',\n"
+ "instead of causing a tree conflict. Use of this\n"
" "
- "'last-changed-date', 'last-changed-author',\n"
+ "option is not recommended! Use 'svn resolve' to\n"
" "
- "'wc-root')")},
+ "resolve tree conflicts instead.")},
+
+ {"vacuum-pristines", opt_vacuum_pristines, 0,
+ N_("remove unreferenced pristines from .svn directory")},
+
+ {"list", opt_list, 0, N_("list shelved patches")},
+ {"keep-shelved", opt_keep_shelved, 0, N_("do not delete the shelved patch")},
+ {"delete", opt_delete, 0, N_("delete the shelved patch")},
/* Long-opt Aliases
*
@@ -455,7 +508,8 @@ const apr_getopt_option_t svn_cl__options[] =
command to take these arguments allows scripts to just pass them
willy-nilly to every invocation of 'svn') . */
const int svn_cl__global_options[] =
-{ opt_auth_username, opt_auth_password, opt_no_auth_cache, opt_non_interactive,
+{ opt_auth_username, opt_auth_password, opt_auth_password_from_stdin,
+ opt_no_auth_cache, opt_non_interactive,
opt_force_interactive, opt_trust_server_cert,
opt_trust_server_cert_failures,
opt_config_dir, opt_config_options, 0
@@ -491,7 +545,7 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
" or more patterns. With the --remove option, remove cached authentication\n"
" credentials matching one or more patterns.\n"
"\n"
- " If more than one pattern is specified credentials are considered only they\n"
+ " If more than one pattern is specified credentials are considered only if they\n"
" match all specified patterns. Patterns are matched case-sensitively and may\n"
" contain glob wildcards:\n"
" ? matches any single character\n"
@@ -571,38 +625,45 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
{'r', 'q', 'N', opt_depth, opt_force, opt_ignore_externals} },
{ "cleanup", svn_cl__cleanup, {0}, N_
- ("Recursively clean up the working copy, removing write locks, resuming\n"
- "unfinished operations, etc.\n"
- "usage: cleanup [WCPATH...]\n"
- "\n"
- " By default, finish any unfinished business in the working copy at WCPATH,\n"
- " and remove write locks (shown as 'L' by the 'svn status' command) from\n"
- " the working copy. Usually, this is only necessary if a Subversion client\n"
- " has crashed while using the working copy, leaving it in an unusable state.\n"
- "\n"
- " WARNING: There is no mechanism that will protect write locks still\n"
- " being used by other Subversion clients. Running this command\n"
- " while another client is using the working copy can corrupt\n"
- " the working copy beyond repair!\n"
- "\n"
- " If the --remove-unversioned option or the --remove-ignored option\n"
- " is given, remove any unversioned or ignored items within WCPATH.\n"
- " To prevent accidental working copy corruption, unversioned or ignored\n"
- " items can only be removed if the working copy is not already locked\n"
- " for writing by another Subversion client.\n"
- " Note that the 'svn status' command shows unversioned items as '?',\n"
- " and ignored items as 'I' if the --no-ignore option is given to it.\n"),
- {opt_merge_cmd, opt_remove_unversioned, opt_remove_ignored,
- opt_include_externals, 'q'} },
-
+ ("Either recover from an interrupted operation that left the working copy locked,\n"
+ "or remove unwanted files.\n"
+ "usage: 1. cleanup [WCPATH...]\n"
+ " 2. cleanup --remove-unversioned [WCPATH...]\n"
+ " cleanup --remove-ignored [WCPATH...]\n"
+ " 3. cleanup --vacuum-pristines [WCPATH...]\n"
+ "\n"
+ " 1. When none of the options --remove-unversioned, --remove-ignored, and\n"
+ " --vacuum-pristines is specified, remove all write locks (shown as 'L' by\n"
+ " the 'svn status' command) from the working copy. Usually, this is only\n"
+ " necessary if a Subversion client has crashed while using the working copy,\n"
+ " leaving it in an unusable state.\n"
+ "\n"
+ " WARNING: There is no mechanism that will protect write locks still\n"
+ " being used by other Subversion clients. Running this command\n"
+ " without any options while another client is using the working\n"
+ " copy can corrupt the working copy beyond repair!\n"
+ "\n"
+ " 2. If the --remove-unversioned option or the --remove-ignored option\n"
+ " is given, remove any unversioned or ignored items within WCPATH.\n"
+ " Note that the 'svn status' command shows unversioned items as '?',\n"
+ " and ignored items as 'I' if the --no-ignore option is given to it.\n"
+ "\n"
+ " 3. If the --vacuum-pristines option is given, remove pristine copies of\n"
+ " files which are stored inside the .svn directory and which are no longer\n"
+ " 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_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"
"\n"
" A log message must be provided, but it can be empty. If it is not\n"
" given by a --message or --file option, an editor will be started.\n"
+ "\n"
" If any targets are (or contain) locked items, those will be\n"
- " unlocked after a successful commit.\n"
+ " unlocked after a successful commit, unless --no-unlock is given.\n"
"\n"
" If --include-externals is given, also commit file and directory\n"
" externals reached by recursion. Do not commit externals with a\n"
@@ -619,8 +680,9 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
" WC -> URL: immediately commit a copy of WC to URL\n"
" URL -> WC: check out URL into WC, schedule for addition\n"
" URL -> URL: complete server-side copy; used to branch and tag\n"
- " All the SRCs must be of the same type. When copying multiple sources,\n"
- " they will be added as children of DST, which must be a directory.\n"
+ " All the SRCs must be of the same type. If DST is an existing directory,\n"
+ " the sources will be added as children of DST. When copying multiple\n"
+ " sources, DST must be an existing directory.\n"
"\n"
" WARNING: For compatibility with previous versions of Subversion,\n"
" copies performed using two working copy paths (WC -> WC) will not\n"
@@ -734,28 +796,44 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
"usage: info [TARGET[@REV]...]\n"
"\n"
" Print information about each TARGET (default: '.').\n"
- " TARGET may be either a working-copy path or URL. If specified, REV\n"
- " determines in which revision the target is first looked up.\n"
+ " TARGET may be either a working-copy path or a URL. If specified, REV\n"
+ " determines in which revision the target is first looked up; the default\n"
+ " is HEAD for a URL or BASE for a WC path.\n"
"\n"
" With --show-item, print only the value of one item of information\n"
- " about TARGET. One of the following items can be selected:\n"
- " kind the kind of TARGET\n"
- " url the URL of TARGET in the repository\n"
- " relative-url the repository-relative URL\n"
- " repos-root-url the repository root URL\n"
- " repos-uuid the repository UUID\n"
- " revision the revision of TARGET (defaults to BASE\n"
- " for working copy paths and HEAD for URLs)\n"
- " last-changed-revision the most recent revision in which TARGET\n"
- " was changed\n"
- " last-changed-date the date of the last-changed revision\n"
- " last-changed-author the author of the last-changed revision\n"
- " wc-root the root of TARGET's working copy\n"),
+ " about TARGET.\n"),
{'r', 'R', opt_depth, opt_targets, opt_incremental, opt_xml,
opt_changelist, opt_include_externals, opt_show_item, opt_no_newline}
},
- { "list", svn_cl__list, {"ls"}, N_
+ { "list", svn_cl__list, {"ls"},
+#if defined(WIN32)
+ N_
+ ("List directory entries in the repository.\n"
+ "usage: list [TARGET[@REV]...]\n"
+ "\n"
+ " List each TARGET file and the contents of each TARGET directory as\n"
+ " they exist in the repository. If TARGET is a working copy path, the\n"
+ " corresponding repository URL will be used. If specified, REV determines\n"
+ " in which revision the target is first looked up.\n"
+ "\n"
+ " The default TARGET is '.', meaning the repository URL of the current\n"
+ " working directory.\n"
+ "\n"
+ " Multiple --search patterns may be specified and the output will be\n"
+ " reduced to those paths whose last segment - i.e. the file or directory\n"
+ " name - contains a sub-string matching at least one of these patterns\n"
+ " (Windows only).\n"
+ "\n"
+ " With --verbose, the following fields will be shown for each item:\n"
+ "\n"
+ " Revision number of the last commit\n"
+ " Author of the last commit\n"
+ " If locked, the letter 'O'. (Use 'svn info URL' to see details)\n"
+ " Size (in bytes)\n"
+ " Date and time of the last commit\n"),
+#else
+ N_
("List directory entries in the repository.\n"
"usage: list [TARGET[@REV]...]\n"
"\n"
@@ -767,6 +845,10 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
" The default TARGET is '.', meaning the repository URL of the current\n"
" working directory.\n"
"\n"
+ " Multiple --search patterns may be specified and the output will be\n"
+ " reduced to those paths whose last segment - i.e. the file or directory\n"
+ " name - matches at least one of these patterns.\n"
+ "\n"
" With --verbose, the following fields will be shown for each item:\n"
"\n"
" Revision number of the last commit\n"
@@ -774,19 +856,21 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
" If locked, the letter 'O'. (Use 'svn info URL' to see details)\n"
" Size (in bytes)\n"
" Date and time of the last commit\n"),
+#endif
{'r', 'v', 'R', opt_depth, opt_incremental, opt_xml,
- opt_include_externals}, },
+ opt_include_externals, opt_search}, },
{ "lock", svn_cl__lock, {0}, N_
("Lock working copy paths or URLs in the repository, so that\n"
"no other user can commit changes to them.\n"
"usage: lock TARGET...\n"
"\n"
- " Use --force to steal the lock from another user or working copy.\n"),
- { opt_targets, 'm', 'F', opt_force_log, opt_encoding, opt_force },
+ " Use --force to steal a lock from another user or working copy.\n"),
+ { opt_targets, 'm', 'F', opt_force_log, opt_encoding, opt_force, 'q' },
{{'F', N_("read lock comment from file ARG")},
{'m', N_("specify lock comment ARG")},
- {opt_force_log, N_("force validity of lock comment source")}} },
+ {opt_force_log, N_("force validity of lock comment source")},
+ {opt_force, N_("steal locks")}} },
{ "log", svn_cl__log, {0}, N_
("Show the log messages for a set of revision(s) and/or path(s).\n"
@@ -810,6 +894,17 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
" reverse ranges is allowed.\n"
"\n"
" With -v, also print all affected paths with each log message.\n"
+ " Each changed path is preceded with a symbol describing the change:\n"
+ " A: The path was added or copied.\n"
+ " D: The path was deleted.\n"
+ " R: The path was replaced (deleted and re-added in the same revision).\n"
+ " M: The path's file and/or property content was modified.\n"
+ " If an added or replaced path was copied from somewhere else, the copy\n"
+ " source path and revision are shown in parentheses.\n"
+ " If a file or directory was moved from one path to another with 'svn move'\n"
+ " the old path will be listed as deleted and the new path will be listed\n"
+ " as copied from the old path at a prior revision.\n"
+ "\n"
" With -q, don't print the log message body itself (note that this is\n"
" compatible with -v).\n"
"\n"
@@ -862,7 +957,12 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
"\n"
" Show the log message for the revision in which /branches/foo\n"
" was created:\n"
- " svn log --stop-on-copy --limit 1 -r0:HEAD ^/branches/foo\n"),
+ " svn log --stop-on-copy --limit 1 -r0:HEAD ^/branches/foo\n"
+ "\n"
+ " If ^/trunk/foo.c was moved to ^/trunk/bar.c' in revision 22, 'svn log -v'\n"
+ " shows a deletion and a copy in its changed paths list, such as:\n"
+ " D /trunk/foo.c\n"
+ " A /trunk/bar.c (from /trunk/foo.c:21)\n"),
{'r', 'c', 'q', 'v', 'g', opt_targets, opt_stop_on_copy, opt_incremental,
opt_xml, 'l', opt_with_all_revprops, opt_with_no_revprops,
opt_with_revprop, opt_depth, opt_diff, opt_diff_cmd,
@@ -1267,18 +1367,18 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
" be committed later (with or without further changes)\n"
" URL -> URL: move an item in the repository directly, immediately\n"
" creating a new revision in the repository\n"
- " All the SRCs must be of the same type. When moving multiple sources,\n"
- " they will be added as children of DST, which must be a directory.\n"
+ " All the SRCs must be of the same type. If DST is an existing directory,\n"
+ " the sources will be added as children of DST. When moving multiple\n"
+ " sources, DST must be an existing directory.\n"
"\n"
" SRC and DST of WC -> WC moves must be committed in the same revision.\n"
" Furthermore, WC -> WC moves will refuse to move a mixed-revision subtree.\n"
" To avoid unnecessary conflicts, it is recommended to run 'svn update'\n"
" to update the subtree to a single revision before moving it.\n"
- " The --allow-mixed-revisions option is provided for backward compatibility.\n"
- "\n"
- " The --revision option has no use and is deprecated.\n"),
- {'r', 'q', opt_force, opt_parents, opt_allow_mixed_revisions,
- SVN_CL__LOG_MSG_OPTIONS} },
+ " The --allow-mixed-revisions option is provided for backward compatibility.\n"),
+ {'q', opt_force, opt_parents, opt_allow_mixed_revisions,
+ SVN_CL__LOG_MSG_OPTIONS, 'r'},
+ {{'r', "deprecated and ignored"}} },
{ "patch", svn_cl__patch, {0}, N_
("Apply a patch to a working copy.\n"
@@ -1519,7 +1619,48 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
"\n"
" The --accept=ARG option prevents interactive prompting and forces\n"
" conflicts on PATH to be resolved in the manner specified by ARG.\n"
- " In this mode, the command is not recursive by default (depth 'empty').\n"),
+ " In this mode, the command is not recursive by default (depth 'empty').\n"
+ "\n"
+ " A conflicted path cannot be committed with 'svn commit' until it\n"
+ " has been marked as resolved with 'svn resolve'.\n"
+ "\n"
+ " Subversion knows three types of conflicts:\n"
+ " Text conflicts, Property conflicts, and Tree conflicts.\n"
+ "\n"
+ " Text conflicts occur when overlapping changes to file contents were\n"
+ " made. Text conflicts are usually resolved by editing the conflicted\n"
+ " file or by using a merge tool (which may be an external program).\n"
+ " 'svn resolve' provides options which can be used to automatically\n"
+ " edit files (such as 'mine-full' or 'theirs-conflict'), but these are\n"
+ " only useful in situations where it is acceptable to discard local or\n"
+ " incoming changes altogether.\n"
+ "\n"
+ " Property conflicts are usually resolved by editing the value of the\n"
+ " conflicted property (either from the interactive prompt, or with\n"
+ " 'svn propedit'). As with text conflicts, options exist to edit a\n"
+ " property automatically, discarding some changes in favour of others.\n"
+ "\n"
+ " Tree conflicts occur when a change to the directory structure was\n"
+ " made, and when this change cannot be applied to the working copy\n"
+ " without affecting other changes (text changes, property changes,\n"
+ " or other changes to the directory structure). Brief information about\n"
+ " tree conflicts is shown by the 'svn status' and 'svn info' commands.\n"
+ " In interactive mode, 'svn resolve' will attempt to describe tree conflicts\n"
+ " in detail, and may offer options to resolve the conflict automatically.\n"
+ " It is recommended to use these automatic options whenever possible,\n"
+ " rather than attempting manual tree conflict resolution.\n"
+ "\n"
+ " If a tree conflict cannot be resolved automatically, it is recommended\n"
+ " to figure out why the conflict occurred before attempting to resolve it.\n"
+ " The 'svn log -v' command can be used to inspect structural changes\n"
+ " made in past revisions, and perhaps even on other branches.\n"
+ " 'svn help log' describes how these structural changes are presented.\n"
+ " Once the conflicting \"incoming\" change has been identified with 'svn log'\n"
+ " the current \"local\" working copy state should be examined and adjusted\n"
+ " in a way such that the conflict is resolved. This may involve editing\n"
+ " files manually or with 'svn merge'. It may be necessary to discard some\n"
+ " local changes with 'svn revert'. Files or directories might have to be\n"
+ " copied, deleted, or moved.\n"),
{opt_targets, 'R', opt_depth, 'q', opt_accept},
{{opt_accept, N_("specify automatic conflict resolution source\n"
" "
@@ -1685,20 +1826,23 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
" 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_relocate,
- opt_ignore_externals, opt_ignore_ancestry, opt_force, opt_accept},
+ { 'r', 'N', opt_depth, opt_set_depth, 'q', opt_merge_cmd,
+ opt_ignore_externals, opt_ignore_ancestry, opt_force, opt_accept,
+ opt_relocate },
{{opt_ignore_ancestry,
N_("allow switching to a node with no common ancestor")},
{opt_force,
- N_("handle unversioned obstructions as changes")}}
+ N_("handle unversioned obstructions as changes")},
+ {opt_relocate,N_("deprecated; use 'svn relocate'")}}
},
{ "unlock", svn_cl__unlock, {0}, N_
("Unlock working copy paths or URLs.\n"
"usage: unlock TARGET...\n"
"\n"
- " Use --force to break the lock.\n"),
- { opt_targets, opt_force } },
+ " Use --force to break a lock held by another user or working copy.\n"),
+ { opt_targets, opt_force, 'q' },
+ {{opt_force, N_("break locks")}} },
{ "update", svn_cl__update, {"up"}, N_
("Bring changes from the repository into the working copy.\n"
@@ -1748,7 +1892,7 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
" targets of this operation.\n"),
{'r', 'N', opt_depth, opt_set_depth, 'q', opt_merge_cmd, opt_force,
opt_ignore_externals, opt_changelist, opt_editor_cmd, opt_accept,
- opt_parents},
+ opt_parents, opt_adds_as_modification},
{ {opt_force,
N_("handle unversioned obstructions as changes")} } },
@@ -1759,6 +1903,74 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table[] =
" Local modifications are preserved.\n"),
{ 'q' } },
+ { "x-shelve", svn_cl__shelve, {"shelve"}, N_
+ ("Put a local change aside, as if putting it on a shelf.\n"
+ "usage: 1. x-shelve [--keep-local] NAME [PATH...]\n"
+ " 2. x-shelve --delete NAME\n"
+ " 3. x-shelve --list\n"
+ "\n"
+ " 1. Save the local change in the given PATHs to a patch file, and\n"
+ " revert that change from the WC unless '--keep-local' is given.\n"
+ " If a log message is given with '-m' or '-F', include it at the\n"
+ " beginning of the patch file.\n"
+ "\n"
+ " 2. Delete the shelved change NAME.\n"
+ " (A backup is kept, named with a '.bak' extension.)\n"
+ "\n"
+ " 3. List shelved changes. Include the first line of any log message\n"
+ " and some details about the contents of the change, unless '-q' is\n"
+ " given.\n"
+ "\n"
+ " The kinds of change you can shelve are those supported by 'svn diff'\n"
+ " and 'svn patch'. The following are currently NOT supported:\n"
+ " mergeinfo changes, copies, moves, mkdir, rmdir,\n"
+ " 'binary' content, uncommittable states\n"
+ "\n"
+ " To bring back a shelved change, use 'svn x-unshelve NAME'.\n"
+ "\n"
+ " Shelved changes are stored in <WC>/.svn/shelves/\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_delete, opt_list, 'q', opt_dry_run, opt_keep_local,
+ opt_depth, opt_targets, opt_changelist,
+ /* almost SVN_CL__LOG_MSG_OPTIONS but not currently opt_with_revprop: */
+ 'm', 'F', opt_force_log, opt_editor_cmd, opt_encoding,
+ } },
+
+ { "x-unshelve", svn_cl__unshelve, {"unshelve"}, N_
+ ("Bring a shelved change back to a local change in the WC.\n"
+ "usage: 1. x-unshelve [--keep-shelved] [NAME]\n"
+ " 2. x-unshelve --list\n"
+ "\n"
+ " 1. Apply the shelved change NAME to the working copy.\n"
+ " Delete the patch unless the '--keep-shelved' option is given.\n"
+ " (A backup is kept, named with a '.bak' extension.)\n"
+ " NAME defaults to the most recent shelved change.\n"
+ "\n"
+ " 2. List shelved changes. Include the first line of any log message\n"
+ " and some details about the contents of the change, unless '-q' is\n"
+ " given.\n"
+ "\n"
+ " Any conflict between the change being unshelved and a change\n"
+ " already in the WC is handled the same way as by 'svn patch',\n"
+ " creating a 'reject' file.\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_keep_shelved, opt_list, 'q', opt_dry_run} },
+
+ { "x-shelves", svn_cl__shelves, {"shelves"}, N_
+ ("List shelved changes.\n"
+ "usage: x-shelves\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'} },
+
{ NULL, NULL, {0}, NULL, {0} }
};
@@ -1782,29 +1994,8 @@ check_lib_versions(void)
return svn_ver_check_list2(&my_version, checklist, svn_ver_equal);
}
-
-/* A flag to see if we've been cancelled by the client or not. */
-static volatile sig_atomic_t cancelled = FALSE;
-
-/* A signal handler to support cancellation. */
-static void
-signal_handler(int signum)
-{
- apr_signal(signum, SIG_IGN);
- cancelled = TRUE;
-}
-
-/* Our cancellation callback. */
-svn_error_t *
-svn_cl__check_cancel(void *baton)
-{
- /* Cancel baton should be always NULL in command line client. */
- SVN_ERR_ASSERT(baton == NULL);
- if (cancelled)
- return svn_error_create(SVN_ERR_CANCELLED, NULL, _("Caught signal"));
- else
- return SVN_NO_ERROR;
-}
+/* The cancelation handler setup by the cmdline library. */
+svn_cancel_func_t svn_cl__check_cancel = NULL;
/* Add a --search argument to OPT_STATE.
* These options start a new search pattern group. */
@@ -1877,6 +2068,8 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
svn_boolean_t reading_file_from_stdin = FALSE;
apr_hash_t *changelists;
apr_hash_t *cfg_hash;
+ svn_membuf_t buf;
+ svn_boolean_t read_pass_from_stdin = FALSE;
received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
@@ -1897,6 +2090,9 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
/* Init our changelists hash. */
changelists = apr_hash_make(pool);
+ /* Init the temporary buffer. */
+ svn_membuf__create(&buf, 0, pool);
+
/* Begin processing arguments. */
opt_state.start_revision.kind = svn_opt_revision_unspecified;
opt_state.end_revision.kind = svn_opt_revision_unspecified;
@@ -2112,6 +2308,9 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
case opt_dry_run:
opt_state.dry_run = TRUE;
break;
+ case opt_list:
+ opt_state.list = TRUE;
+ break;
case opt_revprop:
opt_state.revprop = TRUE;
break;
@@ -2166,6 +2365,9 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_password,
opt_arg, pool));
break;
+ case opt_auth_password_from_stdin:
+ read_pass_from_stdin = TRUE;
+ break;
case opt_encoding:
opt_state.encoding = apr_pstrdup(pool, opt_arg);
break;
@@ -2292,6 +2494,7 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
opt_state.diff.summarize = TRUE;
break;
case opt_remove:
+ case opt_delete:
opt_state.remove = TRUE;
break;
case opt_changelist:
@@ -2307,6 +2510,7 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
opt_state.keep_changelists = TRUE;
break;
case opt_keep_local:
+ case opt_keep_shelved:
opt_state.keep_local = TRUE;
break;
case opt_with_all_revprops:
@@ -2401,11 +2605,20 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
break;
case opt_search:
SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
- add_search_pattern_group(&opt_state, utf8_opt_arg, pool);
+ SVN_ERR(svn_utf__xfrm(&utf8_opt_arg, utf8_opt_arg,
+ strlen(utf8_opt_arg), TRUE, TRUE, &buf));
+ add_search_pattern_group(&opt_state,
+ apr_pstrdup(pool, utf8_opt_arg),
+ pool);
break;
case opt_search_and:
SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
- add_search_pattern_to_latest_group(&opt_state, utf8_opt_arg, pool);
+ SVN_ERR(svn_utf__xfrm(&utf8_opt_arg, utf8_opt_arg,
+ strlen(utf8_opt_arg), TRUE, TRUE, &buf));
+ add_search_pattern_to_latest_group(&opt_state,
+ apr_pstrdup(pool, utf8_opt_arg),
+ pool);
+ break;
case opt_remove_unversioned:
opt_state.remove_unversioned = TRUE;
break;
@@ -2426,6 +2639,12 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
opt_state.show_item = utf8_opt_arg;
break;
+ case opt_adds_as_modification:
+ opt_state.adds_as_modification = TRUE;
+ break;
+ case opt_vacuum_pristines:
+ opt_state.vacuum_pristines = TRUE;
+ break;
default:
/* Hmmm. Perhaps this would be a good place to squirrel away
opts that commands like svn diff might need. Hmmm indeed. */
@@ -2499,22 +2718,22 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
}
else
{
- const char *first_arg = os->argv[os->ind++];
+ const char *first_arg;
+
+ SVN_ERR(svn_utf_cstring_to_utf8(&first_arg, os->argv[os->ind++],
+ pool));
subcommand = svn_opt_get_canonical_subcommand2(svn_cl__cmd_table,
first_arg);
if (subcommand == NULL)
{
- const char *first_arg_utf8;
- SVN_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8,
- first_arg, pool));
svn_error_clear
(svn_cmdline_fprintf(stderr, pool,
_("Unknown subcommand: '%s'\n"),
- first_arg_utf8));
+ first_arg));
svn_error_clear(svn_cl__help(NULL, NULL, pool));
/* Be kind to people who try 'svn undo'. */
- if (strcmp(first_arg_utf8, "undo") == 0)
+ if (strcmp(first_arg, "undo") == 0)
{
svn_error_clear
(svn_cmdline_fprintf(stderr, pool,
@@ -2645,6 +2864,14 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
"--non-interactive"));
}
+ /* --password-from-stdin can only be used with --non-interactive */
+ if (read_pass_from_stdin && !opt_state.non_interactive)
+ {
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("--password-from-stdin requires "
+ "--non-interactive"));
+ }
+
/* Disallow simultaneous use of both --diff-cmd and
--internal-diff. */
if (opt_state.diff.diff_cmd && opt_state.diff.internal_diff)
@@ -2780,6 +3007,7 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
/* Create a client context object. */
command_baton.opt_state = &opt_state;
+ command_baton.conflict_stats = conflict_stats;
SVN_ERR(svn_client_create_context2(&ctx, cfg_hash, pool));
command_baton.ctx = ctx;
@@ -2795,7 +3023,8 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
|| 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__propedit
+ || subcommand->cmd_func == svn_cl__shelve))
{
/* If the -F argument is a file that's under revision control,
that's probably not what the user intended. */
@@ -2803,9 +3032,9 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
{
svn_node_kind_t kind;
const char *local_abspath;
- const char *fname_utf8 = svn_dirent_internal_style(dash_F_arg, pool);
+ const char *fname = svn_dirent_internal_style(dash_F_arg, pool);
- err = svn_dirent_get_absolute(&local_abspath, fname_utf8, pool);
+ err = svn_dirent_get_absolute(&local_abspath, fname, pool);
if (!err)
{
@@ -2933,31 +3162,15 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
conflict_stats, pool));
}
+ /* Get password from stdin if necessary */
+ if (read_pass_from_stdin)
+ {
+ SVN_ERR(svn_cmdline__stdin_readline(&opt_state.auth_password, pool, pool));
+ }
+
/* Set up our cancellation support. */
+ svn_cl__check_cancel = svn_cmdline__setup_cancellation_handler();
ctx->cancel_func = svn_cl__check_cancel;
- apr_signal(SIGINT, signal_handler);
-#ifdef SIGBREAK
- /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
- apr_signal(SIGBREAK, signal_handler);
-#endif
-#ifdef SIGHUP
- apr_signal(SIGHUP, signal_handler);
-#endif
-#ifdef SIGTERM
- apr_signal(SIGTERM, signal_handler);
-#endif
-
-#ifdef SIGPIPE
- /* Disable SIGPIPE generation for the platforms that have it. */
- apr_signal(SIGPIPE, SIG_IGN);
-#endif
-
-#ifdef SIGXFSZ
- /* Disable SIGXFSZ generation for the platforms that have it, otherwise
- * working with large files when compiled against an APR that doesn't have
- * large file support will crash the program, which is uncool. */
- apr_signal(SIGXFSZ, SIG_IGN);
-#endif
/* Set up Authentication stuff. */
SVN_ERR(svn_cmdline_create_auth_baton2(
@@ -2996,10 +3209,11 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
SVN_CL__ACCEPT_LAUNCH);
}
- /* The default action when we're non-interactive is to postpone
- * conflict resolution. */
+ /* The default action when we're non-interactive is to use the
+ * recommended conflict resolution (this will postpone conflicts
+ * for which no recommended resolution is available). */
if (opt_state.accept_which == svn_cl__accept_unspecified)
- opt_state.accept_which = svn_cl__accept_postpone;
+ opt_state.accept_which = svn_cl__accept_recommended;
}
/* Check whether interactive conflict resolution is disabled by
@@ -3021,20 +3235,12 @@ sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
opt_state.accept_which = svn_cl__accept_postpone;
}
- /* Install the default conflict handler. */
+ /* We don't use legacy libsvn_wc conflict handlers by default. */
{
- svn_cl__interactive_conflict_baton_t *b;
-
ctx->conflict_func = NULL;
ctx->conflict_baton = NULL;
-
- ctx->conflict_func2 = svn_cl__conflict_func_interactive;
- SVN_ERR(svn_cl__get_conflict_func_interactive_baton(
- &b,
- opt_state.accept_which,
- ctx->config, opt_state.editor_cmd, conflict_stats,
- ctx->cancel_func, ctx->cancel_baton, pool));
- ctx->conflict_baton2 = b;
+ ctx->conflict_func2 = NULL;
+ ctx->conflict_baton2 = NULL;
}
/* And now we finally run the subcommand. */
@@ -3136,5 +3342,8 @@ main(int argc, const char *argv[])
}
svn_pool_destroy(pool);
+
+ svn_cmdline__cancellation_exit();
+
return exit_code;
}