Author: stsp
Date: Fri Jul  6 19:46:06 2012
New Revision: 1358374

URL: http://svn.apache.org/viewvc?rev=1358374&view=rev
Log:
* subversion/svn/file-merge.c
  (svn_cl__merge_file): Do not operate directly on the file at merged_path,
   but on a temporary file and rename that on top of the merged_path at the
   end of the merge. This prevents the merge tool from truncating the file
   at merged_path at the start of the merge, and potentially leaving the file
   in a bad state if an error occurs mid-way.

Suggested by: jcorvel

Modified:
    subversion/trunk/subversion/svn/file-merge.c

Modified: subversion/trunk/subversion/svn/file-merge.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/file-merge.c?rev=1358374&r1=1358373&r2=1358374&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/file-merge.c (original)
+++ subversion/trunk/subversion/svn/file-merge.c Fri Jul  6 19:46:06 2012
@@ -26,6 +26,7 @@
  * The merge tool is driven by Subversion's diff code and user input. */
 
 #include "svn_cmdline.h"
+#include "svn_dirent_uri.h"
 #include "svn_error.h"
 #include "svn_pools.h"
 #include "svn_io.h"
@@ -794,6 +795,7 @@ svn_cl__merge_file(const char *base_path
   apr_file_t *modified_file;
   apr_file_t *latest_file;
   apr_file_t *merged_file;
+  const char *merged_file_name;
   struct file_merge_baton fmb;
 
   SVN_ERR(svn_io_file_open(&original_file, base_path,
@@ -805,9 +807,9 @@ svn_cl__merge_file(const char *base_path
   SVN_ERR(svn_io_file_open(&latest_file, my_path,
                            APR_READ|APR_BUFFERED|APR_BINARY,
                            APR_OS_DEFAULT, scratch_pool));
-  SVN_ERR(svn_io_file_open(&merged_file, merged_path,
-                           APR_WRITE|APR_TRUNCATE|APR_BUFFERED|APR_BINARY,
-                           APR_OS_DEFAULT, scratch_pool));
+  SVN_ERR(svn_io_open_unique_file3(&merged_file, &merged_file_name,
+                                   NULL, svn_io_file_del_none,
+                                   scratch_pool, scratch_pool));
 
   diff_options = svn_diff_file_options_create(scratch_pool);
   SVN_ERR(svn_diff_file_diff3_2(&diff, base_path, their_path, my_path,
@@ -835,5 +837,14 @@ svn_cl__merge_file(const char *base_path
   if (remains_in_conflict)
     *remains_in_conflict = fmb.remains_in_conflict;
 
+  SVN_ERR_W(svn_io_file_move(merged_file_name, merged_path, scratch_pool),
+            apr_psprintf(scratch_pool,
+                         _("Could not write merged result to '%s', "
+                         "saved instead at '%s'.\n"),
+                         svn_dirent_local_style(merged_path,
+                                                scratch_pool),
+                         svn_dirent_local_style(merged_file_name,
+                                                scratch_pool)));
+
   return SVN_NO_ERROR;
 }


Reply via email to