You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2015/09/28 19:43:26 UTC
svn commit: r1705733 - in /subversion/trunk/subversion:
include/private/svn_diff_private.h libsvn_client/patch.c
libsvn_diff/parse-diff.c tests/cmdline/patch_tests.py
Author: rhuijben
Date: Mon Sep 28 17:43:25 2015
New Revision: 1705733
URL: http://svn.apache.org/viewvc?rev=1705733&view=rev
Log:
Stop applying some kinds of property changes during 'svn patch' that should
have been stopped by a conflict.
Properties were deleted even if the original value didn't match. This
catches some hidden bugs in the svn:executable handling.
* subversion/include/private/svn_diff_private.h
(svn_diff_hunk__create_adds_single_line,
svn_diff_hunk__create_deletes_single_line): Constify argument.
* subversion/libsvn_client/patch.c
(prop_patch_target_t): Add boolean.
(apply_one_patch): Always push diff items to allow notifying conflicts.
Set skip if nothing changed
(install_patched_prop_targets): If skipping the property don't change its
value.
* subversion/libsvn_diff/parse-diff.c
(svn_diff_hunk_t,
svn_diff_binary_patch_t): Constify pointer.
(svn_diff_hunk__create_adds_single_line,
svn_diff_hunk__create_deletes_single_line): Create reversed hunks, to allow
reading them back as not reversed.
* subversion/tests/cmdline/patch_tests.py
(patch_prop_madness): Tweak expectations. Expect conflicts on property
mismatches, but (currently) not on final EOL only changes.
Modified:
subversion/trunk/subversion/include/private/svn_diff_private.h
subversion/trunk/subversion/libsvn_client/patch.c
subversion/trunk/subversion/libsvn_diff/parse-diff.c
subversion/trunk/subversion/tests/cmdline/patch_tests.py
Modified: subversion/trunk/subversion/include/private/svn_diff_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_diff_private.h?rev=1705733&r1=1705732&r2=1705733&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_diff_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_diff_private.h Mon Sep 28 17:43:25 2015
@@ -123,7 +123,7 @@ svn_diff__display_prop_diffs(svn_stream_
svn_error_t *
svn_diff_hunk__create_adds_single_line(svn_diff_hunk_t **hunk,
const char *line,
- svn_patch_t *patch,
+ const svn_patch_t *patch,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
@@ -137,7 +137,7 @@ svn_diff_hunk__create_adds_single_line(s
svn_error_t *
svn_diff_hunk__create_deletes_single_line(svn_diff_hunk_t **hunk,
const char *line,
- svn_patch_t *patch,
+ const svn_patch_t *patch,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
Modified: subversion/trunk/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/patch.c?rev=1705733&r1=1705732&r2=1705733&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/patch.c (original)
+++ subversion/trunk/subversion/libsvn_client/patch.c Mon Sep 28 17:43:25 2015
@@ -153,6 +153,9 @@ typedef struct prop_patch_target_t {
* ### Should we use flags instead since we're not using all enum values? */
svn_diff_operation_kind_t operation;
+ /* When true the property change won't be applied */
+ svn_boolean_t skipped;
+
/* ### Here we'll add flags telling if the prop was added, deleted,
* ### had_rejects, had_local_mods prior to patching and so on. */
} prop_patch_target_t;
@@ -2622,8 +2625,7 @@ apply_one_patch(patch_target_t **patch_t
TRUE /* is_prop_hunk */,
cancel_func, cancel_baton,
result_pool, iterpool));
- if (! hi->already_applied)
- APR_ARRAY_PUSH(prop_target->content->hunks, hunk_info_t *) = hi;
+ APR_ARRAY_PUSH(prop_target->content->hunks, hunk_info_t *) = hi;
}
/* Apply or reject property hunks. */
@@ -2632,6 +2634,7 @@ apply_one_patch(patch_target_t **patch_t
hash_index = apr_hash_next(hash_index))
{
prop_patch_target_t *prop_target;
+ svn_boolean_t applied_one = FALSE;
prop_target = apr_hash_this_val(hash_index);
@@ -2653,24 +2656,30 @@ apply_one_patch(patch_target_t **patch_t
prop_target->name,
iterpool));
else
- SVN_ERR(apply_hunk(target, prop_target->content, hi,
- prop_target->name,
- iterpool));
+ {
+ SVN_ERR(apply_hunk(target, prop_target->content, hi,
+ prop_target->name,
+ iterpool));
+ applied_one = TRUE;
+ }
}
- if (prop_target->content->existed)
- {
- /* Copy any remaining lines to target. */
- SVN_ERR(copy_lines_to_target(prop_target->content, 0,
- scratch_pool));
- if (! prop_target->content->eof)
- {
- /* We could not copy the entire target property to the
- * temporary file, and would truncate the target if we
- * copied the temporary file on top of it. Skip this target. */
- target->skipped = TRUE;
- }
- }
+ if (!applied_one)
+ prop_target->skipped = TRUE;
+
+ if (applied_one && prop_target->content->existed)
+ {
+ /* Copy any remaining lines to target. */
+ SVN_ERR(copy_lines_to_target(prop_target->content, 0,
+ scratch_pool));
+ if (! prop_target->content->eof)
+ {
+ /* We could not copy the entire target property to the
+ * temporary file, and would truncate the target if we
+ * copied the temporary file on top of it. Skip this target. */
+ target->skipped = TRUE;
+ }
+ }
}
svn_pool_destroy(iterpool);
@@ -3102,6 +3111,9 @@ install_patched_prop_targets(patch_targe
if (ctx->cancel_func)
SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+ if (prop_target->skipped)
+ continue;
+
/* For a deleted prop we only set the value to NULL. */
if (prop_target->operation == svn_diff_op_deleted)
{
Modified: subversion/trunk/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/parse-diff.c?rev=1705733&r1=1705732&r2=1705733&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/trunk/subversion/libsvn_diff/parse-diff.c Mon Sep 28 17:43:25 2015
@@ -64,7 +64,7 @@ struct svn_diff__hunk_range {
struct svn_diff_hunk_t {
/* The patch this hunk belongs to. */
- svn_patch_t *patch;
+ const svn_patch_t *patch;
/* APR file handle to the patch file this hunk came from. */
apr_file_t *apr_file;
@@ -93,7 +93,7 @@ struct svn_diff_hunk_t {
struct svn_diff_binary_patch_t {
/* The patch this hunk belongs to. */
- svn_patch_t *patch;
+ const svn_patch_t *patch;
/* APR file handle to the patch file this hunk came from. */
apr_file_t *apr_file;
@@ -117,7 +117,7 @@ struct svn_diff_binary_patch_t {
static svn_error_t *
add_or_delete_single_line(svn_diff_hunk_t **hunk_out,
const char *line,
- svn_patch_t *patch,
+ const svn_patch_t *patch,
svn_boolean_t add,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
@@ -202,11 +202,12 @@ add_or_delete_single_line(svn_diff_hunk_
svn_error_t *
svn_diff_hunk__create_adds_single_line(svn_diff_hunk_t **hunk_out,
const char *line,
- svn_patch_t *patch,
+ const svn_patch_t *patch,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- SVN_ERR(add_or_delete_single_line(hunk_out, line, patch, TRUE,
+ SVN_ERR(add_or_delete_single_line(hunk_out, line, patch,
+ (!patch->reverse),
result_pool, scratch_pool));
return SVN_NO_ERROR;
}
@@ -214,11 +215,12 @@ svn_diff_hunk__create_adds_single_line(s
svn_error_t *
svn_diff_hunk__create_deletes_single_line(svn_diff_hunk_t **hunk_out,
const char *line,
- svn_patch_t *patch,
+ const svn_patch_t *patch,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- SVN_ERR(add_or_delete_single_line(hunk_out, line, patch, FALSE,
+ SVN_ERR(add_or_delete_single_line(hunk_out, line, patch,
+ patch->reverse,
result_pool, scratch_pool));
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/patch_tests.py?rev=1705733&r1=1705732&r2=1705733&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/patch_tests.py Mon Sep 28 17:43:25 2015
@@ -6227,6 +6227,17 @@ def patch_prop_madness(sbox):
sbox.simple_commit()
+ r2_props = {
+ 'mod_l_n' : 'this\nis\na\nvery\nvery\nlong\nvalue.\nwithout\neol',
+ 'mod_l' : 'this\nis\na\nvery\nvery\nlong\nvalue.\n',
+ 'mod_s' : 'value\n',
+ 'mod_s_n' : 'no-eol',
+ 'del' : 'value\n',
+ 'del_n' : 'no-eol',
+ }
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('iota', 'A/mu', props=r2_props)
+
sbox.simple_propset('mod_s', 'other\n',
'iota', 'A/mu')
@@ -6259,7 +6270,6 @@ def patch_prop_madness(sbox):
_, output, _ = svntest.actions.run_and_verify_svn(None, [],
'diff', wc_dir)
- expected_disk = svntest.main.greek_state.copy()
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
new_props = {
@@ -6311,15 +6321,7 @@ def patch_prop_madness(sbox):
# Reverse
expected_output.tweak('A/mu', 'iota', status=' U')
- props = {
- 'mod_l_n' : 'this\nis\na\nvery\nvery\nlong\nvalue.\nwithout\neol',
- 'mod_l' : 'this\nis\na\nvery\nvery\nlong\nvalue.\n',
- 'mod_s' : 'value\n',
- 'mod_s_n' : 'no-eol',
- 'del' : 'value\n',
- 'del_n' : 'no-eol',
- }
- expected_disk.tweak('A/mu', 'iota', props=props)
+ expected_disk.tweak('A/mu', 'iota', props=r2_props)
expected_status.tweak('A/mu', 'iota', status=' ')
svntest.actions.run_and_verify_patch(wc_dir, patch,
expected_output, expected_disk,
@@ -6340,12 +6342,39 @@ def patch_prop_madness(sbox):
# Ok, and now introduce some conflicts
sbox.simple_propset('del', 'value', 'iota') # Wrong EOL
- sbox.simple_propset('del', 'waarde', 'A/mu') # Wrong EOL+value
-
- sbox.simple_propset('del_n', 'no-eol\n', 'iota') # Wrong EOL
sbox.simple_propset('del_n', 'regeleinde\n', 'iota') # Wrong EOL+value
+ sbox.simple_propset('del', 'waarde', 'A/mu') # Wrong EOL+value
+ sbox.simple_propset('del_n', 'no-eol\n', 'A/mu') # Wrong EOL
+
expected_output.tweak('A/mu', 'iota', status=' C')
+ expected_status.tweak('iota', 'A/mu', status=' M')
+
+ iota_props = new_props.copy()
+ iota_props['del_n'] = 'regeleinde\n'
+ mu_props = new_props.copy()
+ mu_props['del'] = 'waarde'
+ expected_disk.tweak('iota', props=iota_props)
+ expected_disk.tweak('A/mu', props=mu_props)
+
+ expected_disk.add({
+ 'A/mu.svnpatch.rej' : Item(contents="--- %s\n"
+ "+++ %s\n"
+ "Property: del\n"
+ "## -1,1 +0,0 ##\n"
+ "-value\n"
+ % (sbox.path('A/mu'),
+ sbox.path('A/mu'))),
+ 'iota.svnpatch.rej' : Item(contents="--- %s\n"
+ "+++ %s\n"
+ "Property: del_n\n"
+ "## -1,1 +0,0 ##\n"
+ "-no-eol\n"
+ "\ No newline at end of property\n"
+ % (sbox.path('iota'),
+ sbox.path('iota'))),
+ })
+
svntest.actions.run_and_verify_patch(wc_dir, patch,
expected_output, expected_disk,
expected_status, expected_skip,