On Thu, May 10, 2012 at 2:13 PM, <rhuijben_at_apache.org> wrote:
> Author: rhuijben
> Date: Thu May 10 19:13:11 2012
> New Revision: 1336833
>
> URL: http://svn.apache.org/viewvc?rev=1336833&view=rev
> Log:
> Make the text and property merge handling of 'svn merge' of a single file an
> atomic operation by moving the handling into a single libsvn_wc call that
> installs or doesn't install the working queue items.
>
> * subversion/include/svn_wc.h
> Â (svn_wc_merge5): New function.
> Â (svn_wc_merge4): Deprecate function.
>
> * subversion/libsvn_client/merge.c
> Â (merge_file_changed): Update caller.
>
> * subversion/libsvn_wc/deprecated.c
> Â (svn_wc_merge4): New function. Wraps svn_wc_merge5().
>
> * subversion/libsvn_wc/merge.c
> Â (svn_wc_merge4): Rename to ...
> Â (svn_wc_merge5): ... this and add support for merging properties in the same
> Â Â operation. At the same time avoid a few more unneeded db operations.
>
...
> Modified: subversion/trunk/subversion/libsvn_wc/merge.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/merge.c?rev=1336833&r1=1336832&r2=1336833&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_wc/merge.c (original)
> +++ subversion/trunk/subversion/libsvn_wc/merge.c Thu May 10 19:13:11 2012
...
> @@ -1476,7 +1476,8 @@ svn_wc__internal_merge(svn_skel_t **work
>
>
> Â svn_error_t *
> -svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome,
> +svn_wc_merge5(enum svn_wc_merge_outcome_t *merge_content_outcome,
> + Â Â Â Â Â Â Â enum svn_wc_notify_state_t *merge_props_outcome,
> Â Â Â Â Â Â Â svn_wc_context_t *wc_ctx,
> Â Â Â Â Â Â Â const char *left_abspath,
> Â Â Â Â Â Â Â const char *right_abspath,
> @@ -1489,6 +1490,7 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
> Â Â Â Â Â Â Â svn_boolean_t dry_run,
> Â Â Â Â Â Â Â const char *diff3_cmd,
> Â Â Â Â Â Â Â const apr_array_header_t *merge_options,
> + Â Â Â Â Â Â Â apr_hash_t *original_props,
> Â Â Â Â Â Â Â const apr_array_header_t *prop_diff,
> Â Â Â Â Â Â Â svn_wc_conflict_resolver_func2_t conflict_func,
> Â Â Â Â Â Â Â void *conflict_baton,
> @@ -1497,8 +1499,11 @@ 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 *prop_items = NULL;
> Â svn_skel_t *work_items;
> - Â apr_hash_t *actual_props;
> + Â apr_hash_t *pristine_props = NULL;
> + Â apr_hash_t *actual_props = NULL;
> + Â apr_hash_t *new_actual_props = NULL;
>
> Â SVN_ERR_ASSERT(svn_dirent_is_absolute(left_abspath));
> Â SVN_ERR_ASSERT(svn_dirent_is_absolute(right_abspath));
> @@ -1508,37 +1513,86 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
> Â if (!dry_run)
> Â Â SVN_ERR(svn_wc__write_check(wc_ctx->db, dir_abspath, scratch_pool));
>
> - Â /* Sanity check: Â the merge target must be under revision control,
> - Â * unless the merge target is a copyfrom text, which lives in a
> - Â * temporary file and does not exist in ACTUAL yet. */
> + Â /* Sanity check: Â the merge target must be a file under revision control */
> Â {
> + Â Â svn_wc__db_status_t status;
> Â Â svn_kind_t kind;
> - Â Â svn_boolean_t hidden;
> - Â Â SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, target_abspath, TRUE,
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool));
> + Â Â svn_boolean_t had_props;
> + Â Â svn_boolean_t props_mod;
>
> - Â Â if (kind == svn_kind_unknown)
> + Â Â SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â NULL, &had_props, &props_mod, NULL, NULL,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â NULL,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â wc_ctx->db, target_abspath,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool, scratch_pool));
> +
> + Â Â if (kind != svn_kind_file || (status != svn_wc__db_status_normal
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â && status != svn_wc__db_status_added))
> Â Â Â {
> - Â Â Â Â *merge_outcome = svn_wc_merge_no_merge;
> + Â Â Â Â *merge_content_outcome = svn_wc_merge_no_merge;
> + Â Â Â Â if (merge_props_outcome)
> + Â Â Â Â Â *merge_props_outcome = svn_wc_merge_no_merge;
There is a type mismatch here: *merge_props_outcome is an enum of type
svn_wc_notify_state_t, but svn_wc_merge_no_merge is one of
svn_wc_merge_outcome_t.
-Hyrum
> Â Â Â Â return SVN_NO_ERROR;
> Â Â Â }
>
> - Â Â SVN_ERR(svn_wc__db_node_hidden(&hidden, wc_ctx->db, target_abspath,
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool));
> + Â Â if (merge_props_outcome && had_props)
> + Â Â Â {
> + Â Â Â Â SVN_ERR(svn_wc__db_read_pristine_props(&pristine_props,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â wc_ctx->db, target_abspath,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool, scratch_pool));
> + Â Â Â }
> + Â Â else if (merge_props_outcome)
> + Â Â Â pristine_props = apr_hash_make(scratch_pool);
>
> - Â Â if (hidden)
> + Â Â if (props_mod)
> Â Â Â {
> - Â Â Â Â *merge_outcome = svn_wc_merge_no_merge;
> - Â Â Â Â return SVN_NO_ERROR;
> + Â Â Â Â SVN_ERR(svn_wc__db_read_props(&actual_props,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â wc_ctx->db, target_abspath,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool, scratch_pool));
> Â Â Â }
> + Â Â else if (pristine_props)
> + Â Â Â actual_props = apr_hash_copy(scratch_pool, pristine_props);
> + Â Â else
> + Â Â Â actual_props = apr_hash_make(scratch_pool);
> Â }
>
> - Â SVN_ERR(svn_wc__db_read_props(&actual_props, wc_ctx->db, target_abspath,
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool, scratch_pool));
> + Â if (merge_props_outcome)
> + Â Â {
> + Â Â Â int i;
> + Â Â Â apr_hash_t *new_pristine_props;
> + Â Â Â /* The PROPCHANGES may not have non-"normal" properties in it. If entry
> + Â Â Â Â or wc props were allowed, then the following code would install them
> + Â Â Â Â into the BASE and/or WORKING properties(!). Â */
> + Â Â Â for (i = prop_diff->nelts; i--; )
> + Â Â Â Â {
> + Â Â Â Â Â const svn_prop_t *change = &APR_ARRAY_IDX(prop_diff, i, svn_prop_t);
> +
> + Â Â Â Â Â if (!svn_wc_is_normal_prop(change->name))
> + Â Â Â Â Â Â return svn_error_createf(SVN_ERR_BAD_PROP_KIND, NULL,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â _("The property '%s' may not be merged "
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "into '%s'."),
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â change->name,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_dirent_local_style(target_abspath,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool));
> + Â Â Â Â }
> +
> + Â Â Â SVN_ERR(svn_wc__merge_props(&prop_items, merge_props_outcome,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â &new_pristine_props, &new_actual_props,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â wc_ctx->db, target_abspath, svn_kind_file,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â left_version, right_version,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â original_props, pristine_props, actual_props,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â prop_diff, FALSE /* base_merge */,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â dry_run,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â conflict_func, conflict_baton,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â cancel_func, cancel_baton,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool, scratch_pool));
> + Â Â }
>
> Â /* Queue all the work. Â */
> Â SVN_ERR(svn_wc__internal_merge(&work_items,
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_outcome,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_content_outcome,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â wc_ctx->db,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â left_abspath, left_version,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â right_abspath, right_version,
> @@ -1554,16 +1608,24 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â cancel_func, cancel_baton,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool, scratch_pool));
>
> + Â work_items = svn_wc__wq_merge(prop_items, work_items, scratch_pool);
> +
> Â /* If this isn't a dry run, then run the work! Â */
> Â if (!dry_run)
> Â Â {
> - Â Â Â SVN_ERR(svn_wc__db_wq_add(wc_ctx->db, target_abspath, work_items,
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool));
> + Â Â Â if (new_actual_props)
> + Â Â Â Â SVN_ERR(svn_wc__db_op_set_props(wc_ctx->db, target_abspath,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â new_actual_props,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_wc__has_magic_property(prop_diff),
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â NULL, work_items, scratch_pool));
> + Â Â Â else
> + Â Â Â Â 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;
> Â }
>
>
>
--
uberSVN: Apache Subversion Made Easy
http://www.uberSVN.com/
Received on 2012-05-31 16:33:00 CEST