Modified: subversion/branches/addremove/subversion/svn/auth-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/auth-cmd.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/auth-cmd.c (original) +++ subversion/branches/addremove/subversion/svn/auth-cmd.c Sat May 23 14:16:56 2020 @@ -455,12 +455,15 @@ svn_cl__auth(apr_getopt_t *os, void *bat { if (b.patterns->nelts == 0) SVN_ERR(svn_cmdline_printf(pool, - _("Credentials cache in '%s' contains %d credentials\n"), + Q_("Credentials cache in '%s' contains %d credential\n", + "Credentials cache in '%s' contains %d credentials\n", + b.matches), svn_dirent_local_style(config_path, pool), b.matches)); else SVN_ERR(svn_cmdline_printf(pool, - _("Credentials cache in '%s' contains %d matching " - "credentials\n"), + Q_("Credentials cache in '%s' contains %d matching credential\n", + "Credentials cache in '%s' contains %d matching credentials\n", + b.matches), svn_dirent_local_style(config_path, pool), b.matches)); } @@ -474,9 +477,11 @@ svn_cl__auth(apr_getopt_t *os, void *bat "no matching credentials"), svn_dirent_local_style(config_path, pool)); else - SVN_ERR(svn_cmdline_printf(pool, _("Deleted %d matching credentials " - "from '%s'\n"), b.matches, - svn_dirent_local_style(config_path, pool))); + SVN_ERR(svn_cmdline_printf(pool, + Q_("Deleted %d matching credential from '%s'\n", + "Deleted %d matching credentials from '%s'\n", + b.matches), + b.matches, svn_dirent_local_style(config_path, pool))); } return SVN_NO_ERROR;
Modified: subversion/branches/addremove/subversion/svn/blame-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/blame-cmd.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/blame-cmd.c (original) +++ subversion/branches/addremove/subversion/svn/blame-cmd.c Sat May 23 14:16:56 2020 @@ -44,6 +44,7 @@ typedef struct blame_baton_t svn_stream_t *out; svn_stringbuf_t *sbuf; + svn_revnum_t start_revnum, end_revnum; int rev_maxlength; } blame_baton_t; @@ -54,15 +55,13 @@ typedef struct blame_baton_t XML to stdout. */ static svn_error_t * blame_receiver_xml(void *baton, - svn_revnum_t start_revnum, - svn_revnum_t end_revnum, apr_int64_t line_no, svn_revnum_t revision, apr_hash_t *rev_props, svn_revnum_t merged_revision, apr_hash_t *merged_rev_props, const char *merged_path, - const char *line, + const svn_string_t *line, svn_boolean_t local_change, apr_pool_t *pool) { @@ -170,15 +169,13 @@ print_line_info(svn_stream_t *out, /* This implements the svn_client_blame_receiver3_t interface. */ static svn_error_t * blame_receiver(void *baton, - svn_revnum_t start_revnum, - svn_revnum_t end_revnum, apr_int64_t line_no, svn_revnum_t revision, apr_hash_t *rev_props, svn_revnum_t merged_revision, apr_hash_t *merged_rev_props, const char *merged_path, - const char *line, + const svn_string_t *line, svn_boolean_t local_change, apr_pool_t *pool) { @@ -188,19 +185,19 @@ blame_receiver(void *baton, svn_boolean_t use_merged = FALSE; if (!bb->rev_maxlength) - { - svn_revnum_t max_revnum = MAX(start_revnum, end_revnum); - /* The standard column width for the revision number is 6 characters. - If the revision number can potentially be larger (i.e. if the end_revnum - is larger than 1000000), we increase the column width as needed. */ - - bb->rev_maxlength = 6; - while (max_revnum >= 1000000) - { - bb->rev_maxlength++; - max_revnum = max_revnum / 10; - } - } + { + svn_revnum_t max_revnum = MAX(bb->start_revnum, bb->end_revnum); + /* The standard column width for the revision number is 6 characters. + If the revision number can potentially be larger (i.e. if the end_revnum + is larger than 1000000), we increase the column width as needed. */ + + bb->rev_maxlength = 6; + while (max_revnum >= 1000000) + { + bb->rev_maxlength++; + max_revnum = max_revnum / 10; + } + } if (opt_state->use_merge_history) { @@ -237,7 +234,7 @@ blame_receiver(void *baton, bb->rev_maxlength, pool)); - return svn_stream_printf(out, pool, "%s%s", line, APR_EOL_STR); + return svn_stream_printf(out, pool, "%s%s", line->data, APR_EOL_STR); } @@ -333,7 +330,7 @@ svn_cl__blame(apr_getopt_t *os, const char *target = APR_ARRAY_IDX(targets, i, const char *); const char *truepath; svn_opt_revision_t peg_revision; - svn_client_blame_receiver3_t receiver; + svn_client_blame_receiver4_t receiver; svn_pool_clear(subpool); SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton)); @@ -368,7 +365,8 @@ svn_cl__blame(apr_getopt_t *os, else receiver = blame_receiver; - err = svn_client_blame5(truepath, + err = svn_client_blame6(&bl.start_revnum, &bl.end_revnum, + truepath, &peg_revision, &opt_state->start_revision, &opt_state->end_revision, Modified: subversion/branches/addremove/subversion/svn/cl.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/cl.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/cl.h (original) +++ subversion/branches/addremove/subversion/svn/cl.h Sat May 23 14:16:56 2020 @@ -32,6 +32,7 @@ #include <apr_tables.h> #include <apr_getopt.h> +#include "svn_types.h" #include "svn_wc.h" #include "svn_client.h" #include "svn_string.h" @@ -126,6 +127,16 @@ typedef enum svn_cl__show_revs_t { svn_cl__show_revs_t svn_cl__show_revs_from_word(const char *word); + +/* Unit types for file size conversion. */ +typedef enum svn_cl__size_unit_t + { + SVN_CL__SIZE_UNIT_NONE = 0, /* Default, no conversion. */ + SVN_CL__SIZE_UNIT_XML = -1, /* Conversion for XML output. */ + SVN_CL__SIZE_UNIT_BASE_10 = 1000, /* Use base-10 SI units. */ + SVN_CL__SIZE_UNIT_BASE_2 = 1024 /* Use base-2 SI units. */ + } svn_cl__size_unit_t; + /*** Command dispatch. ***/ @@ -178,6 +189,7 @@ typedef struct svn_cl__opt_state_t svn_boolean_t help; /* print usage message */ const char *auth_username; /* auth username */ const char *auth_password; /* auth password */ + svn_boolean_t auth_password_from_stdin; /* read password from stdin */ const char *extensions; /* subprocess extension args */ apr_array_header_t *targets; /* target list from file */ svn_boolean_t xml; /* output in xml, e.g., "svn log --xml" */ @@ -249,12 +261,20 @@ typedef struct svn_cl__opt_state_t svn_boolean_t mergeinfo_log; /* show log message in mergeinfo command */ svn_boolean_t remove_unversioned;/* remove unversioned items */ svn_boolean_t remove_ignored; /* remove ignored items */ + svn_boolean_t remove_added; /* reverting added item also removes it */ svn_boolean_t no_newline; /* do not output the trailing newline */ svn_boolean_t show_passwords; /* show cached passwords */ svn_boolean_t pin_externals; /* pin externals to last-changed revisions */ const char *show_item; /* print only the given item */ svn_boolean_t adds_as_modification; /* update 'add vs add' no tree conflict */ svn_boolean_t vacuum_pristines; /* remove unreferenced pristines */ + svn_boolean_t drop; /* drop shelf after successful unshelve */ + svn_cl__size_unit_t file_size_unit; /* file size format */ + enum svn_cl__viewspec_t { + svn_cl__viewspec_unspecified = 0 /* default */, + svn_cl__viewspec_classic, + svn_cl__viewspec_svn11 + } viewspec; /* value of --x-viewspec */ } svn_cl__opt_state_t; /* Conflict stats for operations such as update and merge. */ @@ -268,6 +288,103 @@ typedef struct svn_cl__cmd_baton_t } svn_cl__cmd_baton_t; +/* Add an identifier here for long options that don't have a short + option. Options that have both long and short options should just + use the short option letter as identifier. */ +typedef enum svn_cl__longopt_t { + opt_auth_password = SVN_OPT_FIRST_LONGOPT_ID, + opt_auth_password_from_stdin, + opt_auth_username, + opt_autoprops, + opt_changelist, + opt_config_dir, + opt_config_options, + /* diff options */ + opt_diff_cmd, + opt_internal_diff, + opt_no_diff_added, + opt_no_diff_deleted, + opt_show_copies_as_adds, + opt_notice_ancestry, + opt_summarize, + opt_use_git_diff_format, + opt_ignore_properties, + opt_properties_only, + opt_patch_compatible, + /* end of diff options */ + opt_dry_run, + opt_editor_cmd, + opt_encoding, + opt_force_log, + opt_force, + opt_keep_changelists, + opt_ignore_ancestry, + opt_ignore_externals, + opt_incremental, + opt_merge_cmd, + opt_native_eol, + opt_new_cmd, + opt_no_auth_cache, + opt_no_autoprops, + opt_no_ignore, + opt_no_unlock, + opt_non_interactive, + opt_force_interactive, + opt_old_cmd, + opt_record_only, + opt_relocate, + opt_remove, + opt_revprop, + opt_stop_on_copy, + opt_strict, /* ### DEPRECATED */ + opt_targets, + opt_depth, + opt_set_depth, + opt_version, + opt_xml, + opt_keep_local, + opt_with_revprop, + opt_with_all_revprops, + opt_with_no_revprops, + opt_parents, + opt_accept, + opt_show_revs, + opt_reintegrate, + opt_trust_server_cert, + opt_trust_server_cert_failures, + opt_strip, + opt_ignore_keywords, + opt_reverse_diff, + opt_ignore_whitespace, + opt_diff, + opt_allow_mixed_revisions, + opt_include_externals, + opt_show_inherited_props, + opt_search, + opt_search_and, + opt_mergeinfo_log, + opt_remove_unversioned, + opt_remove_ignored, + opt_remove_added, + opt_no_newline, + opt_show_passwords, + opt_pin_externals, + opt_show_item, + opt_adds_as_modification, + opt_vacuum_pristines, + opt_drop, + opt_viewspec, +} svn_cl__longopt_t; + +/* Options for giving a log message. (Some of these also have other uses.) + */ +#define SVN_CL__LOG_MSG_OPTIONS 'm', 'F', \ + opt_force_log, \ + opt_editor_cmd, \ + opt_encoding, \ + opt_with_revprop + + /* Declare all the command procedures */ svn_opt_subcommand_t svn_cl__add, @@ -311,7 +428,7 @@ svn_opt_subcommand_t /* See definition in svn.c for documentation. */ -extern const svn_opt_subcommand_desc2_t svn_cl__cmd_table[]; +extern const svn_opt_subcommand_desc3_t *svn_cl__cmd_table; /* See definition in svn.c for documentation. */ extern const int svn_cl__global_options[]; @@ -385,7 +502,7 @@ svn_error_t * svn_cl__print_conflict_stats(svn_cl__conflict_stats_t *conflict_stats, apr_pool_t *scratch_pool); -/* +/* * Interactively resolve the conflict a @a CONFLICT. * TODO: more docs */ @@ -402,7 +519,7 @@ svn_cl__resolve_conflict(svn_boolean_t * svn_client_ctx_t *ctx, apr_pool_t *scratch_pool); -/* +/* * Interactively resolve conflicts for all TARGETS. * TODO: more docs */ @@ -417,7 +534,7 @@ svn_cl__walk_conflicts(apr_array_header_ /*** Command-line output functions -- printing to the user. ***/ /* Print out commit information found in COMMIT_INFO to the console. - * POOL is used for temporay allocations. + * POOL is used for temporary allocations. * COMMIT_INFO should not be NULL. * * This function implements svn_commit_callback2_t. @@ -707,6 +824,24 @@ svn_cl__node_kind_str_xml(svn_node_kind_ const char * svn_cl__node_kind_str_human_readable(svn_node_kind_t kind); +/* Set *RESULT to the size of a file, formatted according to BASE. + For base-10 and base-2 units, the size is constrained to at most + three significant digits. + + If LONG_UNITS is TRUE, any unit suffixes will be the whole SI symbol, + e.g., KiB, MiB, etc; otherwise only the first letters will be used. + + File sizes are never negative, so we don't handle that case other than + making sure that the scale adjustment will work. + + The result will be allocated from RESULT_POOL. */ +svn_error_t * +svn_cl__format_file_size(const char **result, + svn_filesize_t size, + svn_cl__size_unit_t base, + svn_boolean_t long_units, + apr_pool_t *result_pool); + /** Provides an XML name for a given OPERATION. * Note: POOL is currently not used. @@ -739,7 +874,7 @@ svn_cl__prop_use_t; * * - start with svn: but do not exactly match a known property; or, * - start with a 3-letter prefix that differs in only one letter - * from "svn:", and the rest exactly matches a known propery. + * from "svn:", and the rest exactly matches a known properly. * * If REVPROP is TRUE, only check revision property names; otherwise * only check node property names. @@ -911,6 +1046,20 @@ svn_cl__similarity_check(const char *key apr_size_t token_count, apr_pool_t *scratch_pool); +/* Return in FUNC_P and BATON_P a callback that prints a summary diff, + * according to the options XML and IGNORE_PROPERTIES. + * + * ANCHOR is a URL or local path to be prefixed to the printed paths. + */ +svn_error_t * +svn_cl__get_diff_summary_writer(svn_client_diff_summarize_func_t *func_p, + void **baton_p, + svn_boolean_t xml, + svn_boolean_t ignore_properties, + const char *anchor, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + #ifdef __cplusplus } #endif /* __cplusplus */ Modified: subversion/branches/addremove/subversion/svn/conflict-callbacks.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/conflict-callbacks.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/conflict-callbacks.c (original) +++ subversion/branches/addremove/subversion/svn/conflict-callbacks.c Sat May 23 14:16:56 2020 @@ -115,7 +115,7 @@ show_diff(svn_client_conflict_t *conflic * as it appears after the merge operation). * * For conflicts recorded by the 'update' and 'switch' operations, - * show a diff beween 'theirs' (the new pristine version of the + * show a diff between 'theirs' (the new pristine version of the * file) and 'merged' (the version of the file as it appears with * local changes merged with the new pristine version). * @@ -234,7 +234,7 @@ merge_prop_conflict(svn_stream_t *output my_propval = svn_string_create_empty(pool); if (their_propval == NULL) their_propval = svn_string_create_empty(pool); - + options->ignore_eol_style = TRUE; SVN_ERR(svn_diff_mem_string_diff3(&diff, base_propval, merged_propval ? @@ -361,7 +361,7 @@ edit_prop_conflict(const svn_string_t ** svn_stringbuf_t *buf; SVN_ERR(svn_stringbuf_from_file2(&buf, file_path, scratch_pool)); - *merged_propval = svn_string_create_from_buf(buf, result_pool); + *merged_propval = svn_string_create_from_buf(buf, result_pool); } return SVN_NO_ERROR; @@ -440,6 +440,17 @@ static const resolver_option_t builtin_r /* Options for local move vs incoming edit. */ { "m", svn_client_conflict_option_local_move_file_text_merge }, + { "m", svn_client_conflict_option_local_move_dir_merge }, + + /* Options for local missing vs incoming edit. */ + { "m", svn_client_conflict_option_sibling_move_file_text_merge }, + { "m", svn_client_conflict_option_sibling_move_dir_merge }, + + /* Options for incoming move vs local move. */ + { "m", svn_client_conflict_option_both_moved_file_merge }, + { "M", svn_client_conflict_option_both_moved_file_move_merge }, + { "m", svn_client_conflict_option_both_moved_dir_merge }, + { "M", svn_client_conflict_option_both_moved_dir_move_merge }, { NULL } }; @@ -889,7 +900,7 @@ handle_text_conflict(svn_boolean_t *reso const char *their_abspath; const char *merged_abspath = svn_client_conflict_get_local_abspath(conflict); apr_array_header_t *text_conflict_options; - svn_client_conflict_option_id_t option_id; + svn_client_conflict_option_id_t option_id; option_id = svn_client_conflict_option_unspecified; @@ -1506,7 +1517,7 @@ build_tree_conflict_options( iterpool)); if (opt == NULL) { - /* Unkown option. Assign a dynamic option code. */ + /* Unknown option. Assign a dynamic option code. */ opt = apr_pcalloc(result_pool, sizeof(*opt)); opt->code = apr_psprintf(result_pool, "%d", next_unknown_option_code); next_unknown_option_code++; @@ -1529,17 +1540,16 @@ build_tree_conflict_options( id != svn_client_conflict_option_accept_current_wc_state) *all_options_are_dumb = FALSE; - if (id == svn_client_conflict_option_incoming_move_file_text_merge || - id == svn_client_conflict_option_incoming_move_dir_merge) - { - SVN_ERR( - svn_client_conflict_option_get_moved_to_repos_relpath_candidates( - possible_moved_to_repos_relpaths, builtin_option, - result_pool, iterpool)); - SVN_ERR(svn_client_conflict_option_get_moved_to_abspath_candidates( - possible_moved_to_abspaths, builtin_option, - result_pool, iterpool)); - } + if (*possible_moved_to_repos_relpaths == NULL) + SVN_ERR( + svn_client_conflict_option_get_moved_to_repos_relpath_candidates2( + possible_moved_to_repos_relpaths, builtin_option, + result_pool, iterpool)); + + if (*possible_moved_to_abspaths == NULL) + SVN_ERR(svn_client_conflict_option_get_moved_to_abspath_candidates2( + possible_moved_to_abspaths, builtin_option, + result_pool, iterpool)); } svn_pool_destroy(iterpool); @@ -1549,11 +1559,11 @@ build_tree_conflict_options( /* Add move target choice options only if there are multiple * move targets to choose from. */ if (strcmp(o->code, "d") == 0 && - (*possible_moved_to_repos_relpaths == NULL || + (*possible_moved_to_repos_relpaths == NULL || (*possible_moved_to_repos_relpaths)->nelts <= 1)) continue; if (strcmp(o->code, "w") == 0 && - (*possible_moved_to_abspaths == NULL || + (*possible_moved_to_abspaths == NULL || (*possible_moved_to_abspaths)->nelts <= 1)) continue; @@ -1654,8 +1664,8 @@ prompt_move_target_path(int *preferred_m { char buf[1024]; - svn_cmdline_fprintf(stderr, iterpool, "%s\n", - svn_err_best_message(err, buf, sizeof(buf))); + SVN_ERR(svn_cmdline_fprintf(stderr, iterpool, "%s\n", + svn_err_best_message(err, buf, sizeof(buf)))); svn_error_clear(err); continue; } @@ -1670,6 +1680,69 @@ prompt_move_target_path(int *preferred_m return SVN_NO_ERROR; } +static svn_error_t * +find_conflict_option_with_repos_move_targets( + svn_client_conflict_option_t **option_with_move_targets, + apr_array_header_t *options, + apr_pool_t *scratch_pool) +{ + apr_pool_t *iterpool = svn_pool_create(scratch_pool); + int i; + apr_array_header_t *possible_moved_to_repos_relpaths = NULL; + + *option_with_move_targets = NULL; + + for (i = 0; i < options->nelts; i++) + { + svn_client_conflict_option_t *option; + + svn_pool_clear(iterpool); + option = APR_ARRAY_IDX(options, i, svn_client_conflict_option_t *); + SVN_ERR(svn_client_conflict_option_get_moved_to_repos_relpath_candidates2( + &possible_moved_to_repos_relpaths, option, iterpool, iterpool)); + if (possible_moved_to_repos_relpaths) + { + *option_with_move_targets = option; + break; + } + } + svn_pool_destroy(iterpool); + + return SVN_NO_ERROR; +} + +static svn_error_t * +find_conflict_option_with_working_copy_move_targets( + svn_client_conflict_option_t **option_with_move_targets, + apr_array_header_t *options, + apr_pool_t *scratch_pool) +{ + apr_pool_t *iterpool = svn_pool_create(scratch_pool); + int i; + apr_array_header_t *possible_moved_to_abspaths = NULL; + + *option_with_move_targets = NULL; + + for (i = 0; i < options->nelts; i++) + { + svn_client_conflict_option_t *option; + + svn_pool_clear(iterpool); + option = APR_ARRAY_IDX(options, i, svn_client_conflict_option_t *); + SVN_ERR(svn_client_conflict_option_get_moved_to_abspath_candidates2( + &possible_moved_to_abspaths, option, scratch_pool, + iterpool)); + if (possible_moved_to_abspaths) + { + *option_with_move_targets = option; + break; + } + } + svn_pool_destroy(iterpool); + + return SVN_NO_ERROR; +} + /* Ask the user what to do about the tree conflict described by CONFLICT * and either resolve the conflict accordingly or postpone resolution. * SCRATCH_POOL is used for temporary allocations. */ @@ -1797,7 +1870,7 @@ handle_tree_conflict(svn_boolean_t *reso { int preferred_move_target_idx; apr_array_header_t *options; - svn_client_conflict_option_t *conflict_option; + svn_client_conflict_option_t *option; SVN_ERR(prompt_move_target_path(&preferred_move_target_idx, possible_moved_to_repos_relpaths, @@ -1810,22 +1883,12 @@ handle_tree_conflict(svn_boolean_t *reso ctx, iterpool, iterpool)); - conflict_option = - svn_client_conflict_option_find_by_id( - options, - svn_client_conflict_option_incoming_move_file_text_merge); - if (conflict_option == NULL) + SVN_ERR(find_conflict_option_with_repos_move_targets( + &option, options, iterpool)); + if (option) { - conflict_option = - svn_client_conflict_option_find_by_id( - options, svn_client_conflict_option_incoming_move_dir_merge); - } - - if (conflict_option) - { - SVN_ERR(svn_client_conflict_option_set_moved_to_repos_relpath( - conflict_option, preferred_move_target_idx, - ctx, iterpool)); + SVN_ERR(svn_client_conflict_option_set_moved_to_repos_relpath2( + option, preferred_move_target_idx, ctx, iterpool)); repos_move_target_chosen = TRUE; wc_move_target_chosen = FALSE; @@ -1851,7 +1914,7 @@ handle_tree_conflict(svn_boolean_t *reso { int preferred_move_target_idx; apr_array_header_t *options; - svn_client_conflict_option_t *conflict_option; + svn_client_conflict_option_t *option; SVN_ERR(prompt_move_target_path(&preferred_move_target_idx, possible_moved_to_abspaths, TRUE, @@ -1863,22 +1926,12 @@ handle_tree_conflict(svn_boolean_t *reso ctx, iterpool, iterpool)); - conflict_option = - svn_client_conflict_option_find_by_id( - options, - svn_client_conflict_option_incoming_move_file_text_merge); - if (conflict_option == NULL) - { - conflict_option = - svn_client_conflict_option_find_by_id( - options, svn_client_conflict_option_incoming_move_dir_merge); - } - - if (conflict_option) + SVN_ERR(find_conflict_option_with_working_copy_move_targets( + &option, options, iterpool)); + if (option) { - SVN_ERR(svn_client_conflict_option_set_moved_to_abspath( - conflict_option, preferred_move_target_idx, ctx, - iterpool)); + SVN_ERR(svn_client_conflict_option_set_moved_to_abspath2( + option, preferred_move_target_idx, ctx, iterpool)); wc_move_target_chosen = TRUE; /* Update option description. */ @@ -1930,7 +1983,6 @@ resolve_conflict_interactively(svn_boole svn_cmdline_prompt_baton_t *pb, svn_cl__conflict_stats_t *conflict_stats, svn_client_ctx_t *ctx, - apr_pool_t *result_pool, apr_pool_t *scratch_pool) { svn_boolean_t text_conflicted; @@ -1964,7 +2016,7 @@ resolve_conflict_interactively(svn_boole if (props_conflicted->nelts > 0) SVN_ERR(handle_prop_conflicts(resolved, postponed, quit, &merged_propval, path_prefix, pb, editor_cmd, config, conflict, - conflict_stats, ctx, result_pool, scratch_pool)); + conflict_stats, ctx, scratch_pool, scratch_pool)); if (tree_conflicted) SVN_ERR(handle_tree_conflict(resolved, postponed, quit, printed_description, conflict, path_prefix, pb, conflict_stats, ctx, @@ -2201,11 +2253,14 @@ svn_cl__resolve_conflict(svn_boolean_t * svn_boolean_t postponed = FALSE; svn_boolean_t printed_description = FALSE; svn_error_t *err; + apr_pool_t *iterpool; *quit = FALSE; + iterpool = svn_pool_create(scratch_pool); while (!resolved && !postponed && !*quit) { + svn_pool_clear(iterpool); err = resolve_conflict_interactively(&resolved, &postponed, quit, external_failed, printed_summary, @@ -2214,7 +2269,7 @@ svn_cl__resolve_conflict(svn_boolean_t * editor_cmd, ctx->config, path_prefix, pb, conflict_stats, ctx, - scratch_pool, scratch_pool); + iterpool); if (err && err->apr_err == SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE) { /* Conflict resolution has failed. Let the user try again. @@ -2226,6 +2281,7 @@ svn_cl__resolve_conflict(svn_boolean_t * } SVN_ERR(err); } + svn_pool_destroy(iterpool); } else if (option_id != svn_client_conflict_option_postpone) SVN_ERR(mark_conflict_resolved(conflict, option_id, Modified: subversion/branches/addremove/subversion/svn/diff-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/diff-cmd.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/diff-cmd.c (original) +++ subversion/branches/addremove/subversion/svn/diff-cmd.c Sat May 23 14:16:56 2020 @@ -181,6 +181,24 @@ summarize_regular(const svn_client_diff_ return svn_cmdline_fflush(stdout); } +svn_error_t * +svn_cl__get_diff_summary_writer(svn_client_diff_summarize_func_t *func_p, + void **baton_p, + svn_boolean_t xml, + svn_boolean_t ignore_properties, + const char *anchor, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + struct summarize_baton_t *b = apr_pcalloc(result_pool, sizeof(*b)); + + b->anchor = anchor; + b->ignore_properties = ignore_properties; + *func_p = xml ? summarize_xml : summarize_regular; + *baton_p = b; + return SVN_NO_ERROR; +} + /* An svn_opt_subcommand_t to handle the 'diff' command. This implements the `svn_opt_subcommand_t' interface. */ svn_error_t * @@ -203,9 +221,6 @@ svn_cl__diff(apr_getopt_t *os, svn_boolean_t ignore_properties = opt_state->diff.patch_compatible || opt_state->diff.ignore_properties; int i; - struct summarize_baton_t summarize_baton; - const svn_client_diff_summarize_func_t summarize_func = - (opt_state->xml ? summarize_xml : summarize_regular); if (opt_state->extensions) options = svn_cstring_split(opt_state->extensions, " \t\n\r", TRUE, pool); @@ -448,9 +463,13 @@ svn_cl__diff(apr_getopt_t *os, if (opt_state->diff.summarize) { - summarize_baton.anchor = target1; - summarize_baton.ignore_properties = ignore_properties; + svn_client_diff_summarize_func_t summarize_func; + void *summarize_baton; + SVN_ERR(svn_cl__get_diff_summary_writer( + &summarize_func, &summarize_baton, + opt_state->xml, ignore_properties, target1, + iterpool, iterpool)); SVN_ERR(svn_client_diff_summarize2( target1, &opt_state->start_revision, @@ -459,11 +478,11 @@ svn_cl__diff(apr_getopt_t *os, opt_state->depth, ! opt_state->diff.notice_ancestry, opt_state->changelists, - summarize_func, &summarize_baton, + summarize_func, summarize_baton, ctx, iterpool)); } else - SVN_ERR(svn_client_diff6( + SVN_ERR(svn_client_diff7( options, target1, &(opt_state->start_revision), @@ -479,6 +498,7 @@ svn_cl__diff(apr_getopt_t *os, ignore_properties, opt_state->diff.properties_only, opt_state->diff.use_git_diff_format, + TRUE /*pretty_print_mergeinfo*/, svn_cmdline_output_encoding(pool), outstream, errstream, @@ -501,8 +521,13 @@ svn_cl__diff(apr_getopt_t *os, if (opt_state->diff.summarize) { - summarize_baton.anchor = truepath; - summarize_baton.ignore_properties = ignore_properties; + svn_client_diff_summarize_func_t summarize_func; + void *summarize_baton; + + SVN_ERR(svn_cl__get_diff_summary_writer( + &summarize_func, &summarize_baton, + opt_state->xml, ignore_properties, truepath, + iterpool, iterpool)); SVN_ERR(svn_client_diff_summarize_peg2( truepath, &peg_revision, @@ -511,11 +536,11 @@ svn_cl__diff(apr_getopt_t *os, opt_state->depth, ! opt_state->diff.notice_ancestry, opt_state->changelists, - summarize_func, &summarize_baton, + summarize_func, summarize_baton, ctx, iterpool)); } else - SVN_ERR(svn_client_diff_peg6( + SVN_ERR(svn_client_diff_peg7( options, truepath, &peg_revision, @@ -531,6 +556,7 @@ svn_cl__diff(apr_getopt_t *os, ignore_properties, opt_state->diff.properties_only, opt_state->diff.use_git_diff_format, + TRUE /*pretty_print_mergeinfo*/, svn_cmdline_output_encoding(pool), outstream, errstream, Modified: subversion/branches/addremove/subversion/svn/help-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/help-cmd.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/help-cmd.c (original) +++ subversion/branches/addremove/subversion/svn/help-cmd.c Sat May 23 14:16:56 2020 @@ -148,22 +148,25 @@ svn_cl__help(apr_getopt_t *os, _("\nThe following authentication credential caches are available:\n\n")); /*### There is no API to query available providers at run time. */ + if (config_path) + { #if (defined(WIN32) && !defined(__MINGW32__)) - version_footer = - svn_stringbuf_create(apr_psprintf(pool, _("%s* Wincrypt cache in %s\n"), - version_footer->data, - svn_dirent_local_style(config_path, - pool)), - pool); + version_footer = + svn_stringbuf_create(apr_psprintf(pool, _("%s* Wincrypt cache in %s\n"), + version_footer->data, + svn_dirent_local_style(config_path, + pool)), + pool); #elif !defined(SVN_DISABLE_PLAINTEXT_PASSWORD_STORAGE) - version_footer = - svn_stringbuf_create(apr_psprintf(pool, _("%s* Plaintext cache in %s\n"), - version_footer->data, - svn_dirent_local_style(config_path, - pool)), - pool); + version_footer = + svn_stringbuf_create(apr_psprintf(pool, _("%s* Plaintext cache in %s\n"), + version_footer->data, + svn_dirent_local_style(config_path, + pool)), + pool); #endif -#ifdef SVN_HAVE_GNOME_KEYRING + } +#if (defined(SVN_HAVE_GNOME_KEYRING) || defined(SVN_HAVE_LIBSECRET)) svn_stringbuf_appendcstr(version_footer, "* Gnome Keyring\n"); #endif #ifdef SVN_HAVE_GPG_AGENT @@ -176,7 +179,7 @@ svn_cl__help(apr_getopt_t *os, svn_stringbuf_appendcstr(version_footer, "* KWallet (KDE)\n"); #endif - return svn_opt_print_help4(os, + return svn_opt_print_help5(os, "svn", /* ### erm, derive somehow? */ opt_state ? opt_state->version : FALSE, opt_state ? opt_state->quiet : FALSE, Modified: subversion/branches/addremove/subversion/svn/info-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/info-cmd.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/info-cmd.c (original) +++ subversion/branches/addremove/subversion/svn/info-cmd.c Sat May 23 14:16:56 2020 @@ -21,6 +21,10 @@ * ==================================================================== */ +/* We define this here to remove any further warnings about the usage of + experimental functions in this file. */ +#define SVN_EXPERIMENTAL + /* ==================================================================== */ @@ -45,6 +49,254 @@ /*** Code. ***/ +struct layout_list_baton_t +{ + svn_boolean_t checkout; + const char *target; + const char *target_abspath; + svn_boolean_t with_revs; + int vs_py_format; +}; + +/* Output as 'svn' command-line commands. + * + * Implements svn_client__layout_func_t + */ +static svn_error_t * +output_svn_command_line(void *layout_baton, + const char *local_abspath, + const char *repos_root_url, + svn_boolean_t not_present, + svn_boolean_t url_changed, + const char *url, + svn_boolean_t revision_changed, + svn_revnum_t revision, + svn_boolean_t depth_changed, + svn_depth_t depth, + apr_pool_t *scratch_pool) +{ + struct layout_list_baton_t *llb = layout_baton; + const char *relpath = svn_dirent_skip_ancestor(llb->target_abspath, + local_abspath); + const char *cmd; + const char *depth_str; + const char *url_rev_str; + + depth_str = (depth_changed + ? apr_psprintf(scratch_pool, " --set-depth=%s", + svn_depth_to_word(depth)) + : ""); + + if (llb->checkout) + { + cmd = "svn checkout"; + if (depth != svn_depth_infinity) + depth_str = apr_psprintf(scratch_pool, + " --depth=%s", svn_depth_to_word(depth)); + url_rev_str = apr_psprintf(scratch_pool, " %s", url); + if (llb->with_revs) + url_rev_str = apr_psprintf(scratch_pool, "%s@%ld", + url_rev_str, revision); + llb->checkout = FALSE; + } + else if (not_present) + { + /* Easiest way to create a not present node: update to r0 */ + cmd = "svn update"; + url_rev_str = " -r0"; + } + else if (url_changed) + { + cmd = "svn switch"; + url_rev_str = apr_psprintf(scratch_pool, " ^/%s", + svn_uri_skip_ancestor(repos_root_url, + url, scratch_pool)); + if (llb->with_revs) + url_rev_str = apr_psprintf(scratch_pool, "%s@%ld", + url_rev_str, revision); + } + else if (llb->with_revs && revision_changed) + { + cmd = "svn update"; + url_rev_str = apr_psprintf(scratch_pool, " -r%ld", revision); + } + else if (depth_changed) + { + cmd = "svn update"; + url_rev_str = ""; + } + else + return SVN_NO_ERROR; + + SVN_ERR(svn_cmdline_printf(scratch_pool, + "%s%-23s%-10s %s\n", + cmd, depth_str, url_rev_str, + svn_dirent_local_style( + svn_dirent_join(llb->target, relpath, + scratch_pool), scratch_pool))); + + return SVN_NO_ERROR; +} + +/* */ +static const char * +depth_to_viewspec_py(svn_depth_t depth, + apr_pool_t *result_pool) +{ + switch (depth) + { + case svn_depth_infinity: + return "/**"; + case svn_depth_immediates: + return "/*"; + case svn_depth_files: + return "/~"; + case svn_depth_empty: + return ""; + case svn_depth_exclude: + return "!"; + default: + break; + } + return NULL; +} + +/* Output in the format used by 'tools/client-side/viewspec.py' + * + * Implements svn_client__layout_func_t + */ +static svn_error_t * +output_svn_viewspec_py(void *layout_baton, + const char *local_abspath, + const char *repos_root_url, + svn_boolean_t not_present, + svn_boolean_t url_changed, + const char *url, + svn_boolean_t revision_changed, + svn_revnum_t revision, + svn_boolean_t depth_changed, + svn_depth_t depth, + apr_pool_t *scratch_pool) +{ + struct layout_list_baton_t *llb = layout_baton; + const char *relpath = svn_dirent_skip_ancestor(llb->target_abspath, + local_abspath); + const char *depth_str; + const char *rev_str = ""; + const char *repos_rel_url = ""; + + depth_str = ((depth_changed || llb->checkout) + ? depth_to_viewspec_py(depth, scratch_pool) + : ""); + if (! llb->with_revs) + revision_changed = FALSE; + if (revision_changed) + rev_str = apr_psprintf(scratch_pool, "@%ld", revision); + + if (llb->checkout) + { + SVN_ERR(svn_cmdline_printf(scratch_pool, + "Format: %d\n" + "Url: %s\n", + llb->vs_py_format, url)); + if (llb->with_revs) + SVN_ERR(svn_cmdline_printf(scratch_pool, + "Revision: %ld\n", + revision)); + SVN_ERR(svn_cmdline_printf(scratch_pool, "\n")); + llb->checkout = FALSE; + + if (depth == svn_depth_empty) + return SVN_NO_ERROR; + if (depth_str[0] == '/') + depth_str++; + } + else if (not_present) + { + /* Easiest way to create a not present node: update to r0 */ + if (llb->vs_py_format < 2) + return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL, + _("svn-viewspec.py format 1 does not support " + "the 'not-present' state found at '%s'"), + relpath); + rev_str = "@0"; + } + else if (url_changed) + { + if (llb->vs_py_format < 2) + return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL, + _("svn-viewspec.py format 1 does not support " + "the 'switched' state found at '%s'"), + relpath); + repos_rel_url = svn_uri_skip_ancestor(repos_root_url, url, + scratch_pool); + repos_rel_url = apr_psprintf(scratch_pool, "^/%s", repos_rel_url); + } + else if (!(revision_changed || depth_changed)) + return SVN_NO_ERROR; + + SVN_ERR(svn_cmdline_printf(scratch_pool, + "%s%s %s%s\n", + relpath, depth_str, repos_rel_url, rev_str)); + + return SVN_NO_ERROR; +} + +/* + * Call svn_client__layout_list(), using a receiver function decided + * by VIEWSPEC. + */ +static svn_error_t * +cl_layout_list(apr_array_header_t *targets, + enum svn_cl__viewspec_t viewspec, + void *baton, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool) +{ + const char *list_path, *list_abspath; + struct layout_list_baton_t llb; + + /* Add "." if user passed 0 arguments */ + svn_opt_push_implicit_dot_target(targets, scratch_pool); + + if (targets->nelts > 1) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL); + + list_path = APR_ARRAY_IDX(targets, 0, const char *); + + SVN_ERR(svn_cl__check_target_is_local_path(list_path)); + + SVN_ERR(svn_dirent_get_absolute(&list_abspath, list_path, + scratch_pool)); + + llb.checkout = TRUE; + llb.target = list_path; + llb.target_abspath = list_abspath; + llb.with_revs = TRUE; + + switch (viewspec) + { + case svn_cl__viewspec_classic: + /* svn-viewspec.py format */ + llb.vs_py_format = 2; + + SVN_ERR(svn_client__layout_list(list_abspath, + output_svn_viewspec_py, &llb, + ctx, scratch_pool)); + break; + case svn_cl__viewspec_svn11: + /* svn command-line format */ + SVN_ERR(svn_client__layout_list(list_abspath, + output_svn_command_line, &llb, + ctx, scratch_pool)); + break; + default: + SVN_ERR_MALFUNCTION(); + } + + return SVN_NO_ERROR; +} + static svn_error_t * svn_cl__info_print_time(apr_time_t atime, const char *desc, @@ -100,6 +352,7 @@ typedef enum info_item_relative_url, info_item_repos_root_url, info_item_repos_uuid, + info_item_repos_size, /* Working copy revision or repository HEAD revision */ info_item_revision, @@ -110,7 +363,10 @@ typedef enum info_item_last_changed_author, /* Working copy information */ - info_item_wc_root + info_item_wc_root, + info_item_schedule, + info_item_depth, + info_item_changelist } info_item_t; /* Mapping between option keywords and info_item_t. */ @@ -128,12 +384,16 @@ static const info_item_map_t info_item_m { MAKE_STRING("relative-url"), info_item_relative_url }, { MAKE_STRING("repos-root-url"), info_item_repos_root_url }, { MAKE_STRING("repos-uuid"), info_item_repos_uuid }, + { MAKE_STRING("repos-size"), info_item_repos_size }, { MAKE_STRING("revision"), info_item_revision }, { MAKE_STRING("last-changed-revision"), info_item_last_changed_rev }, { MAKE_STRING("last-changed-date"), info_item_last_changed_date }, { MAKE_STRING("last-changed-author"), info_item_last_changed_author }, - { MAKE_STRING("wc-root"), info_item_wc_root } + { MAKE_STRING("wc-root"), info_item_wc_root }, + { MAKE_STRING("schedule"), info_item_schedule }, + { MAKE_STRING("depth"), info_item_depth }, + { MAKE_STRING("changelist"), info_item_changelist }, }; #undef MAKE_STRING @@ -163,6 +423,9 @@ typedef struct print_info_baton_t /* Did we already print a line of output? */ svn_boolean_t start_new_line; + /* Format for file sizes */ + svn_cl__size_unit_t file_size_unit; + /* The client context. */ svn_client_ctx_t *ctx; } print_info_baton_t; @@ -251,21 +514,40 @@ print_info_xml(void *baton, apr_pool_t *pool) { svn_stringbuf_t *sb = svn_stringbuf_create_empty(pool); - const char *rev_str; print_info_baton_t *const receiver_baton = baton; - if (SVN_IS_VALID_REVNUM(info->rev)) - rev_str = apr_psprintf(pool, "%ld", info->rev); - else - rev_str = apr_pstrdup(pool, _("Resource is not under version control.")); + const char *const path_str = + svn_cl__local_style_skip_ancestor( + receiver_baton->path_prefix, target, pool); + const char *const kind_str = svn_cl__node_kind_str_xml(info->kind); + const char *const rev_str = + (SVN_IS_VALID_REVNUM(info->rev) + ? apr_psprintf(pool, "%ld", info->rev) + : apr_pstrdup(pool, _("Resource is not under version control."))); /* "<entry ...>" */ - svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry", - "path", svn_cl__local_style_skip_ancestor( - receiver_baton->path_prefix, target, pool), - "kind", svn_cl__node_kind_str_xml(info->kind), - "revision", rev_str, - SVN_VA_NULL); + if (info->kind == svn_node_file && info->size != SVN_INVALID_FILESIZE) + { + const char *size_str; + SVN_ERR(svn_cl__format_file_size(&size_str, info->size, + SVN_CL__SIZE_UNIT_XML, + FALSE, pool)); + + svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry", + "path", path_str, + "kind", kind_str, + "revision", rev_str, + "size", size_str, + SVN_VA_NULL); + } + else + { + svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry", + "path", path_str, + "kind", kind_str, + "revision", rev_str, + SVN_VA_NULL); + } /* "<url> xx </url>" */ svn_cl__xml_tagged_cdata(&sb, pool, "url", info->URL); @@ -487,6 +769,16 @@ print_info(void *baton, break; } + if (info->kind == svn_node_file && info->size != SVN_INVALID_FILESIZE) + { + const char *sizestr; + SVN_ERR(svn_cl__format_file_size(&sizestr, info->size, + receiver_baton->file_size_unit, + TRUE, pool)); + SVN_ERR(svn_cmdline_printf(pool, _("Size in Repository: %s\n"), + sizestr)); + } + if (info->wc_info) { switch (info->wc_info->schedule) @@ -827,11 +1119,12 @@ print_info_item(void *baton, apr_pool_t *pool) { print_info_baton_t *const receiver_baton = baton; + const char *const actual_target_path = + (!receiver_baton->target_is_path ? info->URL + : svn_cl__local_style_skip_ancestor( + receiver_baton->path_prefix, target, pool)); const char *const target_path = - (!receiver_baton->multiple_targets ? NULL - : (!receiver_baton->target_is_path ? info->URL - : svn_cl__local_style_skip_ancestor( - receiver_baton->path_prefix, target, pool))); + (receiver_baton->multiple_targets ? actual_target_path : NULL); if (receiver_baton->start_new_line) SVN_ERR(svn_cmdline_fputs("\n", stdout, pool)); @@ -860,6 +1153,36 @@ print_info_item(void *baton, SVN_ERR(print_info_item_string(info->repos_UUID, target_path, pool)); break; + case info_item_repos_size: + if (info->kind != svn_node_file) + { + receiver_baton->start_new_line = FALSE; + return SVN_NO_ERROR; + } + + if (info->size == SVN_INVALID_FILESIZE) + { + if (receiver_baton->multiple_targets) + { + receiver_baton->start_new_line = FALSE; + return SVN_NO_ERROR; + } + + return svn_error_createf( + SVN_ERR_UNSUPPORTED_FEATURE, NULL, + _("can't show in-repository size of working copy file '%s'"), + actual_target_path); + } + + { + const char *sizestr; + SVN_ERR(svn_cl__format_file_size(&sizestr, info->size, + receiver_baton->file_size_unit, + TRUE, pool)); + SVN_ERR(print_info_item_string(sizestr, target_path, pool)); + } + break; + case info_item_revision: SVN_ERR(print_info_item_revision(info->rev, target_path, pool)); break; @@ -888,6 +1211,27 @@ print_info_item(void *baton, target_path, pool)); break; + case info_item_schedule: + SVN_ERR(print_info_item_string( + (info->wc_info + ? schedule_str(info->wc_info->schedule) : NULL), + target_path, pool)); + break; + + case info_item_depth: + SVN_ERR(print_info_item_string( + ((info->wc_info && info->kind == svn_node_dir) + ? svn_depth_to_word(info->wc_info->depth) : NULL), + target_path, pool)); + break; + + case info_item_changelist: + SVN_ERR(print_info_item_string( + ((info->wc_info && info->wc_info->changelist) + ? info->wc_info->changelist : NULL), + target_path, pool)); + break; + default: SVN_ERR_MALFUNCTION(); } @@ -918,10 +1262,17 @@ svn_cl__info(apr_getopt_t *os, opt_state->targets, ctx, FALSE, pool)); + if (opt_state->viewspec) + { + SVN_ERR(cl_layout_list(targets, opt_state->viewspec, baton, ctx, pool)); + return SVN_NO_ERROR; + } + /* Add "." if user passed 0 arguments. */ svn_opt_push_implicit_dot_target(targets, pool); receiver_baton.ctx = ctx; + receiver_baton.file_size_unit = opt_state->file_size_unit; if (opt_state->xml) { @@ -935,6 +1286,10 @@ svn_cl__info(apr_getopt_t *os, return svn_error_create( SVN_ERR_CL_ARG_PARSING_ERROR, NULL, _("--no-newline is not valid in --xml mode")); + if (opt_state->file_size_unit != SVN_CL__SIZE_UNIT_NONE) + return svn_error_create( + SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--human-readable is not valid in --xml mode")); /* If output is not incremental, output the XML header and wrap everything in a top-level element. This makes the output in Modified: subversion/branches/addremove/subversion/svn/list-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/list-cmd.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/list-cmd.c (original) +++ subversion/branches/addremove/subversion/svn/list-cmd.c Sat May 23 14:16:56 2020 @@ -40,8 +40,13 @@ /* Baton used when printing directory entries. */ struct print_baton { - svn_boolean_t verbose; svn_client_ctx_t *ctx; + svn_boolean_t verbose; + svn_cl__size_unit_t file_size_unit; + + /* Keep track of the width of the author field. */ + int author_width; + int max_author_width; /* To keep track of last seen external information. */ const char *last_external_parent_url; @@ -49,12 +54,23 @@ struct print_baton { svn_boolean_t in_external; }; +/* Starting and maximum width of the author field */ +static const int initial_author_width = 8; +static const int initial_human_readable_author_width = 14; +static const int maximum_author_width = 16; +static const int maximum_human_readable_author_width = 22; + +/* Width of the size field */ +static const int normal_size_width = 10; +static const int human_readable_size_width = 4; + /* Field flags required for this function */ static const apr_uint32_t print_dirent_fields = SVN_DIRENT_KIND; static const apr_uint32_t print_dirent_fields_verbose = ( SVN_DIRENT_KIND | SVN_DIRENT_SIZE | SVN_DIRENT_TIME | SVN_DIRENT_CREATED_REV | SVN_DIRENT_LAST_AUTHOR); + /* This implements the svn_client_list_func2_t API, printing a single directory entry in text format. */ static svn_error_t * @@ -121,7 +137,11 @@ print_dirent(void *baton, apr_status_t apr_err; apr_size_t size; char timestr[20]; - const char *sizestr, *utf8_timestr; + const int sizewidth = (pb->file_size_unit == SVN_CL__SIZE_UNIT_NONE + ? normal_size_width + : human_readable_size_width); + const char *sizestr = ""; + const char *utf8_timestr; /* svn_time_to_human_cstring gives us something *way* too long to use for this, so we have to roll our own. We include @@ -146,15 +166,33 @@ print_dirent(void *baton, /* we need it in UTF-8. */ SVN_ERR(svn_utf_cstring_to_utf8(&utf8_timestr, timestr, scratch_pool)); - sizestr = apr_psprintf(scratch_pool, "%" SVN_FILESIZE_T_FMT, - dirent->size); + /* We may have to adjust the width of th 'author' field. */ + if (dirent->last_author) + { + const int author_width = (int)strlen(dirent->last_author); + if (author_width > pb->author_width) + { + if (author_width < pb->max_author_width) + pb->author_width = author_width; + else + pb->author_width = pb->max_author_width; + } + } + + if (dirent->kind == svn_node_file) + { + SVN_ERR(svn_cl__format_file_size(&sizestr, dirent->size, + pb->file_size_unit, + FALSE, scratch_pool)); + } return svn_cmdline_printf - (scratch_pool, "%7ld %-8.8s %c %10s %12s %s%s\n", + (scratch_pool, "%7ld %-*.*s %c %*s %12s %s%s\n", dirent->created_rev, + pb->author_width, pb->author_width, dirent->last_author ? dirent->last_author : " ? ", lock ? 'O' : ' ', - (dirent->kind == svn_node_file) ? sizestr : "", + sizewidth, sizestr, utf8_timestr, entryname, (dirent->kind == svn_node_dir) ? "/" : ""); @@ -238,9 +276,11 @@ print_dirent_xml(void *baton, if (dirent->kind == svn_node_file) { - svn_cl__xml_tagged_cdata - (&sb, scratch_pool, "size", - apr_psprintf(scratch_pool, "%" SVN_FILESIZE_T_FMT, dirent->size)); + const char *sizestr; + SVN_ERR(svn_cl__format_file_size(&sizestr, dirent->size, + SVN_CL__SIZE_UNIT_XML, + FALSE, scratch_pool)); + svn_cl__xml_tagged_cdata(&sb, scratch_pool, "size", sizestr); } svn_xml_make_open_tag(&sb, scratch_pool, svn_xml_normal, "commit", @@ -303,11 +343,17 @@ svn_cl__list(apr_getopt_t *os, if (opt_state->xml) { - /* The XML output contains all the information, so "--verbose" - does not apply. */ + /* The XML output contains all the information, so "--verbose" does + not apply, and using "--human-readable" with machine-readable + output does not make sense. */ if (opt_state->verbose) - return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, - _("'verbose' option invalid in XML mode")); + return svn_error_create( + SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--verbose is not valid in --xml mode")); + if (opt_state->file_size_unit != SVN_CL__SIZE_UNIT_NONE) + return svn_error_create( + SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--human-readable is not valid in --xml mode")); /* If output is not incremental, output the XML header and wrap everything in a top-level element. This makes the output in @@ -318,9 +364,9 @@ svn_cl__list(apr_getopt_t *os, else { if (opt_state->incremental) - return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, - _("'incremental' option only valid in XML " - "mode")); + return svn_error_create( + SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--incremental is only valid in --xml mode")); } if (opt_state->xml) @@ -332,6 +378,17 @@ svn_cl__list(apr_getopt_t *os, pb.ctx = ctx; pb.verbose = opt_state->verbose; + pb.file_size_unit = opt_state->file_size_unit; + if (pb.file_size_unit == SVN_CL__SIZE_UNIT_NONE) + { + pb.author_width = initial_author_width; + pb.max_author_width = maximum_author_width; + } + else + { + pb.author_width = initial_human_readable_author_width; + pb.max_author_width = maximum_human_readable_author_width; + } if (opt_state->depth == svn_depth_unknown) opt_state->depth = svn_depth_immediates; @@ -385,14 +442,20 @@ svn_cl__list(apr_getopt_t *os, apr_array_header_t *pattern_group = APR_ARRAY_IDX(opt_state->search_patterns, k, apr_array_header_t *); + const char *pattern; /* Should never fail but ... */ if (pattern_group->nelts != 1) return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, _("'search-and' option is not supported")); - APR_ARRAY_PUSH(patterns, const char *) - = APR_ARRAY_IDX(pattern_group, 0, const char *); + pattern = APR_ARRAY_IDX(pattern_group, 0, const char *); +#if defined(WIN32) + /* As we currently can't pass glob patterns via the Windows + CLI, fall back to sub-string search. */ + pattern = apr_psprintf(subpool, "*%s*", pattern); +#endif + APR_ARRAY_PUSH(patterns, const char *) = pattern; } } Modified: subversion/branches/addremove/subversion/svn/log-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/log-cmd.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/log-cmd.c (original) +++ subversion/branches/addremove/subversion/svn/log-cmd.c Sat May 23 14:16:56 2020 @@ -88,7 +88,7 @@ display_diff(const svn_log_entry_t *log_ end_revision.value.number = log_entry->revision; SVN_ERR(svn_stream_puts(outstream, "\n")); - SVN_ERR(svn_client_diff_peg6(diff_options, + SVN_ERR(svn_client_diff_peg7(diff_options, target_path_or_url, target_peg_revision, &start_revision, &end_revision, @@ -102,6 +102,7 @@ display_diff(const svn_log_entry_t *log_ FALSE /* ignore prop diff */, FALSE /* properties only */, FALSE /* use git diff format */, + TRUE /* pretty_print_mergeinfo */, svn_cmdline_output_encoding(pool), outstream, errstream, @@ -333,7 +334,7 @@ svn_cl__log_entry_receiver(void *baton, return SVN_NO_ERROR; } - /* ### See http://subversion.tigris.org/issues/show_bug.cgi?id=807 + /* ### See https://issues.apache.org/jira/browse/SVN-807 for more on the fallback fuzzy conversions below. */ if (author == NULL) @@ -732,10 +733,6 @@ svn_cl__log(apr_getopt_t *os, "XML mode")); } - if (opt_state->quiet && opt_state->show_diff) - return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, - _("'quiet' and 'diff' options are " - "mutually exclusive")); if (opt_state->diff.diff_cmd && (! opt_state->show_diff)) return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, _("'diff-cmd' option requires 'diff' " Modified: subversion/branches/addremove/subversion/svn/merge-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/merge-cmd.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/merge-cmd.c (original) +++ subversion/branches/addremove/subversion/svn/merge-cmd.c Sat May 23 14:16:56 2020 @@ -545,27 +545,31 @@ retry: "fix invalid mergeinfo in target with 'svn propset'")); } - /* Run the interactive resolver if conflicts were raised. */ - SVN_ERR(svn_cl__conflict_stats_get_paths(&conflicted_paths, conflict_stats, - pool, pool)); - if (conflicted_paths) + if (! opt_state->dry_run) { - SVN_ERR(svn_cl__walk_conflicts(conflicted_paths, conflict_stats, - opt_state, ctx, pool)); - if (merge_err && - svn_error_root_cause(merge_err)->apr_err == SVN_ERR_WC_FOUND_CONFLICT) + /* Run the interactive resolver if conflicts were raised. */ + SVN_ERR(svn_cl__conflict_stats_get_paths(&conflicted_paths, + conflict_stats, pool, pool)); + if (conflicted_paths) { - svn_error_t *err; - - /* Check if all conflicts were resolved just now. */ - err = svn_cl__conflict_stats_get_paths(&conflicted_paths, - conflict_stats, pool, pool); - if (err) - merge_err = svn_error_compose_create(merge_err, err); - else if (conflicted_paths == NULL) + SVN_ERR(svn_cl__walk_conflicts(conflicted_paths, conflict_stats, + opt_state, ctx, pool)); + if (merge_err && svn_error_root_cause(merge_err)->apr_err == + SVN_ERR_WC_FOUND_CONFLICT) { - svn_error_clear(merge_err); - goto retry; /* ### conflicts resolved; continue merging */ + svn_error_t *err; + + /* Check if all conflicts were resolved just now. */ + err = svn_cl__conflict_stats_get_paths(&conflicted_paths, + conflict_stats, + pool, pool); + if (err) + merge_err = svn_error_compose_create(merge_err, err); + else if (conflicted_paths == NULL) + { + svn_error_clear(merge_err); + goto retry; /* ### conflicts resolved; continue merging */ + } } } } Modified: subversion/branches/addremove/subversion/svn/notify.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/notify.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/notify.c (original) +++ subversion/branches/addremove/subversion/svn/notify.c Sat May 23 14:16:56 2020 @@ -210,7 +210,7 @@ svn_cl__conflict_stats_get_paths(apr_arr } } - svn_hash_keys(conflicted_paths, all_conflicts, result_pool); + SVN_ERR(svn_hash_keys(conflicted_paths, all_conflicts, result_pool)); svn_sort__array(*conflicted_paths, svn_sort_compare_paths); return SVN_NO_ERROR; Modified: subversion/branches/addremove/subversion/svn/propset-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/propset-cmd.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/propset-cmd.c (original) +++ subversion/branches/addremove/subversion/svn/propset-cmd.c Sat May 23 14:16:56 2020 @@ -151,7 +151,7 @@ svn_cl__propset(apr_getopt_t *os, * must always be explicitly provided when setting a versioned * property. See * - * http://subversion.tigris.org/issues/show_bug.cgi?id=924 + * https://issues.apache.org/jira/browse/SVN-924 * * for more details. */ Modified: subversion/branches/addremove/subversion/svn/resolve-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/resolve-cmd.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/resolve-cmd.c (original) +++ subversion/branches/addremove/subversion/svn/resolve-cmd.c Sat May 23 14:16:56 2020 @@ -109,7 +109,7 @@ svn_cl__walk_conflicts(apr_array_header_ svn_client_conflict_t *conflict; svn_pool_clear(iterpool); - + SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton)); SVN_ERR(svn_dirent_get_absolute(&local_abspath, target, iterpool)); Modified: subversion/branches/addremove/subversion/svn/revert-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/revert-cmd.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svn/revert-cmd.c (original) +++ subversion/branches/addremove/subversion/svn/revert-cmd.c Sat May 23 14:16:56 2020 @@ -67,10 +67,11 @@ svn_cl__revert(apr_getopt_t *os, SVN_ERR(svn_cl__check_targets_are_local_paths(targets)); - err = svn_client_revert3(targets, opt_state->depth, + err = svn_client_revert4(targets, opt_state->depth, opt_state->changelists, FALSE /* clear_changelists */, FALSE /* metadata_only */, + !opt_state->remove_added /*added_keep_local*/, ctx, scratch_pool); if (err && (err->apr_err == SVN_ERR_WC_INVALID_OPERATION_DEPTH)