You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2012/05/10 21:13:12 UTC
svn commit: r1336833 - in /subversion/trunk/subversion: include/svn_wc.h
libsvn_client/merge.c libsvn_wc/deprecated.c libsvn_wc/merge.c
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/include/svn_wc.h
subversion/trunk/subversion/libsvn_client/merge.c
subversion/trunk/subversion/libsvn_wc/deprecated.c
subversion/trunk/subversion/libsvn_wc/merge.c
Modified: subversion/trunk/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_wc.h?rev=1336833&r1=1336832&r2=1336833&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_wc.h (original)
+++ subversion/trunk/subversion/include/svn_wc.h Thu May 10 19:13:11 2012
@@ -6575,7 +6575,7 @@ typedef enum svn_wc_merge_outcome_t
* receive the changes, then translated back again.
*
* If @a target_abspath is absent, or present but not under version
- * control, then set @a *merge_outcome to #svn_wc_merge_no_merge and
+ * control, then set @a *merge_content_outcome to #svn_wc_merge_no_merge and
* return success without merging anything. (The reasoning is that if
* the file is not versioned, then it is probably unrelated to the
* changes being considered, so they should not be merged into it.
@@ -6593,8 +6593,16 @@ typedef enum svn_wc_merge_outcome_t
* svn_diff_file_options_parse()). @a merge_options must contain
* <tt>const char *</tt> elements.
*
- * The outcome of the merge is returned in @a *merge_outcome. If there
- * is a conflict and @a dry_run is @c FALSE, then attempt to call @a
+ * If @a merge_props_state is non-NULL @a propchanges is merged before
+ * merging the text. (If @a merge_props_outcome is NULL, no property changes
+* are merged and @a prop_changes is only used to determine the merge result)
+ * The result of the property merge is stored in @a *merge_props_state. If
+ * there is a conflict and @a dry_run is @c FALSE, then attempt to call @a
+ * conflict_func with @a conflict_baton (if non-NULL). If the conflict
+ * callback cannot resolve the conflict, then a property conflict is installed.
+ *
+ * The outcome of the text merge is returned in @a *merge_text_outcome. If
+ * there is a conflict and @a dry_run is @c FALSE, then attempt to call @a
* conflict_func with @a conflict_baton (if non-NULL). If the
* conflict callback cannot resolve the conflict, then:
*
@@ -6629,9 +6637,39 @@ typedef enum svn_wc_merge_outcome_t
*
* Use @a scratch_pool for any temporary allocation.
*
+ * @since New in 1.8.
+ */ /* ### BH: Two kinds of outcome is not how it should be */
+svn_error_t *
+svn_wc_merge5(enum svn_wc_merge_outcome_t *merge_content_outcome,
+ enum svn_wc_notify_state_t *merge_props_state,
+ svn_wc_context_t *wc_ctx,
+ const char *left_abspath,
+ const char *right_abspath,
+ const char *target_abspath,
+ const char *left_label,
+ const char *right_label,
+ const char *target_label,
+ const svn_wc_conflict_version_t *left_version,
+ const svn_wc_conflict_version_t *right_version,
+ 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,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool);
+
+/** Similar to svn_wc_merge4() but doesn't allow property changes. Instead of
+ * handling this in a single operation, a separate call to svn_wc_merge_props3()
+ * before calling svn_wc_merge4() is needed
+ *
* @since New in 1.7.
+ * @deprecated Provided for backwards compatibility with the 1.7 API.
*/
-svn_error_t *
+SVN_DEPRECATED svn_error_t *
svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome,
svn_wc_context_t *wc_ctx,
const char *left_abspath,
@@ -6652,6 +6690,7 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
void *cancel_baton,
apr_pool_t *scratch_pool);
+
/** Similar to svn_wc_merge4() but takes relative paths and an access
* baton. It doesn't support a cancel function or tracking origin version
* information.
Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1336833&r1=1336832&r2=1336833&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Thu May 10 19:13:11 2012
@@ -1535,7 +1535,7 @@ merge_file_changed(svn_wc_notify_state_t
/* Other easy outs: if the merge target isn't under version
control, or is just missing from disk, fogettaboutit. There's no
- way svn_wc_merge4() can do the merge. */
+ way svn_wc_merge5() can do the merge. */
if (wc_kind != svn_node_file || is_deleted)
{
const char *moved_to_abspath;
@@ -1623,7 +1623,7 @@ merge_file_changed(svn_wc_notify_state_t
*/
/* This callback is essentially no more than a wrapper around
- svn_wc_merge4(). Thank goodness that all the
+ svn_wc_merge5(). Thank goodness that all the
diff-editor-mechanisms are doing the hard work of getting the
fulltexts! */
@@ -1669,7 +1669,7 @@ merge_file_changed(svn_wc_notify_state_t
if (older_abspath)
{
svn_boolean_t has_local_mods;
- enum svn_wc_merge_outcome_t merge_outcome;
+ enum svn_wc_merge_outcome_t content_outcome;
/* xgettext: the '.working', '.merge-left.r%ld' and
'.merge-right.r%ld' strings are used to tag onto a file
@@ -1691,26 +1691,15 @@ merge_file_changed(svn_wc_notify_state_t
conflict_baton.conflicted_paths = &merge_b->conflicted_paths;
conflict_baton.pool = merge_b->pool;
- /* Do property merge before text merge so that keyword expansion takes
- into account the new property values. */
- if (prop_changes)
- {
- SVN_ERR(svn_wc_merge_props3(prop_state, ctx->wc_ctx, local_abspath,
- left, right,
- original_props, prop_changes,
- merge_b->dry_run,
- ctx->conflict_func2,
- ctx->conflict_baton2,
- ctx->cancel_func, ctx->cancel_baton,
- scratch_pool));
- }
-
- SVN_ERR(svn_wc_merge4(&merge_outcome, ctx->wc_ctx,
+ /* Do property merge and text merge in one step so that keyword expansion
+ takes into account the new property values. */
+ SVN_ERR(svn_wc_merge5(&content_outcome, prop_state, ctx->wc_ctx,
older_abspath, yours_abspath, local_abspath,
left_label, right_label, target_label,
left, right,
merge_b->dry_run, merge_b->diff3_cmd,
- merge_b->merge_options, prop_changes,
+ merge_b->merge_options,
+ original_props, prop_changes,
conflict_resolver, &conflict_baton,
ctx->cancel_func,
ctx->cancel_baton,
@@ -1718,14 +1707,14 @@ merge_file_changed(svn_wc_notify_state_t
if (content_state)
{
- if (merge_outcome == svn_wc_merge_conflict)
+ if (content_outcome == svn_wc_merge_conflict)
*content_state = svn_wc_notify_state_conflicted;
else if (has_local_mods
- && merge_outcome != svn_wc_merge_unchanged)
+ && content_outcome != svn_wc_merge_unchanged)
*content_state = svn_wc_notify_state_merged;
- else if (merge_outcome == svn_wc_merge_merged)
+ else if (content_outcome == svn_wc_merge_merged)
*content_state = svn_wc_notify_state_changed;
- else if (merge_outcome == svn_wc_merge_no_merge)
+ else if (content_outcome == svn_wc_merge_no_merge)
*content_state = svn_wc_notify_state_missing;
else /* merge_outcome == svn_wc_merge_unchanged */
*content_state = svn_wc_notify_state_unchanged;
Modified: subversion/trunk/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/deprecated.c?rev=1336833&r1=1336832&r2=1336833&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_wc/deprecated.c Thu May 10 19:13:11 2012
@@ -4185,6 +4185,49 @@ svn_wc_copy(const char *src_path,
/*** From merge.c ***/
svn_error_t *
+svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome,
+ svn_wc_context_t *wc_ctx,
+ const char *left_abspath,
+ const char *right_abspath,
+ const char *target_abspath,
+ const char *left_label,
+ const char *right_label,
+ const char *target_label,
+ const svn_wc_conflict_version_t *left_version,
+ const svn_wc_conflict_version_t *right_version,
+ svn_boolean_t dry_run,
+ const char *diff3_cmd,
+ const apr_array_header_t *merge_options,
+ const apr_array_header_t *prop_diff,
+ svn_wc_conflict_resolver_func2_t conflict_func,
+ void *conflict_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_trace(
+ svn_wc_merge5(merge_outcome,
+ NULL /* merge_props_outcome */,
+ wc_ctx,
+ left_abspath,
+ right_abspath,
+ target_abspath,
+ left_label,
+ right_label,
+ target_label,
+ left_version,
+ right_version,
+ dry_run,
+ diff3_cmd,
+ merge_options,
+ NULL /* original_props */,
+ prop_diff,
+ conflict_func, conflict_baton,
+ cancel_func, cancel_baton,
+ scratch_pool));
+}
+
+svn_error_t *
svn_wc_merge3(enum svn_wc_merge_outcome_t *merge_outcome,
const char *left,
const char *right,
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;
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;
}
Re: svn commit: r1336833 - in /subversion/trunk/subversion:
include/svn_wc.h libsvn_client/merge.c libsvn_wc/deprecated.c libsvn_wc/merge.c
Posted by Hyrum K Wright <hy...@wandisco.com>.
On Thu, May 31, 2012 at 4:32 PM, Hyrum K Wright
<hy...@wandisco.com> wrote:
> On Thu, May 10, 2012 at 2:13 PM, <rh...@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.
Bert,
Any response on this? I'm concerned about this seemingly arbitrary
type mismatch, and the effects it could have. This probably only work
by luck at this point...
-Hyrum
--
uberSVN: Apache Subversion Made Easy
http://www.uberSVN.com/
Re: svn commit: r1336833 - in /subversion/trunk/subversion:
include/svn_wc.h libsvn_client/merge.c libsvn_wc/deprecated.c libsvn_wc/merge.c
Posted by Hyrum K Wright <hy...@wandisco.com>.
On Thu, May 10, 2012 at 2:13 PM, <rh...@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/