You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gs...@apache.org on 2010/05/10 02:59:32 UTC

svn commit: r942637 - in /subversion/trunk/subversion/libsvn_wc: merge.c update_editor.c wc.h

Author: gstein
Date: Mon May 10 00:59:32 2010
New Revision: 942637

URL: http://svn.apache.org/viewvc?rev=942637&view=rev
Log:
Propagate work items out of svn_wc__internal_merge() rather than directly
queuing them. The two callers now queue the resulting work item(s).

* subversion/libsvn_wc/wc.h:
  (svn_wc__internal_merge): add a WORK_ITEMS OUT parameter, and a
    RESULT_POOL parameter. update docstring.

* subversion/libsvn_wc/merge.c:
  (save_merge_result): return the constructed work item rather than
    queueing it. add a WORK_ITEM param to do this, and a RESULT_POOL.
  (maybe_resolve_conflicts): return WORK_ITEMS (a new param) instead of
    directly queueing results. add a RESULT_POOL for the work items.
  (merge_text_file): return WORK_ITEMS instead of queuing. add a
    RESULT_POOL for these items. rather than queuing the OP_FILE_INSTALL,
    merge it into the returned set of work items.
  (svn_wc__internal_merge): accept a new WORK_ITEMS parameter and an
    additional RESULT_POOL. accumulate work items, and return them.
  (svn_wc_merge4): get work items __internal_merge and queue them before
    running the queue.

* subversion/libsvn_wc/update_editor.c:
  (merge_file): get a work item from internal_merge() and shove that into
    the WORK_ITEMS returned by this function

Modified:
    subversion/trunk/subversion/libsvn_wc/merge.c
    subversion/trunk/subversion/libsvn_wc/update_editor.c
    subversion/trunk/subversion/libsvn_wc/wc.h

Modified: subversion/trunk/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/merge.c?rev=942637&r1=942636&r2=942637&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/merge.c (original)
+++ subversion/trunk/subversion/libsvn_wc/merge.c Mon May 10 00:59:32 2010
@@ -35,6 +35,8 @@
 #include "lock.h"
 #include "workqueue.h"
 
+#include "private/svn_skel.h"
+
 #include "svn_private_config.h"
 
 
@@ -397,26 +399,29 @@ do_text_merge_external(svn_boolean_t *co
   return SVN_NO_ERROR;
 }
 
-/* Loggy-copy the merge result obtained during interactive conflict
- * resolution to the file RESULT_TARGET. The merge result is expected
- * in the same directory as TARGET_ABSPATH the same basename as
- * TARGET_ABSPATH, but followed by ".edited".
- * DB contains an access baton with
- * a write lock for the directory containing RESULT_TARGET.
- * Do all allocations in POOL.
- */
+/* Return a work item to copy/translate the merge result, obtained during
+   interactive conflict resolution, to the file RESULT_TARGET. The merge
+   result is expected in the same directory as TARGET_ABSPATH, with the same
+   basename as TARGET_ABSPATH, with a ".edited" extension.
+
+   DB should have a write lock for the directory containing RESULT_TARGET.
+
+   *WORK_ITEM will be allocated in RESULT_POOL. All temporary allocations
+   will be allocated in SCRATCH_POOL.  */
 static svn_error_t*
-save_merge_result(svn_wc__db_t *db,
+save_merge_result(svn_skel_t **work_item,
+                  svn_wc__db_t *db,
                   const char *target_abspath,
                   const char *result_target,
-                  apr_pool_t *pool)
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
   const char *edited_copy_abspath;
   const char *dir_abspath;
   const char *merge_filename;
-  svn_skel_t *work_item;
 
-  svn_dirent_split(target_abspath, &dir_abspath, &merge_filename, pool);
+  svn_dirent_split(target_abspath, &dir_abspath, &merge_filename,
+                   scratch_pool);
 
   /* ### Should use preserved-conflict-file-exts. */
   /* Create the .edited file within this file's DIR_ABSPATH  */
@@ -426,14 +431,13 @@ save_merge_result(svn_wc__db_t *db,
                                      merge_filename,
                                      ".edited",
                                      svn_io_file_del_none,
-                                     pool, pool));
-  SVN_ERR(svn_wc__loggy_translated_file(&work_item,
+                                     scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__loggy_translated_file(work_item,
                                         db, dir_abspath,
                                         edited_copy_abspath,
                                         result_target,
                                         target_abspath,
-                                        pool));
-  SVN_ERR(svn_wc__db_wq_add(db, dir_abspath, work_item, pool));
+                                        result_pool));
 
   return SVN_NO_ERROR;
 }
