Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 5BC39200D2E for ; Tue, 31 Oct 2017 10:40:11 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 5A1311609EB; Tue, 31 Oct 2017 09:40:11 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 322F5160BFC for ; Tue, 31 Oct 2017 10:40:08 +0100 (CET) Received: (qmail 52836 invoked by uid 500); 31 Oct 2017 09:40:07 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 52709 invoked by uid 99); 31 Oct 2017 09:40:07 -0000 Received: from Unknown (HELO svn01-us-west.apache.org) (209.188.14.144) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 31 Oct 2017 09:40:07 +0000 Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id 139743A05CE for ; Tue, 31 Oct 2017 09:40:04 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1813860 [7/8] - in /subversion/branches/shelve-checkpoint: ./ build/ build/generator/ notes/commit-access-templates/ subversion/bindings/javahl/native/ subversion/bindings/swig/include/ subversion/include/ subversion/include/private/ subve... Date: Tue, 31 Oct 2017 09:40:00 -0000 To: commits@subversion.apache.org From: julianfoad@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20171031094004.139743A05CE@svn01-us-west.apache.org> archived-at: Tue, 31 Oct 2017 09:40:11 -0000 Modified: subversion/branches/shelve-checkpoint/subversion/mod_dav_svn/merge.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/mod_dav_svn/merge.c?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/mod_dav_svn/merge.c (original) +++ subversion/branches/shelve-checkpoint/subversion/mod_dav_svn/merge.c Tue Oct 31 09:39:59 2017 @@ -171,7 +171,12 @@ do_resources(const dav_svn_repos *repos, if (! apr_hash_get(sent, path, change->path.len)) { svn_node_kind_t kind; - SVN_ERR(svn_fs_check_path(&kind, root, path, iterpool)); + + if (change->node_kind == svn_node_unknown) + SVN_ERR(svn_fs_check_path(&kind, root, path, iterpool)); + else + kind = change->node_kind; + SVN_ERR(send_response(repos, root, change->path.data, kind == svn_node_dir, output, bb, iterpool)); Modified: subversion/branches/shelve-checkpoint/subversion/mod_dav_svn/mod_dav_svn.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/mod_dav_svn/mod_dav_svn.c?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/mod_dav_svn/mod_dav_svn.c (original) +++ subversion/branches/shelve-checkpoint/subversion/mod_dav_svn/mod_dav_svn.c Tue Oct 31 09:39:59 2017 @@ -288,8 +288,8 @@ merge_dir_config(apr_pool_t *p, void *ba if (parent->fs_path) ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, - "mod_dav_svn: nested Location '%s' hinders access to '%s' " - "in SVNPath Location '%s'", + "mod_dav_svn: Location '%s' hinders access to '%s' " + "in parent SVNPath Location '%s'", child->root_dir, svn_urlpath__skip_ancestor(parent->root_dir, child->root_dir), parent->root_dir); Modified: subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c (original) +++ subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c Tue Oct 31 09:39:59 2017 @@ -30,87 +30,83 @@ #include "cl.h" #include "svn_private_config.h" +#include "private/svn_sorts_private.h" -/* First argument should be the name of a shelve. */ +/* First argument should be the name of a shelved change. */ static svn_error_t * -get_shelf_name(const char **shelf_name, - apr_getopt_t *os, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +get_name(const char **name, + apr_getopt_t *os, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { apr_array_header_t *args; SVN_ERR(svn_opt_parse_num_args(&args, os, 1, scratch_pool)); - SVN_ERR(svn_utf_cstring_to_utf8(shelf_name, + SVN_ERR(svn_utf_cstring_to_utf8(name, APR_ARRAY_IDX(args, 0, const char *), result_pool)); return SVN_NO_ERROR; } -/* ### Currently just reads the first line. +/* */ +static int +compare_dirents_by_mtime(const svn_sort__item_t *a, + const svn_sort__item_t *b) +{ + svn_client_shelved_patch_info_t *a_val = a->value; + svn_client_shelved_patch_info_t *b_val = b->value; + + return (a_val->dirent->mtime < b_val->dirent->mtime) + ? -1 : (a_val->dirent->mtime > b_val->dirent->mtime) ? 1 : 0; +} + +/* Return a list of shelved changes sorted by patch file mtime, oldest first. */ static svn_error_t * -read_logmsg_from_patch(const char **logmsg, - const char *patch_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - apr_file_t *file; - svn_stream_t *stream; - svn_boolean_t eof; - svn_stringbuf_t *line; - - SVN_ERR(svn_io_file_open(&file, patch_abspath, - APR_FOPEN_READ, APR_FPROT_OS_DEFAULT, scratch_pool)); - stream = svn_stream_from_aprfile2(file, FALSE /*disown*/, scratch_pool); - SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, scratch_pool)); - SVN_ERR(svn_stream_close(stream)); - *logmsg = line->data; +list_sorted_by_date(apr_array_header_t **list, + const char *local_abspath, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool) +{ + apr_hash_t *shelved_patch_infos; + + SVN_ERR(svn_client_shelves_list(&shelved_patch_infos, local_abspath, + ctx, scratch_pool, scratch_pool)); + *list = svn_sort__hash(shelved_patch_infos, compare_dirents_by_mtime, + scratch_pool); return SVN_NO_ERROR; } -/* Display a list of shelves */ +/* Display a list of shelved changes */ static svn_error_t * shelves_list(const char *local_abspath, svn_boolean_t diffstat, svn_client_ctx_t *ctx, apr_pool_t *scratch_pool) { - apr_hash_t *dirents; - apr_hash_index_t *hi; + apr_array_header_t *list; + int i; - SVN_ERR(svn_client_shelves_list(&dirents, local_abspath, - ctx, scratch_pool, scratch_pool)); + SVN_ERR(list_sorted_by_date(&list, + local_abspath, ctx, scratch_pool)); - for (hi = apr_hash_first(scratch_pool, dirents); hi; hi = apr_hash_next(hi)) + for (i = 0; i < list->nelts; i++) { - const char *name = apr_hash_this_key(hi); - svn_io_dirent2_t *dirent = apr_hash_this_val(hi); - int age = (apr_time_now() - dirent->mtime) / 1000000 / 60; - const char *patch_abspath; - const char *logmsg; - - if (! strstr(name, ".patch")) - continue; - - patch_abspath = svn_dirent_join_many(scratch_pool, - local_abspath, ".svn", "shelves", name, - SVN_VA_NULL); - SVN_ERR(read_logmsg_from_patch(&logmsg, patch_abspath, - scratch_pool, scratch_pool)); + const svn_sort__item_t *item = &APR_ARRAY_IDX(list, i, svn_sort__item_t); + const char *name = item->key; + svn_client_shelved_patch_info_t *info = item->value; + int age = (apr_time_now() - info->mtime) / 1000000 / 60; + printf("%-30s %6d mins old %10ld bytes\n", - name, age, (long)dirent->filesize); + name, age, (long)info->dirent->filesize); printf(" %.50s\n", - logmsg); + info->message); if (diffstat) { - char *path = svn_path_join_many(scratch_pool, - local_abspath, ".svn/shelves", name, - SVN_VA_NULL); - - system(apr_psprintf(scratch_pool, "diffstat %s 2> /dev/null", path)); + system(apr_psprintf(scratch_pool, "diffstat %s 2> /dev/null", + info->patch_path)); printf("\n"); } } @@ -118,6 +114,29 @@ shelves_list(const char *local_abspath, return SVN_NO_ERROR; } +/* Find the name of the youngest shelved change. + */ +static svn_error_t * +name_of_youngest(const char **name_p, + const char *local_abspath, + svn_client_ctx_t *ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + apr_array_header_t *list; + const svn_sort__item_t *youngest_item; + + SVN_ERR(list_sorted_by_date(&list, + local_abspath, ctx, scratch_pool)); + if (list->nelts == 0) + return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL, + _("No shelved changes found")); + + youngest_item = &APR_ARRAY_IDX(list, list->nelts - 1, svn_sort__item_t); + *name_p = youngest_item->key; + return SVN_NO_ERROR; +} + /* This implements the `svn_opt_subcommand_t' interface. */ svn_error_t * svn_cl__shelve(apr_getopt_t *os, @@ -127,7 +146,7 @@ svn_cl__shelve(apr_getopt_t *os, svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state; svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx; const char *local_abspath; - const char *shelf_name; + const char *name; apr_array_header_t *targets; if (opt_state->quiet) @@ -146,18 +165,18 @@ svn_cl__shelve(apr_getopt_t *os, return SVN_NO_ERROR; } - SVN_ERR(get_shelf_name(&shelf_name, os, pool, pool)); + SVN_ERR(get_name(&name, os, pool, pool)); if (opt_state->remove) { if (os->ind < os->argc) return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL); - SVN_ERR(svn_client_shelves_delete(shelf_name, local_abspath, + SVN_ERR(svn_client_shelves_delete(name, local_abspath, opt_state->dry_run, ctx, pool)); if (! opt_state->quiet) - SVN_ERR(svn_cmdline_printf(pool, "deleted '%s'\n", shelf_name)); + SVN_ERR(svn_cmdline_printf(pool, "deleted '%s'\n", name)); return SVN_NO_ERROR; } @@ -165,6 +184,7 @@ svn_cl__shelve(apr_getopt_t *os, SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os, opt_state->targets, ctx, FALSE, pool)); + svn_opt_push_implicit_dot_target(targets, pool); { svn_depth_t depth = opt_state->depth; @@ -186,9 +206,9 @@ svn_cl__shelve(apr_getopt_t *os, SVN_ERR(svn_cl__make_log_msg_baton(&ctx->log_msg_baton3, opt_state, NULL, ctx->config, pool)); - err = svn_client_shelve(shelf_name, + err = svn_client_shelve(name, targets, depth, opt_state->changelists, - opt_state->dry_run, + opt_state->keep_local, opt_state->dry_run, ctx, pool); if (ctx->log_msg_func3) SVN_ERR(svn_cl__cleanup_log_msg(ctx->log_msg_baton3, @@ -197,7 +217,7 @@ svn_cl__shelve(apr_getopt_t *os, SVN_ERR(err); if (! opt_state->quiet) - SVN_ERR(svn_cmdline_printf(pool, "shelved '%s'\n", shelf_name)); + SVN_ERR(svn_cmdline_printf(pool, "shelved '%s'\n", name)); } return SVN_NO_ERROR; @@ -212,7 +232,7 @@ svn_cl__unshelve(apr_getopt_t *os, svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state; svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx; const char *local_abspath; - const char *shelf_name; + const char *name; apr_array_header_t *targets; SVN_ERR(svn_dirent_get_absolute(&local_abspath, "", pool)); @@ -228,7 +248,15 @@ svn_cl__unshelve(apr_getopt_t *os, return SVN_NO_ERROR; } - SVN_ERR(get_shelf_name(&shelf_name, os, pool, pool)); + if (os->ind < os->argc) + { + SVN_ERR(get_name(&name, os, pool, pool)); + } + else + { + SVN_ERR(name_of_youngest(&name, local_abspath, ctx, pool, pool)); + printf("unshelving the youngest change, '%s'\n", name); + } /* There should be no remaining arguments. */ SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os, @@ -240,11 +268,11 @@ svn_cl__unshelve(apr_getopt_t *os, if (opt_state->quiet) ctx->notify_func2 = NULL; /* Easy out: avoid unneeded work */ - SVN_ERR(svn_client_unshelve(shelf_name, local_abspath, + SVN_ERR(svn_client_unshelve(name, local_abspath, opt_state->keep_local, opt_state->dry_run, ctx, pool)); if (! opt_state->quiet) - SVN_ERR(svn_cmdline_printf(pool, "unshelved '%s'\n", shelf_name)); + SVN_ERR(svn_cmdline_printf(pool, "unshelved '%s'\n", name)); return SVN_NO_ERROR; } Modified: subversion/branches/shelve-checkpoint/subversion/svn/svn.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/svn/svn.c?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/svn/svn.c (original) +++ subversion/branches/shelve-checkpoint/subversion/svn/svn.c Tue Oct 31 09:39:59 2017 @@ -405,7 +405,9 @@ const apr_getopt_option_t svn_cl__option {"show-inherited-props", opt_show_inherited_props, 0, N_("retrieve properties set on parents of the target")}, {"search", opt_search, 1, - N_("use ARG as search pattern (glob syntax)")}, + N_("use ARG as search pattern (glob syntax, case-\n" + " " + "and accent-insensitive)")}, {"search-and", opt_search_and, 1, N_("combine ARG with the previous search pattern")}, {"log", opt_mergeinfo_log, 0, @@ -834,6 +836,10 @@ const svn_opt_subcommand_desc2_t svn_cl_ " The default TARGET is '.', meaning the repository URL of the current\n" " working directory.\n" "\n" + " Multiple --search patterns may be specified and the output will be\n" + " reduced to those paths whose last segment - i.e. the file or directory\n" + " name - matches at least one of these patterns.\n" + "\n" " With --verbose, the following fields will be shown for each item:\n" "\n" " Revision number of the last commit\n" @@ -1675,32 +1681,62 @@ const svn_opt_subcommand_desc2_t svn_cl_ {opt_targets, 'R', opt_depth, 'q', opt_changelist} }, { "shelve", svn_cl__shelve, {0}, N_ - ("Shelve changes.\n" - "usage: 1. shelve NAME PATH...\n" + ("Put a local change aside, as if putting it on a shelf.\n" + "usage: 1. shelve [--keep-local] NAME [PATH...]\n" " 2. shelve --delete NAME\n" " 3. shelve --list\n" "\n" - " 1. Shelve as NAME the local changes in the given PATHs.\n" - " 2. Delete the shelved patch NAME.\n" - " 3. List shelved patches.\n"), - {opt_delete, opt_list, 'q', opt_dry_run, - 'N', opt_depth, opt_targets, opt_changelist, - SVN_CL__LOG_MSG_OPTIONS} }, + " 1. Save the local change in the given PATHs to a patch file, and\n" + " revert that change from the WC unless '--keep-local' is given.\n" + " If a log message is given with '-m' or '-F', include it at the\n" + " beginning of the patch file.\n" + "\n" + " 2. Delete the shelved change NAME.\n" + " (A backup is kept, named with a '.bak' extension.)\n" + "\n" + " 3. List shelved changes. Include the first line of any log message\n" + " and some details about the contents of the change, unless '-q' is\n" + " given.\n" + "\n" + " The kinds of change you can shelve are those supported by 'svn diff'\n" + " and 'svn patch'. The following are currently NOT supported:\n" + " mergeinfo changes, copies, moves, mkdir, rmdir,\n" + " 'binary' content, uncommittable states\n" + "\n" + " To bring back a shelved change, use 'svn unshelve NAME'.\n" + "\n" + " A shelved change is stored as a patch file, .svn/shelves/NAME.patch\n" + ), + {opt_delete, opt_list, 'q', opt_dry_run, opt_keep_local, + opt_depth, opt_targets, opt_changelist, + /* almost SVN_CL__LOG_MSG_OPTIONS but not currently opt_with_revprop: */ + 'm', 'F', opt_force_log, opt_editor_cmd, opt_encoding, + } }, { "unshelve", svn_cl__unshelve, {0}, N_ - ("Unshelve changes.\n" - "usage: 1. unshelve [--keep-shelved] NAME\n" + ("Bring a shelved change back to a local change in the WC.\n" + "usage: 1. unshelve [--keep-shelved] [NAME]\n" " 2. unshelve --list\n" "\n" - " 1. Apply the shelved patch NAME to the working copy.\n" + " 1. Apply the shelved change NAME to the working copy.\n" " Delete the patch unless the '--keep-shelved' option is given.\n" - " 2. List shelved patches.\n"), + " (A backup is kept, named with a '.bak' extension.)\n" + " NAME defaults to the most recent shelved change.\n" + "\n" + " 2. List shelved changes. Include the first line of any log message\n" + " and some details about the contents of the change, unless '-q' is\n" + " given.\n" + "\n" + " Any conflict between the change being unshelved and a change\n" + " already in the WC is handled the same way as by 'svn patch',\n" + " creating a 'reject' file.\n" + ), {opt_keep_shelved, opt_list, 'q', opt_dry_run} }, { "shelves", svn_cl__shelves, {0}, N_ - ("List shelved patches.\n" + ("List shelved changes.\n" "usage: shelves\n"), - {} }, + }, { "status", svn_cl__status, {"stat", "st"}, N_ ("Print the status of working copy files and directories.\n" Modified: subversion/branches/shelve-checkpoint/subversion/svnadmin/svnadmin.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/svnadmin/svnadmin.c?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/svnadmin/svnadmin.c (original) +++ subversion/branches/shelve-checkpoint/subversion/svnadmin/svnadmin.c Tue Oct 31 09:39:59 2017 @@ -151,7 +151,11 @@ enum svnadmin__cmdline_options_t svnadmin__compatible_version, svnadmin__check_normalization, svnadmin__metadata_only, - svnadmin__no_flush_to_disk + svnadmin__no_flush_to_disk, + svnadmin__normalize_props, + svnadmin__exclude, + svnadmin__include, + svnadmin__glob }; /* Option codes and descriptions. @@ -274,6 +278,22 @@ static const apr_getopt_option_t options N_("disable flushing to disk during the operation\n" " (faster, but unsafe on power off)")}, + {"normalize-props", svnadmin__normalize_props, 0, + N_("normalize property values found in the dumpstream\n" + " (currently, only translates non-LF line endings)")}, + + {"exclude", svnadmin__exclude, 1, + N_("filter out nodes with given prefix(es) from dump")}, + + {"include", svnadmin__include, 1, + N_("filter out nodes without given prefix(es) from dump")}, + + {"pattern", svnadmin__glob, 0, + N_("treat the path prefixes as file glob patterns.\n" + " Glob special characters are '*' '?' '[]' and '\\'.\n" + " Character '/' is not treated specially, so\n" + " pattern /*/foo matches paths /a/foo and /a/b/foo.") }, + {NULL} }; @@ -330,8 +350,13 @@ static const svn_opt_subcommand_desc2_t "only the paths changed in that revision; otherwise it will describe\n" "every path present in the repository as of that revision. (In either\n" "case, the second and subsequent revisions, if any, describe only paths\n" - "changed in those revisions.)\n"), - {'r', svnadmin__incremental, svnadmin__deltas, 'q', 'M', 'F'}, + "changed in those revisions.)\n" + "\n" + "Using --exclude or --include gives results equivalent to authz-based\n" + "path exclusions. In particular, when the source of a copy is\n" + "excluded, the copy is transformed into an add (unlike in 'svndumpfilter').\n"), + {'r', svnadmin__incremental, svnadmin__deltas, 'q', 'M', 'F', + svnadmin__exclude, svnadmin__include, svnadmin__glob }, {{'F', N_("write to file ARG instead of stdout")}} }, {"dump-revprops", subcommand_dump_revprops, {0}, N_ @@ -396,7 +421,8 @@ static const svn_opt_subcommand_desc2_t {'q', 'r', svnadmin__ignore_uuid, svnadmin__force_uuid, svnadmin__ignore_dates, svnadmin__use_pre_commit_hook, svnadmin__use_post_commit_hook, - svnadmin__parent_dir, svnadmin__bypass_prop_validation, 'M', + svnadmin__parent_dir, svnadmin__normalize_props, + svnadmin__bypass_prop_validation, 'M', svnadmin__no_flush_to_disk, 'F'}, {{'F', N_("read from file ARG instead of stdin")}} }, @@ -407,8 +433,8 @@ static const svn_opt_subcommand_desc2_t "repository will cause an error. Progress feedback is sent to stdout.\n" "If --revision is specified, limit the loaded revisions to only those\n" "in the dump stream whose revision numbers match the specified range.\n"), - {'q', 'r', svnadmin__force_uuid, svnadmin__bypass_prop_validation, - svnadmin__no_flush_to_disk, 'F'}, + {'q', 'r', svnadmin__force_uuid, svnadmin__normalize_props, + svnadmin__bypass_prop_validation, svnadmin__no_flush_to_disk, 'F'}, {{'F', N_("read from file ARG instead of stdin")}} }, {"lock", subcommand_lock, {0}, N_ @@ -547,11 +573,15 @@ struct svnadmin_opt_state svn_boolean_t bypass_prop_validation; /* --bypass-prop-validation */ svn_boolean_t ignore_dates; /* --ignore-dates */ svn_boolean_t no_flush_to_disk; /* --no-flush-to-disk */ + svn_boolean_t normalize_props; /* --normalize_props */ enum svn_repos_load_uuid uuid_action; /* --ignore-uuid, --force-uuid */ apr_uint64_t memory_cache_size; /* --memory-cache-size M */ const char *parent_dir; /* --parent-dir */ const char *file; /* --file */ + apr_array_header_t *exclude; /* --exclude */ + apr_array_header_t *include; /* --include */ + svn_boolean_t glob; /* --pattern */ const char *config_dir; /* Overriding Configuration Directory */ }; @@ -1248,6 +1278,58 @@ get_dump_range(svn_revnum_t *lower, return SVN_NO_ERROR; } +/* Compare the node-path PATH with the (const char *) prefixes in PFXLIST. + * Return TRUE if any prefix is a prefix of PATH (matching whole path + * components); FALSE otherwise. + * PATH starts with a '/', as do the (const char *) paths in PREFIXES. */ +/* This function is a duplicate of svndumpfilter.c:ary_prefix_match(). */ +static svn_boolean_t +ary_prefix_match(const apr_array_header_t *pfxlist, const char *path) +{ + int i; + size_t path_len = strlen(path); + + for (i = 0; i < pfxlist->nelts; i++) + { + const char *pfx = APR_ARRAY_IDX(pfxlist, i, const char *); + size_t pfx_len = strlen(pfx); + + if (path_len < pfx_len) + continue; + if (strncmp(path, pfx, pfx_len) == 0 + && (pfx_len == 1 || path[pfx_len] == '\0' || path[pfx_len] == '/')) + return TRUE; + } + + return FALSE; +} + +/* Baton for dump_filter_func(). */ +struct dump_filter_baton_t +{ + apr_array_header_t *prefixes; + svn_boolean_t glob; + svn_boolean_t do_exclude; +}; + +/* Implements svn_repos_dump_filter_func_t. */ +static svn_error_t * +dump_filter_func(svn_boolean_t *include, + svn_fs_root_t *root, + const char *path, + void *baton, + apr_pool_t *scratch_pool) +{ + struct dump_filter_baton_t *b = baton; + const svn_boolean_t matches = + (b->glob + ? svn_cstring_match_glob_list(path, b->prefixes) + : ary_prefix_match(b->prefixes, path)); + + *include = b->do_exclude ? !matches : matches; + return SVN_NO_ERROR; +} + /* This implements `svn_opt_subcommand_t'. */ static svn_error_t * subcommand_dump(apr_getopt_t *os, void *baton, apr_pool_t *pool) @@ -1257,6 +1339,7 @@ subcommand_dump(apr_getopt_t *os, void * svn_stream_t *out_stream; svn_revnum_t lower, upper; svn_stream_t *feedback_stream = NULL; + struct dump_filter_baton_t filter_baton = {0}; /* Expect no more arguments. */ SVN_ERR(parse_args(NULL, os, 0, 0, pool)); @@ -1282,11 +1365,34 @@ subcommand_dump(apr_getopt_t *os, void * if (! opt_state->quiet) feedback_stream = recode_stream_create(stderr, pool); + /* Initialize the filter baton. */ + filter_baton.glob = opt_state->glob; + + if (opt_state->exclude && !opt_state->include) + { + filter_baton.prefixes = opt_state->exclude; + filter_baton.do_exclude = TRUE; + } + else if (opt_state->include && !opt_state->exclude) + { + filter_baton.prefixes = opt_state->include; + filter_baton.do_exclude = FALSE; + } + else if (opt_state->include && opt_state->exclude) + { + return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("'--exclude' and '--include' options " + "cannot be used simultaneously")); + } + SVN_ERR(svn_repos_dump_fs4(repos, out_stream, lower, upper, opt_state->incremental, opt_state->use_deltas, TRUE, TRUE, !opt_state->quiet ? repos_notify_handler : NULL, - feedback_stream, check_cancel, NULL, pool)); + feedback_stream, + filter_baton.prefixes ? dump_filter_func : NULL, + &filter_baton, + check_cancel, NULL, pool)); return SVN_NO_ERROR; } @@ -1328,7 +1434,8 @@ subcommand_dump_revprops(apr_getopt_t *o SVN_ERR(svn_repos_dump_fs4(repos, out_stream, lower, upper, FALSE, FALSE, TRUE, FALSE, !opt_state->quiet ? repos_notify_handler : NULL, - feedback_stream, check_cancel, NULL, pool)); + feedback_stream, NULL, NULL, + check_cancel, NULL, pool)); return SVN_NO_ERROR; } @@ -1534,20 +1641,32 @@ subcommand_load(apr_getopt_t *os, void * if (! opt_state->quiet) feedback_stream = recode_stream_create(stdout, pool); - err = svn_repos_load_fs5(repos, in_stream, lower, upper, + err = svn_repos_load_fs6(repos, in_stream, lower, upper, opt_state->uuid_action, opt_state->parent_dir, opt_state->use_pre_commit_hook, opt_state->use_post_commit_hook, !opt_state->bypass_prop_validation, + opt_state->normalize_props, opt_state->ignore_dates, opt_state->quiet ? NULL : repos_notify_handler, feedback_stream, check_cancel, NULL, pool); - if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE) - return svn_error_quick_wrap(err, - _("Invalid property value found in " - "dumpstream; consider repairing the source " - "or using --bypass-prop-validation while " - "loading.")); + + if (svn_error_find_cause(err, SVN_ERR_BAD_PROPERTY_VALUE_EOL)) + { + return svn_error_quick_wrap(err, + _("A property with invalid line ending " + "found in dumpstream; consider using " + "--normalize-props while loading.")); + } + else if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE) + { + return svn_error_quick_wrap(err, + _("Invalid property value found in " + "dumpstream; consider repairing the " + "source or using --bypass-prop-validation " + "while loading.")); + } + return err; } @@ -1584,16 +1703,28 @@ subcommand_load_revprops(apr_getopt_t *o err = svn_repos_load_fs_revprops(repos, in_stream, lower, upper, !opt_state->bypass_prop_validation, + opt_state->normalize_props, opt_state->ignore_dates, opt_state->quiet ? NULL : repos_notify_handler, feedback_stream, check_cancel, NULL, pool); - if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE) - return svn_error_quick_wrap(err, - _("Invalid property value found in " - "dumpstream; consider repairing the source " - "or using --bypass-prop-validation while " - "loading.")); + + if (svn_error_find_cause(err, SVN_ERR_BAD_PROPERTY_VALUE_EOL)) + { + return svn_error_quick_wrap(err, + _("A property with invalid line ending " + "found in dumpstream; consider using " + "--normalize-props while loading.")); + } + else if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE) + { + return svn_error_quick_wrap(err, + _("Invalid property value found in " + "dumpstream; consider repairing the " + "source or using --bypass-prop-validation " + "while loading.")); + } + return err; } @@ -2884,6 +3015,26 @@ sub_main(int *exit_code, int argc, const case svnadmin__no_flush_to_disk: opt_state.no_flush_to_disk = TRUE; break; + case svnadmin__normalize_props: + opt_state.normalize_props = TRUE; + break; + case svnadmin__exclude: + SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool)); + + if (! opt_state.exclude) + opt_state.exclude = apr_array_make(pool, 1, sizeof(const char *)); + APR_ARRAY_PUSH(opt_state.exclude, const char *) = utf8_opt_arg; + break; + case svnadmin__include: + SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool)); + + if (! opt_state.include) + opt_state.include = apr_array_make(pool, 1, sizeof(const char *)); + APR_ARRAY_PUSH(opt_state.include, const char *) = utf8_opt_arg; + break; + case svnadmin__glob: + opt_state.glob = TRUE; + break; default: { SVN_ERR(subcommand_help(NULL, NULL, pool)); Modified: subversion/branches/shelve-checkpoint/subversion/svndumpfilter/svndumpfilter.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/svndumpfilter/svndumpfilter.c?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/svndumpfilter/svndumpfilter.c (original) +++ subversion/branches/shelve-checkpoint/subversion/svndumpfilter/svndumpfilter.c Tue Oct 31 09:39:59 2017 @@ -109,6 +109,7 @@ write_propdel_to_stringbuf(svn_stringbuf * Return TRUE if any prefix is a prefix of PATH (matching whole path * components); FALSE otherwise. * PATH starts with a '/', as do the (const char *) paths in PREFIXES. */ +/* This function is a duplicate of svnadmin.c:ary_prefix_match(). */ static svn_boolean_t ary_prefix_match(const apr_array_header_t *pfxlist, const char *path) { Modified: subversion/branches/shelve-checkpoint/subversion/svnrdump/load_editor.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/svnrdump/load_editor.c?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/svnrdump/load_editor.c (original) +++ subversion/branches/shelve-checkpoint/subversion/svnrdump/load_editor.c Tue Oct 31 09:39:59 2017 @@ -713,16 +713,15 @@ set_revision_property(void *baton, { struct revision_baton *rb = baton; - SVN_ERR(svn_rdump__normalize_prop(name, &value, rb->pool)); - + SVN_ERR(svn_repos__normalize_prop(&value, NULL, name, value, + rb->pool, rb->pool)); SVN_ERR(svn_repos__validate_prop(name, value, rb->pool)); if (rb->rev > 0) { if (! svn_hash_gets(rb->pb->skip_revprops, name)) svn_hash_sets(rb->revprop_table, - apr_pstrdup(rb->pool, name), - svn_string_dup(value, rb->pool)); + apr_pstrdup(rb->pool, name), value); } else if (rb->rev_offset == -1 && ! svn_hash_gets(rb->pb->skip_revprops, name)) @@ -737,9 +736,9 @@ set_revision_property(void *baton, /* Remember any datestamp/ author that passes through (see comment in close_revision). */ if (!strcmp(name, SVN_PROP_REVISION_DATE)) - rb->datestamp = svn_string_dup(value, rb->pool); + rb->datestamp = value; if (!strcmp(name, SVN_PROP_REVISION_AUTHOR)) - rb->author = svn_string_dup(value, rb->pool); + rb->author = value; return SVN_NO_ERROR; } @@ -776,13 +775,13 @@ set_node_property(void *baton, value = new_value; } - SVN_ERR(svn_rdump__normalize_prop(name, &value, pool)); + SVN_ERR(svn_repos__normalize_prop(&value, NULL, name, value, pool, pool)); SVN_ERR(svn_repos__validate_prop(name, value, pool)); prop = apr_palloc(nb->rb->pool, sizeof (*prop)); prop->name = apr_pstrdup(pool, name); - prop->value = svn_string_dup(value, pool); + prop->value = value; svn_hash_sets(nb->prop_changes, prop->name, prop); return SVN_NO_ERROR; Modified: subversion/branches/shelve-checkpoint/subversion/svnrdump/svnrdump.h URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/svnrdump/svnrdump.h?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/svnrdump/svnrdump.h (original) +++ subversion/branches/shelve-checkpoint/subversion/svnrdump/svnrdump.h Tue Oct 31 09:39:59 2017 @@ -100,29 +100,12 @@ svn_rdump__load_dumpstream(svn_stream_t * currently all svn:* props) so that they contain only LF (\n) line endings. * * Put the normalized props into NORMAL_PROPS, allocated in RESULT_POOL. - * - * Note: this function does not do a deep copy; it is expected that PROPS has - * a longer lifetime than NORMAL_PROPS. */ svn_error_t * svn_rdump__normalize_props(apr_hash_t **normal_props, apr_hash_t *props, apr_pool_t *result_pool); -/* Normalize the line ending style of a single property that "needs - * translation" (according to svn_prop_needs_translation(), - * currently all svn:* props) so that they contain only LF (\n) line endings. - * "\r" characters found mid-line are replaced with "\n". - * "\r\n" sequences are replaced with "\n" - * - * NAME is used to check that VALUE should be normalized, and if this is the - * case, VALUE is then normalized, allocated from RESULT_POOL - */ -svn_error_t * -svn_rdump__normalize_prop(const char *name, - const svn_string_t **value, - apr_pool_t *result_pool); - #ifdef __cplusplus } #endif /* __cplusplus */ Modified: subversion/branches/shelve-checkpoint/subversion/svnrdump/util.c URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/svnrdump/util.c?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/svnrdump/util.c (original) +++ subversion/branches/shelve-checkpoint/subversion/svnrdump/util.c Tue Oct 31 09:39:59 2017 @@ -21,53 +21,35 @@ * ==================================================================== */ -#include "svn_error.h" -#include "svn_pools.h" -#include "svn_string.h" -#include "svn_props.h" -#include "svn_subst.h" +#include "private/svn_repos_private.h" #include "svnrdump.h" svn_error_t * -svn_rdump__normalize_prop(const char *name, - const svn_string_t **value, - apr_pool_t *result_pool) -{ - if (svn_prop_needs_translation(name) && *value) - { - const char *cstring; - - SVN_ERR(svn_subst_translate_cstring2((*value)->data, &cstring, - "\n", TRUE, - NULL, FALSE, - result_pool)); - - *value = svn_string_create(cstring, result_pool); - } - return SVN_NO_ERROR; -} - -svn_error_t * svn_rdump__normalize_props(apr_hash_t **normal_props, apr_hash_t *props, apr_pool_t *result_pool) { apr_hash_index_t *hi; + apr_pool_t *iterpool; *normal_props = apr_hash_make(result_pool); + iterpool = svn_pool_create(result_pool); for (hi = apr_hash_first(result_pool, props); hi; hi = apr_hash_next(hi)) { const char *key = apr_hash_this_key(hi); const svn_string_t *value = apr_hash_this_val(hi); - SVN_ERR(svn_rdump__normalize_prop(key, &value, - result_pool)); + svn_pool_clear(iterpool); + SVN_ERR(svn_repos__normalize_prop(&value, NULL, key, value, + result_pool, iterpool)); svn_hash_sets(*normal_props, key, value); } + svn_pool_destroy(iterpool); + return SVN_NO_ERROR; } Modified: subversion/branches/shelve-checkpoint/subversion/tests/cmdline/basic_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/cmdline/basic_tests.py?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/tests/cmdline/basic_tests.py (original) +++ subversion/branches/shelve-checkpoint/subversion/tests/cmdline/basic_tests.py Tue Oct 31 09:39:59 2017 @@ -3126,7 +3126,75 @@ def filtered_ls(sbox): "gamma\n" ] exit_code, output, error = svntest.actions.run_and_verify_svn( - None, [], 'ls', path, '--depth=infinity', '--search=*a') + expected, [], 'ls', path, '--depth=infinity', '--search=*a') + + # check case-insensitivity + exit_code, output, error = svntest.actions.run_and_verify_svn( + expected, [], 'ls', path, '--depth=infinity', '--search=*A') + + expected = [ "H/\n" ] + exit_code, output, error = svntest.actions.run_and_verify_svn( + expected, [], 'ls', path, '--depth=infinity', '--search=h') + + # we don't match full paths + exit_code, output, error = svntest.actions.run_and_verify_svn( + [], [], 'ls', path, '--depth=infinity', '--search=*/*') + +@Issue(4700) +def null_update_last_changed_revision(sbox): + "null 'update' updates last changed rev" + + sbox.build() + wc_dir = sbox.wc_dir + + # r2: Random text change. + old_contents = open(sbox.path("iota")).read() + sbox.simple_append("iota", "Line 2.\n") + sbox.simple_commit(message='r2') + sbox.simple_update() + + # r3: Revert r2. + sbox.simple_append("iota", old_contents, truncate=True) + sbox.simple_commit(message='r3') + sbox.simple_update() + + # Perform a null update. + # + # This used to say '3'; probably because iota@3 and iota@1 were textually + # identical. It seems this problem was introduced in r1760570. + sbox.simple_update(revision='1') + svntest.actions.run_and_verify_svn(["1\n"], [], + 'info', sbox.path('iota'), + '--show-item', 'last-changed-revision') + +@Issue(4700) +@XFail() +def null_prop_update_last_changed_revision(sbox): + "null 'property update' updates last changed rev" + + sbox.build() + wc_dir = sbox.wc_dir + + sbox.simple_propset("prop", "value", "iota") + sbox.simple_commit(message='r2') + sbox.simple_update() + + # r3: change the property + sbox.simple_propset("prop", "changed", "iota") + sbox.simple_commit(message='r3') + sbox.simple_update() + + # r4: Revert r3. + sbox.simple_propset("prop", "value", "iota") + sbox.simple_commit(message='r4') + sbox.simple_update() + + # Perform a null update. + sbox.simple_update(revision='2') + svntest.actions.run_and_verify_svn(["2\n"], [], + 'info', sbox.path('iota'), + '--show-item', 'last-changed-revision') + ######################################################################## # Run the tests @@ -3199,6 +3267,8 @@ test_list = [ None, mkdir_parents_target_exists_on_disk, plaintext_password_storage_disabled, filtered_ls, + null_update_last_changed_revision, + null_prop_update_last_changed_revision, ] if __name__ == '__main__': Modified: subversion/branches/shelve-checkpoint/subversion/tests/cmdline/davautocheck.sh URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/cmdline/davautocheck.sh?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/tests/cmdline/davautocheck.sh (original) +++ subversion/branches/shelve-checkpoint/subversion/tests/cmdline/davautocheck.sh Tue Oct 31 09:39:59 2017 @@ -699,6 +699,15 @@ RedirectMatch permanent ^/svn-test-work/ RedirectMatch ^/svn-test-work/repositories/REDIRECT-TEMP-(.*)\$ /svn-test-work/repositories/\$1 __EOF__ + +# Our configure script extracts the HTTPD version from +# headers. However, that may not be the same as the runtime version; +# an example of this discrepancy occurs on OSX 1.9.5, where the +# headers report 2.2.26 but the server reports 2.2.29. Since our tests +# use the version to interpret test case results, use the actual +# runtime version here to avoid spurious test failures. +HTTPD_VERSION=$("$HTTPD" -V -f $HTTPD_CFG | grep '^Server version:' | sed 's|^.*/\([0-9]*\.[0-9]*\.[0-9]*\).*$|\1|') + START="$HTTPD -f $HTTPD_CFG" printf \ '#!/bin/sh @@ -715,14 +724,14 @@ fi ' >$STOPSCRIPT "$HTTPD_ROOT" "$START" "$HTTPD_PID" "$HTTPD_PID" chmod +x $STOPSCRIPT -$START -t \ +$START -t > /dev/null \ || fail "Configuration file didn't pass the check, most likely modules couldn't be loaded" # need to pause for some time to let HTTPD start $START & sleep 2 -say "HTTPD started and listening on '$BASE_URL'..." +say "HTTPD $HTTPD_VERSION started and listening on '$BASE_URL'..." #query "Ready" "y" # Perform a trivial validation of our httpd configuration by @@ -779,13 +788,13 @@ else fi if [ $# = 0 ]; then - TIME_CMD "$MAKE" check "BASE_URL=$BASE_URL" $SSL_MAKE_VAR + TIME_CMD "$MAKE" check "BASE_URL=$BASE_URL" "HTTPD_VERSION=$HTTPD_VERSION" $SSL_MAKE_VAR r=$? else (cd "$ABS_BUILDDIR/subversion/tests/cmdline/" TEST="$1" shift - TIME_CMD "$ABS_SRCDIR/subversion/tests/cmdline/${TEST}_tests.py" "--url=$BASE_URL" $SSL_TEST_ARG "$@") + TIME_CMD "$ABS_SRCDIR/subversion/tests/cmdline/${TEST}_tests.py" "--url=$BASE_URL" "--httpd-version=$HTTPD_VERSION" $SSL_TEST_ARG "$@") r=$? fi Modified: subversion/branches/shelve-checkpoint/subversion/tests/cmdline/diff_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/cmdline/diff_tests.py?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/tests/cmdline/diff_tests.py (original) +++ subversion/branches/shelve-checkpoint/subversion/tests/cmdline/diff_tests.py Tue Oct 31 09:39:59 2017 @@ -3531,7 +3531,7 @@ def diff_git_empty_files(sbox): expected_output = make_git_diff_header(new_path, "new", "nonexistent", "working copy", add=True, text_changes=False) + [ - ] + make_git_diff_header(iota_path, "iota", "revision 2", "working copy", + ] + make_git_diff_header(iota_path, "iota", "revision 2", "nonexistent", delete=True, text_changes=False) # Two files in diff may be in any order. @@ -5043,7 +5043,7 @@ def diff_symlinks(sbox): '===================================================================\n', 'diff --git a/to-iota b/to-iota\n', 'new file mode 120644\n', - '--- /dev/null\t(nonexistent)\n', + '--- a/to-iota\t(nonexistent)\n', '+++ b/to-iota\t(working copy)\n', '@@ -0,0 +1 @@\n', '+iota\n', Modified: subversion/branches/shelve-checkpoint/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout (original) +++ subversion/branches/shelve-checkpoint/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout Tue Oct 31 09:39:59 2017 @@ -42,6 +42,9 @@ Available subcommands: resolve resolved revert + shelve + unshelve + shelves status (stat, st) switch (sw) unlock Modified: subversion/branches/shelve-checkpoint/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout (original) +++ subversion/branches/shelve-checkpoint/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout Tue Oct 31 09:39:59 2017 @@ -126,7 +126,8 @@ Valid options: --ignore-eol-style: Ignore changes in EOL style -U ARG, --context ARG: Show ARG lines of context -p, --show-c-function: Show C function name - --search ARG : use ARG as search pattern (glob syntax) + --search ARG : use ARG as search pattern (glob syntax, case- + and accent-insensitive) --search-and ARG : combine ARG with the previous search pattern Global options: Modified: subversion/branches/shelve-checkpoint/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout (original) +++ subversion/branches/shelve-checkpoint/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout Tue Oct 31 09:39:59 2017 @@ -42,6 +42,9 @@ Available subcommands: resolve resolved revert + shelve + unshelve + shelves status (stat, st) switch (sw) unlock Modified: subversion/branches/shelve-checkpoint/subversion/tests/cmdline/svnadmin_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/cmdline/svnadmin_tests.py?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/tests/cmdline/svnadmin_tests.py (original) +++ subversion/branches/shelve-checkpoint/subversion/tests/cmdline/svnadmin_tests.py Tue Oct 31 09:39:59 2017 @@ -276,7 +276,7 @@ def load_and_verify_dumpstream(sbox, exp 'load', '--quiet', sbox.repo_dir, *varargs) if expected_stdout: - if expected_stdout == svntest.verify.AnyOutput: + if expected_stdout is svntest.verify.AnyOutput: if len(output) == 0: raise SVNExpectedStdout else: @@ -284,7 +284,7 @@ def load_and_verify_dumpstream(sbox, exp "Standard output", "STDOUT:", expected_stdout, output) if expected_stderr: - if expected_stderr == svntest.verify.AnyOutput: + if expected_stderr is svntest.verify.AnyOutput: if len(errput) == 0: raise SVNExpectedStderr else: @@ -1616,14 +1616,34 @@ text sbox.build(empty=True) # Try to load the dumpstream, expecting a failure (because of mixed EOLs). - load_and_verify_dumpstream(sbox, [], svntest.verify.AnyOutput, - dumpfile_revisions, False, dump_str, - '--ignore-uuid') + exp_err = svntest.verify.RegexListOutput(['svnadmin: E125005', + 'svnadmin: E125005', + 'svnadmin: E125017'], + match_all=False) + load_and_verify_dumpstream(sbox, [], exp_err, dumpfile_revisions, + False, dump_str, '--ignore-uuid') # Now try it again bypassing prop validation. (This interface takes # care of the removal and recreation of the original repository.) svntest.actions.load_repo(sbox, dump_str=dump_str, bypass_prop_validation=True) + # Getting the property should fail. + svntest.actions.run_and_verify_svn(None, 'svn: E135000: ', + 'pg', 'svn:log', '--revprop', '-r1', + sbox.repo_url) + + # Now try it again with prop normalization. + svntest.actions.load_repo(sbox, dump_str=dump_str, + bypass_prop_validation=False, + normalize_props=True) + # We should get the expected property value. + exit_code, output, _ = svntest.main.run_svn(None, 'pg', 'svn:log', + '--revprop', '-r1', + '--no-newline', + sbox.repo_url) + svntest.verify.verify_exit_code(None, exit_code, 0) + if output != ['\n', '\n']: + raise svntest.Failure("Unexpected property value %s" % output) # This test intentionally corrupts a revision and assumes an FSFS # repository. If you can make it work with BDB please do so. @@ -3436,6 +3456,336 @@ def load_from_file(sbox): 'update', sbox.wc_dir) svntest.actions.verify_disk(sbox.wc_dir, expected_tree, check_props=True) +def dump_exclude(sbox): + "svnadmin dump with excluded paths" + + sbox.build(create_wc=False) + + # Dump repository with /A/D/H and /A/B/E paths excluded. + _, dump, _ = svntest.actions.run_and_verify_svnadmin(None, [], + 'dump', '-q', + '--exclude', '/A/D/H', + '--exclude', '/A/B/E', + sbox.repo_dir) + + # Load repository from dump. + sbox2 = sbox.clone_dependent() + sbox2.build(create_wc=False, empty=True) + load_and_verify_dumpstream(sbox2, None, [], None, False, dump) + + # Check log. + expected_output = svntest.verify.RegexListOutput([ + '-+\\n', + 'r1\ .*\n', + # '/A/D/H' and '/A/B/E' is not added. + re.escape('Changed paths:\n'), + re.escape(' A /A\n'), + re.escape(' A /A/B\n'), + re.escape(' A /A/B/F\n'), + re.escape(' A /A/B/lambda\n'), + re.escape(' A /A/C\n'), + re.escape(' A /A/D\n'), + re.escape(' A /A/D/G\n'), + re.escape(' A /A/D/G/pi\n'), + re.escape(' A /A/D/G/rho\n'), + re.escape(' A /A/D/G/tau\n'), + re.escape(' A /A/D/gamma\n'), + re.escape(' A /A/mu\n'), + re.escape(' A /iota\n'), + '-+\\n' + ]) + svntest.actions.run_and_verify_svn(expected_output, [], + 'log', '-v', '-q', sbox2.repo_url) + +def dump_exclude_copysource(sbox): + "svnadmin dump with excluded copysource" + + sbox.build(create_wc=False, empty=True) + + # Create default repository structure. + svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], "mkdir", + sbox.repo_url + '/trunk', + sbox.repo_url + '/branches', + sbox.repo_url + '/tags', + "-m", "Create repository structure.") + + # Create a branch. + svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], "copy", + sbox.repo_url + '/trunk', + sbox.repo_url + '/branches/branch1', + "-m", "Create branch.") + + # Dump repository with /trunk excluded. + _, dump, _ = svntest.actions.run_and_verify_svnadmin(None, [], + 'dump', '-q', + '--exclude', '/trunk', + sbox.repo_dir) + + # Load repository from dump. + sbox2 = sbox.clone_dependent() + sbox2.build(create_wc=False, empty=True) + load_and_verify_dumpstream(sbox2, None, [], None, False, dump) + + # Check log. + expected_output = svntest.verify.RegexListOutput([ + '-+\\n', + 'r2\ .*\n', + re.escape('Changed paths:\n'), + # Simple add, not copy. + re.escape(' A /branches/branch1\n'), + '-+\\n', + 'r1\ .*\n', + # '/trunk' is not added. + re.escape('Changed paths:\n'), + re.escape(' A /branches\n'), + re.escape(' A /tags\n'), + '-+\\n' + ]) + svntest.actions.run_and_verify_svn(expected_output, [], + 'log', '-v', '-q', sbox2.repo_url) + +def dump_include(sbox): + "svnadmin dump with included paths" + + sbox.build(create_wc=False, empty=True) + + # Create a couple of directories. + # Note that we can't use greek tree as it contains only two top-level + # nodes. Including non top-level nodes (e.g. '--include /A/B/E') will + # produce unloadable dump for now. + svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], "mkdir", + sbox.repo_url + '/A', + sbox.repo_url + '/B', + sbox.repo_url + '/C', + "-m", "Create folder.") + + # Dump repository with /A and /C paths included. + _, dump, _ = svntest.actions.run_and_verify_svnadmin(None, [], + 'dump', '-q', + '--include', '/A', + '--include', '/C', + sbox.repo_dir) + + # Load repository from dump. + sbox2 = sbox.clone_dependent() + sbox2.build(create_wc=False, empty=True) + load_and_verify_dumpstream(sbox2, None, [], None, False, dump) + + # Check log. + expected_output = svntest.verify.RegexListOutput([ + '-+\\n', + 'r1\ .*\n', + # '/B' is not added. + re.escape('Changed paths:\n'), + re.escape(' A /A\n'), + re.escape(' A /C\n'), + '-+\\n' + ]) + svntest.actions.run_and_verify_svn(expected_output, [], + 'log', '-v', '-q', sbox2.repo_url) + +def dump_not_include_copysource(sbox): + "svnadmin dump with not included copysource" + + sbox.build(create_wc=False, empty=True) + + # Create default repository structure. + svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], "mkdir", + sbox.repo_url + '/trunk', + sbox.repo_url + '/branches', + sbox.repo_url + '/tags', + "-m", "Create repository structure.") + + # Create a branch. + svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], "copy", + sbox.repo_url + '/trunk', + sbox.repo_url + '/branches/branch1', + "-m", "Create branch.") + + # Dump repository with only /branches included. + _, dump, _ = svntest.actions.run_and_verify_svnadmin(None, [], + 'dump', '-q', + '--include', '/branches', + sbox.repo_dir) + + # Load repository from dump. + sbox2 = sbox.clone_dependent() + sbox2.build(create_wc=False, empty=True) + load_and_verify_dumpstream(sbox2, None, [], None, False, dump) + + # Check log. + expected_output = svntest.verify.RegexListOutput([ + '-+\\n', + 'r2\ .*\n', + re.escape('Changed paths:\n'), + # Simple add, not copy. + re.escape(' A /branches/branch1\n'), + '-+\\n', + 'r1\ .*\n', + # Only '/branches' is added in r1. + re.escape('Changed paths:\n'), + re.escape(' A /branches\n'), + '-+\\n' + ]) + svntest.actions.run_and_verify_svn(expected_output, [], + 'log', '-v', '-q', sbox2.repo_url) + +def dump_exclude_by_pattern(sbox): + "svnadmin dump with paths excluded by pattern" + + sbox.build(create_wc=False, empty=True) + + # Create a couple of directories. + svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], "mkdir", + sbox.repo_url + '/aaa', + sbox.repo_url + '/aab', + sbox.repo_url + '/aac', + sbox.repo_url + '/bbc', + "-m", "Create repository structure.") + + # Dump with paths excluded by pattern. + _, dump, _ = svntest.actions.run_and_verify_svnadmin(None, [], + 'dump', '-q', + '--exclude', '/aa?', + '--pattern', + sbox.repo_dir) + + # Load repository from dump. + sbox2 = sbox.clone_dependent() + sbox2.build(create_wc=False, empty=True) + load_and_verify_dumpstream(sbox2, None, [], None, False, dump) + + # Check log. + expected_output = svntest.verify.RegexListOutput([ + '-+\\n', + 'r1\ .*\n', + re.escape('Changed paths:\n'), + # Only '/bbc' is added in r1. + re.escape(' A /bbc\n'), + '-+\\n' + ]) + svntest.actions.run_and_verify_svn(expected_output, [], + 'log', '-v', '-q', sbox2.repo_url) + +def dump_include_by_pattern(sbox): + "svnadmin dump with paths included by pattern" + + sbox.build(create_wc=False, empty=True) + + # Create a couple of directories. + svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], "mkdir", + sbox.repo_url + '/aaa', + sbox.repo_url + '/aab', + sbox.repo_url + '/aac', + sbox.repo_url + '/bbc', + "-m", "Create repository structure.") + + # Dump with paths included by pattern. + _, dump, _ = svntest.actions.run_and_verify_svnadmin(None, [], + 'dump', '-q', + '--include', '/aa?', + '--pattern', + sbox.repo_dir) + + # Load repository from dump. + sbox2 = sbox.clone_dependent() + sbox2.build(create_wc=False, empty=True) + load_and_verify_dumpstream(sbox2, None, [], None, False, dump) + + # Check log. + expected_output = svntest.verify.RegexListOutput([ + '-+\\n', + 'r1\ .*\n', + # '/bbc' is not added. + re.escape('Changed paths:\n'), + re.escape(' A /aaa\n'), + re.escape(' A /aab\n'), + re.escape(' A /aac\n'), + '-+\\n' + ]) + svntest.actions.run_and_verify_svn(expected_output, [], + 'log', '-v', '-q', sbox2.repo_url) + +def dump_exclude_all_rev_changes(sbox): + "svnadmin dump with all revision changes excluded" + + sbox.build(create_wc=False, empty=True) + + # Create a couple of directories (r1). + svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], "mkdir", + sbox.repo_url + '/r1a', + sbox.repo_url + '/r1b', + sbox.repo_url + '/r1c', + "-m", "Revision 1.") + + # Create a couple of directories (r2). + svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], "mkdir", + sbox.repo_url + '/r2a', + sbox.repo_url + '/r2b', + sbox.repo_url + '/r2c', + "-m", "Revision 2.") + + # Create a couple of directories (r3). + svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [], "mkdir", + sbox.repo_url + '/r3a', + sbox.repo_url + '/r3b', + sbox.repo_url + '/r3c', + "-m", "Revision 3.") + + # Dump with paths excluded by pattern. + _, dump, _ = svntest.actions.run_and_verify_svnadmin(None, [], + 'dump', '-q', + '--exclude', '/r2?', + '--pattern', + sbox.repo_dir) + + # Load repository from dump. + sbox2 = sbox.clone_dependent() + sbox2.build(create_wc=False, empty=True) + load_and_verify_dumpstream(sbox2, None, [], None, False, dump) + + # Check log. Revision properties ('svn:log' etc.) should be empty for r2. + expected_output = svntest.verify.RegexListOutput([ + '-+\\n', + 'r3\ |\ jrandom\ |\ .*\ |\ 1\ line\\n', + re.escape('Changed paths:'), + re.escape(' A /r3a'), + re.escape(' A /r3b'), + re.escape(' A /r3c'), + '', + re.escape('Revision 3.'), + '-+\\n', + re.escape('r2 | (no author) | (no date) | 1 line'), + '', + '', + '-+\\n', + 'r1\ |\ jrandom\ |\ .*\ |\ 1\ line\\n', + re.escape('Changed paths:'), + re.escape(' A /r1a'), + re.escape(' A /r1b'), + re.escape(' A /r1c'), + '', + re.escape('Revision 1.'), + '-+\\n', + ]) + svntest.actions.run_and_verify_svn(expected_output, [], + 'log', '-v', sbox2.repo_url) + +def dump_invalid_filtering_option(sbox): + "dump with --include and --exclude simultaneously" + + sbox.build(create_wc=False, empty=False) + + # Attempt to dump repository with '--include' and '--exclude' options + # specified simultaneously. + expected_error = ".*: '--exclude' and '--include' options cannot be used " \ + "simultaneously" + svntest.actions.run_and_verify_svnadmin(None, expected_error, + 'dump', '-q', + '--exclude', '/A/D/H', + '--include', '/A/B/E', + sbox.repo_dir) + ######################################################################## # Run the tests @@ -3500,7 +3850,15 @@ test_list = [ None, dump_no_op_prop_change, load_no_flush_to_disk, dump_to_file, - load_from_file + load_from_file, + dump_exclude, + dump_exclude_copysource, + dump_include, + dump_not_include_copysource, + dump_exclude_by_pattern, + dump_include_by_pattern, + dump_exclude_all_rev_changes, + dump_invalid_filtering_option ] if __name__ == '__main__': Modified: subversion/branches/shelve-checkpoint/subversion/tests/cmdline/svntest/actions.py URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/cmdline/svntest/actions.py?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/tests/cmdline/svntest/actions.py (original) +++ subversion/branches/shelve-checkpoint/subversion/tests/cmdline/svntest/actions.py Tue Oct 31 09:39:59 2017 @@ -355,7 +355,8 @@ def run_and_verify_svn2(expected_stdout, return exit_code, out, err def run_and_verify_load(repo_dir, dump_file_content, - bypass_prop_validation = False): + bypass_prop_validation = False, + normalize_props = False): "Runs 'svnadmin load' and reports any errors." if not isinstance(dump_file_content, list): raise TypeError("dump_file_content argument should have list type") @@ -363,6 +364,8 @@ def run_and_verify_load(repo_dir, dump_f args = () if bypass_prop_validation: args += ('--bypass-prop-validation',) + if normalize_props: + args += ('--normalize-props',) main.run_command_stdin( main.svnadmin_binary, expected_stderr, 0, True, dump_file_content, 'load', '--force-uuid', '--quiet', repo_dir, *args) @@ -473,7 +476,8 @@ def run_and_verify_svnsync2(expected_std def load_repo(sbox, dumpfile_path = None, dump_str = None, - bypass_prop_validation = False,create_wc=True): + bypass_prop_validation = False, create_wc=True, + normalize_props = False): "Loads the dumpfile into sbox" if not dump_str: dump_str = open(dumpfile_path, "rb").read() @@ -485,7 +489,7 @@ def load_repo(sbox, dumpfile_path = None # Load the mergetracking dumpfile into the repos, and check it out the repo run_and_verify_load(sbox.repo_dir, dump_str.splitlines(True), - bypass_prop_validation) + bypass_prop_validation, normalize_props) if create_wc: run_and_verify_svn(None, [], "co", sbox.repo_url, sbox.wc_dir) Modified: subversion/branches/shelve-checkpoint/subversion/tests/cmdline/svntest/verify.py URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/cmdline/svntest/verify.py?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/tests/cmdline/svntest/verify.py (original) +++ subversion/branches/shelve-checkpoint/subversion/tests/cmdline/svntest/verify.py Tue Oct 31 09:39:59 2017 @@ -860,7 +860,7 @@ def make_git_diff_header(target_path, re ]) if text_changes: output.extend([ - "--- /dev/null\t(" + old_tag + ")\n", + "--- a/" + repos_relpath + src_label + "\t(" + old_tag + ")\n", "+++ b/" + repos_relpath + dst_label + "\t(" + new_tag + ")\n" ]) elif delete: @@ -871,7 +871,7 @@ def make_git_diff_header(target_path, re if text_changes: output.extend([ "--- a/" + repos_relpath + src_label + "\t(" + old_tag + ")\n", - "+++ /dev/null\t(" + new_tag + ")\n" + "+++ b/" + repos_relpath + dst_label + "\t(" + new_tag + ")\n" ]) elif cp: if copyfrom_rev: Modified: subversion/branches/shelve-checkpoint/subversion/tests/cmdline/upgrade_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/cmdline/upgrade_tests.py?rev=1813860&r1=1813859&r2=1813860&view=diff ============================================================================== --- subversion/branches/shelve-checkpoint/subversion/tests/cmdline/upgrade_tests.py (original) +++ subversion/branches/shelve-checkpoint/subversion/tests/cmdline/upgrade_tests.py Tue Oct 31 09:39:59 2017 @@ -761,61 +761,6 @@ def dirs_only_upgrade(sbox): }) run_and_verify_status_no_server(sbox.wc_dir, expected_status) -def read_tree_conflict_data(sbox, path): - dot_svn = svntest.main.get_admin_name() - db = svntest.sqlite3.connect(os.path.join(sbox.wc_dir, dot_svn, 'wc.db')) - for row in db.execute("select tree_conflict_data from actual_node " - "where tree_conflict_data is not null " - "and local_relpath = '%s'" % path): - return - raise svntest.Failure("conflict expected for '%s'" % path) - -def no_actual_node(sbox, path): - dot_svn = svntest.main.get_admin_name() - db = svntest.sqlite3.connect(os.path.join(sbox.wc_dir, dot_svn, 'wc.db')) - for row in db.execute("select 1 from actual_node " - "where local_relpath = '%s'" % path): - raise svntest.Failure("no actual node expected for '%s'" % path) - -def upgrade_tree_conflict_data(sbox): - "upgrade tree conflict data (f20->f21)" - - wc_dir = sbox.wc_dir - replace_sbox_with_tarfile(sbox, 'upgrade_tc.tar.bz2') - - # Check and see if we can still read our tree conflicts - expected_status = svntest.actions.get_virginal_state(wc_dir, 2) - expected_status.tweak('A/D/G/pi', status='D ', treeconflict='C') - expected_status.tweak('A/D/G/tau', status='! ', treeconflict='C', - wc_rev=None) - expected_status.tweak('A/D/G/rho', status='A ', copied='+', - treeconflict='C', wc_rev='-') - - # Look inside pre-upgrade database - read_tree_conflict_data(sbox, 'A/D/G') - no_actual_node(sbox, 'A/D/G/pi') - no_actual_node(sbox, 'A/D/G/rho') - no_actual_node(sbox, 'A/D/G/tau') - - # While the upgrade from f20 to f21 will work the upgrade from f22 - # to f23 will not, since working nodes are present. - exit_code, output, errput = svntest.main.run_svn('format 22', 'upgrade', - wc_dir) - - if not exit_code: - run_and_verify_status_no_server(wc_dir, expected_status) - else: - if not svntest.verify.RegexOutput('.*format 22 with WORKING nodes.*', - match_all=False).matches(errput): - raise svntest.Failure() - - # Look insde post-upgrade database - read_tree_conflict_data(sbox, 'A/D/G/pi') - read_tree_conflict_data(sbox, 'A/D/G/rho') - read_tree_conflict_data(sbox, 'A/D/G/tau') - # no_actual_node(sbox, 'A/D/G') ### not removed but should be? - - @Issue(3898) def delete_in_copy_upgrade(sbox): "upgrade a delete within a copy" @@ -972,27 +917,6 @@ def tree_replace2(sbox): }) run_and_verify_status_no_server(sbox.wc_dir, expected_status) -def upgrade_from_format_28(sbox): - """upgrade from format 28: rename pristines""" - - # Start with a format-28 WC that is a clean checkout of the Greek tree. - replace_sbox_with_tarfile(sbox, 'format_28.tar.bz2') - - # Get the old and new pristine file paths for file 'iota'. - checksum = '2c0aa9014a0cd07f01795a333d82485ef6d083e2' - old_pristine_path = os.path.join(sbox.wc_dir, svntest.main.get_admin_name(), - 'pristine', checksum[0:2], checksum) - new_pristine_path = old_pristine_path + '.svn-base' - - assert os.path.exists(old_pristine_path) - assert not os.path.exists(new_pristine_path) - - # Upgrade the WC - svntest.actions.run_and_verify_svn(None, [], 'upgrade', sbox.wc_dir) - - assert not os.path.exists(old_pristine_path) - assert os.path.exists(new_pristine_path) - @Issue(3901) def depth_exclude(sbox): "upgrade 1.6.x wc that has depth=exclude" @@ -1606,13 +1530,11 @@ test_list = [ None, missing_dirs2, delete_and_keep_local, dirs_only_upgrade, - upgrade_tree_conflict_data, delete_in_copy_upgrade, replaced_files, upgrade_with_scheduled_change, tree_replace1, tree_replace2, - upgrade_from_format_28, depth_exclude, depth_exclude_2, add_add_del_del_tc,