After this change, trunk Subversion gets many warnings like this:
subversion/libsvn_wc/deprecated.c:643: warning: \
initialization from incompatible pointer type
It's because in subversion/libsvn_wc/deprecated.c, we already have this
code:
static struct svn_wc_diff_callbacks3_t callbacks_wrapper = {
file_changed,
file_added,
file_deleted,
dir_added,
etc, ...
}
r33989 changed 'svn_wc_diff_callbacks3_t' by adding a new parameter
(TREE_CONFLICTED) to many of its callback functions. But the static
functions in deprecated.c were never updated with the new parameter --
thus, they give a warning when used in those positions in the struct.
-Karl
neels_at_tigris.org writes:
> Log:
> Merge (lightweight) branch tc-merge-notify to trunk.
>
> Implement per-victim tree-conflicts notification during merge.
> Use newly implemented notification style in merge operations (as done
> for update/switch recently).
>
> Do not show `Skipped' messages within newly tree-conflicted directories.
> Pass a boolean SKIP down the item batons and completely skip *all*
> action in the editor if SKIP is TRUE (i.e. don't even call diff callbacks).
> Since the diff callbacks don't have an item baton to fill, I solved it
> by skipping child nodes already in the general editor that calls the diff
> callbacks. But it would probably do this code good to move to a standard
> editor implementation altogether, like `update/switch' does it.
>
>
> * subversion/include/svn_wc.h (svn_wc_diff_callbacks3_t): Add a svn_boolean_t
> *TREE_CONFLICTED argument to all of the callbacks functions, which
> returns whether the callback wants this node to be notified as
> tree-conflicted. Returning TRUE in *TREE_CONFLICTED makes a repos
> diff (and consequently a merge) skip any child nodes.
>
> * subversion/libsvn_wc/diff.c
> (file_diff, directory_elements_diff, report_wc_file_as_added,
> report_wc_directory_as_added, delete_entry, close_directory,
> close_file): Pass NULL for new *TREE_CONFLICTED parameter upon calling
> the svn_wc_diff_callbacks3_t callback functions. Currently, handling
> tree-conflicts notifications here is not needed, since there is no
> code using it. Note that this variant of diff will also not skip
> child nodes of a tree-conflicted item for the same reason.
>
> * subversion/libsvn_client/repos_diff.c
> (dir_baton, file_baton): Add two booleans TREE_CONFLICTED and SKIPPED.
> (make_dir_baton, make_file_baton): Default TREE_CONFLICTED to FALSE.
> Default SKIPPED to FALSE.
> (delete_entry, add_directory, open_directory, close_file, close_directory):
> Pass the tree-conflict state through to the notify_func, and change some
> of the logic around the notify action to not show tree-conflicts as
> skipped paths.
> (delete_entry, add_directory, open_directory, add_file, open_file):
> Skip *all* action if the parent node is SKIPped or TREE_CONFLICTED.
> Propagate the SKIP flag to child batons where necessary.
> (window_handler, apply_textdelta, close_file, close_directory,
> change_file_prop, change_dir_prop): Skip *all* action if this node's
> SKIP flag is TRUE.
> (kind_action_state_t): Add a boolean TREE_CONFLICTED field (breaking the
> name kind_action_state_t which says "it has a kind, an action and a
> state") used for notification of deleted nodes.
> (absent_directory, absent_file): Add a question comment.
>
> * subversion/libsvn_client/merge.c
> (merge_props_changed, merge_file_changed, merge_file_added,
> merge_file_deleted, merge_dir_added, merge_dir_deleted, merge_dir_opened,
> merge_dir_closed, single_file_merge_notify, do_file_merge): Apply addition
> of new callbacks argument called *TREE_CONFLICTED and use it.
> (merge_cmd_baton_t): Remove obsoleted field TREE_CONFLICTED_DIRS which
> used to list all dirs that contain tree-conflicts.
> (add_parent_to_tree_conflicted_dirs, is_tree_conflicted_dir_p): Remove
> obsoleted functions related to TREE_CONFLICTED_DIRS.
> (do_merge, tree_conflict): Remove use of TREE_CONFLICTED_DIRS.
>
> * subversion/libsvn_client/diff.c
> (diff_props_changed, diff_file_changed, diff_file_added,
> diff_file_deleted_with_diff, diff_file_deleted_no_diff,
> diff_dir_added, diff_dir_deleted, diff_dir_opened, diff_dir_closed):
> Apply addition of callbacks parameter *TREE_CONFLICTED and ignore it.
> These are the callbacks for a plain diff, they don't cause
> tree-conflicts by definition.
>
> * subversion/tests/cmdline/merge_tests.py
> (delete_file_and_dir, merge_catches_nonexistent_target,
> merge_tree_deleted_in_target, merge_added_dir_to_deleted_in_target,
> three_way_merge_add_of_existing_binary_file, del_differing_file,
> tree_conflicts_and_obstructions,
> tree_conflicts_on_merge_local_ci_4_1,
> tree_conflicts_on_merge_local_ci_4_2, tree_conflicts_on_merge_local_ci_5_1,
> tree_conflicts_on_merge_local_ci_5_2, tree_conflicts_on_merge_local_ci_6,
> tree_conflicts_on_merge_no_local_ci_4_1,
> tree_conflicts_on_merge_no_local_ci_4_2,
> tree_conflicts_on_merge_no_local_ci_5_1,
> tree_conflicts_on_merge_no_local_ci_5_2,
> tree_conflicts_on_merge_no_local_ci_6): Fix up some tests. Intentionally
> leaving some merge tests unfixed for now. Their common problem shall be
> fixed on trunk, since update/switch/checkout are also affected.
>
> Modified:
> trunk/ (props changed)
> trunk/build.conf (props changed)
> trunk/notes/tree-conflicts/design-overview.txt (props changed)
> trunk/notes/tree-conflicts/requirements.txt (props changed)
> trunk/subversion/include/ (props changed)
> trunk/subversion/include/private/svn_auth_private.h (props changed)
> trunk/subversion/include/private/svn_cache.h (props changed)
> trunk/subversion/include/svn_wc.h
> trunk/subversion/libsvn_auth_kwallet/kwallet.cpp (props changed)
> trunk/subversion/libsvn_client/diff.c
> trunk/subversion/libsvn_client/merge.c
> trunk/subversion/libsvn_client/repos_diff.c
> trunk/subversion/libsvn_subr/ (props changed)
> trunk/subversion/libsvn_wc/diff.c
> trunk/subversion/tests/cmdline/merge_tests.py
> trunk/subversion/tests/cmdline/tree_conflict_tests.txt (props changed)
> trunk/subversion/tests/libsvn_subr/ (props changed)
> trunk/tools/buildbot/slaves/win32-xp-VS2005/ (props changed)
> trunk/tools/server-side/svn_server_log_parse.py (props changed)
> trunk/tools/server-side/test_svn_server_log_parse.py (props changed)
> trunk/www/development.html (props changed)
> trunk/www/issue-tracker.html (props changed)
> trunk/www/tasks.html (props changed)
>
> Merged:
> /branches/tc-merge-notify:r33943-33988
>
> Modified: trunk/subversion/include/svn_wc.h
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/include/svn_wc.h?pathrev=33989&r1=33988&r2=33989
> ==============================================================================
> --- trunk/subversion/include/svn_wc.h Fri Oct 31 19:55:38 2008 (r33988)
> +++ trunk/subversion/include/svn_wc.h Fri Oct 31 20:39:02 2008 (r33989)
> @@ -1461,6 +1461,7 @@ typedef struct svn_wc_diff_callbacks3_t
> svn_error_t *(*file_changed)(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *contentstate,
> svn_wc_notify_state_t *propstate,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> const char *tmpfile1,
> const char *tmpfile2,
> @@ -1491,6 +1492,7 @@ typedef struct svn_wc_diff_callbacks3_t
> svn_error_t *(*file_added)(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *contentstate,
> svn_wc_notify_state_t *propstate,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> const char *tmpfile1,
> const char *tmpfile2,
> @@ -1514,6 +1516,7 @@ typedef struct svn_wc_diff_callbacks3_t
> */
> svn_error_t *(*file_deleted)(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> const char *tmpfile1,
> const char *tmpfile2,
> @@ -1528,6 +1531,7 @@ typedef struct svn_wc_diff_callbacks3_t
> */
> svn_error_t *(*dir_added)(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> svn_revnum_t rev,
> void *diff_baton);
> @@ -1537,6 +1541,7 @@ typedef struct svn_wc_diff_callbacks3_t
> */
> svn_error_t *(*dir_deleted)(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> void *diff_baton);
>
> @@ -1552,6 +1557,7 @@ typedef struct svn_wc_diff_callbacks3_t
> */
> svn_error_t *(*dir_props_changed)(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *propstate,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> const apr_array_header_t *propchanges,
> apr_hash_t *original_props,
> @@ -1563,6 +1569,7 @@ typedef struct svn_wc_diff_callbacks3_t
> *
> */
> svn_error_t *(*dir_opened)(svn_wc_adm_access_t *adm_access,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> svn_revnum_t rev,
> void *diff_baton);
> @@ -1578,6 +1585,7 @@ typedef struct svn_wc_diff_callbacks3_t
> */
> svn_error_t *(*dir_closed)(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> void *diff_baton);
>
>
> Modified: trunk/subversion/libsvn_client/diff.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_client/diff.c?pathrev=33989&r1=33988&r2=33989
> ==============================================================================
> --- trunk/subversion/libsvn_client/diff.c Fri Oct 31 19:55:38 2008 (r33988)
> +++ trunk/subversion/libsvn_client/diff.c Fri Oct 31 20:39:02 2008 (r33989)
> @@ -374,6 +374,7 @@ diff_label(const char *path,
> static svn_error_t *
> diff_props_changed(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> const apr_array_header_t *propchanges,
> apr_hash_t *original_props,
> @@ -394,6 +395,8 @@ diff_props_changed(svn_wc_adm_access_t *
>
> if (state)
> *state = svn_wc_notify_state_unknown;
> + if (tree_conflicted)
> + *tree_conflicted = FALSE;
>
> svn_pool_destroy(subpool);
> return SVN_NO_ERROR;
> @@ -604,6 +607,7 @@ static svn_error_t *
> diff_file_changed(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *content_state,
> svn_wc_notify_state_t *prop_state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> const char *tmpfile1,
> const char *tmpfile2,
> @@ -620,12 +624,15 @@ diff_file_changed(svn_wc_adm_access_t *a
> tmpfile1, tmpfile2, rev1, rev2,
> mimetype1, mimetype2, diff_baton));
> if (prop_changes->nelts > 0)
> - SVN_ERR(diff_props_changed(adm_access, prop_state, path, prop_changes,
> + SVN_ERR(diff_props_changed(adm_access, prop_state, tree_conflicted,
> + path, prop_changes,
> original_props, diff_baton));
> if (content_state)
> *content_state = svn_wc_notify_state_unknown;
> if (prop_state)
> *prop_state = svn_wc_notify_state_unknown;
> + if (tree_conflicted)
> + *tree_conflicted = FALSE;
> return SVN_NO_ERROR;
> }
>
> @@ -638,6 +645,7 @@ static svn_error_t *
> diff_file_added(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *content_state,
> svn_wc_notify_state_t *prop_state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> const char *tmpfile1,
> const char *tmpfile2,
> @@ -658,7 +666,8 @@ diff_file_added(svn_wc_adm_access_t *adm
> user see that *something* happened. */
> diff_cmd_baton->force_empty = TRUE;
>
> - SVN_ERR(diff_file_changed(adm_access, content_state, prop_state, path,
> + SVN_ERR(diff_file_changed(adm_access, content_state, prop_state,
> + tree_conflicted, path,
> tmpfile1, tmpfile2,
> rev1, rev2,
> mimetype1, mimetype2,
> @@ -673,6 +682,7 @@ diff_file_added(svn_wc_adm_access_t *adm
> static svn_error_t *
> diff_file_deleted_with_diff(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> const char *tmpfile1,
> const char *tmpfile2,
> @@ -684,7 +694,7 @@ diff_file_deleted_with_diff(svn_wc_adm_a
> struct diff_cmd_baton *diff_cmd_baton = diff_baton;
>
> /* We don't list all the deleted properties. */
> - return diff_file_changed(adm_access, state, NULL, path,
> + return diff_file_changed(adm_access, state, NULL, tree_conflicted, path,
> tmpfile1, tmpfile2,
> diff_cmd_baton->revnum1, diff_cmd_baton->revnum2,
> mimetype1, mimetype2,
> @@ -697,6 +707,7 @@ diff_file_deleted_with_diff(svn_wc_adm_a
> static svn_error_t *
> diff_file_deleted_no_diff(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> const char *tmpfile1,
> const char *tmpfile2,
> @@ -709,6 +720,8 @@ diff_file_deleted_no_diff(svn_wc_adm_acc
>
> if (state)
> *state = svn_wc_notify_state_unknown;
> + if (tree_conflicted)
> + *tree_conflicted = FALSE;
>
> return file_printf_from_utf8
> (diff_cmd_baton->outfile,
> @@ -717,21 +730,22 @@ diff_file_deleted_no_diff(svn_wc_adm_acc
> path, equal_string);
> }
>
> -/* An svn_wc_diff_callbacks3_t function.
> - For now, let's have 'svn diff' send feedback to the top-level
> - application, so that something reasonable about directories and
> - propsets gets printed to stdout. */
> +/* An svn_wc_diff_callbacks3_t function. */
> static svn_error_t *
> diff_dir_added(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> svn_revnum_t rev,
> void *diff_baton)
> {
> if (state)
> *state = svn_wc_notify_state_unknown;
> + if (tree_conflicted)
> + *tree_conflicted = FALSE;
> +
> + /* Do nothing. */
>
> - /* ### todo: send feedback to app */
> return SVN_NO_ERROR;
> }
>
> @@ -739,11 +753,16 @@ diff_dir_added(svn_wc_adm_access_t *adm_
> static svn_error_t *
> diff_dir_deleted(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> void *diff_baton)
> {
> if (state)
> *state = svn_wc_notify_state_unknown;
> + if (tree_conflicted)
> + *tree_conflicted = FALSE;
> +
> + /* Do nothing. */
>
> return SVN_NO_ERROR;
> }
> @@ -751,10 +770,16 @@ diff_dir_deleted(svn_wc_adm_access_t *ad
> /* An svn_wc_diff_callbacks3_t function. */
> static svn_error_t *
> diff_dir_opened(svn_wc_adm_access_t *adm_access,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> svn_revnum_t rev,
> void *diff_baton)
> {
> + if (tree_conflicted)
> + *tree_conflicted = FALSE;
> +
> + /* Do nothing. */
> +
> return SVN_NO_ERROR;
> }
>
> @@ -762,11 +787,16 @@ diff_dir_opened(svn_wc_adm_access_t *adm
> static svn_error_t *
> diff_dir_closed(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> void *diff_baton)
> {
> if (state)
> *state = svn_wc_notify_state_unknown;
> + if (tree_conflicted)
> + *tree_conflicted = FALSE;
> +
> + /* Do nothing. */
>
> return SVN_NO_ERROR;
> }
>
> Modified: trunk/subversion/libsvn_client/merge.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_client/merge.c?pathrev=33989&r1=33988&r2=33989
> ==============================================================================
> --- trunk/subversion/libsvn_client/merge.c Fri Oct 31 19:55:38 2008 (r33988)
> +++ trunk/subversion/libsvn_client/merge.c Fri Oct 31 20:39:02 2008 (r33989)
> @@ -280,9 +280,6 @@ typedef struct merge_cmd_baton_t {
> svn_ra_session_t *ra_session1;
> svn_ra_session_t *ra_session2;
>
> - /* A list of directories containing tree conflicts. */
> - apr_array_header_t *tree_conflicted_dirs;
> -
> /* During the merge, *USE_SLEEP is set to TRUE if a sleep will be required
> afterwards to ensure timestamp integrity, or unchanged if not. */
> svn_boolean_t *use_sleep;
> @@ -323,28 +320,6 @@ is_path_conflicted_by_merge(merge_cmd_ba
> apr_hash_count(merge_b->conflicted_paths) > 0);
> }
>
> -/* Add the parent dir of VICTIM_PATH to the merge baton's list of
> - tree-conflicted directories, if it isn't already in the list. */
> -static void
> -add_parent_to_tree_conflicted_dirs(merge_cmd_baton_t *merge_b,
> - const char *victim_path)
> -{
> - const char *dir_path, *old_path;
> - int i;
> -
> - dir_path = svn_path_dirname(victim_path, merge_b->pool);
> -
> - for (i = 0; i < merge_b->tree_conflicted_dirs->nelts; i++)
> - {
> - old_path = APR_ARRAY_IDX(merge_b->tree_conflicted_dirs, i,
> - const char *);
> - if (strcmp(old_path, dir_path) == 0)
> - return;
> - }
> -
> - APR_ARRAY_PUSH(merge_b->tree_conflicted_dirs, const char *) = dir_path;
> -}
> -
> /* Cause a tree conflict notification, and if the merge is not
> * a dry run, also make the tree conflict persistent. Do nothing
> * if the merge is record-only.
> @@ -368,12 +343,7 @@ tree_conflict(merge_cmd_baton_t *merge_b
> {
> svn_wc_conflict_description_t *conflict;
>
> - if (merge_b->record_only)
> - return SVN_NO_ERROR;
> -
> - add_parent_to_tree_conflicted_dirs(merge_b, victim_path);
> -
> - if (merge_b->dry_run)
> + if (merge_b->record_only || merge_b->dry_run)
> return SVN_NO_ERROR;
>
> conflict = svn_wc_conflict_description_create_tree(
> @@ -384,26 +354,6 @@ tree_conflict(merge_cmd_baton_t *merge_b
> return SVN_NO_ERROR;
> }
>
> -/* TRUE iff DIR_PATH is in the merge baton's list of tree-conflicted
> - directories. */
> -static svn_boolean_t
> -is_tree_conflicted_dir_p(merge_cmd_baton_t *merge_b,
> - const char *dir_path)
> -{
> - const char *old_path;
> - int i;
> -
> - for (i = 0; i < merge_b->tree_conflicted_dirs->nelts; i++)
> - {
> - old_path = APR_ARRAY_IDX(merge_b->tree_conflicted_dirs, i,
> - const char *);
> - if (strcmp(old_path, dir_path) == 0)
> - return TRUE;
> - }
> -
> - return FALSE;
> -}
> -
> /* Set *HONOR_MERGEINFO and *RECORD_MERGEINFO (if non-NULL) based on the
> merge being performed as described in MERGE_B.
>
> @@ -820,6 +770,7 @@ filter_self_referential_mergeinfo(apr_ar
> static svn_error_t *
> merge_props_changed(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> const apr_array_header_t *propchanges,
> apr_hash_t *original_props,
> @@ -969,6 +920,7 @@ static svn_error_t *
> merge_file_changed(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *content_state,
> svn_wc_notify_state_t *prop_state,
> + svn_boolean_t *tree_conflicted,
> const char *mine,
> const char *older,
> const char *yours,
> @@ -985,6 +937,9 @@ merge_file_changed(svn_wc_adm_access_t *
> svn_boolean_t merge_required = TRUE;
> enum svn_wc_merge_outcome_t merge_outcome;
>
> + if (tree_conflicted)
> + *tree_conflicted = FALSE;
> +
> /* Easy out: no access baton means there ain't no merge target */
> if (adm_access == NULL)
> {
> @@ -992,6 +947,10 @@ merge_file_changed(svn_wc_adm_access_t *
> *content_state = svn_wc_notify_state_missing;
> if (prop_state)
> *prop_state = svn_wc_notify_state_missing;
> + /* Trying to change a file at a non-existing path.
> + * Although this is a tree-conflict, it will already have been
> + * raised by the merge_dir_opened() callback. Not raising additional tree
> + * conflicts for the child nodes inside. */
> svn_pool_destroy(subpool);
> return SVN_NO_ERROR;
> }
> @@ -1019,6 +978,8 @@ merge_file_changed(svn_wc_adm_access_t *
> svn_node_file,
> svn_wc_conflict_action_edit,
> svn_wc_conflict_reason_missing));
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
> if (content_state)
> *content_state = svn_wc_notify_state_missing;
> if (prop_state)
> @@ -1049,8 +1010,8 @@ merge_file_changed(svn_wc_adm_access_t *
> /* Do property merge before text merge so that keyword expansion takes
> into account the new property values. */
> if (prop_changes->nelts > 0)
> - SVN_ERR(merge_props_changed(adm_access, prop_state, mine, prop_changes,
> - original_props, baton));
> + SVN_ERR(merge_props_changed(adm_access, prop_state, tree_conflicted,
> + mine, prop_changes, original_props, baton));
> else
> if (prop_state)
> *prop_state = svn_wc_notify_state_unchanged;
> @@ -1141,6 +1102,7 @@ static svn_error_t *
> merge_file_added(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *content_state,
> svn_wc_notify_state_t *prop_state,
> + svn_boolean_t *tree_conflicted,
> const char *mine,
> const char *older,
> const char *yours,
> @@ -1164,6 +1126,9 @@ merge_file_added(svn_wc_adm_access_t *ad
> if (prop_state)
> *prop_state = svn_wc_notify_state_unknown;
>
> + if (tree_conflicted)
> + *tree_conflicted = FALSE;
> +
> /* Apply the prop changes to a new hash table. */
> new_props = apr_hash_copy(subpool, original_props);
> for (i = 0; i < prop_changes->nelts; ++i)
> @@ -1197,6 +1162,10 @@ merge_file_added(svn_wc_adm_access_t *ad
> }
> else
> *content_state = svn_wc_notify_state_missing;
> + /* Trying to add a file at a non-existing path.
> + * Although this is a tree-conflict, it will already have been
> + * raised by the merge_dir_opened() callback. Not raising additional tree
> + * conflicts for the child nodes inside. */
> svn_pool_destroy(subpool);
> return SVN_NO_ERROR;
> }
> @@ -1223,6 +1192,8 @@ merge_file_added(svn_wc_adm_access_t *ad
> svn_node_file,
> svn_wc_conflict_action_add,
> svn_wc_conflict_reason_obstructed));
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
> if (content_state)
> *content_state = svn_wc_notify_state_obstructed;
> svn_pool_destroy(subpool);
> @@ -1284,6 +1255,8 @@ merge_file_added(svn_wc_adm_access_t *ad
> svn_node_file,
> svn_wc_conflict_action_add,
> svn_wc_conflict_reason_obstructed));
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
> if (content_state)
> {
> /* directory already exists, is it under version control? */
> @@ -1317,6 +1290,8 @@ merge_file_added(svn_wc_adm_access_t *ad
> svn_node_file,
> svn_wc_conflict_action_add,
> svn_wc_conflict_reason_obstructed));
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
>
> /* this will make the repos_editor send a 'skipped' message */
> if (content_state)
> @@ -1340,26 +1315,8 @@ merge_file_added(svn_wc_adm_access_t *ad
> svn_node_file,
> svn_wc_conflict_action_add,
> svn_wc_conflict_reason_obstructed));
> - /*
> - * FIXME: The above doesn't seem to correspond to the
> - * following code which seems to be handling this
> - * as a non-conflict!
> - */
> -
> - /* Indicate that we merge because of an add to handle a
> - special case for binary files with no local mods. */
> - merge_b->add_necessitated_merge = TRUE;
> -
> - SVN_ERR(merge_file_changed(adm_access, content_state,
> - prop_state, mine, older, yours,
> - rev1, rev2,
> - mimetype1, mimetype2,
> - prop_changes, original_props,
> - baton));
> -
> - /* Reset the state so that the baton can safely be reused
> - in subsequent ops occurring during this merge. */
> - merge_b->add_necessitated_merge = FALSE;
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
> }
> }
> break;
> @@ -1440,6 +1397,7 @@ files_same_p(svn_boolean_t *same,
> static svn_error_t *
> merge_file_deleted(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *mine,
> const char *older,
> const char *yours,
> @@ -1495,6 +1453,8 @@ merge_file_deleted(svn_wc_adm_access_t *
> svn_node_file,
> svn_wc_conflict_action_delete,
> svn_wc_conflict_reason_edited));
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
>
> if (state)
> *state = svn_wc_notify_state_obstructed;
> @@ -1511,6 +1471,8 @@ merge_file_deleted(svn_wc_adm_access_t *
> svn_node_file,
> svn_wc_conflict_action_delete,
> svn_wc_conflict_reason_obstructed));
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
> if (state)
> *state = svn_wc_notify_state_obstructed;
> break;
> @@ -1524,6 +1486,8 @@ merge_file_deleted(svn_wc_adm_access_t *
> svn_node_file,
> svn_wc_conflict_action_delete,
> svn_wc_conflict_reason_deleted));
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
> if (state)
> *state = svn_wc_notify_state_missing;
> break;
> @@ -1541,6 +1505,7 @@ merge_file_deleted(svn_wc_adm_access_t *
> static svn_error_t *
> merge_dir_added(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> svn_revnum_t rev,
> void *baton)
> @@ -1566,10 +1531,17 @@ merge_dir_added(svn_wc_adm_access_t *adm
> else
> *state = svn_wc_notify_state_missing;
> }
> + /* Trying to add a directory at a non-existing path.
> + * Although this is a tree-conflict, it will already have been
> + * raised by the merge_dir_opened() callback. Not raising additional tree
> + * conflicts for the child nodes inside. */
> svn_pool_destroy(subpool);
> return SVN_NO_ERROR;
> }
>
> + if (tree_conflicted)
> + *tree_conflicted = FALSE;
> +
> child = svn_path_is_child(merge_b->target, path, subpool);
> SVN_ERR_ASSERT(child != NULL);
>
> @@ -1650,6 +1622,8 @@ merge_dir_added(svn_wc_adm_access_t *adm
> svn_node_dir,
> svn_wc_conflict_action_add,
> svn_wc_conflict_reason_added));
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
> if (state)
> *state = svn_wc_notify_state_obstructed;
> }
> @@ -1675,6 +1649,8 @@ merge_dir_added(svn_wc_adm_access_t *adm
> svn_node_dir,
> svn_wc_conflict_action_add,
> svn_wc_conflict_reason_obstructed));
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
> if (state)
> *state = svn_wc_notify_state_obstructed;
> }
> @@ -1695,6 +1671,7 @@ merge_dir_added(svn_wc_adm_access_t *adm
> static svn_error_t *
> merge_dir_deleted(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> void *baton)
> {
> @@ -1714,10 +1691,17 @@ merge_dir_deleted(svn_wc_adm_access_t *a
> {
> if (state)
> *state = svn_wc_notify_state_missing;
> + /* Trying to delete a directory at a non-existing path.
> + * Although this is a tree-conflict, it will already have been
> + * raised by the merge_dir_opened() callback. Not raising additional tree
> + * conflicts for the child nodes inside. */
> svn_pool_destroy(subpool);
> return SVN_NO_ERROR;
> }
>
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
> +
> /* Find the version-control state of this path */
> SVN_ERR(svn_wc_entry(&entry, path, adm_access, TRUE, subpool));
>
> @@ -1765,6 +1749,8 @@ merge_dir_deleted(svn_wc_adm_access_t *a
> svn_node_dir,
> svn_wc_conflict_action_delete,
> svn_wc_conflict_reason_deleted));
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
> }
> }
> break;
> @@ -1780,6 +1766,8 @@ merge_dir_deleted(svn_wc_adm_access_t *a
> svn_node_dir,
> svn_wc_conflict_action_delete,
> svn_wc_conflict_reason_deleted));
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
> if (state)
> *state = svn_wc_notify_state_missing;
> break;
> @@ -1796,55 +1784,52 @@ merge_dir_deleted(svn_wc_adm_access_t *a
> /* An svn_wc_diff_callbacks3_t function. */
> static svn_error_t *
> merge_dir_opened(svn_wc_adm_access_t *adm_access,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> svn_revnum_t rev,
> void *baton)
> {
> - /* If adm_access == NULL, the tree conflict detection can be skipped,
> - * because:
> - *
> - * adm_access refers to the parent(!) directory of the directory that
> - * is to be opened. If adm_access == NULL, it means that the parent
> - * of const char *path does not exist in the current working copy.
> - *
> - * We are at arbitrary depth in a directory subtree that does not exist
> - * in the working copy, but nevertheless in a subtree off an existing
> - * working copy directory (at least off the working copy "root").
> - *
> - * This function has already been called on the first non-existent
> - * path element of this subtree, which has an existing parent (adm_access
> - * != NULL), and a tree conflict has been triggered there.
> - *
> - * Even if we wanted to report another tree-conflict, there'd be no
> - * working copy to mark the conflict in. Since the nearest existing parent
> - * directory is already marked tree-conflicted, we can rest at that.
> - */
> - if (adm_access != NULL)
> + if (tree_conflicted)
> + *tree_conflicted = FALSE;
> +
> + if (adm_access == NULL)
> {
> - /* adm_access is not NULL, detect a tree-conflict, if any. */
> + /* Trying to open a directory at a non-existing path.
> + * Although this is a tree-conflict, it will already have been
> + * raised by the merge_dir_opened() callback on the topmost nonexisting
> + * ancestor, where an adm_access was still present. Not raising
> + * additional tree conflicts for the child nodes inside. */
> + /* ### TODO: Verify that this holds true for explicit targets that
> + * # point deep into a nonexisting subtree. */
> + return SVN_NO_ERROR;
> + }
>
> - merge_cmd_baton_t *merge_b = baton;
> - apr_pool_t *subpool = svn_pool_create(merge_b->pool);
> - svn_node_kind_t kind;
> - const svn_wc_entry_t *entry;
> -
> - /* Find the version-control and on-disk states of this path */
> - SVN_ERR(svn_wc_entry(&entry, path, adm_access, TRUE, subpool));
> - SVN_ERR(svn_io_check_path(path, &kind, subpool));
> -
> - /* If we're trying to open a directory that's not a directory,
> - * raise a tree conflict. */
> - if (!entry || entry->schedule == svn_wc_schedule_delete
> - || kind != svn_node_dir)
> - {
> - SVN_ERR(tree_conflict(merge_b, adm_access, path,
> - svn_node_dir,
> - svn_wc_conflict_action_edit,
> - svn_wc_conflict_reason_deleted));
> - }
> + /* Detect a tree-conflict, if any. */
> + {
> + merge_cmd_baton_t *merge_b = baton;
> + apr_pool_t *subpool = svn_pool_create(merge_b->pool);
> + svn_node_kind_t kind;
> + const svn_wc_entry_t *entry;
>
> - svn_pool_destroy(subpool);
> - }
> + /* Find the version-control and on-disk states of this path */
> + SVN_ERR(svn_wc_entry(&entry, path, adm_access, TRUE, subpool));
> + SVN_ERR(svn_io_check_path(path, &kind, subpool));
> +
> + /* If we're trying to open a directory that's not a directory,
> + * raise a tree conflict. */
> + if (!entry || entry->schedule == svn_wc_schedule_delete
> + || kind != svn_node_dir)
> + {
> + SVN_ERR(tree_conflict(merge_b, adm_access, path,
> + svn_node_dir,
> + svn_wc_conflict_action_edit,
> + svn_wc_conflict_reason_deleted));
> + if (tree_conflicted)
> + *tree_conflicted = TRUE;
> + }
> +
> + svn_pool_destroy(subpool);
> + }
>
> return SVN_NO_ERROR;
> }
> @@ -1853,21 +1838,13 @@ merge_dir_opened(svn_wc_adm_access_t *ad
> static svn_error_t *
> merge_dir_closed(svn_wc_adm_access_t *adm_access,
> svn_wc_notify_state_t *state,
> + svn_boolean_t *tree_conflicted,
> const char *path,
> void *baton)
> {
> - merge_cmd_baton_t *merge_b = baton;
> -
> - if (state)
> - {
> - /* Check if we encountered any tree conflicts
> - * in this directory while visiting it.
> - */
> - if (is_tree_conflicted_dir_p(merge_b, path))
> - *state = svn_wc_notify_state_conflicted;
> - else
> - *state = svn_wc_notify_state_unknown;
> - }
> + /* Nothing to be done.
> + * The reason why this callback was created is no more.
> + * Maybe this callback should be removed. */
>
> return SVN_NO_ERROR;
> }
> @@ -3880,6 +3857,7 @@ single_file_merge_notify(void *notify_ba
> svn_wc_notify_action_t action,
> svn_wc_notify_state_t text_state,
> svn_wc_notify_state_t prop_state,
> + svn_boolean_t tree_conflicted,
> svn_wc_notify_t *header_notification,
> svn_boolean_t *header_sent,
> apr_pool_t *pool)
> @@ -3888,6 +3866,7 @@ single_file_merge_notify(void *notify_ba
> notify->kind = svn_node_file;
> notify->content_state = text_state;
> notify->prop_state = prop_state;
> + notify->tree_conflicted = tree_conflicted;
> if (notify->content_state == svn_wc_notify_state_missing)
> notify->action = svn_wc_notify_skip;
>
> @@ -5094,6 +5073,7 @@ do_file_merge(const char *url1,
> apr_array_header_t *propchanges, *remaining_ranges;
> svn_wc_notify_state_t prop_state = svn_wc_notify_state_unknown;
> svn_wc_notify_state_t text_state = svn_wc_notify_state_unknown;
> + svn_boolean_t tree_conflicted = FALSE;
> svn_client_ctx_t *ctx = merge_b->ctx;
> const char *mergeinfo_path;
> svn_merge_range_t range;
> @@ -5271,6 +5251,7 @@ do_file_merge(const char *url1,
> /* Delete... */
> SVN_ERR(merge_file_deleted(adm_access,
> &text_state,
> + &tree_conflicted,
> target_wcpath,
> tmpfile1,
> tmpfile2,
> @@ -5279,12 +5260,14 @@ do_file_merge(const char *url1,
> merge_b));
> single_file_merge_notify(notify_b, target_wcpath,
> svn_wc_notify_update_delete, text_state,
> - svn_wc_notify_state_unknown, n,
> + svn_wc_notify_state_unknown,
> + tree_conflicted, n,
> &header_sent, subpool);
>
> /* ...plus add... */
> SVN_ERR(merge_file_added(adm_access,
> &text_state, &prop_state,
> + &tree_conflicted,
> target_wcpath,
> tmpfile1,
> tmpfile2,
> @@ -5295,13 +5278,15 @@ do_file_merge(const char *url1,
> merge_b));
> single_file_merge_notify(notify_b, target_wcpath,
> svn_wc_notify_update_add, text_state,
> - prop_state, n, &header_sent, subpool);
> + prop_state, tree_conflicted,
> + n, &header_sent, subpool);
> /* ... equals replace. */
> }
> else
> {
> SVN_ERR(merge_file_changed(adm_access,
> &text_state, &prop_state,
> + &tree_conflicted,
> target_wcpath,
> tmpfile1,
> tmpfile2,
> @@ -5312,7 +5297,8 @@ do_file_merge(const char *url1,
> merge_b));
> single_file_merge_notify(notify_b, target_wcpath,
> svn_wc_notify_update_update, text_state,
> - prop_state, n, &header_sent, subpool);
> + prop_state, tree_conflicted,
> + n, &header_sent, subpool);
> }
>
> /* Ignore if temporary file not found. It may have been renamed. */
> @@ -6290,8 +6276,6 @@ do_merge(apr_array_header_t *merge_sourc
> merge_cmd_baton.paths_with_new_mergeinfo = NULL;
> merge_cmd_baton.ra_session1 = ra_session1;
> merge_cmd_baton.ra_session2 = ra_session2;
> - merge_cmd_baton.tree_conflicted_dirs =
> - apr_array_make(pool, 0, sizeof(const char *));
>
> /* Populate the portions of the merge context baton that require
> an RA session to set, but shouldn't be reset for each iteration. */
>
> Modified: trunk/subversion/libsvn_client/repos_diff.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_client/repos_diff.c?pathrev=33989&r1=33988&r2=33989
> ==============================================================================
> --- trunk/subversion/libsvn_client/repos_diff.c Fri Oct 31 19:55:38 2008 (r33988)
> +++ trunk/subversion/libsvn_client/repos_diff.c Fri Oct 31 20:39:02 2008 (r33989)
> @@ -88,6 +88,7 @@ typedef struct kind_action_state_t
> svn_node_kind_t kind;
> svn_wc_notify_action_t action;
> svn_wc_notify_state_t state;
> + svn_boolean_t tree_conflicted;
> } kind_action_state_t;
>
> /* Directory level baton.
> @@ -96,6 +97,15 @@ struct dir_baton {
> /* Gets set if the directory is added rather than replaced/unchanged. */
> svn_boolean_t added;
>
> + /* Gets set if this operation caused a tree-conflict on this directory
> + * (does not show tree-conflicts persisting from before this operation). */
> + svn_boolean_t tree_conflicted;
> +
> + /* If TRUE, this node is skipped entirely.
> + * This is currently used to skip all children of a tree-conflicted
> + * directory without setting TREE_CONFLICTED to TRUE everywhere. */
> + svn_boolean_t skip;
> +
> /* The path of the directory within the repository */
> const char *path;
>
> @@ -115,6 +125,7 @@ struct dir_baton {
> /* The pristine-property list attached to this directory. */
> apr_hash_t *pristine_props;
>
> +
> /* The pool passed in by add_dir, open_dir, or open_root.
> Also, the pool this dir baton is allocated in. */
> apr_pool_t *pool;
> @@ -126,6 +137,15 @@ struct file_baton {
> /* Gets set if the file is added rather than replaced. */
> svn_boolean_t added;
>
> + /* Gets set if this operation caused a tree-conflict on this file
> + * (does not show tree-conflicts persisting from before this operation). */
> + svn_boolean_t tree_conflicted;
> +
> + /* If TRUE, this node is skipped entirely.
> + * This is currently used to skip all children of a tree-conflicted
> + * directory. */
> + svn_boolean_t skip;
> +
> /* The path of the file within the repository */
> const char *path;
>
> @@ -181,6 +201,8 @@ make_dir_baton(const char *path,
> dir_baton->dir_baton = parent_baton;
> dir_baton->edit_baton = edit_baton;
> dir_baton->added = added;
> + dir_baton->tree_conflicted = FALSE;
> + dir_baton->skip = FALSE;
> dir_baton->pool = pool;
> dir_baton->path = apr_pstrdup(pool, path);
> dir_baton->wcpath = svn_path_join(edit_baton->target, path, pool);
> @@ -205,6 +227,8 @@ make_file_baton(const char *path,
>
> file_baton->edit_baton = edit_baton;
> file_baton->added = added;
> + file_baton->tree_conflicted = FALSE;
> + file_baton->skip = FALSE;
> file_baton->pool = pool;
> file_baton->path = apr_pstrdup(pool, path);
> file_baton->wcpath = svn_path_join(eb->target, path, pool);
> @@ -435,6 +459,11 @@ delete_entry(const char *path,
> svn_wc_adm_access_t *adm_access;
> svn_wc_notify_state_t state = svn_wc_notify_state_inapplicable;
> svn_wc_notify_action_t action = svn_wc_notify_skip;
> + svn_boolean_t tree_conflicted = FALSE;
> +
> + /* Skip *everything* within a newly tree-conflicted directory. */
> + if (pb->skip || pb->tree_conflicted)
> + return SVN_NO_ERROR;
>
> /* We need to know if this is a directory or a file */
> SVN_ERR(svn_ra_check_path(eb->ra_session, path, eb->revision, &kind, pool));
> @@ -457,7 +486,7 @@ delete_entry(const char *path,
> get_file_mime_types(&mimetype1, &mimetype2, b);
>
> SVN_ERR(eb->diff_callbacks->file_deleted
> - (adm_access, &state, b->wcpath,
> + (adm_access, &state, &tree_conflicted, b->wcpath,
> b->path_start_revision,
> b->path_end_revision,
> mimetype1, mimetype2,
> @@ -469,7 +498,7 @@ delete_entry(const char *path,
> case svn_node_dir:
> {
> SVN_ERR(eb->diff_callbacks->dir_deleted
> - (adm_access, &state,
> + (adm_access, &state, &tree_conflicted,
> svn_path_join(eb->target, path, pool),
> eb->diff_cmd_baton));
> break;
> @@ -479,7 +508,8 @@ delete_entry(const char *path,
> }
>
> if ((state != svn_wc_notify_state_missing)
> - && (state != svn_wc_notify_state_obstructed))
> + && (state != svn_wc_notify_state_obstructed)
> + && !tree_conflicted)
> {
> action = svn_wc_notify_update_delete;
> if (eb->dry_run)
> @@ -502,8 +532,9 @@ delete_entry(const char *path,
> kind_action_state_t *kas = apr_palloc(eb->pool, sizeof(*kas));
> deleted_path = svn_path_join(eb->target, path, eb->pool);
> kas->kind = kind;
> - kas->action = action;
> + kas->action = tree_conflicted ? svn_wc_notify_update_update : action;
> kas->state = state;
> + kas->tree_conflicted = tree_conflicted;
> apr_hash_set(eb->deleted_paths, deleted_path, APR_HASH_KEY_STRING, kas);
> }
> return SVN_NO_ERROR;
> @@ -531,13 +562,24 @@ add_directory(const char *path,
> b->pristine_props = eb->empty_hash;
> *child_baton = b;
>
> + /* Skip *everything* within a newly tree-conflicted directory. */
> + if (pb->skip || pb->tree_conflicted)
> + {
> + b->skip = TRUE;
> + return SVN_NO_ERROR;
> + }
> +
> +
> SVN_ERR(get_path_access(&adm_access, eb->adm_access, pb->wcpath, TRUE,
> pool));
>
> SVN_ERR(eb->diff_callbacks->dir_added
> - (adm_access, &state, b->wcpath, eb->target_revision,
> - eb->diff_cmd_baton));
> + (adm_access, &state, &b->tree_conflicted, b->wcpath,
> + eb->target_revision, eb->diff_cmd_baton));
>
> + if (b->tree_conflicted)
> + action = svn_wc_notify_update_update;
> + else
> if ((state == svn_wc_notify_state_missing)
> || (state == svn_wc_notify_state_obstructed))
> action = svn_wc_notify_skip;
> @@ -553,7 +595,8 @@ add_directory(const char *path,
> if (kas)
> {
> svn_wc_notify_action_t new_action;
> - if (kas->action == svn_wc_notify_update_delete
> + if ((! kas->tree_conflicted)
> + && kas->action == svn_wc_notify_update_delete
> && action == svn_wc_notify_update_add)
> {
> is_replace = TRUE;
> @@ -561,10 +604,11 @@ add_directory(const char *path,
> }
> else
> new_action = kas->action;
> - notify = svn_wc_create_notify(b->wcpath, new_action, pool);
> + notify = svn_wc_create_notify(b->wcpath, new_action, pool);
> notify->kind = kas->kind;
> notify->content_state = notify->prop_state = kas->state;
> notify->lock_state = svn_wc_notify_lock_state_inapplicable;
> + notify->tree_conflicted = kas->tree_conflicted;
> (*eb->notify_func)(eb->notify_baton, notify, pool);
> apr_hash_set(eb->deleted_paths, b->wcpath,
> APR_HASH_KEY_STRING, NULL);
> @@ -574,6 +618,7 @@ add_directory(const char *path,
> {
> notify = svn_wc_create_notify(b->wcpath, action, pool);
> notify->kind = svn_node_dir;
> + notify->tree_conflicted = b->tree_conflicted;
> (*eb->notify_func)(eb->notify_baton, notify, pool);
> }
> }
> @@ -597,13 +642,20 @@ open_directory(const char *path,
> b = make_dir_baton(path, pb, pb->edit_baton, FALSE, pool);
> *child_baton = b;
>
> + /* Skip *everything* within a newly tree-conflicted directory. */
> + if (pb->skip || pb->tree_conflicted)
> + {
> + b->skip = TRUE;
> + return SVN_NO_ERROR;
> + }
> +
> SVN_ERR(get_dirprops_from_ra(b, base_revision));
>
> SVN_ERR(get_path_access(&adm_access, eb->adm_access, pb->wcpath, TRUE,
> pool));
>
> return eb->diff_callbacks->dir_opened
> - (adm_access, b->wcpath, base_revision,
> + (adm_access, &b->tree_conflicted, b->wcpath, base_revision,
> b->edit_baton->diff_cmd_baton);
> }
>
> @@ -625,6 +677,13 @@ add_file(const char *path,
> b = make_file_baton(path, TRUE, pb->edit_baton, pool);
> *file_baton = b;
>
> + /* Skip *everything* within a newly tree-conflicted directory. */
> + if (pb->skip || pb->tree_conflicted)
> + {
> + b->skip = TRUE;
> + return SVN_NO_ERROR;
> + }
> +
> SVN_ERR(get_empty_file(b->edit_baton, &(b->path_start_revision)));
> b->pristine_props = pb->edit_baton->empty_hash;
>
> @@ -645,6 +704,13 @@ open_file(const char *path,
> b = make_file_baton(path, FALSE, pb->edit_baton, pool);
> *file_baton = b;
>
> + /* Skip *everything* within a newly tree-conflicted directory. */
> + if (pb->skip || pb->tree_conflicted)
> + {
> + b->skip = TRUE;
> + return SVN_NO_ERROR;
> + }
> +
> return get_file_from_ra(b, base_revision);
> }
>
> @@ -655,6 +721,10 @@ window_handler(svn_txdelta_window_t *win
> {
> struct file_baton *b = window_baton;
>
> + /* Skip *everything* within a newly tree-conflicted directory. */
> + if (b->skip)
> + return SVN_NO_ERROR;
> +
> SVN_ERR(b->apply_handler(window, b->apply_baton));
>
> if (!window)
> @@ -677,6 +747,14 @@ apply_textdelta(void *file_baton,
> struct file_baton *b = file_baton;
> svn_wc_adm_access_t *adm_access;
>
> + /* Skip *everything* within a newly tree-conflicted directory. */
> + if (b->skip)
> + {
> + *handler = window_handler;
> + *handler_baton = file_baton;
> + return SVN_NO_ERROR;
> + }
> +
> /* Open the file to be used as the base for second revision */
> SVN_ERR(svn_io_file_open(&(b->file_start_revision),
> b->path_start_revision,
> @@ -735,9 +813,12 @@ close_file(void *file_baton,
> svn_wc_adm_access_t *adm_access;
> svn_error_t *err;
> svn_wc_notify_action_t action;
> - svn_wc_notify_state_t
> - content_state = svn_wc_notify_state_unknown,
> - prop_state = svn_wc_notify_state_unknown;
> + svn_wc_notify_state_t content_state = svn_wc_notify_state_unknown;
> + svn_wc_notify_state_t prop_state = svn_wc_notify_state_unknown;
> +
> + /* Skip *everything* within a newly tree-conflicted directory. */
> + if (b->skip)
> + return SVN_NO_ERROR;
>
> err = get_parent_access(&adm_access, eb->adm_access,
> b->wcpath, eb->dry_run, b->pool);
> @@ -748,12 +829,16 @@ close_file(void *file_baton,
> /* If the file path doesn't exist, then send a 'skipped' notification. */
> if (eb->notify_func)
> {
> - svn_wc_notify_t *notify = svn_wc_create_notify(b->wcpath,
> - svn_wc_notify_skip,
> - pool);
> + svn_wc_notify_t *notify = svn_wc_create_notify(
> + b->wcpath,
> + b->tree_conflicted
> + ? svn_wc_notify_update_update
> + : svn_wc_notify_skip,
> + pool);
> notify->kind = svn_node_file;
> notify->content_state = svn_wc_notify_state_missing;
> notify->prop_state = prop_state;
> + notify->tree_conflicted = b->tree_conflicted;
> (*eb->notify_func)(eb->notify_baton, notify, pool);
> }
>
> @@ -770,7 +855,7 @@ close_file(void *file_baton,
>
> if (b->added)
> SVN_ERR(eb->diff_callbacks->file_added
> - (adm_access, &content_state, &prop_state,
> + (adm_access, &content_state, &prop_state, &b->tree_conflicted,
> b->wcpath,
> b->path_end_revision ? b->path_start_revision : NULL,
> b->path_end_revision,
> @@ -781,7 +866,7 @@ close_file(void *file_baton,
> b->edit_baton->diff_cmd_baton));
> else
> SVN_ERR(eb->diff_callbacks->file_changed
> - (adm_access, &content_state, &prop_state,
> + (adm_access, &content_state, &prop_state, &b->tree_conflicted,
> b->wcpath,
> b->path_end_revision ? b->path_start_revision : NULL,
> b->path_end_revision,
> @@ -793,8 +878,10 @@ close_file(void *file_baton,
> }
>
>
> - if ((content_state == svn_wc_notify_state_missing)
> - || (content_state == svn_wc_notify_state_obstructed))
> + if (b->tree_conflicted)
> + action = svn_wc_notify_update_update;
> + else if ((content_state == svn_wc_notify_state_missing)
> + || (content_state == svn_wc_notify_state_obstructed))
> action = svn_wc_notify_skip;
> else if (b->added)
> action = svn_wc_notify_update_add;
> @@ -810,7 +897,8 @@ close_file(void *file_baton,
> if (kas)
> {
> svn_wc_notify_action_t new_action;
> - if (kas->action == svn_wc_notify_update_delete
> + if ((! kas->tree_conflicted)
> + && kas->action == svn_wc_notify_update_delete
> && action == svn_wc_notify_update_add)
> {
> is_replace = TRUE;
> @@ -822,6 +910,7 @@ close_file(void *file_baton,
> notify->kind = kas->kind;
> notify->content_state = notify->prop_state = kas->state;
> notify->lock_state = svn_wc_notify_lock_state_inapplicable;
> + notify->tree_conflicted = kas->tree_conflicted;
> (*eb->notify_func)(eb->notify_baton, notify, pool);
> apr_hash_set(eb->deleted_paths, b->wcpath,
> APR_HASH_KEY_STRING, NULL);
> @@ -833,6 +922,7 @@ close_file(void *file_baton,
> notify->kind = svn_node_file;
> notify->content_state = content_state;
> notify->prop_state = prop_state;
> + notify->tree_conflicted = b->tree_conflicted;
> (*eb->notify_func)(eb->notify_baton, notify, pool);
> }
> }
> @@ -852,6 +942,10 @@ close_directory(void *dir_baton,
> svn_error_t *err;
> svn_wc_adm_access_t *adm_access;
>
> + /* Skip *everything* within a newly tree-conflicted directory. */
> + if (b->skip)
> + return SVN_NO_ERROR;
> +
> if (eb->dry_run)
> svn_hash__clear(svn_client__dry_run_deletions(eb->diff_cmd_baton));
>
> @@ -865,10 +959,15 @@ close_directory(void *dir_baton,
> if (eb->notify_func)
> {
> svn_wc_notify_t *notify
> - = svn_wc_create_notify(b->wcpath, svn_wc_notify_skip, pool);
> + = svn_wc_create_notify(b->wcpath,
> + b->tree_conflicted
> + ? svn_wc_notify_update_update
> + : svn_wc_notify_skip,
> + pool);
> notify->kind = svn_node_dir;
> notify->content_state = notify->prop_state
> = svn_wc_notify_state_missing;
> + notify->tree_conflicted = b->tree_conflicted;
> (*eb->notify_func)(eb->notify_baton, notify, pool);
> }
> svn_error_clear(err);
> @@ -882,13 +981,13 @@ close_directory(void *dir_baton,
> have been recognised as added, in which case they cannot conflict. */
> if ((b->propchanges->nelts > 0) && (! eb->dry_run || adm_access))
> SVN_ERR(eb->diff_callbacks->dir_props_changed
> - (adm_access, &prop_state,
> + (adm_access, &prop_state, &b->tree_conflicted,
> b->wcpath,
> b->propchanges, b->pristine_props,
> b->edit_baton->diff_cmd_baton));
>
> SVN_ERR(eb->diff_callbacks->dir_closed
> - (adm_access, &content_state,
> + (adm_access, &content_state, &b->tree_conflicted,
> b->wcpath, b->edit_baton->diff_cmd_baton));
>
> /* ### Don't notify added directories as they triggered notification
> @@ -905,10 +1004,11 @@ close_directory(void *dir_baton,
> const void *deleted_path;
> kind_action_state_t *kas;
> apr_hash_this(hi, &deleted_path, NULL, (void *)&kas);
> - notify = svn_wc_create_notify(deleted_path, kas->action, pool);
> + notify = svn_wc_create_notify(deleted_path, kas->action, pool);
> notify->kind = kas->kind;
> notify->content_state = notify->prop_state = kas->state;
> notify->lock_state = svn_wc_notify_lock_state_inapplicable;
> + notify->tree_conflicted = kas->tree_conflicted;
> (*eb->notify_func)(eb->notify_baton, notify, pool);
> apr_hash_set(eb->deleted_paths, deleted_path,
> APR_HASH_KEY_STRING, NULL);
> @@ -925,6 +1025,7 @@ close_directory(void *dir_baton,
>
> notify->prop_state = prop_state;
> notify->lock_state = svn_wc_notify_lock_state_inapplicable;
> + notify->tree_conflicted = b->tree_conflicted;
> (*eb->notify_func)(eb->notify_baton, notify, pool);
> }
>
> @@ -942,6 +1043,10 @@ change_file_prop(void *file_baton,
> struct file_baton *b = file_baton;
> svn_prop_t *propchange;
>
> + /* Skip *everything* within a newly tree-conflicted directory. */
> + if (b->skip)
> + return SVN_NO_ERROR;
> +
> propchange = apr_array_push(b->propchanges);
> propchange->name = apr_pstrdup(b->pool, name);
> propchange->value = value ? svn_string_dup(value, b->pool) : NULL;
> @@ -959,6 +1064,10 @@ change_dir_prop(void *dir_baton,
> struct dir_baton *db = dir_baton;
> svn_prop_t *propchange;
>
> + /* Skip *everything* within a newly tree-conflicted directory. */
> + if (db->skip)
> + return SVN_NO_ERROR;
> +
> propchange = apr_array_push(db->propchanges);
> propchange->name = apr_pstrdup(db->pool, name);
> propchange->value = value ? svn_string_dup(value, db->pool) : NULL;
> @@ -988,6 +1097,8 @@ absent_directory(const char *path,
> struct dir_baton *pb = parent_baton;
> struct edit_baton *eb = pb->edit_baton;
>
> + /* ### TODO: Raise a tree-conflict?? I sure hope not.*/
> +
> if (eb->notify_func)
> {
> svn_wc_notify_t *notify
> @@ -1014,6 +1125,8 @@ absent_file(const char *path,
> struct dir_baton *pb = parent_baton;
> struct edit_baton *eb = pb->edit_baton;
>
> + /* ### TODO: Raise a tree-conflict?? I sure hope not.*/
> +
> if (eb->notify_func)
> {
> svn_wc_notify_t *notify
>
> Modified: trunk/subversion/libsvn_wc/diff.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_wc/diff.c?pathrev=33989&r1=33988&r2=33989
> ==============================================================================
> --- trunk/subversion/libsvn_wc/diff.c Fri Oct 31 19:55:38 2008 (r33988)
> +++ trunk/subversion/libsvn_wc/diff.c Fri Oct 31 20:39:02 2008 (r33989)
> @@ -586,7 +586,7 @@ file_diff(struct dir_baton *dir_baton,
> adm_access, path, pool));
>
> SVN_ERR(dir_baton->edit_baton->callbacks->file_deleted
> - (NULL, NULL, path,
> + (NULL, NULL, NULL, path,
> textbase,
> empty_file,
> base_mimetype,
> @@ -610,7 +610,7 @@ file_diff(struct dir_baton *dir_baton,
> pool));
>
> SVN_ERR(dir_baton->edit_baton->callbacks->file_added
> - (NULL, NULL, NULL, path,
> + (NULL, NULL, NULL, NULL, path,
> empty_file,
> translated,
> 0, entry->revision,
> @@ -648,7 +648,7 @@ file_diff(struct dir_baton *dir_baton,
> adm_access, path, pool));
>
> SVN_ERR(dir_baton->edit_baton->callbacks->file_changed
> - (NULL, NULL, NULL,
> + (NULL, NULL, NULL, NULL,
> path,
> modified ? textbase : NULL,
> translated,
> @@ -727,7 +727,7 @@ directory_elements_diff(struct dir_baton
> dir_baton->pool));
>
> SVN_ERR(dir_baton->edit_baton->callbacks->dir_props_changed
> - (adm_access, NULL,
> + (adm_access, NULL, NULL,
> dir_baton->path,
> propchanges, baseprops,
> dir_baton->edit_baton->callback_baton));
> @@ -893,7 +893,7 @@ report_wc_file_as_added(struct dir_baton
> pool));
>
> return eb->callbacks->file_added
> - (adm_access, NULL, NULL,
> + (adm_access, NULL, NULL, NULL,
> path,
> empty_file, translated_file,
> 0, entry->revision,
> @@ -947,7 +947,7 @@ report_wc_directory_as_added(struct dir_
>
> if (propchanges->nelts > 0)
> SVN_ERR(eb->callbacks->dir_props_changed
> - (adm_access, NULL,
> + (adm_access, NULL, NULL,
> dir_baton->path,
> propchanges, emptyprops,
> eb->callback_baton));
> @@ -1104,7 +1104,7 @@ delete_entry(const char *path,
> adm_access, full_path, pool));
>
> SVN_ERR(pb->edit_baton->callbacks->file_deleted
> - (NULL, NULL, full_path,
> + (NULL, NULL, NULL, full_path,
> textbase,
> empty_file,
> base_mimetype,
> @@ -1243,7 +1243,7 @@ close_directory(void *dir_baton,
> reverse_propchanges(originalprops, b->propchanges, b->pool);
>
> SVN_ERR(b->edit_baton->callbacks->dir_props_changed
> - (NULL, NULL,
> + (NULL, NULL, NULL,
> b->path,
> b->propchanges,
> originalprops,
> @@ -1453,7 +1453,7 @@ close_file(void *file_baton,
> {
> if (eb->reverse_order)
> return b->edit_baton->callbacks->file_added
> - (NULL, NULL, NULL, b->path,
> + (NULL, NULL, NULL, NULL, b->path,
> empty_file,
> temp_file_path,
> 0,
> @@ -1465,7 +1465,7 @@ close_file(void *file_baton,
> b->edit_baton->callback_baton);
> else
> return b->edit_baton->callbacks->file_deleted
> - (NULL, NULL, b->path,
> + (NULL, NULL, NULL, b->path,
> temp_file_path,
> empty_file,
> repos_mimetype,
> @@ -1524,7 +1524,7 @@ close_file(void *file_baton,
> reverse_propchanges(originalprops, b->propchanges, b->pool);
>
> SVN_ERR(b->edit_baton->callbacks->file_changed
> - (NULL, NULL, NULL,
> + (NULL, NULL, NULL, NULL,
> b->path,
> eb->reverse_order ? localfile : temp_file_path,
> eb->reverse_order ? temp_file_path : localfile,
>
> Modified: trunk/subversion/tests/cmdline/merge_tests.py
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/tests/cmdline/merge_tests.py?pathrev=33989&r1=33988&r2=33989
> ==============================================================================
> --- trunk/subversion/tests/cmdline/merge_tests.py Fri Oct 31 19:55:38 2008 (r33988)
> +++ trunk/subversion/tests/cmdline/merge_tests.py Fri Oct 31 20:39:02 2008 (r33989)
> @@ -563,18 +563,18 @@ def delete_file_and_dir(sbox):
> # children, 'E' and 'lambda', get override mergeinfo reflecting their
> # mergeinfo prior to the merge (in this case empty mergeinfo).
> expected_output = wc.State(B2_path, {
> - '' : Item(status='C ')
> + '' : Item(),
> + 'lambda' : Item(status=' ', treeconflict='C'),
> + 'E' : Item(status=' ', treeconflict='C'),
> })
> expected_disk = wc.State('', {
> '' : Item(props={SVN_PROP_MERGEINFO : '/A/B:3'}),
> - 'E' : Item(props={SVN_PROP_MERGEINFO : '',
> - 'foo' : 'foo_val'}),
> + 'E' : Item(props={'foo' : 'foo_val'}),
> 'E/alpha' : Item("This is the file 'alpha'.\n"),
> 'E/beta' : Item("This is the file 'beta'.\n"),
> 'F' : Item(),
> 'lambda' : Item("This is the file 'lambda'.\n",
> - props={SVN_PROP_MERGEINFO : '',
> - 'foo' : 'foo_val'}),
> + props={'foo' : 'foo_val'}),
> })
> expected_status2 = wc.State(B2_path, {
> '' : Item(status=' M'),
> @@ -586,8 +586,6 @@ def delete_file_and_dir(sbox):
> })
> expected_status2.tweak(wc_rev=2)
> expected_skip = wc.State(B2_path, {
> - 'lambda' : Item(),
> - 'E' : Item(),
> })
> svntest.actions.run_and_verify_merge(B2_path, '2', '3', B_url,
> expected_output,
> @@ -614,7 +612,6 @@ def delete_file_and_dir(sbox):
> expected_disk.tweak('E', props={'foo' : 'foo_val'})
> expected_status2.tweak('E', 'E/alpha', 'E/beta', 'lambda', status='D ')
> expected_status2.tweak('', status=' M')
> - expected_skip.remove('lambda', 'E')
>
> ### Full-to-dry-run automatic comparison disabled because a) dry-run
> ### doesn't descend into deleted directories, and b) the full merge
> @@ -890,7 +887,7 @@ def merge_catches_nonexistent_target(sbo
> # notes/tree-conflicts/detection.txt).
> os.chdir(G_path)
> expected_output = wc.State('', {
> - '' : Item(status='C '),
> + 'newfile' : Item(status=' ', treeconflict='C'),
> })
> expected_status = wc.State('', {
> '' : Item(status=' M' ),
> @@ -909,7 +906,6 @@ def merge_catches_nonexistent_target(sbo
> 'tau' : Item("This is the file 'tau'.\n"),
> })
> expected_skip = wc.State('', {
> - 'newfile' :Item(),
> })
> svntest.actions.run_and_verify_merge('', '2', '3', Q_url,
> expected_output,
> @@ -962,8 +958,8 @@ def merge_tree_deleted_in_target(sbox):
> 'up', os.path.join(wc_dir,'A'))
>
> expected_output = wc.State(I_path, {
> - '' : Item(status='C '),
> 'lambda' : Item(status='U '),
> + 'E' : Item(status=' ', treeconflict='C'),
> })
> expected_disk = wc.State('', {
> '' : Item(props={SVN_PROP_MERGEINFO : '/A/B:3'}),
> @@ -977,8 +973,6 @@ def merge_tree_deleted_in_target(sbox):
> })
> expected_status.tweak(wc_rev=4)
> expected_skip = wc.State(I_path, {
> - 'E' : Item(),
> - 'E/alpha' : Item(),
> })
> svntest.actions.run_and_verify_merge(I_path, '2', '3', B_url,
> expected_output,
> @@ -1027,7 +1021,7 @@ def merge_added_dir_to_deleted_in_target
> 'up', os.path.join(wc_dir,'A'))
>
> expected_output = wc.State(I_path, {
> - '' : Item(status='C '),
> + 'F' : Item(status=' ', treeconflict='C'),
> })
> expected_disk = wc.State('', {
> 'E' : Item(),
> @@ -1036,8 +1030,6 @@ def merge_added_dir_to_deleted_in_target
> 'lambda' : Item("This is the file 'lambda'.\n"),
> })
> expected_skip = wc.State(I_path, {
> - 'F/J' : Item(),
> - 'F' : Item(),
> })
>
> svntest.actions.run_and_verify_merge(I_path, '2', '4', B_url,
> @@ -1589,8 +1581,7 @@ def three_way_merge_add_of_existing_bina
> # And after the merge, the status should not report any differences.
>
> expected_output = wc.State(wc_dir, {
> - "A" : Item(status="C "),
> - "A/theta" : Item(status="A "),
> + "A/theta" : Item(status=" ", treeconflict='C'),
> })
>
> # As greek_state is rooted at / instead of /A (our merge target), we
> @@ -12238,20 +12229,14 @@ def del_differing_file(sbox):
> pi = os.path.join(dir_D, 'G2', 'pi')
> # Should complain and "skip" it.
> svn_merge(s_rev_tau, source, target, [
> - "Skipped '%s'\n" % tau,
> - "--- Merging r2 into '%s':\n" % dir_G2,
> - "C %s\n" % dir_G2,
> + " C %s\n" % tau,
> "Summary of conflicts:\n",
> - " Text conflicts: 1\n",
> - " Skipped paths: 1\n"])
> + " Tree conflicts: 1\n"])
>
> svn_merge(s_rev_pi, source, target, [
> - "Skipped '%s'\n" % pi,
> - "--- Merging r3 into '%s':\n" % dir_G2,
> - "C %s\n" % dir_G2,
> + " C %s\n" % pi,
> "Summary of conflicts:\n",
> - " Text conflicts: 1\n",
> - " Skipped paths: 1\n"])
> + " Tree conflicts: 1\n"])
>
>
> # Copy a file, modify it, commit, and merge a deletion to it.
> @@ -12269,20 +12254,14 @@ def del_differing_file(sbox):
>
> # Should complain and "skip" it.
> svn_merge(s_rev_tau, source, target, [
> - "Skipped '%s'\n" % tau,
> - "--- Merging r2 into '%s':\n" % dir_G3,
> - "C %s\n" % dir_G3,
> + " C %s\n" % tau,
> "Summary of conflicts:\n",
> - " Text conflicts: 1\n",
> - " Skipped paths: 1\n"])
> + " Tree conflicts: 1\n"])
>
> svn_merge(s_rev_pi, source, target, [
> - "Skipped '%s'\n" % pi,
> - "--- Merging r3 into '%s':\n" % dir_G3,
> - "C %s\n" % dir_G3,
> + " C %s\n" % pi,
> "Summary of conflicts:\n",
> - " Text conflicts: 1\n",
> - " Skipped paths: 1\n"])
> + " Tree conflicts: 1\n"])
>
> os.chdir(saved_cwd)
>
> @@ -13308,8 +13287,8 @@ def tree_conflicts_and_obstructions(sbox
>
> # Merge the obstructions into the branch.
> expected_output = svntest.wc.State(branch_path, {
> - '' : Item(status='C '),
> 'alpha' : Item(status='D '),
> + 'alpha-moved' : Item(status=' ', treeconflict='C'),
> })
> expected_disk = wc.State('', {
> 'beta' : Item("This is the file 'beta'.\n"),
> @@ -13321,7 +13300,6 @@ def tree_conflicts_and_obstructions(sbox
> 'beta' : Item(status=' ', wc_rev=3),
> })
> expected_skip = wc.State(branch_path, {
> - 'alpha-moved' : Item(),
> })
>
> svntest.actions.run_and_verify_merge(branch_path,
> @@ -13373,12 +13351,12 @@ def tree_conflicts_on_merge_local_ci_4_1
> # 4.1) local tree delete, incoming leaf edit
>
> expected_output = svntest.wc.State('', {
> - 'F' : Item(status='C '),
> - 'D' : Item(status='C '),
> - 'DF' : Item(status='C '),
> - 'DD' : Item(status='C '),
> - 'DDF' : Item(status='C '),
> - 'DDD' : Item(status='C '),
> + 'F/alpha' : Item(status=' ', treeconflict='C'),
> + 'D/D1' : Item(status=' ', treeconflict='C'),
> + 'DF/D1' : Item(status=' ', treeconflict='C'),
> + 'DD/D1' : Item(status=' ', treeconflict='C'),
> + 'DDF/D1' : Item(status=' ', treeconflict='C'),
> + 'DDD/D1' : Item(status=' ', treeconflict='C'),
> })
>
> expected_disk = state_after_tree_del
> @@ -13394,12 +13372,6 @@ def tree_conflicts_on_merge_local_ci_4_1
> })
>
> expected_skip = svntest.wc.State('', {
> - 'F/alpha' : Item(),
> - 'DF/D1/beta' : Item(),
> - 'DDF/D1/D2/gamma' : Item(),
> - 'D/D1/delta' : Item(),
> - 'DD/D1/D2/epsilon' : Item(),
> - 'DDD/D1/D2/D3/zeta' : Item(),
> })
>
> svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
> @@ -13431,12 +13403,12 @@ def tree_conflicts_on_merge_local_ci_4_2
> # 4.2) local tree delete, incoming leaf delete
>
> expected_output = svntest.wc.State('', {
> - 'F' : Item(status='C '),
> - 'D' : Item(status='C '),
> - 'DF' : Item(status='C '),
> - 'DD' : Item(status='C '),
> - 'DDF' : Item(status='C '),
> - 'DDD' : Item(status='C '),
> + 'F/alpha' : Item(status=' ', treeconflict='C'),
> + 'D/D1' : Item(status=' ', treeconflict='C'),
> + 'DF/D1' : Item(status=' ', treeconflict='C'),
> + 'DD/D1' : Item(status=' ', treeconflict='C'),
> + 'DDF/D1' : Item(status=' ', treeconflict='C'),
> + 'DDD/D1' : Item(status=' ', treeconflict='C'),
> })
>
> expected_disk = state_after_tree_del
> @@ -13452,12 +13424,6 @@ def tree_conflicts_on_merge_local_ci_4_2
> })
>
> expected_skip = svntest.wc.State('', {
> - 'F/alpha' : Item(),
> - 'DF/D1/beta' : Item(),
> - 'DDF/D1/D2/gamma' : Item(),
> - 'D/D1' : Item(),
> - 'DD/D1/D2' : Item(),
> - 'DDD/D1/D2/D3' : Item(),
> })
>
> svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
> @@ -13479,35 +13445,20 @@ def tree_conflicts_on_merge_local_ci_5_1
> # 5.1) local leaf edit, incoming tree delete
>
> expected_output = svntest.wc.State('', {
> - 'D' : Item(),
> - 'D/D1' : Item(status='D '),
> - 'F' : Item(status='C '),
> - 'DD' : Item(),
> - 'DD/D1' : Item(status='D '),
> - 'DF' : Item(),
> - 'DF/D1' : Item(status='D '),
> - 'DDD' : Item(),
> - 'DDD/D1' : Item(status='D '),
> - 'DDF' : Item(),
> - 'DDF/D1' : Item(status='D '),
> + 'F/alpha' : Item(status=' ', treeconflict='C'),
> + 'D/D1' : Item(status=' U', treeconflict='C'),
> + 'DF/D1' : Item(status=' U', treeconflict='C'),
> + 'DD/D1' : Item(status=' U', treeconflict='C'),
> + 'DDF/D1' : Item(status=' U', treeconflict='C'),
> + 'DDD/D1' : Item(status=' U', treeconflict='C'),
> })
>
> expected_disk = svntest.wc.State('', {
> - 'DF' : Item(),
> 'DF/D1' : Item(),
> - 'DDF' : Item(),
> - 'DDF/D1' : Item(),
> 'DDF/D1/D2' : Item(),
> - 'F' : Item(),
> 'F/alpha' : Item(contents="This is the file 'alpha'.\nMore text for file alpha.\n"),
> - 'DDD' : Item(),
> - 'DDD/D1' : Item(),
> - 'DDD/D1/D2' : Item(),
> 'DDD/D1/D2/D3' : Item(),
> - 'DD' : Item(),
> - 'DD/D1' : Item(),
> 'DD/D1/D2' : Item(),
> - 'D' : Item(),
> 'D/D1' : Item(),
> })
>
> @@ -13518,15 +13469,10 @@ def tree_conflicts_on_merge_local_ci_5_1
> 'D' : Item(status=' ', wc_rev='3'),
> 'D/D1' : Item(status='D ', wc_rev='3'), # tree conflict?
> 'D/D1/delta' : Item(status='D ', wc_rev='4'),
> - 'F' : Item(status=' ', wc_rev='3'),
> - 'F/alpha' : Item(status=' M', wc_rev='4', treeconflict='C'),
> 'DD' : Item(status=' ', wc_rev='3'),
> 'DD/D1' : Item(status='D ', wc_rev='3'), # tree conflict?
> 'DD/D1/D2' : Item(status='D ', wc_rev='3'),
> 'DD/D1/D2/epsilon' : Item(status='D ', wc_rev='4'),
> - 'DF' : Item(status=' ', wc_rev='3'),
> - 'DF/D1' : Item(status='D ', wc_rev='3'), # tree conflict?
> - 'DF/D1/beta' : Item(status='D ', wc_rev='4'),
> 'DDD' : Item(status=' ', wc_rev='3'),
> 'DDD/D1' : Item(status='D ', wc_rev='3'), # tree conflict?
> 'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
> @@ -13536,10 +13482,15 @@ def tree_conflicts_on_merge_local_ci_5_1
> 'DDF/D1' : Item(status='D ', wc_rev='3'), # tree conflict?
> 'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
> 'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='4'),
> + 'DF' : Item(status=' ', wc_rev='3'),
> + 'DF/D1' : Item(status='D ', wc_rev='3'), # tree conflict?
> + 'DF/D1/beta' : Item(status='D ', wc_rev='4'),
> + 'F' : Item(status=' ', wc_rev='3'),
> + 'F/alpha' : Item(status=' ', treeconflict='C', wc_rev='4'),
> +
> })
>
> expected_skip = svntest.wc.State('', {
> - 'F/alpha' : Item(),
> })
>
> svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
> @@ -13559,16 +13510,12 @@ def tree_conflicts_on_merge_local_ci_5_2
> # 5.2) local leaf del, incoming tree delete
>
> expected_output = svntest.wc.State('', {
> - 'D' : Item(status='C '),
> - 'F' : Item(status='C '),
> - 'DD' : Item(),
> - 'DD/D1' : Item(status='D '),
> - 'DF' : Item(),
> - 'DF/D1' : Item(status='D '),
> - 'DDD' : Item(),
> - 'DDD/D1' : Item(status='D '),
> - 'DDF' : Item(),
> - 'DDF/D1' : Item(status='D '),
> + 'F/alpha' : Item(status=' ', treeconflict='C'),
> + 'D/D1' : Item(status=' ', treeconflict='C'),
> + 'DF/D1' : Item(status=' U', treeconflict='C'),
> + 'DD/D1' : Item(status=' U', treeconflict='C'),
> + 'DDF/D1' : Item(status=' U', treeconflict='C'),
> + 'DDD/D1' : Item(status=' U', treeconflict='C'),
> })
>
>
> @@ -13598,8 +13545,6 @@ def tree_conflicts_on_merge_local_ci_5_2
> })
>
> expected_skip = svntest.wc.State('', {
> - 'F/alpha' : Item(),
> - 'D/D1' : Item(),
> })
>
> svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
> @@ -13629,12 +13574,12 @@ def tree_conflicts_on_merge_local_ci_6(s
> # local tree delete, incoming tree delete
>
> expected_output = svntest.wc.State('', {
> - 'F' : Item(status='C '),
> - 'D' : Item(status='C '),
> - 'DF' : Item(status='C '),
> - 'DD' : Item(status='C '),
> - 'DDF' : Item(status='C '),
> - 'DDD' : Item(status='C '),
> + 'F/alpha' : Item(status=' ', treeconflict='C'),
> + 'D/D1' : Item(status=' ', treeconflict='C'),
> + 'DF/D1' : Item(status=' ', treeconflict='C'),
> + 'DD/D1' : Item(status=' ', treeconflict='C'),
> + 'DDF/D1' : Item(status=' ', treeconflict='C'),
> + 'DDD/D1' : Item(status=' ', treeconflict='C'),
> })
>
> expected_disk = state_after_tree_del
> @@ -13650,12 +13595,6 @@ def tree_conflicts_on_merge_local_ci_6(s
> })
>
> expected_skip = svntest.wc.State('', {
> - 'D/D1' : Item(),
> - 'F/alpha' : Item(),
> - 'DD/D1' : Item(),
> - 'DF/D1' : Item(),
> - 'DDD/D1' : Item(),
> - 'DDF/D1' : Item(),
> })
>
> svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
> @@ -13690,61 +13629,47 @@ def tree_conflicts_on_merge_no_local_ci_
> # 4.1) local tree delete, incoming leaf edit
>
> expected_output = svntest.wc.State('', {
> - 'F' : Item(status='C '),
> - 'D' : Item(status='C '),
> - 'D/D1' : Item(),
> - 'D/D1/delta' : Item(status='A '),
> - 'DF' : Item(status='C '),
> - 'DF/D1' : Item(status='C '),
> - 'DD' : Item(status='C '),
> - 'DD/D1' : Item(status='C '),
> - 'DD/D1/D2' : Item(),
> - 'DD/D1/D2/epsilon' : Item(status='A '),
> - 'DDF' : Item(status='C '),
> - 'DDF/D1' : Item(status='C '),
> - 'DDF/D1/D2' : Item(status='C '),
> - 'DDD' : Item(status='C '),
> - 'DDD/D1' : Item(status='C '),
> - 'DDD/D1/D2' : Item(status='C '),
> - 'DDD/D1/D2/D3' : Item(),
> - 'DDD/D1/D2/D3/zeta' : Item(status='A '),
> + 'F/alpha' : Item(status=' ', treeconflict='C'),
> + 'D/D1' : Item(status=' ', treeconflict='C'),
> + 'DF/D1' : Item(status=' ', treeconflict='C'),
> + 'DD/D1' : Item(status=' ', treeconflict='C'),
> + 'DDF/D1' : Item(status=' ', treeconflict='C'),
> + 'DDD/D1' : Item(status=' ', treeconflict='C'),
> })
>
> expected_disk = svntest.wc.State('', {
> 'F' : Item(),
> - 'D/D1/delta' : Item(contents="This is the file 'delta'.\n"),
> + 'D/D1' : Item(),
> 'DF/D1' : Item(),
> - 'DD/D1/D2/epsilon' : Item(contents="This is the file 'epsilon'.\n"),
> + 'DD/D1/D2' : Item(),
> 'DDF/D1/D2' : Item(),
> - 'DDD/D1/D2/D3/zeta' : Item(contents="This is the file 'zeta'.\n"),
> + 'DDD/D1/D2/D3' : Item(),
> })
>
> expected_status = svntest.wc.State('', {
> '' : Item(status=' M', wc_rev='3'),
> - 'F' : Item(status=' ', wc_rev='3'),
> - 'F/alpha' : Item(status='D ', wc_rev='3', treeconflict='C'),
> + 'D' : Item(status=' ', wc_rev='3'),
> + 'D/D1' : Item(status='D ', treeconflict='C', wc_rev='3'),
> 'DD' : Item(status=' ', wc_rev='3'),
> - 'DD/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DD/D1/D2' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DD/D1/D2/epsilon' : Item(status='A ', copied='+', wc_rev='-'),
> - 'DF' : Item(status=' ', wc_rev='3'),
> - 'DF/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DF/D1/beta' : Item(status='D ', wc_rev='3', treeconflict='C'),
> + 'DD/D1' : Item(status='D ', treeconflict='C', wc_rev='3'),
> + 'DD/D1/D2' : Item(status='D ', wc_rev='3'),
> 'DDD' : Item(status=' ', wc_rev='3'),
> - 'DDD/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DDD/D1/D2' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DDD/D1/D2/D3/zeta' : Item(status='A ', copied='+', wc_rev='-'),
> + 'DDD/D1' : Item(status='D ', treeconflict='C', wc_rev='3'),
> + 'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
> + 'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3'),
> 'DDF' : Item(status=' ', wc_rev='3'),
> - 'DDF/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DDF/D1/D2' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'D' : Item(status=' ', wc_rev='3'),
> - 'D/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'D/D1/delta' : Item(status='A ', copied='+', wc_rev='-'),
> + 'DDF/D1' : Item(status='D ', treeconflict='C', wc_rev='3'),
> + 'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
> + 'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='3'),
> + 'DF' : Item(status=' ', wc_rev='3'),
> + 'DF/D1' : Item(status='D ', treeconflict='C', wc_rev='3'),
> + 'DF/D1/beta' : Item(status='D ', wc_rev='3'),
> + 'F' : Item(status=' ', wc_rev='3'),
> + 'F/alpha' : Item(status='D ', treeconflict='C', wc_rev='3'),
> })
>
> - expected_skip = alpha_beta_gamma
> + expected_skip = svntest.wc.State('', {
> + })
>
> svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
> [ DeepTreesTestCase(
> @@ -13764,21 +13689,12 @@ def tree_conflicts_on_merge_no_local_ci_
> # 4.2) local tree delete, incoming leaf delete
>
> expected_output = svntest.wc.State('', {
> - 'F' : Item(status='C '),
> - 'D' : Item(status='C '),
> - 'D/D1' : Item(status='D '),
> - 'DF' : Item(status='C '),
> - 'DF/D1' : Item(status='C '),
> - 'DD' : Item(status='C '),
> - 'DD/D1' : Item(status='C '),
> - 'DD/D1/D2' : Item(status='D '),
> - 'DDF' : Item(status='C '),
> - 'DDF/D1' : Item(status='C '),
> - 'DDF/D1/D2' : Item(status='C '),
> - 'DDD' : Item(status='C '),
> - 'DDD/D1' : Item(status='C '),
> - 'DDD/D1/D2' : Item(status='C '),
> - 'DDD/D1/D2/D3' : Item(status='D '),
> + 'F/alpha' : Item(status=' ', treeconflict='C'),
> + 'D/D1' : Item(status=' ', treeconflict='C'),
> + 'DF/D1' : Item(status=' ', treeconflict='C'),
> + 'DD/D1' : Item(status=' ', treeconflict='C'),
> + 'DDF/D1' : Item(status=' ', treeconflict='C'),
> + 'DDD/D1' : Item(status=' ', treeconflict='C'),
> })
>
> expected_disk = svntest.wc.State('', {
> @@ -13792,27 +13708,28 @@ def tree_conflicts_on_merge_no_local_ci_
>
> expected_status = svntest.wc.State('', {
> '' : Item(status=' M', wc_rev='3'),
> - 'F' : Item(status=' ', wc_rev='3'),
> - 'F/alpha' : Item(status='D ', wc_rev='3', treeconflict='C'),
> 'D' : Item(status=' ', wc_rev='3'),
> - 'D/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DF' : Item(status=' ', wc_rev='3'),
> - 'DF/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DF/D1/beta' : Item(status='D ', wc_rev='3', treeconflict='C'),
> + 'D/D1' : Item(status='D ', treeconflict='C', wc_rev='3'),
> 'DD' : Item(status=' ', wc_rev='3'),
> - 'DD/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DD/D1/D2' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DDF' : Item(status=' ', wc_rev='3'),
> - 'DDF/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DDF/D1/D2' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='3', treeconflict='C'),
> + 'DD/D1' : Item(status='D ', treeconflict='C', wc_rev='3'),
> + 'DD/D1/D2' : Item(status='D ', wc_rev='3'),
> 'DDD' : Item(status=' ', wc_rev='3'),
> - 'DDD/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DDD/D1/D2' : Item(status='D ', wc_rev='3', treeconflict='C'),
> - 'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3', treeconflict='C'),
> + 'DDD/D1' : Item(status='D ', treeconflict='C', wc_rev='3'),
> + 'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
> + 'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3'),
> + 'DDF' : Item(status=' ', wc_rev='3'),
> + 'DDF/D1' : Item(status='D ', treeconflict='C', wc_rev='3'),
> + 'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
> + 'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='3'),
> + 'DF' : Item(status=' ', wc_rev='3'),
> + 'DF/D1' : Item(status='D ', treeconflict='C', wc_rev='3'),
> + 'DF/D1/beta' : Item(status='D ', wc_rev='3'),
> + 'F' : Item(status=' ', wc_rev='3'),
> + 'F/alpha' : Item(status='D ', treeconflict='C', wc_rev='3'),
> })
>
> - expected_skip = alpha_beta_gamma
> + expected_skip = svntest.wc.State('', {
> + })
>
> svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
> [ DeepTreesTestCase(
> @@ -13836,7 +13753,12 @@ def tree_conflicts_on_merge_no_local_ci_
> # 5.1) local leaf edit, incoming tree delete
>
> expected_output = svntest.wc.State('', {
> - 'F' : Item(status='C '),
> + 'F/alpha' : Item(status=' ', treeconflict='C'),
> + 'D/D1' : Item(status=' ', treeconflict='C'),
> + 'DF/D1' : Item(status=' ', treeconflict='C'),
> + 'DD/D1' : Item(status=' ', treeconflict='C'),
> + 'DDF/D1' : Item(status=' ', treeconflict='C'),
> + 'DDD/D1' : Item(status=' ', treeconflict='C'),
> })
>
> expected_disk = state_after_leaf_edit
> @@ -13844,35 +13766,29 @@ def tree_conflicts_on_merge_no_local_ci_
> expected_status = svntest.wc.State('', {
> '' : Item(status=' M', wc_rev='3'),
> 'D' : Item(status=' ', wc_rev='3'),
> - 'D/D1' : Item(status=' M', wc_rev='3'), # tree conflict?
> + 'D/D1' : Item(status=' ', wc_rev='3'), # tree conflict?
> 'D/D1/delta' : Item(status='A ', wc_rev='0'),
> - 'F' : Item(status=' ', wc_rev='3'),
> - 'F/alpha' : Item(status='MM', wc_rev='3', treeconflict='C'),
> 'DD' : Item(status=' ', wc_rev='3'),
> - 'DD/D1' : Item(status=' M', wc_rev='3'), # tree conflict?
> + 'DD/D1' : Item(status=' ', wc_rev='3'), # tree conflict?
> 'DD/D1/D2' : Item(status=' ', wc_rev='3'),
> 'DD/D1/D2/epsilon' : Item(status='A ', wc_rev='0'),
> - 'DF' : Item(status=' ', wc_rev='3'),
> - 'DF/D1' : Item(status=' M', wc_rev='3'), # tree conflict?
> - 'DF/D1/beta' : Item(status='M ', wc_rev='3'),
> 'DDD' : Item(status=' ', wc_rev='3'),
> - 'DDD/D1' : Item(status=' M', wc_rev='3'), # tree conflict?
> + 'DDD/D1' : Item(status=' ', wc_rev='3'), # tree conflict?
> 'DDD/D1/D2' : Item(status=' ', wc_rev='3'),
> 'DDD/D1/D2/D3' : Item(status=' ', wc_rev='3'),
> 'DDD/D1/D2/D3/zeta' : Item(status='A ', wc_rev='0'),
> 'DDF' : Item(status=' ', wc_rev='3'),
> - 'DDF/D1' : Item(status=' M', wc_rev='3'), # tree conflict?
> + 'DDF/D1' : Item(status=' ', wc_rev='3'), # tree conflict?
> 'DDF/D1/D2' : Item(status=' ', wc_rev='3'),
> 'DDF/D1/D2/gamma' : Item(status='M ', wc_rev='3'),
> + 'DF' : Item(status=' ', wc_rev='3'),
> + 'DF/D1' : Item(status=' ', wc_rev='3'), # tree conflict?
> + 'DF/D1/beta' : Item(status='M ', wc_rev='3'),
> + 'F' : Item(status=' ', wc_rev='3'),
> + 'F/alpha' : Item(status='M ', treeconflict='C', wc_rev='3'),
> })
>
> expected_skip = svntest.wc.State('', {
> - 'D/D1' : Item(),
> - 'F/alpha' : Item(),
> - 'DD/D1' : Item(),
> - 'DF/D1' : Item(),
> - 'DDD/D1' : Item(),
> - 'DDF/D1' : Item(),
> })
>
> svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
> @@ -13894,17 +13810,12 @@ def tree_conflicts_on_merge_no_local_ci_
> # 5.2) local leaf del, incoming tree delete
>
> expected_output = svntest.wc.State('', {
> - 'D' : Item(status='C '),
> - 'D/D1' : Item(status='D '),
> - 'F' : Item(status='C '),
> - 'DD' : Item(),
> - 'DD/D1' : Item(status='D '),
> - 'DF' : Item(),
> - 'DF/D1' : Item(status='D '),
> - 'DDD' : Item(),
> - 'DDD/D1' : Item(status='D '),
> - 'DDF' : Item(),
> - 'DDF/D1' : Item(status='D '),
> + 'F/alpha' : Item(status=' ', treeconflict='C'),
> + 'D/D1' : Item(status=' ', treeconflict='C'),
> + 'DF/D1' : Item(status=' U', treeconflict='C'),
> + 'DD/D1' : Item(status=' U', treeconflict='C'),
> + 'DDF/D1' : Item(status=' U', treeconflict='C'),
> + 'DDD/D1' : Item(status=' U', treeconflict='C'),
> })
>
>
> @@ -13940,7 +13851,6 @@ def tree_conflicts_on_merge_no_local_ci_
> })
>
> expected_skip = svntest.wc.State('', {
> - 'F/alpha' : Item(),
> })
>
> svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
> @@ -13962,17 +13872,12 @@ def tree_conflicts_on_merge_no_local_ci_
> # local tree delete, incoming tree delete
>
> expected_output = svntest.wc.State('', {
> - 'D' : Item(status='C '),
> - 'D/D1' : Item(status='D '),
> - 'F' : Item(status='C '),
> - 'DD' : Item(status='C '),
> - 'DD/D1' : Item(status='D '),
> - 'DF' : Item(status='C '),
> - 'DF/D1' : Item(status='D '),
> - 'DDD' : Item(status='C '),
> - 'DDD/D1' : Item(status='D '),
> - 'DDF' : Item(status='C '),
> - 'DDF/D1' : Item(status='D '),
> + 'F/alpha' : Item(status=' ', treeconflict='C'),
> + 'D/D1' : Item(status=' ', treeconflict='C'),
> + 'DF/D1' : Item(status=' ', treeconflict='C'),
> + 'DD/D1' : Item(status=' ', treeconflict='C'),
> + 'DDF/D1' : Item(status=' ', treeconflict='C'),
> + 'DDD/D1' : Item(status=' ', treeconflict='C'),
> })
>
> expected_disk = svntest.wc.State('', {
> @@ -14007,7 +13912,6 @@ def tree_conflicts_on_merge_no_local_ci_
> })
>
> expected_skip = svntest.wc.State('', {
> - 'F/alpha' : Item(),
> })
>
> svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: svn-unsubscribe_at_subversion.tigris.org
> For additional commands, e-mail: svn-help_at_subversion.tigris.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-11-03 02:51:11 CET