@@ -759,7 +763,8 @@ setup_text_conflict_desc(const char *lef
 
 /* XXX Insane amount of parameters... */
 static svn_error_t*
-maybe_resolve_conflicts(svn_wc__db_t *db,
+maybe_resolve_conflicts(svn_skel_t **work_items,
+                        svn_wc__db_t *db,
                         const char *left_abspath,
                         const char *right_abspath,
                         const char *target_abspath,
@@ -778,11 +783,15 @@ maybe_resolve_conflicts(svn_wc__db_t *db
                         void *conflict_baton,
                         svn_cancel_func_t cancel_func,
                         void *cancel_baton,
-                        apr_pool_t *pool)
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool)
 {
+  apr_pool_t *pool = scratch_pool;  /* ### temporary rename  */
   svn_wc_conflict_result_t *result = NULL;
   const char *dir_abspath;
 
+  *work_items = NULL;
+
   dir_abspath = svn_dirent_dirname(target_abspath, pool);
 
   /* Give the conflict resolution callback a chance to clean
@@ -816,14 +825,17 @@ maybe_resolve_conflicts(svn_wc__db_t *db
                                         " returned no results"));
 
       if (result->save_merged)
-        SVN_ERR(save_merge_result(db,
-                                  target_abspath,
-                                  /* Look for callback's own
-                                     merged-file first: */
-                                  result->merged_file
-                                    ? result->merged_file
-                                    : result_target,
-                                  pool));
+        {
+          SVN_ERR(save_merge_result(work_items,
+                                    db,
+                                    target_abspath,
+                                    /* Look for callback's own
+                                       merged-file first: */
+                                    result->merged_file
+                                      ? result->merged_file
+                                      : result_target,
+                                    result_pool, scratch_pool));
+        }
     }
 
   SVN_ERR(eval_conflict_func_result(merge_outcome,
@@ -862,7 +874,8 @@ maybe_resolve_conflicts(svn_wc__db_t *db
 
 /* XXX Insane amount of parameters... */
 static svn_error_t*
-merge_text_file(enum svn_wc_merge_outcome_t *merge_outcome,
+merge_text_file(svn_skel_t **work_items,
+                enum svn_wc_merge_outcome_t *merge_outcome,
                 svn_wc__db_t *db,
                 const char *left_abspath,
                 const char *right_abspath,
@@ -882,8 +895,10 @@ merge_text_file(enum svn_wc_merge_outcom
                 void *conflict_baton,
                 svn_cancel_func_t cancel_func,
                 void *cancel_baton,
-                apr_pool_t *pool)
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
 {
+  apr_pool_t *pool = scratch_pool;  /* ### temporary rename  */
   svn_diff_file_options_t *options;
   svn_boolean_t contains_conflicts;
   apr_file_t *result_f;
@@ -891,6 +906,8 @@ merge_text_file(enum svn_wc_merge_outcom
   const char *dir_abspath, *base_name;
   const char *temp_dir;
 
+  *work_items = NULL;
+
   svn_dirent_split(target_abspath, &dir_abspath, &base_name, pool);
 
   /* Open a second temporary file for writing; this is where diff3
@@ -938,7 +955,8 @@ merge_text_file(enum svn_wc_merge_outcom
 
   if (contains_conflicts && ! dry_run)
     {
-      SVN_ERR(maybe_resolve_conflicts(db,
+      SVN_ERR(maybe_resolve_conflicts(work_items,
+                                      db,
                                       left_abspath,
                                       right_abspath,
                                       target_abspath,
@@ -955,7 +973,7 @@ merge_text_file(enum svn_wc_merge_outcom
                                       options,
                                       conflict_func, conflict_baton,
                                       cancel_func, cancel_baton,
-                                      pool));
+                                      result_pool, scratch_pool));
 
       if (*merge_outcome == svn_wc_merge_merged)
         return SVN_NO_ERROR;
@@ -992,8 +1010,8 @@ merge_text_file(enum svn_wc_merge_outcom
                                             result_target,
                                             FALSE /* use_commit_times */,
                                             FALSE /* record_fileinfo */,
-                                            pool, pool));
-      SVN_ERR(svn_wc__db_wq_add(db, dir_abspath, work_item, pool));
+                                            result_pool, scratch_pool));
+      *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
     }
 
   return SVN_NO_ERROR;
@@ -1189,7 +1207,8 @@ merge_binary_file(enum svn_wc_merge_outc
 
 /* XXX Insane amount of parameters... */
 svn_error_t *
-svn_wc__internal_merge(enum svn_wc_merge_outcome_t *merge_outcome,
+svn_wc__internal_merge(svn_skel_t **work_items,
+                       enum svn_wc_merge_outcome_t *merge_outcome,
                        svn_wc__db_t *db,
                        const char *left_abspath,
                        const svn_wc_conflict_version_t *left_version,
@@ -1208,13 +1227,16 @@ svn_wc__internal_merge(enum svn_wc_merge
                        void *conflict_baton,
                        svn_cancel_func_t cancel_func,
                        void *cancel_baton,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
+  apr_pool_t *pool = scratch_pool;  /* ### temporary rename  */
   const char *working_abspath;
   const char *detranslated_target_abspath;
   const char *dir_abspath;
   svn_boolean_t is_binary = FALSE;
   const svn_prop_t *mimeprop;
+  svn_skel_t *work_item;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(left_abspath));
   SVN_ERR_ASSERT(svn_dirent_is_absolute(right_abspath));
@@ -1222,6 +1244,8 @@ svn_wc__internal_merge(enum svn_wc_merge
   SVN_ERR_ASSERT(copyfrom_abspath == NULL
                  || svn_dirent_is_absolute(copyfrom_abspath));
 
+  *work_items = NULL;
+
   dir_abspath = svn_dirent_dirname(target_abspath, pool);
 
   /* Sanity check:  the merge target must be under revision control,
@@ -1290,37 +1314,39 @@ svn_wc__internal_merge(enum svn_wc_merge
                                   pool));
     }
   else
-    SVN_ERR(merge_text_file(merge_outcome,
-                            db,
-                            left_abspath,
-                            right_abspath,
-                            target_abspath,
-                            left_label,
-                            right_label,
-                            target_label,
-                            dry_run,
-                            diff3_cmd,
-                            merge_options,
-                            left_version,
-                            right_version,
-                            copyfrom_abspath,
-                            detranslated_target_abspath,
-                            mimeprop,
-                            conflict_func, conflict_baton,
-                            cancel_func, cancel_baton,
-                            pool));
+    {
+      SVN_ERR(merge_text_file(&work_item,
+                              merge_outcome,
+                              db,
+                              left_abspath,
+                              right_abspath,
+                              target_abspath,
+                              left_label,
+                              right_label,
+                              target_label,
+                              dry_run,
+                              diff3_cmd,
+                              merge_options,
+                              left_version,
+                              right_version,
+                              copyfrom_abspath,
+                              detranslated_target_abspath,
+                              mimeprop,
+                              conflict_func, conflict_baton,
+                              cancel_func, cancel_baton,
+                              result_pool, scratch_pool));
+      *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
+    }
 
   /* Merging is complete.  Regardless of text or binariness, we might
      need to tweak the executable bit on the new working file, and
      possibly make it read-only. */
   if (! dry_run)
     {
-      svn_skel_t *work_item;
-
       SVN_ERR(svn_wc__wq_build_sync_file_flags(&work_item, db,
                                                target_abspath,
-                                               pool, pool));
-      SVN_ERR(svn_wc__db_wq_add(db, dir_abspath, work_item, pool));
+                                               result_pool, scratch_pool));
+      *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
     }
 
   return SVN_NO_ERROR;
@@ -1349,6 +1375,7 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
               apr_pool_t *scratch_pool)
 {
   const char *dir_abspath = svn_dirent_dirname(target_abspath, scratch_pool);
+  svn_skel_t *work_items;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(left_abspath));
   SVN_ERR_ASSERT(svn_dirent_is_absolute(right_abspath));
@@ -1359,7 +1386,8 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
     SVN_ERR(svn_wc__write_check(wc_ctx->db, dir_abspath, scratch_pool));
 
   /* Queue all the work.  */
-  SVN_ERR(svn_wc__internal_merge(merge_outcome,
+  SVN_ERR(svn_wc__internal_merge(&work_items,
+                                 merge_outcome,
                                  wc_ctx->db,
                                  left_abspath, left_version,
                                  right_abspath, right_version,
@@ -1372,13 +1400,17 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
                                  prop_diff,
                                  conflict_func, conflict_baton,
                                  cancel_func, cancel_baton,
-                                 scratch_pool));
+                                 scratch_pool, scratch_pool));
 
   /* If this isn't a dry run, then run the work!  */
   if (!dry_run)
-    SVN_ERR(svn_wc__wq_run(wc_ctx->db, target_abspath,
-                           cancel_func, cancel_baton,
-                           scratch_pool));
+    {
+      SVN_ERR(svn_wc__db_wq_add(wc_ctx->db, target_abspath, work_items,
+                                scratch_pool));
+      SVN_ERR(svn_wc__wq_run(wc_ctx->db, target_abspath,
+                             cancel_func, cancel_baton,
+                             scratch_pool));
+    }
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=942637&r1=942636&r2=942637&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Mon May 10 00:59:32 2010
@@ -4562,6 +4562,7 @@ merge_file(svn_skel_t **work_items,
                  ###   made atomically.  */
               /* ### this should return a work_items  */
               SVN_ERR(svn_wc__internal_merge(
+                        &work_item,
                         &merge_outcome,
                         eb->db,
                         merge_left, NULL,
@@ -4573,7 +4574,8 @@ merge_file(svn_skel_t **work_items,
                         eb->diff3_cmd, NULL, fb->propchanges,
                         eb->conflict_func, eb->conflict_baton,
                         eb->cancel_func, eb->cancel_baton,
-                        pool));
+                        pool, pool));
+              *work_items = svn_wc__wq_merge(*work_items, work_item, pool);
 
               /* If we created a temporary left merge file, get rid of it. */
               if (delete_left)

Modified: subversion/trunk/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc.h?rev=942637&r1=942636&r2=942637&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc.h Mon May 10 00:59:32 2010
@@ -31,8 +31,10 @@
 #include "svn_types.h"
 #include "svn_error.h"
 #include "svn_wc.h"
+
 #include "private/svn_sqlite.h"
 #include "private/svn_wc_private.h"
+#include "private/svn_skel.h"
 
 #include "wc_db.h"
 
@@ -380,8 +382,8 @@ svn_wc__internal_text_modified_p(svn_boo
 
 
 /* Merge the difference between LEFT_ABSPATH and RIGHT_ABSPATH into
-   TARGET_ABSPATH, accumulating instructions to update the working
-   copy into LOG_ACCUM.
+   TARGET_ABSPATH, return the appropriate work queue operations in
+   *WORK_ITEMS.
 
    Note that, in the case of updating, the update can have sent new
    properties, which could affect the way the wc target is
@@ -419,9 +421,13 @@ svn_wc__internal_text_modified_p(svn_boo
 
    For a complete description, see svn_wc_merge3() for which this is
    the (loggy) implementation.
+
+   *WORK_ITEMS will be allocated in RESULT_POOL. All temporary allocations
+   will be performed in SCRATCH_POOL.
 */
 svn_error_t *
-svn_wc__internal_merge(enum svn_wc_merge_outcome_t *merge_outcome,
+svn_wc__internal_merge(svn_skel_t **work_items,
+                       enum svn_wc_merge_outcome_t *merge_outcome,
                        svn_wc__db_t *db,
                        const char *left_abspath,
                        const svn_wc_conflict_version_t *left_version,
@@ -440,7 +446,8 @@ svn_wc__internal_merge(enum svn_wc_merge
                        void *conflict_baton,
                        svn_cancel_func_t cancel_func,
                        void *cancel_baton,
-                       apr_pool_t *pool);
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool);
 
 /* A default error handler for svn_wc_walk_entries3().  Returns ERR in
    all cases. */