You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/03/18 12:58:09 UTC
svn commit: r924737 - in /subversion/trunk/subversion: include/svn_client.h
libsvn_client/patch.c svn/cl.h svn/main.c svn/patch-cmd.c
tests/cmdline/patch_tests.py
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: dev@subversion.apache.org
Subject: Re: svn commit: r919460 - filtering svn patch targets
Message-ID: <20...@jack.stsp.name>
http://svn.haxx.se/dev/archive-2010-03/0236.shtml
http://mail-archives.apache.org/mod_mbox/subversion-dev/201003.mbox/%3C20100310104635.GD14558@jack.stsp.name%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__':