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. */