You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2012/08/16 12:18:03 UTC
svn commit: r1373783 [38/50] - in /subversion/branches/compressed-pristines:
./ build/ build/ac-macros/ build/generator/ build/generator/templates/
build/win32/ contrib/client-side/emacs/ contrib/client-side/svn-push/
contrib/client-side/svnmerge/ cont...
Modified: subversion/branches/compressed-pristines/subversion/svn/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/svn/main.c?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/svn/main.c (original)
+++ subversion/branches/compressed-pristines/subversion/svn/main.c Thu Aug 16 10:17:48 2012
@@ -66,14 +66,24 @@
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_ancestor_path = SVN_OPT_FIRST_LONGOPT_ID,
- opt_auth_password,
+ opt_auth_password = SVN_OPT_FIRST_LONGOPT_ID,
opt_auth_username,
opt_autoprops,
opt_changelist,
opt_config_dir,
opt_config_options,
+ /* diff options */
opt_diff_cmd,
+ opt_internal_diff,
+ 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,
@@ -88,12 +98,9 @@ typedef enum svn_cl__longopt_t {
opt_new_cmd,
opt_no_auth_cache,
opt_no_autoprops,
- opt_no_diff_deleted,
- opt_ignore_props,
opt_no_ignore,
opt_no_unlock,
opt_non_interactive,
- opt_notice_ancestry,
opt_old_cmd,
opt_record_only,
opt_relocate,
@@ -101,7 +108,6 @@ typedef enum svn_cl__longopt_t {
opt_revprop,
opt_stop_on_copy,
opt_strict,
- opt_summarize,
opt_targets,
opt_depth,
opt_set_depth,
@@ -117,17 +123,14 @@ typedef enum svn_cl__longopt_t {
opt_reintegrate,
opt_trust_server_cert,
opt_strip,
- opt_show_copies_as_adds,
opt_ignore_keywords,
opt_reverse_diff,
opt_ignore_whitespace,
opt_diff,
- opt_internal_diff,
- opt_use_git_diff_format,
- opt_use_patch_diff_format,
opt_allow_mixed_revisions,
opt_include_externals,
- opt_symmetric,
+ opt_search,
+ opt_isearch,
} svn_cl__longopt_t;
@@ -240,17 +243,10 @@ const apr_getopt_option_t svn_cl__option
N_("do no interactive prompting")},
{"dry-run", opt_dry_run, 0,
N_("try operation but make no changes")},
- {"no-diff-deleted", opt_no_diff_deleted, 0,
- N_("do not print differences for deleted files")},
- {"ignore-properties", opt_ignore_props, 0,
- N_("ignore properties during the operation")},
- {"notice-ancestry", opt_notice_ancestry, 0,
- N_("notice ancestry when calculating differences")},
{"ignore-ancestry", opt_ignore_ancestry, 0,
N_("ignore ancestry when calculating merges")},
{"ignore-externals", opt_ignore_externals, 0,
N_("ignore externals definitions")},
- {"diff-cmd", opt_diff_cmd, 1, N_("use ARG as diff command")},
{"diff3-cmd", opt_merge_cmd, 1, N_("use ARG as merge command")},
{"editor-cmd", opt_editor_cmd, 1, N_("use ARG as external editor")},
{"record-only", opt_record_only, 0,
@@ -282,7 +278,6 @@ const apr_getopt_option_t svn_cl__option
"ARG may be one of 'LF', 'CR', 'CRLF'")},
{"limit", 'l', 1, N_("maximum number of log entries")},
{"no-unlock", opt_no_unlock, 0, N_("don't unlock the targets")},
- {"summarize", opt_summarize, 0, N_("show a summary of the results")},
{"remove", opt_remove, 0, N_("remove changelist association")},
{"changelist", opt_changelist, 1,
N_("operate only on members of changelist ARG")},
@@ -318,7 +313,7 @@ const apr_getopt_option_t svn_cl__option
" "
"('merged', 'eligible')")},
{"reintegrate", opt_reintegrate, 0,
- N_("merge a branch back into its parent branch")},
+ N_("deprecated")},
{"strip", opt_strip, 1,
N_("number of leading path components to strip from\n"
" "
@@ -335,8 +330,6 @@ const apr_getopt_option_t svn_cl__option
"The expected component separator is '/' on all\n"
" "
"platforms. A leading '/' counts as one component.")},
- {"show-copies-as-adds", opt_show_copies_as_adds, 0,
- N_("don't diff copied or moved files with their source")},
{"ignore-keywords", opt_ignore_keywords, 0,
N_("don't expand keywords")},
{"reverse-diff", opt_reverse_diff, 0,
@@ -344,17 +337,31 @@ const apr_getopt_option_t svn_cl__option
{"ignore-whitespace", opt_ignore_whitespace, 0,
N_("ignore whitespace during pattern matching")},
{"diff", opt_diff, 0, N_("produce diff output")}, /* maps to show_diff */
+ /* diff options */
+ {"diff-cmd", opt_diff_cmd, 1, N_("use ARG as diff command")},
{"internal-diff", opt_internal_diff, 0,
N_("override diff-cmd specified in config file")},
+ {"no-diff-deleted", opt_no_diff_deleted, 0,
+ N_("do not print differences for deleted files")},
+ {"show-copies-as-adds", opt_show_copies_as_adds, 0,
+ N_("don't diff copied or moved files with their source")},
+ {"notice-ancestry", opt_notice_ancestry, 0,
+ N_("notice ancestry when calculating differences")},
+ {"summarize", opt_summarize, 0, N_("show a summary of the results")},
{"git", opt_use_git_diff_format, 0,
N_("use git's extended diff format")},
- {"patch-compatible", opt_use_patch_diff_format, 0,
+ {"ignore-properties", opt_ignore_properties, 0,
+ N_("ignore properties during the operation")},
+ {"properties-only", opt_properties_only, 0,
+ N_("show only properties during the operation")},
+ {"patch-compatible", opt_patch_compatible, 0,
N_("generate diff suitable for generic third-party\n"
" "
"patch tools; currently the same as\n"
" "
- "--show-copies-as-adds --ignore-properties\n"
+ "--show-copies-as-adds --ignore-properties"
)},
+ /* end of diff options */
{"allow-mixed-revisions", opt_allow_mixed_revisions, 0,
N_("Allow merge into mixed-revision working copy.\n"
" "
@@ -367,8 +374,11 @@ const apr_getopt_option_t svn_cl__option
"recursion. This does not include externals with a\n"
" "
"fixed revision. (See the svn:externals property)")},
- {"symmetric", opt_symmetric, 0,
- N_("Symmetric merge")},
+ {"search", opt_search, 1,
+ N_("use ARG as search pattern (glob syntax)")},
+
+ {"isearch", opt_isearch, 1,
+ N_("like --search, but case-insensitive")},
/* Long-opt Aliases
*
@@ -552,9 +562,10 @@ const svn_opt_subcommand_desc2_t svn_cl_
"\n"
" Use just 'svn diff' to display local modifications in a working copy.\n"),
{'r', 'c', opt_old_cmd, opt_new_cmd, 'N', opt_depth, opt_diff_cmd,
- opt_internal_diff, 'x', opt_no_diff_deleted, opt_ignore_props,
+ opt_internal_diff, 'x', opt_no_diff_deleted, opt_ignore_properties,
+ opt_properties_only,
opt_show_copies_as_adds, opt_notice_ancestry, opt_summarize, opt_changelist,
- opt_force, opt_xml, opt_use_git_diff_format, opt_use_patch_diff_format} },
+ opt_force, opt_xml, opt_use_git_diff_format, opt_patch_compatible} },
{ "export", svn_cl__export, {0}, N_
("Create an unversioned copy of a tree.\n"
"usage: 1. export [-r REV] URL[@PEGREV] [PATH]\n"
@@ -671,22 +682,47 @@ const svn_opt_subcommand_desc2_t svn_cl_
"\n"
" The --depth option is only valid in combination with the --diff option\n"
" and limits the scope of the displayed diff to the specified depth.\n"
-
+ "\n"
+ " If the --search option is used, log messages are displayed only if the\n"
+ " provided search pattern matches the author, date, log message text,\n"
+ " or, if the --verbose option is also provided, a changed path.\n"
+ " The search pattern may include glob syntax wildcards:\n"
+ " ? matches any single character\n"
+ " * matches a sequence of arbitrary characters\n"
+ " [...] matches any of the characters listed inside the brackets\n"
+ " If --limit is used in combination with --search, --limit restricts the\n"
+ " number of log messages searched, rather than restricting the output\n"
+ " to a particular number of matching log messages.\n"
"\n"
" Examples:\n"
- " svn log\n"
- " svn log foo.c\n"
- " svn log bar.c@42\n"
- " svn log http://www.example.com/repo/project/foo.c\n"
- " svn log http://www.example.com/repo/project foo.c bar.c\n"
- " svn log http://www.example.com/repo/project@50 foo.c bar.c\n"
"\n"
- " This command shows the log entry for the revision the branch\n"
- " ^/branches/foo was created in:\n"
+ " Show the latest 5 log messages for the current working copy\n"
+ " directory and display paths changed in each commit:\n"
+ " svn log -l 5 -v\n"
+ "\n"
+ " Show the log for bar.c as of revision 42:\n"
+ " svn log bar.c@42\n"
+ "\n"
+ " Show log messages and diffs for each commit to foo.c:\n"
+ " svn log --diff http://www.example.com/repo/project/foo.c\n"
+ " (Because the above command uses a full URL it does not require\n"
+ " a working copy.)\n"
+ "\n"
+ " Show log messages for the children foo.c and bar.c of the directory\n"
+ " '/trunk' as it appeared in revision 50, using the ^/ URL shortcut:\n"
+ " svn log ^/trunk@50 foo.c bar.c\n"
+ "\n"
+ " Show the log messages for any incoming changes to foo.c during the\n"
+ " next 'svn update':\n"
+ " svn log -r BASE:HEAD foo.c\n"
+ "\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"),
{'r', 'q', 'v', 'g', 'c', 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, opt_internal_diff, 'x'},
+ opt_depth, opt_diff, opt_diff_cmd, opt_internal_diff, 'x', opt_search,
+ opt_isearch},
{{opt_with_revprop, N_("retrieve revision property ARG")},
{'c', N_("the change made in revision ARG")}} },
@@ -699,22 +735,16 @@ const svn_opt_subcommand_desc2_t svn_cl_
" (the 'sync' merge)\n"
" 2. merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [TARGET_WCPATH]\n"
" (the 'cherry-pick' merge)\n"
-" 3. merge --reintegrate SOURCE[@REV] [TARGET_WCPATH]\n"
-" (the 'reintegrate' merge)\n"
-" 4. merge SOURCE1[@N] SOURCE2[@M] [TARGET_WCPATH]\n"
+" 3. merge SOURCE1[@N] SOURCE2[@M] [TARGET_WCPATH]\n"
" (the '2-URL' merge)\n"
"\n"
-" 1. This form is called a 'sync' (or 'catch-up') merge:\n"
+" 1. This form, with one source path and no revision range:\n"
"\n"
" svn merge SOURCE[@REV] [TARGET_WCPATH]\n"
"\n"
-" A sync merge is used to fetch all the latest changes made on a parent\n"
-" branch. In other words, the target branch has originally been created\n"
-" by copying the source branch, and any changes committed on the source\n"
-" branch since branching are applied to the target branch. This uses\n"
-" merge tracking to skip all those revisions that have already been\n"
-" merged, so a sync merge can be repeated periodically to stay up-to-\n"
-" date with the source branch.\n"
+" finds all the changes on the source branch that have not already been\n"
+" merged to the target branch, and merges them. Merge tracking is used\n"
+" to know which changes have already been merged.\n"
"\n"
" SOURCE specifies the branch from where the changes will be pulled, and\n"
" TARGET_WCPATH specifies a working copy of the target branch to which\n"
@@ -730,22 +760,44 @@ const svn_opt_subcommand_desc2_t svn_cl_
" used, and the default value of 'REV' is the base revision (usually the\n"
" revision last updated to).\n"
"\n"
-" TARGET_WCPATH is a working copy path; if omitted, '.' is assumed.\n"
+" TARGET_WCPATH is a working copy path; if omitted, '.' is assumed. In\n"
+" normal usage the working copy should be up to date, at a single\n"
+" revision, with no local modifications and no switched subtrees.\n"
+"\n"
+" - The 'Feature Branch' Merging Pattern -\n"
+"\n"
+" In this commonly used pattern of merging, a developer is working on\n"
+" a feature development branch, committing a series of changes that\n"
+" implement the feature. The developer periodically merges all the\n"
+" latest changes from the 'parent' branch (from which the feature branch\n"
+" is branched off). When the feature development is complete, the\n"
+" developer integrates the feature back into the parent branch by\n"
+" merging the other way, into a trunk working copy.\n"
+"\n"
+" trunk --+----------o------o-o-------------o--\n"
+" \\ \\ \\ /\n"
+" \\ merge merge merge\n"
+" \\ \\ \\ /\n"
+" feature +--o-o-------o----o-o----o-------\n"
+"\n"
+" In this pattern, a merge from the parent branch to the feature branch\n"
+" is known as a 'sync' merge (or 'catch-up' merge), and a merge from the\n"
+" feature branch to the parent branch may be called a 'reintegrate'\n"
+" merge. The 'sync' merges are normally low-risk because the parent\n"
+" branch is considered to be more 'stable' than the feature branch, in\n"
+" the sense of being less likely to contain incomplete or broken work.\n"
+" By syncing often, these merges can be kept small, avoiding the need\n"
+" for a difficult 'big bang' merge at reintegration time.\n"
"\n"
" - Sync Merge Example -\n"
-"\n"
-" A feature is being developed on a branch called 'feature', which has\n"
-" originally been a copy of trunk. The feature branch has been regularly\n"
-" synced with trunk to keep up with the changes made there. The previous\n"
-" sync merges are not shown on this diagram, and the last of them was\n"
-" done when HEAD was r100. Currently, HEAD is r200.\n"
-"\n"
-" feature +------------------------o-----\n"
-" / ^\n"
-" / ............ |\n"
-" / . . /\n"
-" trunk ------+------------L--------------R------\n"
-" r100 r200\n"
+" ............\n"
+" . .\n"
+" trunk --+------------L--------------R------\n"
+" \\ \\\n"
+" \\ |\n"
+" \\ v\n"
+" feature +------------------------o-----\n"
+" r100 r200\n"
"\n"
" Subversion will locate all the changes on 'trunk' that have not yet\n"
" been merged into the 'feature' branch. In this case that is a single\n"
@@ -766,6 +818,40 @@ const svn_opt_subcommand_desc2_t svn_cl_
" conflicts before you commit the merge.\n"
"\n"
"\n"
+" - Reintegrate Merge Example -\n"
+"\n"
+" The feature branch was last synced with trunk up to revision X. So the\n"
+" difference between trunk@X and feature@HEAD contains the complete set\n"
+" of changes that implement the feature, and no other changes. These\n"
+" changes are applied to trunk.\n"
+"\n"
+" rW rX\n"
+" trunk ------+--------------------L------------------o\n"
+" \\ . ^\n"
+" \\ ............. /\n"
+" \\ . /\n"
+" feature +--------------------------------R\n"
+"\n"
+" In the diagram above, L marks the left side (trunk@X) and R marks the\n"
+" right side (feature@HEAD) of the merge. The difference between the\n"
+" left and right side is merged into trunk, the target.\n"
+"\n"
+" To perform the merge, have a clean working copy of trunk and run the\n"
+" following command in its top-level directory:\n"
+"\n"
+" svn merge ^/feature\n"
+"\n"
+" To prevent unnecessary merge conflicts, a reintegrate merge requires\n"
+" that TARGET_WCPATH is not a mixed-revision working copy, has no local\n"
+" modifications, and has no switched subtrees.\n"
+"\n"
+" A reintegrate merge also requires that the source branch is coherently\n"
+" synced with the target -- in the above example, this means that all\n"
+" revisions between the branch point W and the last merged revision X\n"
+" are merged to the feature branch, so that there are no unmerged\n"
+" revisions in-between.\n"
+"\n"
+"\n"
" 2. This form is called a 'cherry-pick' merge:\n"
"\n"
" svn merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [TARGET_WCPATH]\n"
@@ -835,66 +921,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
" svn merge -c50,54,60 -r65:68 ^/trunk\n"
"\n"
"\n"
-" 3. This form is called a 'reintegrate merge':\n"
-"\n"
-" svn merge --reintegrate SOURCE[@REV] [TARGET_WCPATH]\n"
-"\n"
-" In a reintegrate merge, an (e.g. feature) branch is merged back to its\n"
-" originating branch. In other words, the source branch has originally\n"
-" been created by copying the target branch, development has concluded\n"
-" on the source branch and it should now be merged back into the target\n"
-" branch.\n"
-" \n"
-" SOURCE is the URL of a branch to be merged back. If REV is specified,\n"
-" it is used as the peg revision for SOURCE; if REV is not specified,\n"
-" the HEAD revision is assumed.\n"
-"\n"
-" TARGET_WCPATH is a working copy of the branch the changes will be\n"
-" applied to.\n"
-"\n"
-" - Reintegrate Merge Example -\n"
-"\n"
-" A feature has been developed on a branch called 'feature'. The feature\n"
-" branch started as a copy of trunk@W. Work on the feature has completed\n"
-" and it should be merged back into the trunk.\n"
-"\n"
-" The feature branch was last synced with trunk up to revision X. So the\n"
-" difference between trunk@X and feature@HEAD contains the complete set\n"
-" of changes that implement the feature, and no other changes. These\n"
-" changes are applied to trunk.\n"
-"\n"
-" feature +--------------------------------R\n"
-" / . \\\n"
-" / ............. \\\n"
-" / . v\n"
-" trunk ------+--------------------L------------------o\n"
-" rW rX\n"
-"\n"
-" In the diagram above, L marks the left side (trunk@X) and R marks the\n"
-" right side (feature@HEAD) of the merge. The difference between the\n"
-" left and right side is merged into trunk, the target.\n"
-"\n"
-" To perform the merge, have a clean working copy of trunk and run the\n"
-" following command in its top-level directory:\n"
-"\n"
-" svn merge --reintegrate ^/feature\n"
-"\n"
-" To prevent unnecessary merge conflicts, a reintegrate merge requires\n"
-" that TARGET_WCPATH is not a mixed-revision working copy, has no local\n"
-" modifications, and has no switched subtrees.\n"
-"\n"
-" A reintegrate merge also requires that the source branch is coherently\n"
-" synced with the target -- in the above example, this means that all\n"
-" revisions between the branch point W and the last merged revision X\n"
-" are merged to the feature branch, so that there are no unmerged\n"
-" revisions in-between.\n"
-"\n"
-" After the reintegrate merge, the feature branch cannot be synced to\n"
-" the trunk again without merge conflicts. If further work must be done\n"
-" on the feature branch, it should be deleted and then re-created.\n"
-"\n"
-"\n"
-" 4. This form is called a '2-URL merge':\n"
+" 3. This form is called a '2-URL merge':\n"
"\n"
" svn merge SOURCE1[@N] SOURCE2[@M] [TARGET_WCPATH]\n"
"\n"
@@ -1017,7 +1044,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
" repositories.\n"),
{'r', 'c', 'N', opt_depth, 'q', opt_force, opt_dry_run, opt_merge_cmd,
opt_record_only, 'x', opt_ignore_ancestry, opt_accept, opt_reintegrate,
- opt_allow_mixed_revisions, opt_symmetric} },
+ opt_allow_mixed_revisions} },
{ "mergeinfo", svn_cl__mergeinfo, {0}, N_
("Display merge-related information.\n"
@@ -1028,6 +1055,11 @@ const svn_opt_subcommand_desc2_t svn_cl_
" specified by the --show-revs option. If --show-revs isn't passed,\n"
" it defaults to --show-revs='merged'.\n"
"\n"
+ " If --revision (-r) is provided, filter the displayed information to\n"
+ " show only that which is associated with the revisions within the\n"
+ " specified range. Revision numbers, dates, and the 'HEAD' keyword are\n"
+ " valid range values.\n"
+ "\n"
" The depth can be 'empty' or 'infinity'; the default is 'empty'.\n"),
{'r', 'R', opt_depth, opt_show_revs} },
@@ -1143,15 +1175,19 @@ const svn_opt_subcommand_desc2_t svn_cl_
" 2. Prints unversioned remote prop on repos revision.\n"
" TARGET only determines which repository to access.\n"
"\n"
- " By default, this subcommand will add an extra newline to the end\n"
- " of the property values so that the output looks pretty. Also,\n"
- " whenever there are multiple paths involved, each property value\n"
- " is prefixed with the path with which it is associated. Use the\n"
- " --strict option to disable these beautifications (useful when\n"
- " redirecting a binary property value to a file, but available only\n"
- " if you supply a single TARGET to a non-recursive propget operation).\n"),
+ " With --verbose, the target path and the property name are printed on\n"
+ " separate lines before each value, like 'svn proplist --verbose'.\n"
+ " Otherwise, if there is more than one TARGET or a depth other than\n"
+ " 'empty', the target path is printed on the same line before each value.\n"
+ "\n"
+ " By default, an extra newline is printed after the property value so that\n"
+ " the output looks pretty. With a single TARGET and depth 'empty', you can\n"
+ " use the --strict option to disable this (useful when redirecting a binary\n"
+ " property value to a file, for example).\n"),
{'v', 'R', opt_depth, 'r', opt_revprop, opt_strict, opt_xml,
- opt_changelist } },
+ opt_changelist },
+ {{'v', N_("print path, name and value on separate lines")},
+ {opt_strict, N_("don't print an extra newline")}} },
{ "proplist", svn_cl__proplist, {"plist", "pl"}, N_
("List all properties on files, dirs, or revisions.\n"
@@ -1161,8 +1197,13 @@ const svn_opt_subcommand_desc2_t svn_cl_
" 1. Lists versioned props. If specified, REV determines in which\n"
" revision the target is first looked up.\n"
" 2. Lists unversioned remote props on repos revision.\n"
- " TARGET only determines which repository to access.\n"),
- {'v', 'R', opt_depth, 'r', 'q', opt_revprop, opt_xml, opt_changelist } },
+ " TARGET only determines which repository to access.\n"
+ "\n"
+ " With --verbose, the property values are printed as well, like 'svn propget\n"
+ " --verbose'. With --quiet, the paths are not printed.\n"),
+ {'v', 'R', opt_depth, 'r', 'q', opt_revprop, opt_xml, opt_changelist },
+ {{'v', N_("print path, name and value on separate lines")},
+ {'q', N_("don't print the path")}} },
{ "propset", svn_cl__propset, {"pset", "ps"}, N_
("Set the value of a property on files, dirs, or revisions.\n"
@@ -1260,9 +1301,12 @@ const svn_opt_subcommand_desc2_t svn_cl_
{ "resolve", svn_cl__resolve, {0}, N_
("Resolve conflicts on working copy files or directories.\n"
- "usage: resolve --accept=ARG [PATH...]\n"
+ "usage: resolve [PATH...]\n"
"\n"
- " Note: the --accept option is currently required.\n"),
+ " If no arguments are given, perform interactive conflict resolution for\n"
+ " all conflicted paths in the working copy, with default depth 'infinity'.\n"
+ " The --accept=ARG option prevents prompting and forces conflicts on PATH\n"
+ " to resolved in the manner specified by ARG, with default depth 'empty'.\n"),
{opt_targets, 'R', opt_depth, 'q', opt_accept},
{{opt_accept, N_("specify automatic conflict resolution source\n"
" "
@@ -1358,20 +1402,20 @@ const svn_opt_subcommand_desc2_t svn_cl_
"\n"
" Example output:\n"
" svn status wc\n"
- " M wc/bar.c\n"
- " A + wc/qax.c\n"
+ " M wc/bar.c\n"
+ " A + wc/qax.c\n"
"\n"
" svn status -u wc\n"
- " M 965 wc/bar.c\n"
- " * 965 wc/foo.c\n"
- " A + - wc/qax.c\n"
+ " M 965 wc/bar.c\n"
+ " * 965 wc/foo.c\n"
+ " A + - wc/qax.c\n"
" Status against revision: 981\n"
"\n"
" svn status --show-updates --verbose wc\n"
- " M 965 938 kfogel wc/bar.c\n"
- " * 965 922 sussman wc/foo.c\n"
- " A + - 687 joe wc/qax.c\n"
- " 965 687 joe wc/zig.c\n"
+ " M 965 938 kfogel wc/bar.c\n"
+ " * 965 922 sussman wc/foo.c\n"
+ " A + - 687 joe wc/qax.c\n"
+ " 965 687 joe wc/zig.c\n"
" Status against revision: 981\n"
"\n"
" svn status\n"
@@ -1508,8 +1552,8 @@ check_lib_versions(void)
{ "svn_diff", svn_diff_version },
{ NULL, NULL }
};
-
SVN_VERSION_DEFINE(my_version);
+
return svn_ver_check_list(&my_version, checklist);
}
@@ -1535,14 +1579,28 @@ svn_cl__check_cancel(void *baton)
return SVN_NO_ERROR;
}
+
/*** Main. ***/
-int
-main(int argc, const char *argv[])
+/* Report and clear the error ERR, and return EXIT_FAILURE. */
+#define EXIT_ERROR(err) \
+ svn_cmdline_handle_exit_error(err, NULL, "svn: ")
+
+/* A redefinition of the public SVN_INT_ERR macro, that suppresses the
+ * error message if it is SVN_ERR_IO_PIPE_WRITE_ERROR. */
+#undef SVN_INT_ERR
+#define SVN_INT_ERR(expr) \
+ do { \
+ svn_error_t *svn_err__temp = (expr); \
+ if (svn_err__temp) \
+ return EXIT_ERROR(svn_err__temp); \
+ } while (0)
+
+static int
+sub_main(int argc, const char *argv[], apr_pool_t *pool)
{
svn_error_t *err;
- apr_pool_t *pool;
int opt_id;
apr_getopt_t *os;
svn_cl__opt_state_t opt_state = { 0, { 0 } };
@@ -1559,35 +1617,21 @@ main(int argc, const char *argv[])
svn_boolean_t use_notifier = TRUE;
apr_hash_t *changelists;
- /* Initialize the app. */
- if (svn_cmdline_init("svn", stderr) != EXIT_SUCCESS)
- return EXIT_FAILURE;
-
- /* Create our top-level pool. Use a separate mutexless allocator,
- * given this application is single threaded.
- */
- pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
/* Check library versions */
- err = check_lib_versions();
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(check_lib_versions());
#if defined(WIN32) || defined(__CYGWIN__)
/* Set the working copy administrative directory name. */
if (getenv("SVN_ASP_DOT_NET_HACK"))
{
- err = svn_wc_set_adm_dir("_svn", pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_wc_set_adm_dir("_svn", pool));
}
#endif
/* Initialize the RA library. */
- err = svn_ra_initialize(pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_ra_initialize(pool));
/* Init our changelists hash. */
changelists = apr_hash_make(pool);
@@ -1606,14 +1650,11 @@ main(int argc, const char *argv[])
if (argc <= 1)
{
svn_cl__help(NULL, NULL, pool);
- svn_pool_destroy(pool);
return EXIT_FAILURE;
}
/* Else, parse options. */
- err = svn_cmdline__getopt_init(&os, argc, argv, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
os->interleave = 1;
while (1)
@@ -1629,7 +1670,6 @@ main(int argc, const char *argv[])
else if (apr_err)
{
svn_cl__help(NULL, NULL, pool);
- svn_pool_destroy(pool);
return EXIT_FAILURE;
}
@@ -1644,13 +1684,13 @@ main(int argc, const char *argv[])
{
err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, err,
_("Non-numeric limit argument given"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
if (opt_state.limit <= 0)
{
err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
_("Argument to --limit must be positive"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
}
break;
@@ -1671,7 +1711,7 @@ main(int argc, const char *argv[])
err = svn_error_create
(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("Can't specify -c with --old"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
for (i = 0; i < change_revs->nelts; i++)
@@ -1704,7 +1744,7 @@ main(int argc, const char *argv[])
_("Negative number in range (%s)"
" not supported with -c"),
change_str);
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
s = end + 1;
while (*s == 'r')
@@ -1716,14 +1756,14 @@ main(int argc, const char *argv[])
err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("Non-numeric change argument (%s) "
"given to -c"), change_str);
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
if (changeno == 0)
{
err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("There is no change 0"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
if (is_negative)
@@ -1762,13 +1802,12 @@ main(int argc, const char *argv[])
if (svn_opt_parse_revision_to_range(opt_state.revision_ranges,
opt_arg, pool) != 0)
{
- err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
- if (! err)
- err = svn_error_createf
+ SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+ err = svn_error_createf
(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("Syntax error in revision argument '%s'"),
utf8_opt_arg);
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
break;
case 'v':
@@ -1788,12 +1827,9 @@ main(int argc, const char *argv[])
opt_state.incremental = TRUE;
break;
case 'F':
- err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
- if (! err)
- err = svn_stringbuf_from_file2(&(opt_state.filedata),
- utf8_opt_arg, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+ SVN_INT_ERR(svn_stringbuf_from_file2(&(opt_state.filedata),
+ utf8_opt_arg, pool));
dash_F_arg = opt_arg;
break;
case opt_targets:
@@ -1804,14 +1840,9 @@ main(int argc, const char *argv[])
the targets into an array, because otherwise we wouldn't
know what delimiter to use for svn_cstring_split(). */
- err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
-
- if (! err)
- err = svn_stringbuf_from_file2(&buffer, utf8_opt_arg, pool);
- if (! err)
- err = svn_utf_stringbuf_to_utf8(&buffer_utf8, buffer, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+ SVN_INT_ERR(svn_stringbuf_from_file2(&buffer, utf8_opt_arg, pool));
+ SVN_INT_ERR(svn_utf_stringbuf_to_utf8(&buffer_utf8, buffer, pool));
opt_state.targets = svn_cstring_split(buffer_utf8->data, "\n\r",
TRUE, pool);
}
@@ -1837,55 +1868,51 @@ main(int argc, const char *argv[])
case opt_depth:
err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
if (err)
- return svn_cmdline_handle_exit_error
- (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ return EXIT_ERROR
+ (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
_("Error converting depth "
- "from locale to UTF-8")), pool, "svn: ");
+ "from locale to UTF-8")));
opt_state.depth = svn_depth_from_word(utf8_opt_arg);
if (opt_state.depth == svn_depth_unknown
|| opt_state.depth == svn_depth_exclude)
{
- return svn_cmdline_handle_exit_error
+ return EXIT_ERROR
(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("'%s' is not a valid depth; try "
"'empty', 'files', 'immediates', "
"or 'infinity'"),
- utf8_opt_arg), pool, "svn: ");
+ utf8_opt_arg));
}
break;
case opt_set_depth:
err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
if (err)
- return svn_cmdline_handle_exit_error
- (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ return EXIT_ERROR
+ (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
_("Error converting depth "
- "from locale to UTF-8")), pool, "svn: ");
+ "from locale to UTF-8")));
opt_state.set_depth = svn_depth_from_word(utf8_opt_arg);
/* svn_depth_exclude is okay for --set-depth. */
if (opt_state.set_depth == svn_depth_unknown)
{
- return svn_cmdline_handle_exit_error
+ return EXIT_ERROR
(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("'%s' is not a valid depth; try "
"'exclude', 'empty', 'files', "
"'immediates', or 'infinity'"),
- utf8_opt_arg), pool, "svn: ");
+ utf8_opt_arg));
}
break;
case opt_version:
opt_state.version = TRUE;
break;
case opt_auth_username:
- err = svn_utf_cstring_to_utf8(&opt_state.auth_username,
- opt_arg, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_username,
+ opt_arg, pool));
break;
case opt_auth_password:
- err = svn_utf_cstring_to_utf8(&opt_state.auth_password,
- opt_arg, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_password,
+ opt_arg, pool));
break;
case opt_encoding:
opt_state.encoding = apr_pstrdup(pool, opt_arg);
@@ -1912,16 +1939,16 @@ main(int argc, const char *argv[])
opt_state.trust_server_cert = TRUE;
break;
case opt_no_diff_deleted:
- opt_state.no_diff_deleted = TRUE;
+ opt_state.diff.no_diff_deleted = TRUE;
break;
- case opt_ignore_props:
- opt_state.ignore_props = TRUE;
+ case opt_ignore_properties:
+ opt_state.diff.ignore_properties = TRUE;
break;
case opt_show_copies_as_adds:
- opt_state.show_copies_as_adds = TRUE;
+ opt_state.diff.show_copies_as_adds = TRUE;
break;
case opt_notice_ancestry:
- opt_state.notice_ancestry = TRUE;
+ opt_state.diff.notice_ancestry = TRUE;
break;
case opt_ignore_ancestry:
opt_state.ignore_ancestry = TRUE;
@@ -1933,12 +1960,11 @@ main(int argc, const char *argv[])
opt_state.relocate = TRUE;
break;
case 'x':
- err = svn_utf_cstring_to_utf8(&opt_state.extensions, opt_arg, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.extensions,
+ opt_arg, pool));
break;
case opt_diff_cmd:
- opt_state.diff_cmd = apr_pstrdup(pool, opt_arg);
+ opt_state.diff.diff_cmd = apr_pstrdup(pool, opt_arg);
break;
case opt_merge_cmd:
opt_state.merge_cmd = apr_pstrdup(pool, opt_arg);
@@ -1946,9 +1972,6 @@ main(int argc, const char *argv[])
case opt_record_only:
opt_state.record_only = TRUE;
break;
- case opt_symmetric:
- opt_state.symmetric_merge = TRUE;
- break;
case opt_editor_cmd:
opt_state.editor_cmd = apr_pstrdup(pool, opt_arg);
break;
@@ -1958,7 +1981,7 @@ main(int argc, const char *argv[])
err = svn_error_create
(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("Can't specify -c with --old"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
opt_state.old_target = apr_pstrdup(pool, opt_arg);
break;
@@ -1968,9 +1991,7 @@ main(int argc, const char *argv[])
case opt_config_dir:
{
const char *path_utf8;
- err = svn_utf_cstring_to_utf8(&path_utf8, opt_arg, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_utf_cstring_to_utf8(&path_utf8, opt_arg, pool));
opt_state.config_dir = svn_dirent_internal_style(path_utf8, pool);
}
break;
@@ -1980,12 +2001,9 @@ main(int argc, const char *argv[])
apr_array_make(pool, 1,
sizeof(svn_cmdline__config_argument_t*));
- err = svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool);
- if (!err)
- err = svn_cmdline__parse_config_option(opt_state.config_options,
- opt_arg, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool));
+ SVN_INT_ERR(svn_cmdline__parse_config_option(opt_state.config_options,
+ opt_arg, pool));
break;
case opt_autoprops:
opt_state.autoprops = TRUE;
@@ -1999,20 +2017,19 @@ main(int argc, const char *argv[])
opt_state.native_eol = apr_pstrdup(pool, opt_arg);
else
{
- err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
- if (! err)
- err = svn_error_createf
+ SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+ err = svn_error_createf
(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("Syntax error in native-eol argument '%s'"),
utf8_opt_arg);
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
break;
case opt_no_unlock:
opt_state.no_unlock = TRUE;
break;
case opt_summarize:
- opt_state.summarize = TRUE;
+ opt_state.diff.summarize = TRUE;
break;
case opt_remove:
opt_state.remove = TRUE;
@@ -2037,9 +2054,8 @@ main(int argc, const char *argv[])
opt_state.no_revprops = TRUE;
break;
case opt_with_revprop:
- err = svn_opt_parse_revprop(&opt_state.revprop_table, opt_arg, pool);
- if (err != SVN_NO_ERROR)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_opt_parse_revprop(&opt_state.revprop_table,
+ opt_arg, pool));
break;
case opt_parents:
opt_state.parents = TRUE;
@@ -2050,20 +2066,18 @@ main(int argc, const char *argv[])
case opt_accept:
opt_state.accept_which = svn_cl__accept_from_word(opt_arg);
if (opt_state.accept_which == svn_cl__accept_invalid)
- return svn_cmdline_handle_exit_error
+ return EXIT_ERROR
(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("'%s' is not a valid --accept value"),
- opt_arg),
- pool, "svn: ");
+ opt_arg));
break;
case opt_show_revs:
opt_state.show_revs = svn_cl__show_revs_from_word(opt_arg);
if (opt_state.show_revs == svn_cl__show_revs_invalid)
- return svn_cmdline_handle_exit_error
+ return EXIT_ERROR
(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("'%s' is not a valid --show-revs value"),
- opt_arg),
- pool, "svn: ");
+ opt_arg));
break;
case opt_reintegrate:
opt_state.reintegrate = TRUE;
@@ -2075,13 +2089,13 @@ main(int argc, const char *argv[])
{
err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
_("Invalid strip count '%s'"), opt_arg);
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
if (opt_state.strip < 0)
{
err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
_("Argument to --strip must be positive"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
}
break;
@@ -2098,13 +2112,13 @@ main(int argc, const char *argv[])
opt_state.show_diff = TRUE;
break;
case opt_internal_diff:
- opt_state.internal_diff = TRUE;
+ opt_state.diff.internal_diff = TRUE;
break;
- case opt_use_patch_diff_format:
- opt_state.use_patch_diff_format = TRUE;
+ case opt_patch_compatible:
+ opt_state.diff.patch_compatible = TRUE;
break;
case opt_use_git_diff_format:
- opt_state.use_git_diff_format = TRUE;
+ opt_state.diff.use_git_diff_format = TRUE;
break;
case opt_allow_mixed_revisions:
opt_state.allow_mixed_rev = TRUE;
@@ -2112,6 +2126,16 @@ main(int argc, const char *argv[])
case opt_include_externals:
opt_state.include_externals = TRUE;
break;
+ case opt_properties_only:
+ opt_state.diff.properties_only = TRUE;
+ break;
+ case opt_search:
+ opt_state.search_pattern = opt_arg;
+ break;
+ case opt_isearch:
+ opt_state.search_pattern = opt_arg;
+ opt_state.case_insensitive_search = TRUE;
+ break;
default:
/* Hmmm. Perhaps this would be a good place to squirrel away
opts that commands like svn diff might need. Hmmm indeed. */
@@ -2120,9 +2144,7 @@ main(int argc, const char *argv[])
}
/* Turn our hash of changelists into an array of unique ones. */
- err = svn_hash_keys(&(opt_state.changelists), changelists, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_hash_keys(&(opt_state.changelists), changelists, pool));
/* ### This really belongs in libsvn_client. The trouble is,
there's no one place there to run it from, no
@@ -2134,9 +2156,7 @@ main(int argc, const char *argv[])
hand, the alternative is effectively to demand that they call
svn_config_ensure() instead, so maybe we should have a generic
init function anyway. Thoughts? */
- err = svn_config_ensure(opt_state.config_dir, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_config_ensure(opt_state.config_dir, pool));
/* If the user asked for help, then the rest of the arguments are
the names of subcommands to get help on (if any), or else they're
@@ -2158,6 +2178,7 @@ main(int argc, const char *argv[])
{ "--version", svn_cl__help, {0}, "",
{opt_version, /* must accept its own option */
'q', /* brief output */
+ 'v', /* verbose output */
opt_config_dir /* all commands accept this */
} };
@@ -2169,7 +2190,6 @@ main(int argc, const char *argv[])
(svn_cmdline_fprintf(stderr, pool,
_("Subcommand argument required\n")));
svn_cl__help(NULL, NULL, pool);
- svn_pool_destroy(pool);
return EXIT_FAILURE;
}
}
@@ -2181,15 +2201,13 @@ main(int argc, const char *argv[])
if (subcommand == NULL)
{
const char *first_arg_utf8;
- err = svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8,
+ first_arg, pool));
svn_error_clear
(svn_cmdline_fprintf(stderr, pool,
_("Unknown command: '%s'\n"),
first_arg_utf8));
svn_cl__help(NULL, NULL, pool);
- svn_pool_destroy(pool);
return EXIT_FAILURE;
}
}
@@ -2223,7 +2241,6 @@ main(int argc, const char *argv[])
(stderr, pool, _("Subcommand '%s' doesn't accept option '%s'\n"
"Type 'svn help %s' for usage.\n"),
subcommand->name, optstr, subcommand->name));
- svn_pool_destroy(pool);
return EXIT_FAILURE;
}
}
@@ -2238,7 +2255,7 @@ main(int argc, const char *argv[])
_("Multiple revision arguments "
"encountered; can't specify -c twice, "
"or both -c and -r"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
}
@@ -2249,7 +2266,7 @@ main(int argc, const char *argv[])
err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("--depth and --set-depth are mutually "
"exclusive"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
/* Disallow simultaneous use of both --with-all-revprops and
@@ -2259,7 +2276,7 @@ main(int argc, const char *argv[])
err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("--with-all-revprops and --with-no-revprops "
"are mutually exclusive"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
/* Disallow simultaneous use of both --with-revprop and
@@ -2269,7 +2286,7 @@ main(int argc, const char *argv[])
err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("--with-revprop and --with-no-revprops "
"are mutually exclusive"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
/* Disallow simultaneous use of both -m and -F, when they are
@@ -2282,7 +2299,7 @@ main(int argc, const char *argv[])
err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("--message (-m) and --file (-F) "
"are mutually exclusive"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
/* --trust-server-cert can only be used with --non-interactive */
@@ -2291,17 +2308,17 @@ main(int argc, const char *argv[])
err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("--trust-server-cert requires "
"--non-interactive"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
/* Disallow simultaneous use of both --diff-cmd and
--internal-diff. */
- if (opt_state.diff_cmd && opt_state.internal_diff)
+ if (opt_state.diff.diff_cmd && opt_state.diff.internal_diff)
{
err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("--diff-cmd and --internal-diff "
"are mutually exclusive"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
/* Ensure that 'revision_ranges' has at least one item, and make
@@ -2321,8 +2338,7 @@ main(int argc, const char *argv[])
/* Create a client context object. */
command_baton.opt_state = &opt_state;
- if ((err = svn_client_create_context(&ctx, pool)))
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_client_create_context(&ctx, pool));
command_baton.ctx = ctx;
/* If we're running a command that could result in a commit, verify
@@ -2369,7 +2385,7 @@ main(int argc, const char *argv[])
_("Lock comment file is a versioned file; "
"use '--force-log' to override"));
}
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
}
svn_error_clear(err);
@@ -2397,7 +2413,7 @@ main(int argc, const char *argv[])
_("The lock comment is a pathname "
"(was -F intended?); use '--force-log' to override"));
}
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
}
}
@@ -2410,7 +2426,7 @@ main(int argc, const char *argv[])
err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
_("--relocate and --depth are mutually "
"exclusive"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
if (! descend)
{
@@ -2418,7 +2434,7 @@ main(int argc, const char *argv[])
SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
_("--relocate and --non-recursive (-N) are mutually "
"exclusive"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
}
@@ -2427,12 +2443,13 @@ main(int argc, const char *argv[])
if (subcommand->cmd_func != svn_cl__blame
&& subcommand->cmd_func != svn_cl__diff
&& subcommand->cmd_func != svn_cl__log
+ && subcommand->cmd_func != svn_cl__mergeinfo
&& subcommand->cmd_func != svn_cl__merge)
{
if (opt_state.end_revision.kind != svn_opt_revision_unspecified)
{
err = svn_error_create(SVN_ERR_CLIENT_REVISION_RANGE, NULL, NULL);
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
}
@@ -2472,7 +2489,7 @@ main(int argc, const char *argv[])
svn_error_clear(err);
}
else
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ return EXIT_ERROR(err);
}
cfg_config = apr_hash_get(ctx->config, SVN_CONFIG_CATEGORY_CONFIG,
@@ -2489,13 +2506,13 @@ main(int argc, const char *argv[])
/* XXX: Only diff_cmd for now, overlay rest later and stop passing
opt_state altogether? */
- if (opt_state.diff_cmd)
+ if (opt_state.diff.diff_cmd)
svn_config_set(cfg_config, SVN_CONFIG_SECTION_HELPERS,
- SVN_CONFIG_OPTION_DIFF_CMD, opt_state.diff_cmd);
+ SVN_CONFIG_OPTION_DIFF_CMD, opt_state.diff.diff_cmd);
if (opt_state.merge_cmd)
svn_config_set(cfg_config, SVN_CONFIG_SECTION_HELPERS,
SVN_CONFIG_OPTION_DIFF3_CMD, opt_state.merge_cmd);
- if (opt_state.internal_diff)
+ if (opt_state.diff.internal_diff)
svn_config_set(cfg_config, SVN_CONFIG_SECTION_HELPERS,
SVN_CONFIG_OPTION_DIFF_CMD, NULL);
@@ -2505,38 +2522,7 @@ main(int argc, const char *argv[])
err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
_("--auto-props and --no-auto-props are "
"mutually exclusive"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
- }
-
- /* The --reintegrate option is mutually exclusive with both
- --ignore-ancestry and --record-only. */
- if (opt_state.reintegrate)
- {
- if (opt_state.ignore_ancestry)
- {
- if (opt_state.record_only)
- {
- err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
- _("--reintegrate cannot be used with "
- "--ignore-ancestry or "
- "--record-only"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
- }
- else
- {
- err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
- _("--reintegrate cannot be used with "
- "--ignore-ancestry"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
- }
- }
- else if (opt_state.record_only)
- {
- err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
- _("--reintegrate cannot be used with "
- "--record-only"));
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
- }
+ return EXIT_ERROR(err);
}
/* Update auto-props-enable option, and populate the MIME types map,
@@ -2550,9 +2536,8 @@ main(int argc, const char *argv[])
SVN_CONFIG_OPTION_MIMETYPES_FILE, FALSE);
if (mimetypes_file && *mimetypes_file)
{
- if ((err = svn_io_parse_mimetypes_file(&(ctx->mimetypes_map),
- mimetypes_file, pool)))
- svn_handle_error2(err, stderr, TRUE, "svn: ");
+ SVN_INT_ERR(svn_io_parse_mimetypes_file(&(ctx->mimetypes_map),
+ mimetypes_file, pool));
}
if (opt_state.autoprops)
@@ -2590,9 +2575,8 @@ main(int argc, const char *argv[])
use_notifier = FALSE;
if (use_notifier)
{
- err = svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2,
+ pool));
}
/* Set up our cancellation support. */
@@ -2622,28 +2606,33 @@ main(int argc, const char *argv[])
#endif
/* Set up Authentication stuff. */
- if ((err = svn_cmdline_create_auth_baton(&ab,
- opt_state.non_interactive,
- opt_state.auth_username,
- opt_state.auth_password,
- opt_state.config_dir,
- opt_state.no_auth_cache,
- opt_state.trust_server_cert,
- cfg_config,
- ctx->cancel_func,
- ctx->cancel_baton,
- pool)))
- svn_handle_error2(err, stderr, TRUE, "svn: ");
+ SVN_INT_ERR(svn_cmdline_create_auth_baton(&ab,
+ opt_state.non_interactive,
+ opt_state.auth_username,
+ opt_state.auth_password,
+ opt_state.config_dir,
+ opt_state.no_auth_cache,
+ opt_state.trust_server_cert,
+ cfg_config,
+ ctx->cancel_func,
+ ctx->cancel_baton,
+ pool));
ctx->auth_baton = ab;
/* Set up conflict resolution callback. */
- if ((err = svn_config_get_bool(cfg_config, &interactive_conflicts,
- SVN_CONFIG_SECTION_MISCELLANY,
- SVN_CONFIG_OPTION_INTERACTIVE_CONFLICTS,
- TRUE))) /* ### interactivity on by default.
- we can change this. */
- svn_handle_error2(err, stderr, TRUE, "svn: ");
+ SVN_INT_ERR(svn_config_get_bool(cfg_config, &interactive_conflicts,
+ SVN_CONFIG_SECTION_MISCELLANY,
+ SVN_CONFIG_OPTION_INTERACTIVE_CONFLICTS,
+ TRUE)); /* ### interactivity on by default.
+ we can change this. */
+
+ /* The new svn behavior is to postpone everything until after the operation
+ completed */
+ ctx->conflict_func = NULL;
+ ctx->conflict_baton = NULL;
+ ctx->conflict_func2 = NULL;
+ ctx->conflict_baton2 = NULL;
if ((opt_state.accept_which == svn_cl__accept_unspecified
&& (!interactive_conflicts || opt_state.non_interactive))
@@ -2652,11 +2641,12 @@ main(int argc, const char *argv[])
/* If no --accept option at all and we're non-interactive, we're
leaving the conflicts behind, so don't need the callback. Same if
the user said to postpone. */
- ctx->conflict_func = NULL;
- ctx->conflict_baton = NULL;
+ opt_state.conflict_func = NULL;
+ opt_state.conflict_baton = NULL;
}
else
{
+ svn_cl__conflict_baton_t * conflict_baton2;
svn_cmdline_prompt_baton_t *pb = apr_palloc(pool, sizeof(*pb));
pb->cancel_func = ctx->cancel_func;
pb->cancel_baton = ctx->cancel_baton;
@@ -2664,27 +2654,26 @@ main(int argc, const char *argv[])
if (opt_state.non_interactive)
{
if (opt_state.accept_which == svn_cl__accept_edit)
- return svn_cmdline_handle_exit_error
+ return EXIT_ERROR
(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("--accept=%s incompatible with"
- " --non-interactive"), SVN_CL__ACCEPT_EDIT),
- pool, "svn: ");
+ " --non-interactive"), SVN_CL__ACCEPT_EDIT));
if (opt_state.accept_which == svn_cl__accept_launch)
- return svn_cmdline_handle_exit_error
+ return EXIT_ERROR
(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("--accept=%s incompatible with"
" --non-interactive"),
- SVN_CL__ACCEPT_LAUNCH),
- pool, "svn: ");
+ SVN_CL__ACCEPT_LAUNCH));
}
- ctx->conflict_func = svn_cl__conflict_handler;
- ctx->conflict_baton = svn_cl__conflict_baton_make(
- opt_state.accept_which,
- ctx->config,
- opt_state.editor_cmd,
- pb,
- pool);
+ opt_state.conflict_func = svn_cl__conflict_handler;
+ SVN_INT_ERR(svn_cl__conflict_baton_make(&conflict_baton2,
+ opt_state.accept_which,
+ ctx->config,
+ opt_state.editor_cmd,
+ pb,
+ pool));
+ opt_state.conflict_baton = conflict_baton2;
}
/* And now we finally run the subcommand. */
@@ -2696,8 +2685,10 @@ main(int argc, const char *argv[])
if (err->apr_err == SVN_ERR_CL_INSUFFICIENT_ARGS
|| err->apr_err == SVN_ERR_CL_ARG_PARSING_ERROR)
{
- err = svn_error_quick_wrap(err,
- _("Try 'svn help' for more info"));
+ err = svn_error_quick_wrap(
+ err, apr_psprintf(pool,
+ _("Try 'svn help %s' for more information"),
+ subcommand->name));
}
if (err->apr_err == SVN_ERR_WC_UPGRADE_REQUIRED)
{
@@ -2714,29 +2705,35 @@ main(int argc, const char *argv[])
"(type 'svn help cleanup' for details)"));
}
- /* Issue #3014:
- * Don't print anything on broken pipes. The pipe was likely
- * closed by the process at the other end. We expect that
- * process to perform error reporting as necessary.
- *
- * ### This assumes that there is only one error in a chain for
- * ### SVN_ERR_IO_PIPE_WRITE_ERROR. See svn_cmdline_fputs(). */
- if (err->apr_err != SVN_ERR_IO_PIPE_WRITE_ERROR)
- svn_handle_error2(err, stderr, FALSE, "svn: ");
-
- svn_error_clear(err);
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ return EXIT_ERROR(err);
}
else
{
/* Ensure that stdout is flushed, so the user will see any write errors.
This makes sure that output is not silently lost. */
- err = svn_cmdline_fflush(stdout);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+ SVN_INT_ERR(svn_cmdline_fflush(stdout));
- svn_pool_destroy(pool);
return EXIT_SUCCESS;
}
}
+
+int
+main(int argc, const char *argv[])
+{
+ apr_pool_t *pool;
+ int exit_code;
+
+ /* Initialize the app. */
+ if (svn_cmdline_init("svn", stderr) != EXIT_SUCCESS)
+ return EXIT_FAILURE;
+
+ /* Create our top-level pool. Use a separate mutexless allocator,
+ * given this application is single threaded.
+ */
+ pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
+
+ exit_code = sub_main(argc, argv, pool);
+
+ svn_pool_destroy(pool);
+ return exit_code;
+}
Modified: subversion/branches/compressed-pristines/subversion/svn/merge-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/svn/merge-cmd.c?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/svn/merge-cmd.c (original)
+++ subversion/branches/compressed-pristines/subversion/svn/merge-cmd.c Thu Aug 16 10:17:48 2012
@@ -61,8 +61,14 @@ merge_reintegrate(const char *source_pat
if (url1)
{
- svn_opt_revision_t revision1 = { svn_opt_revision_number, { rev1 } };
- svn_opt_revision_t revision2 = { svn_opt_revision_number, { rev2 } };
+ svn_opt_revision_t revision1;
+ svn_opt_revision_t revision2;
+
+ revision1.kind = svn_opt_revision_number;
+ revision1.value.number = rev1;
+
+ revision2.kind = svn_opt_revision_number;
+ revision2.value.number = rev2;
/* Do the merge. Set 'allow_mixed_rev' to true, not because we want
* to allow a mixed-rev WC but simply to bypass the check, as it was
@@ -98,14 +104,12 @@ ensure_wc_path_has_repo_revision(const c
return SVN_NO_ERROR;
}
-#ifdef SVN_WITH_SYMMETRIC_MERGE
/* Symmetric, merge-tracking merge, used for sync or reintegrate purposes. */
static svn_error_t *
symmetric_merge(const char *source_path_or_url,
const svn_opt_revision_t *source_revision,
const char *target_wcpath,
svn_depth_t depth,
- svn_boolean_t ignore_ancestry,
svn_boolean_t force,
svn_boolean_t record_only,
svn_boolean_t dry_run,
@@ -117,6 +121,7 @@ symmetric_merge(const char *source_path_
apr_pool_t *scratch_pool)
{
svn_client__symmetric_merge_t *merge;
+ svn_boolean_t reintegrate_like;
/* Find the 3-way merges needed (and check suitability of the WC). */
SVN_ERR(svn_client__find_symmetric_merge(&merge,
@@ -125,15 +130,43 @@ symmetric_merge(const char *source_path_
allow_local_mods, allow_switched_subtrees,
ctx, scratch_pool, scratch_pool));
+ reintegrate_like = (merge->mid != NULL);
+
+ if (reintegrate_like)
+ {
+ if (record_only)
+ return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
+ _("The required merge is reintegrate-like, "
+ "and the --record-only option "
+ "cannot be used with this kind of merge"));
+
+ if (depth != svn_depth_unknown)
+ return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
+ _("The required merge is reintegrate-like, "
+ "and the --depth option "
+ "cannot be used with this kind of merge"));
+
+ if (force)
+ return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
+ _("The required merge is reintegrate-like, "
+ "and the --force option "
+ "cannot be used with this kind of merge"));
+
+ if (allow_mixed_rev)
+ return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
+ _("The required merge is reintegrate-like, "
+ "and the --allow-mixed-revisions option "
+ "cannot be used with this kind of merge"));
+ }
+
/* Perform the 3-way merges */
SVN_ERR(svn_client__do_symmetric_merge(merge, target_wcpath, depth,
- ignore_ancestry, force, record_only,
+ force, record_only,
dry_run, merge_options,
ctx, scratch_pool));
return SVN_NO_ERROR;
}
-#endif
/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
@@ -146,7 +179,8 @@ svn_cl__merge(apr_getopt_t *os,
apr_array_header_t *targets;
const char *sourcepath1 = NULL, *sourcepath2 = NULL, *targetpath = "";
svn_boolean_t two_sources_specified = TRUE;
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
+ svn_error_t *merge_err = SVN_NO_ERROR;
svn_opt_revision_t first_range_start, first_range_end, peg_revision1,
peg_revision2;
apr_array_header_t *options, *ranges_to_merge = opt_state->revision_ranges;
@@ -364,6 +398,16 @@ svn_cl__merge(apr_getopt_t *os,
/* More input validation. */
if (opt_state->reintegrate)
{
+ if (opt_state->ignore_ancestry)
+ return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
+ _("--reintegrate cannot be used with "
+ "--ignore-ancestry"));
+
+ if (opt_state->record_only)
+ return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
+ _("--reintegrate cannot be used with "
+ "--record-only"));
+
if (opt_state->depth != svn_depth_unknown)
return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
_("--depth cannot be used with "
@@ -384,43 +428,40 @@ svn_cl__merge(apr_getopt_t *os,
"with --reintegrate"));
}
-#ifdef SVN_WITH_SYMMETRIC_MERGE
- if (opt_state->symmetric_merge)
- {
- svn_boolean_t allow_local_mods = ! opt_state->reintegrate;
- svn_boolean_t allow_switched_subtrees = ! opt_state->reintegrate;
-
- if (two_sources_specified)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("SOURCE2 can't be used with --symmetric"));
+ /* Postpone conflict resolution during the merge operation.
+ * If any conflicts occur we'll run the conflict resolver later. */
+ /* Do a symmetric merge if just one source and no revisions. */
+ if ((! two_sources_specified)
+ && (! opt_state->reintegrate)
+ && (! opt_state->ignore_ancestry)
+ && first_range_start.kind == svn_opt_revision_unspecified
+ && first_range_end.kind == svn_opt_revision_unspecified)
+ {
SVN_ERR_W(svn_cl__check_related_source_and_target(
sourcepath1, &peg_revision1, targetpath, &unspecified,
ctx, pool),
_("Source and target must be different but related branches"));
- err = symmetric_merge(sourcepath1, &peg_revision1, targetpath,
- opt_state->depth,
- opt_state->ignore_ancestry,
- opt_state->force,
- opt_state->record_only,
- opt_state->dry_run,
- opt_state->allow_mixed_rev,
- allow_local_mods,
- allow_switched_subtrees,
- options, ctx, pool);
+ merge_err = symmetric_merge(sourcepath1, &peg_revision1, targetpath,
+ opt_state->depth,
+ opt_state->force,
+ opt_state->record_only,
+ opt_state->dry_run,
+ opt_state->allow_mixed_rev,
+ TRUE /*allow_local_mods*/,
+ TRUE /*allow_switched_subtrees*/,
+ options, ctx, pool);
}
- else
-#endif
- if (opt_state->reintegrate)
+ else if (opt_state->reintegrate)
{
SVN_ERR_W(svn_cl__check_related_source_and_target(
sourcepath1, &peg_revision1, targetpath, &unspecified,
ctx, pool),
_("Source and target must be different but related branches"));
- err = merge_reintegrate(sourcepath1, &peg_revision1, targetpath,
- opt_state->dry_run, options, ctx, pool);
+ merge_err = merge_reintegrate(sourcepath1, &peg_revision1, targetpath,
+ opt_state->dry_run, options, ctx, pool);
}
else if (! two_sources_specified)
{
@@ -444,19 +485,19 @@ svn_cl__merge(apr_getopt_t *os,
_("Source and target must be different but related branches"));
}
- err = svn_client_merge_peg4(sourcepath1,
- ranges_to_merge,
- &peg_revision1,
- targetpath,
- opt_state->depth,
- opt_state->ignore_ancestry,
- opt_state->force,
- opt_state->record_only,
- opt_state->dry_run,
- opt_state->allow_mixed_rev,
- options,
- ctx,
- pool);
+ merge_err = svn_client_merge_peg4(sourcepath1,
+ ranges_to_merge,
+ &peg_revision1,
+ targetpath,
+ opt_state->depth,
+ opt_state->ignore_ancestry,
+ opt_state->force,
+ opt_state->record_only,
+ opt_state->dry_run,
+ opt_state->allow_mixed_rev,
+ options,
+ ctx,
+ pool);
}
else
{
@@ -464,36 +505,47 @@ svn_cl__merge(apr_getopt_t *os,
return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("Merge sources must both be "
"either paths or URLs"));
- err = svn_client_merge4(sourcepath1,
- &first_range_start,
- sourcepath2,
- &first_range_end,
- targetpath,
- opt_state->depth,
- opt_state->ignore_ancestry,
- opt_state->force,
- opt_state->record_only,
- opt_state->dry_run,
- opt_state->allow_mixed_rev,
- options,
- ctx,
- pool);
+ merge_err = svn_client_merge4(sourcepath1,
+ &first_range_start,
+ sourcepath2,
+ &first_range_end,
+ targetpath,
+ opt_state->depth,
+ opt_state->ignore_ancestry,
+ opt_state->force,
+ opt_state->record_only,
+ opt_state->dry_run,
+ opt_state->allow_mixed_rev,
+ options,
+ ctx,
+ pool);
}
if (! opt_state->quiet)
- SVN_ERR(svn_cl__print_conflict_stats(ctx->notify_baton2, pool));
+ err = svn_cl__print_conflict_stats(ctx->notify_baton2, pool);
+
+ if (!err
+ && opt_state->conflict_func
+ && svn_cl__notifier_check_conflicts(ctx->notify_baton2))
+ {
+ err = svn_cl__resolve_conflicts(
+ svn_cl__notifier_get_conflicted_paths(ctx->notify_baton2, pool),
+ opt_state->depth, opt_state, ctx, pool);
+ }
- if (err)
+ if (merge_err)
{
- if(err->apr_err == SVN_ERR_CLIENT_INVALID_MERGEINFO_NO_MERGETRACKING)
+ if (merge_err->apr_err ==
+ SVN_ERR_CLIENT_INVALID_MERGEINFO_NO_MERGETRACKING)
{
err = svn_error_quick_wrap(
- err,
+ svn_error_compose_create(merge_err, err),
_("Merge tracking not possible, use --ignore-ancestry or\n"
"fix invalid mergeinfo in target with 'svn propset'"));
}
- else if (! opt_state->reintegrate)
+ else
{
+ err = svn_error_compose_create(merge_err, err);
return svn_cl__may_need_force(err);
}
}
Modified: subversion/branches/compressed-pristines/subversion/svn/mergeinfo-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/svn/mergeinfo-cmd.c?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/svn/mergeinfo-cmd.c (original)
+++ subversion/branches/compressed-pristines/subversion/svn/mergeinfo-cmd.c Thu Aug 16 10:17:48 2012
@@ -122,19 +122,23 @@ svn_cl__mergeinfo(apr_getopt_t *os,
/* Do the real work, depending on the requested data flavor. */
if (opt_state->show_revs == svn_cl__show_revs_merged)
{
- SVN_ERR(svn_client_mergeinfo_log(TRUE, target, &tgt_peg_revision,
- source, &src_peg_revision,
- print_log_rev, NULL,
- TRUE, depth, NULL, ctx,
- pool));
+ SVN_ERR(svn_client_mergeinfo_log2(TRUE, target, &tgt_peg_revision,
+ source, &src_peg_revision,
+ &(opt_state->start_revision),
+ &(opt_state->end_revision),
+ print_log_rev, NULL,
+ TRUE, depth, NULL, ctx,
+ pool));
}
else if (opt_state->show_revs == svn_cl__show_revs_eligible)
{
- SVN_ERR(svn_client_mergeinfo_log(FALSE, target, &tgt_peg_revision,
- source, &src_peg_revision,
- print_log_rev, NULL,
- TRUE, depth, NULL, ctx,
- pool));
+ SVN_ERR(svn_client_mergeinfo_log2(FALSE, target, &tgt_peg_revision,
+ source, &src_peg_revision,
+ &(opt_state->start_revision),
+ &(opt_state->end_revision),
+ print_log_rev, NULL,
+ TRUE, depth, NULL, ctx,
+ pool));
}
return SVN_NO_ERROR;
}
Modified: subversion/branches/compressed-pristines/subversion/svn/notify.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/svn/notify.c?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/svn/notify.c (original)
+++ subversion/branches/compressed-pristines/subversion/svn/notify.c Thu Aug 16 10:17:48 2012
@@ -35,6 +35,7 @@
#include "svn_pools.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
+#include "svn_sorts.h"
#include "cl.h"
#include "svn_private_config.h"
@@ -57,6 +58,7 @@ struct notify_baton
unsigned int prop_conflicts;
unsigned int tree_conflicts;
unsigned int skipped_paths;
+ apr_hash_t *conflicted_paths;
/* The cwd, for use in decomposing absolute paths. */
const char *path_prefix;
@@ -100,6 +102,16 @@ svn_cl__print_conflict_stats(void *notif
return SVN_NO_ERROR;
}
+/* Add a conflicted path to the list of conflicted paths stored
+ * in the notify baton. */
+static void
+add_conflicted_path(struct notify_baton *nb, const char *path)
+{
+ apr_hash_set(nb->conflicted_paths,
+ apr_pstrdup(apr_hash_pool_get(nb->conflicted_paths), path),
+ APR_HASH_KEY_STRING, "");
+}
+
/* This implements `svn_wc_notify_func2_t'.
* NOTE: This function can't fail, so we just ignore any print errors. */
static void
@@ -181,6 +193,10 @@ notify(void *baton, const svn_wc_notify_
if ((err = svn_cmdline_printf(pool, "D %s\n", path_local)))
goto print_error;
break;
+ case svn_wc_notify_update_broken_lock:
+ if ((err = svn_cmdline_printf(pool, "B %s\n", path_local)))
+ goto print_error;
+ break;
case svn_wc_notify_update_external_removed:
nb->received_some_change = TRUE;
@@ -198,6 +214,12 @@ notify(void *baton, const svn_wc_notify_
}
break;
+ case svn_wc_notify_left_local_modifications:
+ if ((err = svn_cmdline_printf(pool, "Left local modifications as '%s'\n",
+ path_local)))
+ goto print_error;
+ break;
+
case svn_wc_notify_update_replace:
nb->received_some_change = TRUE;
if ((err = svn_cmdline_printf(pool, "R %s\n", path_local)))
@@ -209,6 +231,7 @@ notify(void *baton, const svn_wc_notify_
if (n->content_state == svn_wc_notify_state_conflicted)
{
nb->text_conflicts++;
+ add_conflicted_path(nb, n->path);
if ((err = svn_cmdline_printf(pool, "C %s\n", path_local)))
goto print_error;
}
@@ -224,6 +247,7 @@ notify(void *baton, const svn_wc_notify_
if (n->content_state == svn_wc_notify_state_conflicted)
{
nb->text_conflicts++;
+ add_conflicted_path(nb, n->path);
statchar_buf[0] = 'C';
}
else
@@ -232,6 +256,7 @@ notify(void *baton, const svn_wc_notify_
if (n->prop_state == svn_wc_notify_state_conflicted)
{
nb->prop_conflicts++;
+ add_conflicted_path(nb, n->path);
statchar_buf[1] = 'C';
}
else if (n->prop_state == svn_wc_notify_state_merged)
@@ -298,6 +323,7 @@ notify(void *baton, const svn_wc_notify_
if (n->content_state == svn_wc_notify_state_conflicted)
{
nb->text_conflicts++;
+ add_conflicted_path(nb, n->path);
statchar_buf[0] = 'C';
}
else if (n->kind == svn_node_file)
@@ -311,6 +337,7 @@ notify(void *baton, const svn_wc_notify_
if (n->prop_state == svn_wc_notify_state_conflicted)
{
nb->prop_conflicts++;
+ add_conflicted_path(nb, n->path);
statchar_buf[1] = 'C';
}
else if (n->prop_state == svn_wc_notify_state_changed)
@@ -504,6 +531,7 @@ notify(void *baton, const svn_wc_notify_
if (n->content_state == svn_wc_notify_state_conflicted)
{
nb->text_conflicts++;
+ add_conflicted_path(nb, n->path);
statchar_buf[0] = 'C';
}
else if (n->kind == svn_node_file)
@@ -517,6 +545,7 @@ notify(void *baton, const svn_wc_notify_
if (n->prop_state == svn_wc_notify_state_conflicted)
{
nb->prop_conflicts++;
+ add_conflicted_path(nb, n->path);
statchar_buf[1] = 'C';
}
else if (n->prop_state == svn_wc_notify_state_merged)
@@ -894,6 +923,7 @@ notify(void *baton, const svn_wc_notify_
case svn_wc_notify_tree_conflict:
nb->tree_conflicts++;
+ add_conflicted_path(nb, n->path);
if ((err = svn_cmdline_printf(pool, " C %s\n", path_local)))
goto print_error;
break;
@@ -978,6 +1008,14 @@ notify(void *baton, const svn_wc_notify_
goto print_error;
break;
+ case svn_wc_notify_conflict_resolver_starting:
+ /* Once all operations invoke the interactive conflict resolution after
+ * they've completed, we can run svn_cl__print_conflict_stats() here. */
+ break;
+
+ case svn_wc_notify_conflict_resolver_done:
+ break;
+
default:
break;
}
@@ -1026,6 +1064,7 @@ svn_cl__get_notifier(svn_wc_notify_func2
nb->prop_conflicts = 0;
nb->tree_conflicts = 0;
nb->skipped_paths = 0;
+ nb->conflicted_paths = apr_hash_make(pool);
SVN_ERR(svn_dirent_get_absolute(&nb->path_prefix, "", pool));
*notify_func_p = notify;
@@ -1074,3 +1113,35 @@ svn_cl__check_externals_failed_notify_wr
nwb->wrapped_func(nwb->wrapped_baton, n, pool);
}
+svn_boolean_t
+svn_cl__notifier_check_conflicts(void *baton)
+{
+ struct notify_baton *nb = baton;
+
+ return (nb->text_conflicts || nb->prop_conflicts || nb->tree_conflicts);
+}
+
+apr_array_header_t *
+svn_cl__notifier_get_conflicted_paths(void *baton, apr_pool_t *result_pool)
+{
+ struct notify_baton *nb = baton;
+ apr_array_header_t *sorted_array;
+ apr_array_header_t *result_array;
+ int i;
+
+ sorted_array = svn_sort__hash(nb->conflicted_paths,
+ svn_sort_compare_items_as_paths,
+ apr_hash_pool_get(nb->conflicted_paths));
+ result_array = apr_array_make(result_pool, sorted_array->nelts,
+ sizeof(const char *));
+ for (i = 0; i < sorted_array->nelts; i++)
+ {
+ svn_sort__item_t item;
+
+ item = APR_ARRAY_IDX(sorted_array, i, svn_sort__item_t);
+ APR_ARRAY_PUSH(result_array, const char *) = apr_pstrdup(result_pool,
+ item.key);
+ }
+
+ return result_array;
+}