Author: danielsh
Date: Tue Aug 4 10:49:41 2015
New Revision: 1694029
URL: http://svn.apache.org/r1694029
Log:
On the patch-exec branch, support mode changes that remove executability.
* subversion/include/private/svn_diff_private.h
(svn_diff_hunk__create_deletes_single_line): New function.
* subversion/libsvn_client/patch.c
(apply_one_patch): Call it, closing an "unimplemented" codepath.
* subversion/libsvn_diff/parse-diff.c
(svn_diff_hunk__create_adds_single_line): Make this a wrapper around..
(add_or_delete_single_line): .. this new function.
(svn_diff_hunk__create_deletes_single_line): Implement in terms of
add_or_delete_single_line().
* subversion/tests/cmdline/patch_tests.py
(patch_deletes_executability): New test.
* BRANCH-README: Mark this task done.
Modified:
subversion/branches/patch-exec/BRANCH-README
subversion/branches/patch-exec/subversion/include/private/svn_diff_private.h
subversion/branches/patch-exec/subversion/libsvn_client/patch.c
subversion/branches/patch-exec/subversion/libsvn_diff/parse-diff.c
subversion/branches/patch-exec/subversion/tests/cmdline/patch_tests.py
Modified: subversion/branches/patch-exec/BRANCH-README
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/BRANCH-README?rev=1694029&r1=1694028&r2=1694029&view=diff
==============================================================================
--- subversion/branches/patch-exec/BRANCH-README (original)
+++ subversion/branches/patch-exec/BRANCH-README Tue Aug 4 10:49:41 2015
@@ -7,7 +7,7 @@ Steps:
- [DONE] Implement parse-diff.c support
- [DONE] Implement "make it executable" support, with tests
-- [TODO] Implement "make it non-executable" support, with tests
+- [DONE] Implement "make it non-executable" support, with tests
- [TODO] Write tests for adding/remove svn:executable using the normal
'svn diff' property add/removal syntax
- [TODO] parser: Review handling of modes other than 0644/0755
Modified: subversion/branches/patch-exec/subversion/include/private/svn_diff_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/include/private/svn_diff_private.h?rev=1694029&r1=1694028&r2=1694029&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/include/private/svn_diff_private.h (original)
+++ subversion/branches/patch-exec/subversion/include/private/svn_diff_private.h Tue Aug
4 10:49:41 2015
@@ -127,6 +127,20 @@ svn_diff_hunk__create_adds_single_line(s
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/** Create a hunk object that deletes a single line. Return the new object
+ * in @a *hunk.
+ *
+ * @a line is the deleted text, without a trailing newline.
+ *
+ * The hunk will be associated with @a patch.
+ */
+svn_error_t *
+svn_diff_hunk__create_deletes_single_line(svn_diff_hunk_t **hunk,
+ const char *line,
+ svn_patch_t *patch,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/branches/patch-exec/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_client/patch.c?rev=1694029&r1=1694028&r2=1694029&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_client/patch.c Tue Aug 4 10:49:41 2015
@@ -2480,7 +2480,11 @@ apply_one_patch(patch_target_t **patch_t
break;
case svn_diff_op_deleted:
- SVN__NOT_IMPLEMENTED();
+ SVN_ERR(svn_diff_hunk__create_deletes_single_line(&hunk, value,
+ patch,
+ result_pool,
+ iterpool));
+ break;
case svn_diff_op_unchanged:
/* ### What to do? */
Modified: subversion/branches/patch-exec/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_diff/parse-diff.c?rev=1694029&r1=1694028&r2=1694029&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_diff/parse-diff.c Tue Aug 4 10:49:41
2015
@@ -83,18 +83,24 @@ struct svn_diff_hunk_t {
svn_linenum_t trailing_context;
};
+/* Common guts of svn_diff_hunk__create_adds_single_line() and
+ * svn_diff_hunk__create_deletes_single_line().
+ *
+ * ADD is TRUE if adding and FALSE if deleting.
+ */
svn_error_t *
-svn_diff_hunk__create_adds_single_line(svn_diff_hunk_t **hunk_out,
- const char *line,
- svn_patch_t *patch,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+add_or_delete_single_line(svn_diff_hunk_t **hunk_out,
+ const char *line,
+ svn_patch_t *patch,
+ svn_boolean_t add,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_diff_hunk_t *hunk = apr_palloc(result_pool, sizeof(*hunk));
- static const char hunk_header[] = "@@ -0,0 +1 @@\n";
+ static const char *hunk_header[] = { "@@ -1 +0,0 @@\n", "@@ -0,0 +1 @@\n" };
const unsigned len = strlen(line);
/* The +1 is for the 'plus' start-of-line character. */
- const apr_off_t end = STRLEN_LITERAL(hunk_header) + (1 + len);
+ const apr_off_t end = STRLEN_LITERAL(hunk_header[add]) + (1 + len);
/* The +1 is for the second \n. */
svn_stringbuf_t *buf = svn_stringbuf_create_ensure(end + 1, scratch_pool);
@@ -102,31 +108,51 @@ svn_diff_hunk__create_adds_single_line(s
/* hunk->apr_file is created below. */
- hunk->diff_text_range.start = STRLEN_LITERAL(hunk_header);
- hunk->diff_text_range.current = STRLEN_LITERAL(hunk_header);
+ hunk->diff_text_range.start = STRLEN_LITERAL(hunk_header[add]);
+ hunk->diff_text_range.current = STRLEN_LITERAL(hunk_header[add]);
hunk->diff_text_range.end = end;
- hunk->original_text_range.start = 0; /* There's no "original" text. */
- hunk->original_text_range.current = 0;
- hunk->original_text_range.end = 0;
-
- hunk->original_start = 0;
- hunk->original_length = 0;
-
- hunk->modified_start = 1;
- hunk->modified_length = 1;
-
- hunk->modified_text_range.start = STRLEN_LITERAL(hunk_header);
- hunk->modified_text_range.current = STRLEN_LITERAL(hunk_header);
- hunk->modified_text_range.end = end;
+ if (add)
+ {
+ hunk->original_text_range.start = 0; /* There's no "original" text. */
+ hunk->original_text_range.current = 0;
+ hunk->original_text_range.end = 0;
+
+ hunk->modified_text_range.start = STRLEN_LITERAL(hunk_header[add]);
+ hunk->modified_text_range.current = STRLEN_LITERAL(hunk_header[add]);
+ hunk->modified_text_range.end = end;
+
+ hunk->original_start = 0;
+ hunk->original_length = 0;
+
+ hunk->modified_start = 1;
+ hunk->modified_length = 1;
+ }
+ else /* delete */
+ {
+ hunk->original_text_range.start = STRLEN_LITERAL(hunk_header[add]);
+ hunk->original_text_range.current = STRLEN_LITERAL(hunk_header[add]);
+ hunk->original_text_range.end = end;
+
+ hunk->modified_text_range.start = 0; /* There's no "original" text. */
+ hunk->modified_text_range.current = 0;
+ hunk->modified_text_range.end = 0;
+
+ hunk->original_start = 1;
+ hunk->original_length = 1;
+
+ hunk->modified_start = 0;
+ hunk->modified_length = 0; /* setting to '1' works too */
+ }
hunk->leading_context = 0;
hunk->trailing_context = 0;
/* Create APR_FILE and put just a hunk in it (without a diff header).
* Save the offset of the last byte of the diff line. */
- svn_stringbuf_appendbytes(buf, hunk_header, STRLEN_LITERAL(hunk_header));
- svn_stringbuf_appendbyte(buf, '+');
+ svn_stringbuf_appendbytes(buf, hunk_header[add],
+ STRLEN_LITERAL(hunk_header[add]));
+ svn_stringbuf_appendbyte(buf, add ? '+' : '-');
svn_stringbuf_appendbytes(buf, line, len);
svn_stringbuf_appendbyte(buf, '\n');
@@ -143,6 +169,30 @@ svn_diff_hunk__create_adds_single_line(s
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_diff_hunk__create_adds_single_line(svn_diff_hunk_t **hunk_out,
+ const char *line,
+ 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,
+ result_pool, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_diff_hunk__create_deletes_single_line(svn_diff_hunk_t **hunk_out,
+ const char *line,
+ 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,
+ result_pool, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
void
svn_diff_hunk_reset_diff_text(svn_diff_hunk_t *hunk)
{
Modified: subversion/branches/patch-exec/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/cmdline/patch_tests.py?rev=1694029&r1=1694028&r2=1694029&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/patch-exec/subversion/tests/cmdline/patch_tests.py Tue Aug 4 10:49:41
2015
@@ -5696,6 +5696,40 @@ def patch_adds_executability_yescontents
expected_status, expected_skip,
check_props=True)
+def patch_deletes_executability(sbox):
+ """patch deletes svn:executable"""
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ ## Set up the basic state.
+ sbox.simple_propset('svn:executable', 'yes', 'iota')
+ sbox.simple_commit(target='iota', message="Make 'iota' executable.")
+
+ unidiff_patch = (
+ "diff --git a/iota b/iota\n"
+ "old mode 100755\n"
+ "new mode 100644\n"
+ )
+ patch_file_path = make_patch_path(sbox)
+ svntest.main.file_write(patch_file_path, unidiff_patch)
+
+ expected_output = [
+ ' U %s\n' % sbox.ospath('iota'),
+ ]
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('iota') # props=None by default
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('iota', 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,
+ check_props=True)
+
########################################################################
#Run the tests
@@ -5759,6 +5793,7 @@ test_list = [ None,
patch_obstructing_symlink_traversal,
patch_adds_executability_nocontents,
patch_adds_executability_yescontents,
+ patch_deletes_executability,
]
if __name__ == '__main__':
|