Author: stsp Date: Thu Mar 18 11:58:08 2010 New Revision: 924737 URL: http://svn.apache.org/viewvc?rev=924737&view=rev Log: More work on issue #3434, which wasn't really fixed by r919460 alone.
For related discussion, see this and related messages: From: Stefan Sperling To: Julian Foad Cc: [email protected] Subject: Re: svn commit: r919460 - filtering svn patch targets Message-ID: <[email protected]> http://svn.haxx.se/dev/archive-2010-03/0236.shtml http://mail-archives.apache.org/mod_mbox/subversion-dev/201003.mbox/%[email protected]%3e * subversion/include/svn_client.h (svn_client_patch): Add INCLUDE_PATTERNS paramter. * subversion/libsvn_client/patch.c (init_patch_target): Add INCLUDE_PATTERNS parameter. If specified, only patch targets matching include patterns. Tweak scope of some variables. (apply_one_patch, apply_patches_baton_t, svn_client_patch): Add INCLUDE_PATTERNS parameter / member. * subversion/svn/cl.h (svn_cl__opt_state_t): Add INCLUDE_PATTERNS member. * subversion/svn/main.c (svn_cl__longopt_t, svn_cl__options): Add OPT_INCLUDE_PATTERN and corresponding --include-pattern option. (svn_cl__cmd_table, main): Make 'svn patch' accept --include-pattern. * subversion/svn/patch-cmd.c (svn_cl__patch): Pass include patterns to svn_client_patch(). * subversion/tests/cmdline/patch_tests.py (patch_with_include_patterns): New test. (patch_with_exclude_patterns): Tweak test description. (patch_with_include_exclude_patterns): New test. (test_list): Add new tests. Modified: subversion/trunk/subversion/include/svn_client.h subversion/trunk/subversion/libsvn_client/patch.c subversion/trunk/subversion/svn/cl.h subversion/trunk/subversion/svn/main.c subversion/trunk/subversion/svn/patch-cmd.c subversion/trunk/subversion/tests/cmdline/patch_tests.py Modified: subversion/trunk/subversion/include/svn_client.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=924737&r1=924736&r2=924737&view=diff ============================================================================== --- subversion/trunk/subversion/include/svn_client.h (original) +++ subversion/trunk/subversion/include/svn_client.h Thu Mar 18 11:58:08 2010 @@ -4849,10 +4849,17 @@ svn_client_info(const char *path_or_url, * original and modified files swapped due to human error. * * Excluding patch targets from the patching process is possible by passing - * an @a exclude_patterns array containing elements of type const char *. + * @a include_patterns and/or @a exclude_patterns arrays containing + * elements of type const char *. + * If @a include_patterns is not NULL, patch targets not matching any glob + * pattern in @a include_patterns will not be patched. * If @a exclude_patterns is not NULL, patch targets matching any glob pattern - * in @a exclude_patterns will not be patched. The match is performed on the - * target path as parsed from the patch file, after canonicalization. + * in @a exclude_patterns will not be patched + * The match is performed on the target path as parsed from the patch file, + * after canonicalization. + * If both @a include_patterns and @a exclude_patterns are specified, + * the @a include_patterns are applied first, i.e. the @a exclude_patterns + * are applied to all targets which matched one of the @a include_patterns. * * If @a ctx->notify_func2 is non-NULL, invoke @a ctx->notify_func2 with * @a ctx->notify_baton2 as patching progresses. @@ -4868,6 +4875,7 @@ svn_client_patch(const char *abs_patch_p svn_boolean_t dry_run, int strip_count, svn_boolean_t reverse, + const apr_array_header_t *include_patterns, const apr_array_header_t *exclude_patterns, svn_client_ctx_t *ctx, apr_pool_t *pool); Modified: subversion/trunk/subversion/libsvn_client/patch.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/patch.c?rev=924737&r1=924736&r2=924737&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_client/patch.c (original) +++ subversion/trunk/subversion/libsvn_client/patch.c Thu Mar 18 11:58:08 2010 @@ -325,6 +325,7 @@ resolve_target_path(patch_target_t *targ * which should be stripped from target paths in the patch. * Upon success, allocate the patch target structure in RESULT_POOL. * Else, set *target to NULL. + * If a target does not match a glob in INCLUDE_PATTERNS, mark it as filtered. * If a target matches a glob in EXCLUDE_PATTERNS, mark it as filtered. * Use SCRATCH_POOL for all other allocations. */ static svn_error_t * @@ -332,11 +333,11 @@ init_patch_target(patch_target_t **patch const svn_patch_t *patch, const char *base_dir, svn_wc_context_t *wc_ctx, int strip_count, + const apr_array_header_t *include_patterns, const apr_array_header_t *exclude_patterns, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { patch_target_t *target; - int i; target = apr_pcalloc(result_pool, sizeof(*target)); @@ -345,12 +346,36 @@ init_patch_target(patch_target_t **patch result_pool, scratch_pool)); target->filtered = FALSE; + if (include_patterns) + { + int i; + const char *glob; + svn_boolean_t match; + + match = FALSE; + for (i = 0; i < include_patterns->nelts; i++) + { + glob = APR_ARRAY_IDX(include_patterns, i, const char *); + match = (apr_fnmatch(glob, target->canon_path_from_patchfile, + APR_FNM_CASE_BLIND) == APR_SUCCESS); + if (match) + break; + } + + if (! match) + { + target->filtered = TRUE; + *patch_target = target; + return SVN_NO_ERROR; + } + } if (exclude_patterns) { + int i; + const char *glob; + for (i = 0; i < exclude_patterns->nelts; i++) { - const char *glob; - glob = APR_ARRAY_IDX(exclude_patterns, i, const char *); target->filtered = (apr_fnmatch(glob, target->canon_path_from_patchfile, @@ -1055,12 +1080,15 @@ send_patch_notification(const patch_targ * in RESULT_POOL. Use WC_CTX as the working copy context. * STRIP_COUNT specifies the number of leading path components * which should be stripped from target paths in the patch. + * If a target does not match a glob in INCLUDE_PATTERNS, mark it as filtered. * If a target matches a glob in EXCLUDE_PATTERNS, mark it as filtered. * Do temporary allocations in SCRATCH_POOL. */ static svn_error_t * apply_one_patch(patch_target_t **patch_target, svn_patch_t *patch, const char *abs_wc_path, svn_wc_context_t *wc_ctx, - int strip_count, const apr_array_header_t *exclude_patterns, + int strip_count, + const apr_array_header_t *include_patterns, + const apr_array_header_t *exclude_patterns, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { patch_target_t *target; @@ -1069,7 +1097,8 @@ apply_one_patch(patch_target_t **patch_t static const int MAX_FUZZ = 2; SVN_ERR(init_patch_target(&target, patch, abs_wc_path, wc_ctx, strip_count, - exclude_patterns, result_pool, scratch_pool)); + include_patterns, exclude_patterns, + result_pool, scratch_pool)); if (target->skipped || target->filtered) { @@ -1378,7 +1407,10 @@ typedef struct { /* Whether to apply the patch in reverse. */ svn_boolean_t reverse; - /* Glob patterns. Files matching any of these patterns won't be patched. */ + /* Files not matching any of these patterns won't be patched. */ + const apr_array_header_t *include_patterns; + + /* Files matching any of these patterns won't be patched. */ const apr_array_header_t *exclude_patterns; /* The client context. */ @@ -1433,7 +1465,8 @@ apply_patches(void *baton, SVN_ERR(apply_one_patch(&target, patch, btn->abs_wc_path, btn->ctx->wc_ctx, btn->strip_count, - btn->exclude_patterns, scratch_pool, iterpool)); + btn->include_patterns, btn->exclude_patterns, + scratch_pool, iterpool)); if (target->filtered) SVN_ERR(svn_diff__close_patch(patch)); else @@ -1473,6 +1506,7 @@ svn_client_patch(const char *abs_patch_p svn_boolean_t dry_run, int strip_count, svn_boolean_t reverse, + const apr_array_header_t *include_patterns, const apr_array_header_t *exclude_patterns, svn_client_ctx_t *ctx, apr_pool_t *pool) @@ -1489,6 +1523,7 @@ svn_client_patch(const char *abs_patch_p baton.ctx = ctx; baton.strip_count = strip_count; baton.reverse = reverse; + baton.include_patterns = include_patterns; baton.exclude_patterns = exclude_patterns; SVN_ERR(svn_wc__call_with_write_lock(apply_patches, &baton, Modified: subversion/trunk/subversion/svn/cl.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=924737&r1=924736&r2=924737&view=diff ============================================================================== --- subversion/trunk/subversion/svn/cl.h (original) +++ subversion/trunk/subversion/svn/cl.h Thu Mar 18 11:58:08 2010 @@ -224,6 +224,7 @@ typedef struct svn_cl__opt_state_t int strip_count; /* number of leading path components to strip */ svn_boolean_t ignore_keywords; /* do not expand keywords */ svn_boolean_t reverse_diff; /* reverse a diff (e.g. when patching) */ + apr_array_header_t *include_patterns; /* targets to include in operation */ apr_array_header_t *exclude_patterns; /* targets to exclude from operation */ } svn_cl__opt_state_t; Modified: subversion/trunk/subversion/svn/main.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/main.c?rev=924737&r1=924736&r2=924737&view=diff ============================================================================== --- subversion/trunk/subversion/svn/main.c (original) +++ subversion/trunk/subversion/svn/main.c Thu Mar 18 11:58:08 2010 @@ -117,6 +117,7 @@ typedef enum { opt_show_copies_as_adds, opt_ignore_keywords, opt_reverse_diff, + opt_include_pattern, opt_exclude_pattern, } svn_cl__longopt_t; @@ -348,6 +349,24 @@ const apr_getopt_option_t svn_cl__option N_("apply the unidiff in reverse\n" " " "[alias: --rd]")}, + {"include-pattern", opt_include_pattern, 1, + N_("operate only on targets matching ARG,\n" + " " + "which may be a glob pattern such as '*.txt'.\n" + " " + "If this option is specified multiple times,\n" + " " + "all patterns are matched in turn.\n" + " " + "If both --include-pattern and --exclude-pattern\n" + " " + "options are specified include patterns are applied\n" + " " + "first, i.e. exclude patterns are applied to all\n" + " " + "targets which match an include pattern.\n" + " " + "[alias: --ip]")}, {"exclude-pattern", opt_exclude_pattern, 1, N_("do not operate on targets matching ARG,\n" " " @@ -357,6 +376,8 @@ const apr_getopt_option_t svn_cl__option " " "all patterns are matched in turn.\n" " " + "See also the --include-pattern option.\n" + " " "[alias: --ep]")}, /* Long-opt Aliases * @@ -382,6 +403,7 @@ const apr_getopt_option_t svn_cl__option {"ri", opt_reintegrate, 0, NULL}, {"sca", opt_show_copies_as_adds, 0, NULL}, {"ik", opt_ignore_keywords, 0, NULL}, + {"ip", opt_include_pattern, 1, NULL}, {"ep", opt_exclude_pattern, 1, NULL}, {0, 0, 0, 0}, @@ -824,7 +846,8 @@ const svn_opt_subcommand_desc2_t svn_cl_ " for addition. Use 'svn revert' to undo deletions and additions you\n" " do not agree with.\n" ), - {'q', opt_dry_run, 'p', opt_reverse_diff, opt_exclude_pattern} }, + {'q', opt_dry_run, 'p', opt_reverse_diff, opt_include_pattern, + opt_exclude_pattern} }, { "propdel", svn_cl__propdel, {"pdel", "pd"}, N_ ("Remove a property from files, dirs, or revisions.\n" @@ -1739,6 +1762,12 @@ main(int argc, const char *argv[]) case opt_reverse_diff: opt_state.reverse_diff = TRUE; break; + case opt_include_pattern: + if (opt_state.include_patterns == NULL) + opt_state.include_patterns = apr_array_make(pool, 1, + sizeof (const char *)); + APR_ARRAY_PUSH(opt_state.include_patterns, const char *) = opt_arg; + break; case opt_exclude_pattern: if (opt_state.exclude_patterns == NULL) opt_state.exclude_patterns = apr_array_make(pool, 1, Modified: subversion/trunk/subversion/svn/patch-cmd.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/patch-cmd.c?rev=924737&r1=924736&r2=924737&view=diff ============================================================================== --- subversion/trunk/subversion/svn/patch-cmd.c (original) +++ subversion/trunk/subversion/svn/patch-cmd.c Thu Mar 18 11:58:08 2010 @@ -79,6 +79,7 @@ svn_cl__patch(apr_getopt_t *os, SVN_ERR(svn_client_patch(abs_patch_path, abs_target_path, opt_state->dry_run, opt_state->strip_count, opt_state->reverse_diff, + opt_state->include_patterns, opt_state->exclude_patterns, ctx, pool)); if (! opt_state->quiet) Modified: subversion/trunk/subversion/tests/cmdline/patch_tests.py URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/patch_tests.py?rev=924737&r1=924736&r2=924737&view=diff ============================================================================== --- subversion/trunk/subversion/tests/cmdline/patch_tests.py (original) +++ subversion/trunk/subversion/tests/cmdline/patch_tests.py Thu Mar 18 11:58:08 2010 @@ -1677,8 +1677,166 @@ def patch_with_svn_eol_style_uncommitted expected_output = ["Reverted '" + mu_path + "'\n"] svntest.actions.run_and_verify_svn(None, expected_output, [], 'revert', '-R', wc_dir) +def patch_with_include_patterns(sbox): + "patch with include-patterns" + + sbox.build() + wc_dir = sbox.wc_dir + + patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1] + mu_path = os.path.join(wc_dir, 'A', 'mu') + + mu_contents = [ + "Dear internet user,\n", + "\n", + "We wish to congratulate you over your email success in our computer\n", + "Balloting. This is a Millennium Scientific Electronic Computer Draw\n", + "in which email addresses were used. All participants were selected\n", + "through a computer ballot system drawn from over 100,000 company\n", + "and 50,000,000 individual email addresses from all over the world.\n", + "\n", + "Your email address drew and have won the sum of 750,000 Euros\n", + "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n", + "file with\n", + " REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n", + " WINNING NUMBER : 14-17-24-34-37-45-16\n", + " BATCH NUMBERS :\n", + " EULO/1007/444/606/08;\n", + " SERIAL NUMBER: 45327\n", + "and PROMOTION DATE: 13th June. 2009\n", + "\n", + "To claim your winning prize, you are to contact the appointed\n", + "agent below as soon as possible for the immediate release of your\n", + "winnings with the below details.\n", + "\n", + "Again, we wish to congratulate you over your email success in our\n" + "computer Balloting.\n" + ] + + # Set mu contents + svntest.main.file_write(mu_path, ''.join(mu_contents)) + expected_output = svntest.wc.State(wc_dir, { + 'A/mu' : Item(verb='Sending'), + }) + expected_status = svntest.actions.get_virginal_state(wc_dir, 1) + expected_status.tweak('A/mu', wc_rev=2) + svntest.actions.run_and_verify_commit(wc_dir, expected_output, + expected_status, None, wc_dir) + + # Apply patch + + unidiff_patch = [ + "Index: A/D/gamma\n", + "===================================================================\n", + "--- A/D/gamma\t(revision 1)\n", + "+++ A/D/gamma\t(working copy)\n", + "@@ -1 +1 @@\n", + "-This is the file 'gamma'.\n", + "+It is the file 'gamma'.\n", + "Index: iota\n", + "===================================================================\n", + "--- iota\t(revision 1)\n", + "+++ iota\t(working copy)\n", + "@@ -1 +1,2 @@\n", + " This is the file 'iota'.\n", + "+Some more bytes\n", + "\n", + "Index: new\n", + "===================================================================\n", + "--- new (revision 0)\n", + "+++ new (revision 0)\n", + "@@ -0,0 +1 @@\n", + "+new\n", + "\n", + "--- A/mu.orig 2009-06-24 15:23:55.000000000 +0100\n", + "+++ A/mu 2009-06-24 15:21:23.000000000 +0100\n", + "@@ -6,6 +6,9 @@\n", + " through a computer ballot system drawn from over 100,000 company\n", + " and 50,000,000 individual email addresses from all over the world.\n", + " \n", + "+It is a promotional program aimed at encouraging internet users;\n", + "+therefore you do not need to buy ticket to enter for it.\n", + "+\n", + " Your email address drew and have won the sum of 750,000 Euros\n", + " ( Seven Hundred and Fifty Thousand Euros) in cash credited to\n", + " file with\n", + "@@ -14,11 +17,8 @@\n", + " BATCH NUMBERS :\n", + " EULO/1007/444/606/08;\n", + " SERIAL NUMBER: 45327\n", + "-and PROMOTION DATE: 13th June. 2009\n", + "+and PROMOTION DATE: 14th June. 2009\n", + " \n", + " To claim your winning prize, you are to contact the appointed\n", + " agent below as soon as possible for the immediate release of your\n", + " winnings with the below details.\n", + "-\n", + "-Again, we wish to congratulate you over your email success in our\n", + "-computer Balloting.\n", + "Index: A/B/E/beta\n", + "===================================================================\n", + "--- A/B/E/beta (revision 1)\n", + "+++ A/B/E/beta (working copy)\n", + "@@ -1 +0,0 @@\n", + "-This is the file 'beta'.\n", + ] + + svntest.main.file_write(patch_file_path, ''.join(unidiff_patch)) + + gamma_contents = "It is the file 'gamma'.\n" + iota_contents = "This is the file 'iota'.\nSome more bytes\n" + new_contents = "new\n" + mu_contents = [ + "Dear internet user,\n", + "\n", + "We wish to congratulate you over your email success in our computer\n", + "Balloting. This is a Millennium Scientific Electronic Computer Draw\n", + "in which email addresses were used. All participants were selected\n", + "through a computer ballot system drawn from over 100,000 company\n", + "and 50,000,000 individual email addresses from all over the world.\n", + "\n", + "It is a promotional program aimed at encouraging internet users;\n", + "therefore you do not need to buy ticket to enter for it.\n", + "\n", + "Your email address drew and have won the sum of 750,000 Euros\n", + "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n", + "file with\n", + " REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n", + " WINNING NUMBER : 14-17-24-34-37-45-16\n", + " BATCH NUMBERS :\n", + " EULO/1007/444/606/08;\n", + " SERIAL NUMBER: 45327\n", + "and PROMOTION DATE: 14th June. 2009\n", + "\n", + "To claim your winning prize, you are to contact the appointed\n", + "agent below as soon as possible for the immediate release of your\n", + "winnings with the below details.\n", + ] + + expected_output = [ + 'U %s\n' % os.path.join(wc_dir, 'A', 'mu'), + ] + + expected_disk = svntest.main.greek_state.copy() + expected_disk.tweak('A/mu', contents=''.join(mu_contents)) + + expected_status = svntest.actions.get_virginal_state(wc_dir, 1) + expected_status.tweak('A/mu', status='M ', wc_rev=2) + + expected_skip = wc.State('', { }) + + svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path), + expected_output, + expected_disk, + expected_status, + expected_skip, + None, # expected err + 1, # check-props + 1, # dry-run + "--include-pattern", "A/mu") + def patch_with_exclude_patterns(sbox): - "patch with --exclude-patterns" + "patch with exclude-patterns" sbox.build() wc_dir = sbox.wc_dir @@ -1837,6 +1995,172 @@ def patch_with_exclude_patterns(sbox): "--exclude-pattern", "new", "--exclude-pattern", "*a") +def patch_with_include_exclude_patterns(sbox): + "patch with include-patterns and exclude-patterns" + + sbox.build() + wc_dir = sbox.wc_dir + + patch_file_path = tempfile.mkstemp(dir=os.path.abspath(svntest.main.temp_dir))[1] + mu_path = os.path.join(wc_dir, 'A', 'mu') + + mu_contents = [ + "Dear internet user,\n", + "\n", + "We wish to congratulate you over your email success in our computer\n", + "Balloting. This is a Millennium Scientific Electronic Computer Draw\n", + "in which email addresses were used. All participants were selected\n", + "through a computer ballot system drawn from over 100,000 company\n", + "and 50,000,000 individual email addresses from all over the world.\n", + "\n", + "Your email address drew and have won the sum of 750,000 Euros\n", + "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n", + "file with\n", + " REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n", + " WINNING NUMBER : 14-17-24-34-37-45-16\n", + " BATCH NUMBERS :\n", + " EULO/1007/444/606/08;\n", + " SERIAL NUMBER: 45327\n", + "and PROMOTION DATE: 13th June. 2009\n", + "\n", + "To claim your winning prize, you are to contact the appointed\n", + "agent below as soon as possible for the immediate release of your\n", + "winnings with the below details.\n", + "\n", + "Again, we wish to congratulate you over your email success in our\n" + "computer Balloting.\n" + ] + + # Set mu contents + svntest.main.file_write(mu_path, ''.join(mu_contents)) + expected_output = svntest.wc.State(wc_dir, { + 'A/mu' : Item(verb='Sending'), + }) + expected_status = svntest.actions.get_virginal_state(wc_dir, 1) + expected_status.tweak('A/mu', wc_rev=2) + svntest.actions.run_and_verify_commit(wc_dir, expected_output, + expected_status, None, wc_dir) + + # Apply patch + + unidiff_patch = [ + "Index: A/D/gamma\n", + "===================================================================\n", + "--- A/D/gamma\t(revision 1)\n", + "+++ A/D/gamma\t(working copy)\n", + "@@ -1 +1 @@\n", + "-This is the file 'gamma'.\n", + "+It is the file 'gamma'.\n", + "Index: iota\n", + "===================================================================\n", + "--- iota\t(revision 1)\n", + "+++ iota\t(working copy)\n", + "@@ -1 +1,2 @@\n", + " This is the file 'iota'.\n", + "+Some more bytes\n", + "\n", + "Index: new\n", + "===================================================================\n", + "--- new (revision 0)\n", + "+++ new (revision 0)\n", + "@@ -0,0 +1 @@\n", + "+new\n", + "\n", + "--- A/mu.orig 2009-06-24 15:23:55.000000000 +0100\n", + "+++ A/mu 2009-06-24 15:21:23.000000000 +0100\n", + "@@ -6,6 +6,9 @@\n", + " through a computer ballot system drawn from over 100,000 company\n", + " and 50,000,000 individual email addresses from all over the world.\n", + " \n", + "+It is a promotional program aimed at encouraging internet users;\n", + "+therefore you do not need to buy ticket to enter for it.\n", + "+\n", + " Your email address drew and have won the sum of 750,000 Euros\n", + " ( Seven Hundred and Fifty Thousand Euros) in cash credited to\n", + " file with\n", + "@@ -14,11 +17,8 @@\n", + " BATCH NUMBERS :\n", + " EULO/1007/444/606/08;\n", + " SERIAL NUMBER: 45327\n", + "-and PROMOTION DATE: 13th June. 2009\n", + "+and PROMOTION DATE: 14th June. 2009\n", + " \n", + " To claim your winning prize, you are to contact the appointed\n", + " agent below as soon as possible for the immediate release of your\n", + " winnings with the below details.\n", + "-\n", + "-Again, we wish to congratulate you over your email success in our\n", + "-computer Balloting.\n", + "Index: A/B/E/beta\n", + "===================================================================\n", + "--- A/B/E/beta (revision 1)\n", + "+++ A/B/E/beta (working copy)\n", + "@@ -1 +0,0 @@\n", + "-This is the file 'beta'.\n", + ] + + svntest.main.file_write(patch_file_path, ''.join(unidiff_patch)) + + gamma_contents = "It is the file 'gamma'.\n" + iota_contents = "This is the file 'iota'.\nSome more bytes\n" + new_contents = "new\n" + mu_contents = [ + "Dear internet user,\n", + "\n", + "We wish to congratulate you over your email success in our computer\n", + "Balloting. This is a Millennium Scientific Electronic Computer Draw\n", + "in which email addresses were used. All participants were selected\n", + "through a computer ballot system drawn from over 100,000 company\n", + "and 50,000,000 individual email addresses from all over the world.\n", + "\n", + "It is a promotional program aimed at encouraging internet users;\n", + "therefore you do not need to buy ticket to enter for it.\n", + "\n", + "Your email address drew and have won the sum of 750,000 Euros\n", + "( Seven Hundred and Fifty Thousand Euros) in cash credited to\n", + "file with\n", + " REFERENCE NUMBER: ESP/WIN/008/05/10/MA;\n", + " WINNING NUMBER : 14-17-24-34-37-45-16\n", + " BATCH NUMBERS :\n", + " EULO/1007/444/606/08;\n", + " SERIAL NUMBER: 45327\n", + "and PROMOTION DATE: 14th June. 2009\n", + "\n", + "To claim your winning prize, you are to contact the appointed\n", + "agent below as soon as possible for the immediate release of your\n", + "winnings with the below details.\n", + ] + + expected_output = [ + 'U %s\n' % os.path.join(wc_dir, 'iota'), + 'U %s\n' % os.path.join(wc_dir, 'A', 'mu'), + 'D %s\n' % os.path.join(wc_dir, 'A', 'B', 'E', 'beta'), + ] + + expected_disk = svntest.main.greek_state.copy() + expected_disk.tweak('A/mu', contents=''.join(mu_contents)) + expected_disk.tweak('iota', contents=''.join(iota_contents)) + expected_disk.remove('A/B/E/beta') + + expected_status = svntest.actions.get_virginal_state(wc_dir, 1) + expected_status.tweak('A/mu', status='M ', wc_rev=2) + expected_status.tweak('iota', status='M ') + expected_status.tweak('A/B/E/beta', status='D ') + + expected_skip = wc.State('', { }) + + svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path), + expected_output, + expected_disk, + expected_status, + expected_skip, + None, # expected err + 1, # check-props + 1, # dry-run + "--include-pattern", "A/mu", + "--include-pattern", "*a", + "--exclude-pattern", "A/*/gamma") + ######################################################################## #Run the tests @@ -1855,7 +2179,9 @@ test_list = [ None, patch_no_svn_eol_style, patch_with_svn_eol_style, patch_with_svn_eol_style_uncommitted, + patch_with_include_patterns, patch_with_exclude_patterns, + patch_with_include_exclude_patterns, ] if __name__ == '__main__':
