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/10/03 17:54:44 UTC
svn commit: r1706600 - in /subversion/trunk/subversion:
libsvn_client/patch.c tests/cmdline/patch_tests.py
Author: rhuijben
Date: Sat Oct 3 15:54:44 2015
New Revision: 1706600
URL: http://svn.apache.org/viewvc?rev=1706600&view=rev
Log:
Properly create 'svn patch' reject files with a unique name, instead of
blindly overwriting pre-existing .svnpatch.rej files. Just like how we
create other conflict markers.
* subversion/libsvn_client/patch.c
(patch_target_t): Use a stream for rejection info.
(init_patch_target): Update creation.
(reject_hunk): Use stream helpers for writing.
(write_out_rejected_hunks): Create final file using
svn_io_open_uniquely_named(), to ensure a unique name.
* subversion/tests/cmdline/patch_tests.py
(patch_closest): Remove reject file before creating a new one.
Modified:
subversion/trunk/subversion/libsvn_client/patch.c
subversion/trunk/subversion/tests/cmdline/patch_tests.py
Modified: subversion/trunk/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/patch.c?rev=1706600&r1=1706599&r2=1706600&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/patch.c (original)
+++ subversion/trunk/subversion/libsvn_client/patch.c Sat Oct 3 15:54:44 2015
@@ -194,8 +194,8 @@ typedef struct patch_target_t {
/* Path to the patched file. */
const char *patched_path;
- /* Hunks that are rejected will be written to this file. */
- apr_file_t *reject_file;
+ /* Hunks that are rejected will be written to this stream. */
+ svn_stream_t *reject_stream;
/* Path to the reject file. */
const char *reject_path;
@@ -1049,9 +1049,6 @@ init_patch_target(patch_target_t **patch
*patch_target = target;
if (! target->skipped)
{
- const char *diff_header;
- apr_size_t len;
-
if (patch->old_symlink_bit == svn_tristate_true
|| patch->new_symlink_bit == svn_tristate_true)
{
@@ -1180,23 +1177,20 @@ init_patch_target(patch_target_t **patch
content->write = write_file;
content->write_baton = target->patched_file;
- /* Open a temporary file to write rejected hunks to. */
- SVN_ERR(svn_io_open_unique_file3(&target->reject_file,
- &target->reject_path, NULL,
- remove_tempfiles ?
+ /* Open a temporary stream to write rejected hunks to. */
+ SVN_ERR(svn_stream_open_unique(&target->reject_stream,
+ &target->reject_path, NULL,
+ remove_tempfiles ?
svn_io_file_del_on_pool_cleanup :
svn_io_file_del_none,
- result_pool, scratch_pool));
+ result_pool, scratch_pool));
/* The reject file needs a diff header. */
- diff_header = apr_psprintf(scratch_pool, "--- %s%s+++ %s%s",
+ SVN_ERR(svn_stream_printf(target->reject_stream, scratch_pool,
+ "--- %s" APR_EOL_STR
+ "+++ %s" APR_EOL_STR,
target->canon_path_from_patchfile,
- APR_EOL_STR,
- target->canon_path_from_patchfile,
- APR_EOL_STR);
- len = strlen(diff_header);
- SVN_ERR(svn_io_file_write_full(target->reject_file, diff_header, len,
- &len, scratch_pool));
+ target->canon_path_from_patchfile));
/* Handle properties. */
if (! target->skipped)
@@ -1982,8 +1976,6 @@ reject_hunk(patch_target_t *target, targ
svn_diff_hunk_t *hunk, const char *prop_name,
apr_pool_t *pool)
{
- const char *hunk_header;
- apr_size_t len;
svn_boolean_t eof;
static const char * const text_atat = "@@";
static const char * const prop_atat = "##";
@@ -1992,14 +1984,9 @@ reject_hunk(patch_target_t *target, targ
if (prop_name)
{
- const char *prop_header;
-
- /* ### Print 'Added', 'Deleted' or 'Modified' instead of 'Property'.
- */
- prop_header = apr_psprintf(pool, "Property: %s\n", prop_name);
- len = strlen(prop_header);
- SVN_ERR(svn_io_file_write_full(target->reject_file, prop_header,
- len, &len, pool));
+ /* ### Print 'Added', 'Deleted' or 'Modified' instead of 'Property'. */
+ svn_stream_printf(target->reject_stream,
+ pool, "Property: %s" APR_EOL_STR, prop_name);
atat = prop_atat;
}
else
@@ -2007,17 +1994,14 @@ reject_hunk(patch_target_t *target, targ
atat = text_atat;
}
- hunk_header = apr_psprintf(pool, "%s -%lu,%lu +%lu,%lu %s%s",
- atat,
- svn_diff_hunk_get_original_start(hunk),
- svn_diff_hunk_get_original_length(hunk),
- svn_diff_hunk_get_modified_start(hunk),
- svn_diff_hunk_get_modified_length(hunk),
- atat,
- APR_EOL_STR);
- len = strlen(hunk_header);
- SVN_ERR(svn_io_file_write_full(target->reject_file, hunk_header, len,
- &len, pool));
+ SVN_ERR(svn_stream_printf(target->reject_stream, pool,
+ "%s -%lu,%lu +%lu,%lu %s" APR_EOL_STR,
+ atat,
+ svn_diff_hunk_get_original_start(hunk),
+ svn_diff_hunk_get_original_length(hunk),
+ svn_diff_hunk_get_modified_start(hunk),
+ svn_diff_hunk_get_modified_length(hunk),
+ atat));
iterpool = svn_pool_create(pool);
do
@@ -2033,17 +2017,15 @@ reject_hunk(patch_target_t *target, targ
{
if (hunk_line->len >= 1)
{
- len = hunk_line->len;
- SVN_ERR(svn_io_file_write_full(target->reject_file,
- hunk_line->data, len, &len,
- iterpool));
+ apr_size_t len = hunk_line->len;
+
+ SVN_ERR(svn_stream_write(target->reject_stream,
+ hunk_line->data, &len));
}
if (eol_str)
{
- len = strlen(eol_str);
- SVN_ERR(svn_io_file_write_full(target->reject_file, eol_str,
- len, &len, iterpool));
+ SVN_ERR(svn_stream_puts(target->reject_stream, eol_str));
}
}
}
@@ -3263,19 +3245,36 @@ install_patched_target(patch_target_t *t
static svn_error_t *
write_out_rejected_hunks(patch_target_t *target,
svn_boolean_t dry_run,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
- SVN_ERR(svn_io_file_close(target->reject_file, pool));
-
if (! dry_run && (target->had_rejects || target->had_prop_rejects))
{
/* Write out rejected hunks, if any. */
- SVN_ERR(svn_io_copy_file(target->reject_path,
- apr_psprintf(pool, "%s.svnpatch.rej",
- target->local_abspath),
- FALSE, pool));
+ apr_file_t *reject_file;
+
+ SVN_ERR(svn_io_open_uniquely_named(&reject_file, NULL,
+ svn_dirent_dirname(
+ target->local_abspath,
+ scratch_pool),
+ svn_dirent_basename(
+ target->local_abspath,
+ NULL),
+ ".svnpatch.rej",
+ svn_io_file_del_none,
+ scratch_pool, scratch_pool));
+
+ SVN_ERR(svn_stream_reset(target->reject_stream));
+
+ /* svn_stream_copy3() closes the files for us */
+ SVN_ERR(svn_stream_copy3(target->reject_stream,
+ svn_stream_from_aprfile2(reject_file, FALSE,
+ scratch_pool),
+ NULL, NULL, scratch_pool));
/* ### TODO mark file as conflicted. */
}
+ else
+ SVN_ERR(svn_stream_close(target->reject_stream));
+
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=1706600&r1=1706599&r2=1706600&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/patch_tests.py Sat Oct 3 15:54:44 2015
@@ -5372,6 +5372,7 @@ def patch_closest(sbox):
truncate=True)
sbox.simple_commit()
+ os.remove(sbox.ospath('A/mu.svnpatch.rej'))
expected_output = [
'C %s\n' % sbox.ospath('A/mu'),
'> applied hunk @@ -47,7 +47,7 @@ with offset 4\n',
@@ -5410,6 +5411,7 @@ def patch_closest(sbox):
truncate=True)
sbox.simple_commit()
+ os.remove(sbox.ospath('A/mu.svnpatch.rej'))
expected_output = [
'C %s\n' % sbox.ospath('A/mu'),
'> applied hunk @@ -47,7 +47,7 @@ with offset 4\n',
@@ -5448,6 +5450,7 @@ def patch_closest(sbox):
truncate=True)
sbox.simple_commit()
+ os.remove(sbox.ospath('A/mu.svnpatch.rej'))
expected_output = [
'C %s\n' % sbox.ospath('A/mu'),
'> applied hunk @@ -47,7 +47,7 @@ with offset 4\n',
@@ -5486,6 +5489,7 @@ def patch_closest(sbox):
truncate=True)
sbox.simple_commit()
+ os.remove(sbox.ospath('A/mu.svnpatch.rej'))
expected_output = [
'C %s\n' % sbox.ospath('A/mu'),
'> applied hunk @@ -180,7 +180,7 @@ with offset -169\n',