Author: rhuijben
Date: Thu Dec 13 17:17:40 2012
New Revision: 1421391
URL: http://svn.apache.org/viewvc?rev=1421391&view=rev
Log:
Switch the property merge code implementation to use explicit output arguments
instead of updating a passed apr_hash_t and state.
* subversion/libsvn_wc/props.c
(apply_single_prop_add,
apply_single_prop_delete,
apply_single_mergeinfo_prop_change,
apply_single_generic_prop_change,
apply_single_prop_change): Move updating the property hash and state from
here to ...
(svn_wc__merge_props): ... here.
Modified:
subversion/trunk/subversion/libsvn_wc/props.c
Modified: subversion/trunk/subversion/libsvn_wc/props.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/props.c?rev=1421391&r1=1421390&r2=1421391&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/props.c (original)
+++ subversion/trunk/subversion/libsvn_wc/props.c Thu Dec 13 17:17:40 2012
@@ -738,30 +738,26 @@ set_prop_merge_state(svn_wc_notify_state
*state = new_value;
}
-/* Add the property with name PROPNAME to the set of ACTUAL_PROPS,
- * setting *STATE or *CONFLICT_REMAINS according to the merge outcome.
- *
- * *STATE is an input and output parameter, its value is to be
- * set using set_merge_prop_state().
+/* Apply the addition of a property with name PROPNAME and value NEW_VAL to
+ * the existing property with value WORKING_VAL, that originally had value
+ * PRISTINE_VAL.
*
- * BASE_VAL contains the working copy base property value
- *
- * NEW_VAL contains the value to be set.
+ * Sets *RESULT_VAL to the resulting value.
+ * Sets *CONFLICT_REMAINS to TRUE if the change caused a conflict.
+ * Sets *DID_MERGE to true if the result is caused by a merge
*/
static svn_error_t *
-apply_single_prop_add(svn_wc_notify_state_t *state,
+apply_single_prop_add(const svn_string_t **result_val,
svn_boolean_t *conflict_remains,
- apr_hash_t *actual_props,
+ svn_boolean_t *did_merge,
const char *propname,
- const svn_string_t *base_val,
+ const svn_string_t *pristine_val,
const svn_string_t *new_val,
+ const svn_string_t *working_val,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_string_t *working_val
- = apr_hash_get(actual_props, propname, APR_HASH_KEY_STRING);
-
*conflict_remains = FALSE;
if (working_val)
@@ -770,7 +766,7 @@ apply_single_prop_add(svn_wc_notify_stat
if (svn_string_compare(working_val, new_val))
/* The value we want is already there, so it's a merge. */
- set_prop_merge_state(state, svn_wc_notify_state_merged);
+ *did_merge = TRUE;
else
{
@@ -800,9 +796,8 @@ apply_single_prop_add(svn_wc_notify_stat
else
{
merged_prop = TRUE;
- apr_hash_set(actual_props, propname,
- APR_HASH_KEY_STRING, merged_val);
- set_prop_merge_state(state, svn_wc_notify_state_merged);
+ *result_val = merged_val;
+ *did_merge = TRUE;
}
}
@@ -810,40 +805,34 @@ apply_single_prop_add(svn_wc_notify_stat
*conflict_remains = TRUE;
}
}
- else if (base_val)
+ else if (pristine_val)
*conflict_remains = TRUE;
else /* property doesn't yet exist in actual_props... */
/* so just set it */
- apr_hash_set(actual_props, propname, APR_HASH_KEY_STRING, new_val);
+ *result_val = new_val;
return SVN_NO_ERROR;
}
-/* Delete the property with name PROPNAME from the set of ACTUAL_PROPS,
- * setting *STATE or *CONFLICT_REMAINS according to the merge outcome.
- *
- * *STATE is an input and output parameter, its value is to be
- * set using set_merge_prop_state().
+/* Apply the deletion of a property with name PROPNAME to the existing
+ * property with value WORKING_VAL, that originally had value PRISTINE_VAL.
*
- * BASE_VAL contains the working copy base property value
- *
- * OLD_VAL contains the value the of the property the server
- * thinks it's deleting.
+ * Sets *RESULT_VAL to the resulting value.
+ * Sets *CONFLICT_REMAINS to TRUE if the change caused a conflict.
+ * Sets *DID_MERGE to true if the result is caused by a merge
*/
static svn_error_t *
-apply_single_prop_delete(svn_wc_notify_state_t *state,
+apply_single_prop_delete(const svn_string_t **result_val,
svn_boolean_t *conflict_remains,
- apr_hash_t *actual_props,
+ svn_boolean_t *did_merge,
const char *propname,
const svn_string_t *base_val,
const svn_string_t *old_val,
+ const svn_string_t *working_val,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_string_t *working_val
- = apr_hash_get(actual_props, propname, APR_HASH_KEY_STRING);
-
*conflict_remains = FALSE;
if (! base_val)
@@ -856,11 +845,11 @@ apply_single_prop_delete(svn_wc_notify_s
}
else
{
- apr_hash_set(actual_props, propname, APR_HASH_KEY_STRING, NULL);
+ *result_val = NULL;
if (old_val)
/* This is a merge, merging a delete into non-existent
property or a local addition of same prop value. */
- set_prop_merge_state(state, svn_wc_notify_state_merged);
+ *did_merge = TRUE;
}
}
@@ -870,14 +859,14 @@ apply_single_prop_delete(svn_wc_notify_s
{
if (svn_string_compare(working_val, old_val))
/* they have the same values, so it's an update */
- apr_hash_set(actual_props, propname, APR_HASH_KEY_STRING, NULL);
+ *result_val = NULL;
else
*conflict_remains = TRUE;
}
else
/* The property is locally deleted from the same value, so it's
a merge */
- set_prop_merge_state(state, svn_wc_notify_state_merged);
+ *did_merge = TRUE;
}
else
@@ -895,19 +884,17 @@ apply_single_prop_delete(svn_wc_notify_s
were not followed for this property, but with no attempt to rationalize
the remainder. */
static svn_error_t *
-apply_single_mergeinfo_prop_change(svn_wc_notify_state_t *state,
+apply_single_mergeinfo_prop_change(const svn_string_t **result_val,
svn_boolean_t *conflict_remains,
- apr_hash_t *actual_props,
+ svn_boolean_t *did_merge,
const char *propname,
const svn_string_t *base_val,
const svn_string_t *old_val,
const svn_string_t *new_val,
+ const svn_string_t *working_val,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_string_t *working_val
- = apr_hash_get(actual_props, propname, APR_HASH_KEY_STRING);
-
if ((working_val && ! base_val)
|| (! working_val && base_val)
|| (working_val && base_val
@@ -918,7 +905,7 @@ apply_single_mergeinfo_prop_change(svn_w
{
if (svn_string_compare(working_val, new_val))
/* The new value equals the changed value: a no-op merge */
- set_prop_merge_state(state, svn_wc_notify_state_merged);
+ *did_merge = TRUE;
else
{
/* We have base, WC, and new values. Discover
@@ -930,12 +917,10 @@ apply_single_mergeinfo_prop_change(svn_w
new_val,
result_pool,
scratch_pool));
- apr_hash_set(actual_props, propname,
- APR_HASH_KEY_STRING, new_val);
- set_prop_merge_state(state, svn_wc_notify_state_merged);
+ *result_val = new_val;
+ *did_merge = TRUE;
}
}
-
else
{
/* There is a base_val but no working_val */
@@ -957,15 +942,13 @@ apply_single_mergeinfo_prop_change(svn_w
old_val, new_val, scratch_pool));
SVN_ERR(svn_mergeinfo_to_string(&mergeinfo_string,
added_mergeinfo, result_pool));
- apr_hash_set(actual_props, propname, APR_HASH_KEY_STRING,
- mergeinfo_string);
+ *result_val = mergeinfo_string;
}
else /* means working && base && svn_string_compare(working, base) */
{
if (svn_string_compare(old_val, base_val))
- apr_hash_set(actual_props, propname, APR_HASH_KEY_STRING, new_val);
-
+ *result_val = new_val;
else
{
/* We have base, WC, and new values. Discover
@@ -976,9 +959,8 @@ apply_single_mergeinfo_prop_change(svn_w
working_val,
new_val, result_pool,
scratch_pool));
- apr_hash_set(actual_props, propname,
- APR_HASH_KEY_STRING, new_val);
- set_prop_merge_state(state, svn_wc_notify_state_merged);
+ *result_val = new_val;
+ *did_merge = TRUE;
}
}
@@ -992,19 +974,17 @@ apply_single_mergeinfo_prop_change(svn_w
The definition of the arguments and behaviour is the same as
apply_single_prop_change(). */
static svn_error_t *
-apply_single_generic_prop_change(svn_wc_notify_state_t *state,
+apply_single_generic_prop_change(const svn_string_t **result_val,
svn_boolean_t *conflict_remains,
- apr_hash_t *actual_props,
+ svn_boolean_t *did_merge,
const char *propname,
const svn_string_t *base_val,
const svn_string_t *old_val,
const svn_string_t *new_val,
+ const svn_string_t *working_val,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_string_t *working_val
- = apr_hash_get(actual_props, propname, APR_HASH_KEY_STRING);
-
SVN_ERR_ASSERT(old_val != NULL);
/* If working_val is the same as new_val already then there is
@@ -1014,14 +994,14 @@ apply_single_generic_prop_change(svn_wc_
{
/* All values identical is a trivial, non-notifiable merge */
if (! old_val || ! svn_string_compare(old_val, new_val))
- set_prop_merge_state(state, svn_wc_notify_state_merged);
+ *did_merge = TRUE;
}
/* If working_val is the same as old_val... */
else if (working_val && old_val
&& svn_string_compare(working_val, old_val))
{
/* A trivial update: change it to new_val. */
- apr_hash_set(actual_props, propname, APR_HASH_KEY_STRING, new_val);
+ *result_val = new_val;
}
else
{
@@ -1046,13 +1026,14 @@ apply_single_generic_prop_change(svn_wc_
* NEW_VAL contains the value to be set. (Not null.)
*/
static svn_error_t *
-apply_single_prop_change(svn_wc_notify_state_t *state,
+apply_single_prop_change(const svn_string_t **result_val,
svn_boolean_t *conflict_remains,
- apr_hash_t *actual_props,
+ svn_boolean_t *did_merge,
const char *propname,
const svn_string_t *base_val,
const svn_string_t *old_val,
const svn_string_t *new_val,
+ const svn_string_t *working_val,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -1075,13 +1056,14 @@ apply_single_prop_change(svn_wc_notify_s
gracefully' might thwart us. If bogus mergeinfo is present we
can't merge intelligently, so let the standard method deal with
it instead. */
- svn_error_t *err = apply_single_mergeinfo_prop_change(state,
+ svn_error_t *err = apply_single_mergeinfo_prop_change(result_val,
conflict_remains,
- actual_props,
+ did_merge,
propname,
base_val,
old_val,
new_val,
+ working_val,
result_pool,
scratch_pool);
if (err)
@@ -1102,10 +1084,10 @@ apply_single_prop_change(svn_wc_notify_s
/* The standard method: perform a simple update automatically, but
pass any other kind of merge to maybe_generate_propconflict(). */
- SVN_ERR(apply_single_generic_prop_change(state, conflict_remains,
- actual_props,
+ SVN_ERR(apply_single_generic_prop_change(result_val, conflict_remains,
+ did_merge,
propname, base_val, old_val,
- new_val,
+ new_val, working_val,
result_pool, scratch_pool));
}
@@ -1163,6 +1145,9 @@ svn_wc__merge_props(svn_skel_t **conflic
const svn_string_t *base_val; /* Pristine in WC */
const svn_string_t *from_val; /* Merge left */
const svn_string_t *to_val; /* Merge right */
+ const svn_string_t *working_val; /* Mine */
+ const svn_string_t *result_val;
+ svn_boolean_t did_merge = FALSE;
svn_pool_clear(iterpool);
@@ -1174,36 +1159,45 @@ svn_wc__merge_props(svn_skel_t **conflic
from_val = apr_hash_get(server_baseprops, propname, APR_HASH_KEY_STRING);
base_val = apr_hash_get(pristine_props, propname, APR_HASH_KEY_STRING);
+ working_val = apr_hash_get(actual_props, propname, APR_HASH_KEY_STRING);
if (new_pristine_props)
apr_hash_set(*new_pristine_props, propname, APR_HASH_KEY_STRING,
to_val);
apr_hash_set(their_props, propname, APR_HASH_KEY_STRING, to_val);
+
/* We already know that state is at least `changed', so mark
that, but remember that we may later upgrade to `merged' or
even `conflicted'. */
set_prop_merge_state(state, svn_wc_notify_state_changed);
+ result_val = working_val;
+
if (! from_val) /* adding a new property */
- SVN_ERR(apply_single_prop_add(state, &conflict_remains,
- *new_actual_props,
- propname, base_val, to_val,
+ SVN_ERR(apply_single_prop_add(&result_val, &conflict_remains,
+ &did_merge, propname,
+ base_val, to_val, working_val,
result_pool, iterpool));
else if (! to_val) /* delete an existing property */
- SVN_ERR(apply_single_prop_delete(state, &conflict_remains,
- *new_actual_props,
- propname, base_val, from_val,
+ SVN_ERR(apply_single_prop_delete(&result_val, &conflict_remains,
+ &did_merge, propname,
+ base_val, from_val, working_val,
result_pool, iterpool));
else /* changing an existing property */
- SVN_ERR(apply_single_prop_change(state, &conflict_remains,
- *new_actual_props,
- propname, base_val, from_val, to_val,
+ SVN_ERR(apply_single_prop_change(&result_val, &conflict_remains,
+ &did_merge, propname,
+ base_val, from_val, to_val,
working_val,
result_pool, iterpool));
+ if (result_val != working_val)
+ apr_hash_set(*new_actual_props, propname, APR_HASH_KEY_STRING,
+ result_val);
+ if (did_merge)
+ set_prop_merge_state(state, svn_wc_notify_state_merged);
/* merging logic complete, now we need to possibly log conflict
data to tmpfiles. */