Author: philip
Date: Wed Jun 15 13:45:40 2011
New Revision: 1136038

URL: http://svn.apache.org/viewvc?rev=1136038&view=rev
Log:
Fix issue 3920, wq refers to file that does not exist.

* subversion/libsvn_wc/merge.c
  (detranslate_wc_file): Don't set del_on_pool_cleanup if FORCE_COPY
   is given, put temporary file in wcroot temp dir.
  (preserve_pre_merge_files): Add wq item to delete detranslated file.

* subversion/libsvn_wc/workqueue.c
  (run_file_copy_translated): Allow source file to be missing.

Modified:
    subversion/trunk/subversion/libsvn_wc/merge.c
    subversion/trunk/subversion/libsvn_wc/workqueue.c

Modified: subversion/trunk/subversion/libsvn_wc/merge.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/merge.c?rev=1136038&r1=1136037&r2=1136038&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/merge.c (original)
+++ subversion/trunk/subversion/libsvn_wc/merge.c Wed Jun 15 13:45:40 2011
@@ -132,6 +132,18 @@ get_prop(const merge_target_t *mt,
 
      Always use the old settings (same reasons as for svn:keywords)
 
+  Sets *DETRANSLATED_ABSPATH to the path to the detranslated file,
+  this may be the same as SOURCE_ABSPATH if FORCE_COPY is FALSE and no
+  translation is required.
+
+  If FORCE_COPY is FALSE and *DETRANSLATED_ABSPATH is a file distinct
+  from SOURCE_ABSPATH then the file will be deleted on RESULT_POOL
+  cleanup.
+
+  If FORCE_COPY is TRUE then *DETRANSLATED_ABSPATH will always be a
+  new file distinct from SOURCE_ABSPATH and it will be the callers
+  responsibility to delete the file.
+
 */
 static svn_error_t *
 detranslate_wc_file(const char **detranslated_abspath,
@@ -229,16 +241,24 @@ detranslate_wc_file(const char **detrans
 
   if (force_copy || keywords || eol || special)
     {
+      const char *wcroot_abspath, *temp_dir_abspath;
       const char *detranslated;
 
       /* Force a copy into the temporary wc area to avoid having
          temporary files created below to appear in the actual wc. */
+      SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath, mt->db, mt->wri_abspath,
+                                    scratch_pool, scratch_pool));
+      SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath, mt->db,
+                                             mt->wri_abspath,
+                                             scratch_pool, scratch_pool));
 
       /* ### svn_subst_copy_and_translate4() also creates a tempfile
          ### internally.  Anyway to piggyback on that? */
-      SVN_ERR(svn_io_open_unique_file3(NULL, &detranslated, NULL,
-                                      svn_io_file_del_on_pool_cleanup,
-                                      result_pool, scratch_pool));
+      SVN_ERR(svn_io_open_unique_file3(NULL, &detranslated, temp_dir_abspath,
+                                       (force_copy
+                                        ? svn_io_file_del_none
+                                        : svn_io_file_del_on_pool_cleanup),
+                                       result_pool, scratch_pool));
 
       /* Always 'repair' EOLs here, so that we can apply a diff that
          changes from inconsistent newlines and no 'svn:eol-style' to
@@ -691,7 +711,7 @@ preserve_pre_merge_files(svn_skel_t **wo
   /* We preserve all the files with keywords expanded and line
      endings in local (working) form. */
 
-  /* The workingqueue prefers (requires?) its paths to be in the subtree
+  /* The workingqueue requires its paths to be in the subtree
      relative to the wcroot path they are executed in.
 
      Make our LEFT and RIGHT files 'local' if they aren't... */
@@ -769,6 +789,11 @@ preserve_pre_merge_files(svn_skel_t **wo
   *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
 
   /* And maybe delete some tempfiles */
+  SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db,
+                                       detranslated_target_copy,
+                                       result_pool, scratch_pool));
+  *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
+
   *work_items = svn_wc__wq_merge(*work_items, last_items, result_pool);
 
   return SVN_NO_ERROR;

Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=1136038&r1=1136037&r2=1136038&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Wed Jun 15 13:45:40 2011
@@ -955,6 +955,7 @@ run_file_copy_translated(svn_wc__db_t *d
   const char *eol;
   apr_hash_t *keywords;
   svn_boolean_t special;
+  svn_error_t *err;
 
   local_relpath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
   SVN_ERR(svn_wc__db_from_relpath(&local_abspath, db, wri_abspath,
@@ -976,12 +977,27 @@ run_file_copy_translated(svn_wc__db_t *d
                                      db, local_abspath, NULL, FALSE,
                                      scratch_pool, scratch_pool));
 
-  SVN_ERR(svn_subst_copy_and_translate4(src_abspath, dst_abspath,
-                                        eol, TRUE /* repair */,
-                                        keywords, TRUE /* expand */,
-                                        special,
-                                        cancel_func, cancel_baton,
-                                        scratch_pool));
+  err = svn_subst_copy_and_translate4(src_abspath, dst_abspath,
+                                      eol, TRUE /* repair */,
+                                      keywords, TRUE /* expand */,
+                                      special,
+                                      cancel_func, cancel_baton,
+                                      scratch_pool);
+  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
+    {
+      svn_error_t *err2;
+      svn_node_kind_t kind;
+
+      /* The source file can be missing when the wq item is rerun. */
+      err2 = svn_io_check_path(src_abspath, &kind, scratch_pool);
+      if (!err2 && kind == svn_node_none)
+        {
+          svn_error_clear(err);
+          return SVN_NO_ERROR;
+        }
+      svn_error_clear(err2);
+      return svn_error_return(err);
+    }
 
   return SVN_NO_ERROR;
 }


Reply via email to