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',