[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

wc-ng question -- is this an optimization?

From: Neels J Hofmeyr <neels_at_elego.de>
Date: Fri, 05 Feb 2010 03:01:42 +0100

In this commit, I run svn_wc__db_read_info() in check_tree_conflicts(), when
half or more of its callers have already called svn_wc__db_read_info().

So would it be an optimization to pass STATUS, maybe more, as args to
check_tree_conflict(), rather than calling svn_wc__db_read_info() twice?
Code readability wise it wouldn't be one. Which way to bend?

Thanks
~Neels

neels_at_apache.org wrote:
> Author: neels
> Date: Wed Feb 3 16:25:15 2010
> New Revision: 906110
>
> URL: http://svn.apache.org/viewvc?rev=906110&view=rev
> Log:
> wc-ng: Change tree-conflict checking during 'update' to use the new WC API.
> In effect, 'svn info' now always reports the right node kind in the "Tree
> conflict:" section, even for deleted nodes.
> Also change another static function's KIND arg's type to avoid translating
> node kinds once and then back again.
>
> * subversion/libsvn_wc/update_editor.c
> (entry_has_local_mods):
> Change the type of KIND argument to svn_wc__db_kind_t.
> (modcheck_found_node):
> Call entry_has_local_mods() with new KIND type.
> (SVN_WC_CONFLICT_REASON_NONE):
> New local #define.
> (check_tree_conflict):
> Don't use svn_wc_entry_t, use wc-ng (almost a complete rewrite).
> Lose the IN_DELETED_AND_TREE_CONFLICTED_SUBTREE argument, since, if TRUE,
> this skips the entire function anyway; move this check out to each caller.
> (do_entry_deletion,
> add_directory,
> open_directory,
> add_file,
> open_file):
> Evaluate IN_DELETED_AND_TREE_CONFLICTED_SUBTREE inline instead of passing
> it to check_tree_conflict() first.
>
>
> Modified:
> subversion/trunk/subversion/libsvn_wc/update_editor.c
>
> Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=906110&r1=906109&r2=906110&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
> +++ subversion/trunk/subversion/libsvn_wc/update_editor.c Wed Feb 3 16:25:15 2010
> @@ -1434,14 +1434,15 @@
> entry_has_local_mods(svn_boolean_t *modified,
> svn_wc__db_t *db,
> const char *local_abspath,
> - svn_node_kind_t kind,
> + svn_wc__db_kind_t kind,
> apr_pool_t *scratch_pool)
> {
> svn_boolean_t text_modified;
> svn_boolean_t props_modified;
>
> /* Check for text modifications */
> - if (kind == svn_node_file)
> + if (kind == svn_wc__db_kind_file
> + || kind == svn_wc__db_kind_symlink)
> SVN_ERR(svn_wc__internal_text_modified_p(&text_modified, db, local_abspath,
> FALSE, TRUE, scratch_pool));
> else
> @@ -1486,10 +1487,7 @@
> modified = TRUE;
> else
> SVN_ERR(entry_has_local_mods(&modified, baton->db, local_abspath,
> - (kind == svn_wc__db_kind_file
> - || kind == svn_wc__db_kind_symlink)
> - ? svn_node_file : svn_node_dir,
> - scratch_pool));
> + kind, scratch_pool));
>
> if (modified)
> {
> @@ -1536,6 +1534,9 @@
> }
>
>
> +/* Indicates an unset svn_wc_conflict_reason_t. */
> +#define SVN_WC_CONFLICT_REASON_NONE (svn_wc_conflict_reason_t)(-1)
> +
> /* Check whether the incoming change ACTION on FULL_PATH would conflict with
> * LOCAL_ABSPATH's scheduled change. If so, then raise a tree conflict with
> * LOCAL_ABSPATH as the victim.
> @@ -1568,189 +1569,315 @@
> svn_wc_conflict_action_t action,
> svn_node_kind_t their_node_kind,
> const char *their_url,
> - svn_boolean_t in_deleted_and_tree_conflicted_subtree,
> apr_pool_t *pool)
> {
> - svn_wc_conflict_reason_t reason = (svn_wc_conflict_reason_t)(-1);
> + svn_wc__db_status_t status;
> + svn_wc__db_kind_t db_node_kind;
> + svn_boolean_t base_shadowed;
> + svn_wc_conflict_reason_t reason = SVN_WC_CONFLICT_REASON_NONE;
> + svn_boolean_t locally_replaced = FALSE;
> + svn_boolean_t modified = FALSE;
> svn_boolean_t all_mods_are_deletes = FALSE;
> - const svn_wc_entry_t *entry;
> - svn_error_t *err;
>
> - err = svn_wc__get_entry(&entry, eb->db, local_abspath, TRUE,
> - svn_node_unknown, FALSE, pool, pool);
> + *pconflict = NULL;
>
> - if (err && err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND)
> - svn_error_clear(err);
> - else
> - SVN_ERR(err);
> + SVN_ERR(svn_wc__db_read_info(&status,
> + &db_node_kind,
> + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> + NULL, NULL, NULL,
> + &base_shadowed,
> + NULL, NULL,
> + eb->db,
> + local_abspath,
> + pool,
> + pool));
>
> - if (entry)
> - {
> - svn_boolean_t hidden;
> - SVN_ERR(svn_wc__db_node_hidden(&hidden, eb->db, local_abspath, pool));
> + /* Find out if there are any local changes to this node that may
> + * be the "reason" of a tree-conflict with the incoming "action". */
> + switch (status)
> + {
> + case svn_wc__db_status_added:
> + case svn_wc__db_status_obstructed_add:
> + case svn_wc__db_status_moved_here:
> + case svn_wc__db_status_copied:
> + /* Is it a replace? */
> + if (base_shadowed)
> + {
> + svn_wc__db_status_t base_status;
> + SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, NULL,
> + NULL, NULL, NULL, NULL, NULL,
> + NULL, NULL, NULL, NULL, NULL,
> + NULL, NULL,
> + eb->db, local_abspath,
> + pool,
> + pool));
> + if (base_status != svn_wc__db_status_not_present)
> + locally_replaced = TRUE;
> + }
>
> - if (hidden)
> - entry = NULL;
> - }
> + if (!locally_replaced)
> + {
> + /* The node is locally added, and it did not exist before. This
> + * is an 'update', so the local add can only conflict with an
> + * incoming 'add'. In fact, if we receive anything else than an
> + * svn_wc_conflict_action_add (which includes 'added',
> + * 'copied-here' and 'moved-here') during update on a node that
> + * did not exist before, then something is very wrong.
> + * Note that if there was no action on the node, this code
> + * would not have been called in the first place. */
> + SVN_ERR_ASSERT(action == svn_wc_conflict_action_add);
>
> - switch (action)
> - {
> - case svn_wc_conflict_action_edit:
> - /* Use case 1: Modifying a locally-deleted item.
> - If LOCAL_ABSPATH is an incoming leaf edit within a local
> - tree deletion then we will already have recorded a tree
> - conflict on the locally deleted parent tree. No need
> - to record a conflict within the conflict. */
> - if ((entry->schedule == svn_wc_schedule_delete
> - || entry->schedule == svn_wc_schedule_replace)
> - && !in_deleted_and_tree_conflicted_subtree)
> - reason = entry->schedule == svn_wc_schedule_delete
> - ? svn_wc_conflict_reason_deleted
> - : svn_wc_conflict_reason_replaced;
> - break;
> + reason = svn_wc_conflict_reason_added;
> + }
> + else
> + {
> + /* The node is locally replaced. */
> + reason = svn_wc_conflict_reason_replaced;
> + }
> + break;
>
> - case svn_wc_conflict_action_add:
> - /* Use case "3.5": Adding a locally-added item.
> - *
> - * When checking out a file-external, add_file() is called twice:
> - * 1.) In the main update, a minimal entry is created.
> - * 2.) In the external update, the file is added properly.
> - * Don't raise a tree conflict the second time! */
> - if (entry && !entry->file_external_path)
> - reason = svn_wc_conflict_reason_added;
> - break;
> -
> - case svn_wc_conflict_action_delete:
> - case svn_wc_conflict_action_replace:
> - /* Use case 3: Deleting a locally-deleted item. */
> - if (entry->schedule == svn_wc_schedule_delete
> - || entry->schedule == svn_wc_schedule_replace)
> - {
> - /* If LOCAL_ABSPATH is an incoming leaf deletion within a local
> - tree deletion then we will already have recorded a tree
> - conflict on the locally deleted parent tree. No need
> - to record a conflict within the conflict. */
> - if (!in_deleted_and_tree_conflicted_subtree)
> - reason = entry->schedule == svn_wc_schedule_delete
> - ? svn_wc_conflict_reason_deleted
> - : svn_wc_conflict_reason_replaced;
> - }
> - else
> - {
> - svn_boolean_t modified = FALSE;
>
> - /* Use case 2: Deleting a locally-modified item. */
> - if (entry->kind == svn_node_file)
> - {
> - if (entry->schedule != svn_wc_schedule_normal)
> - modified = TRUE;
> - else
> - SVN_ERR(entry_has_local_mods(&modified, eb->db, local_abspath,
> - entry->kind, pool));
> - if (entry->schedule == svn_wc_schedule_delete)
> - all_mods_are_deletes = TRUE;
> - }
> - else if (entry->kind == svn_node_dir)
> - {
> + case svn_wc__db_status_deleted:
> + case svn_wc__db_status_obstructed_delete:
> + /* The node is locally deleted. */
> + reason = svn_wc_conflict_reason_deleted;
> + break;
> +
> + case svn_wc__db_status_incomplete:
> + /* We used svn_wc__db_read_info(), so 'incomplete' means
> + * - there is no node in the WORKING tree
> + * - a BASE node is known to exist
> + * So the node exists and is essentially 'normal'. We still need to
> + * check prop and text mods, and those checks will retrieve the
> + * missing information (hopefully). */
> + case svn_wc__db_status_obstructed:
> + /* Tree-conflicts during update are only concerned with local
> + * modifications. We can safely update BASE, disregarding the
> + * obstruction. So let's treat this as normal. */
> + case svn_wc__db_status_normal:
> + if (action == svn_wc_conflict_action_edit)
> + /* An edit onto a local edit or onto *no* local changes is no
> + * tree-conflict. (It's possibly a text- or prop-conflict,
> + * but we don't handle those here.) */
> + return SVN_NO_ERROR;
> +
> + /* Check if the update wants to delete or replace a locally
> + * modified node. */
> + switch (db_node_kind)
> + {
> + case svn_wc__db_kind_file:
> + case svn_wc__db_kind_symlink:
> + all_mods_are_deletes = FALSE;
> + SVN_ERR(entry_has_local_mods(&modified, eb->db, local_abspath,
> + db_node_kind, pool));
> + break;
> +
> + case svn_wc__db_kind_dir:
> /* We must detect deep modifications in a directory tree,
> * but the update editor will not visit the subdirectories
> * of a directory that it wants to delete. Therefore, we
> * need to start a separate crawl here. */
> -
> if (!svn_wc__adm_missing(eb->db, local_abspath, pool))
> SVN_ERR(tree_has_local_mods(&modified, &all_mods_are_deletes,
> eb->db, local_abspath,
> eb->cancel_func, eb->cancel_baton,
> pool));
> - }
> + break;
>
> - if (modified)
> - {
> - if (all_mods_are_deletes)
> - reason = svn_wc_conflict_reason_deleted;
> - else
> - reason = svn_wc_conflict_reason_edited;
> - }
> + default:
> + /* It's supposed to be in 'normal' status. So how can it be
> + * neither file nor folder? */
> + SVN_ERR_MALFUNCTION();
> + break;
> + }
> +
> + if (modified)
> + {
> + if (all_mods_are_deletes)
> + reason = svn_wc_conflict_reason_deleted;
> + else
> + reason = svn_wc_conflict_reason_edited;
> + }
> + break;
> +
> + case svn_wc__db_status_absent:
> + /* Not allowed to view the node. Not allowed to report tree
> + * conflicts. */
> + case svn_wc__db_status_excluded:
> + /* Locally marked as excluded. No conflicts wanted. */
> + case svn_wc__db_status_not_present:
> + /* A committed delete (but parent not updated). The delete is
> + committed, so no conflict possible during update. */
> + return SVN_NO_ERROR;
> +
> + case svn_wc__db_status_base_deleted:
> + /* An internal status. Should never show up here. */
> + SVN_ERR_MALFUNCTION();
> + break;
>
> - }
> - break;
> }
>
> - *pconflict = NULL;
> + if (reason == SVN_WC_CONFLICT_REASON_NONE)
> + /* No conflict with the current action. */
> + return SVN_NO_ERROR;
> +
> +
> + /* Sanity checks.
> + * When the node existed before (it was locally deleted, replaced or
> + * edited), then, to be sane, 'update' can only send
> + * svn_wc_conflict_action_edit, svn_wc_conflict_action_delete or
> + * svn_wc_conflict_action_replace. Note that if there was no action on
> + * the node, this code would not have been called in the first place. */
> + if (reason == svn_wc_conflict_reason_edited
> + || reason == svn_wc_conflict_reason_deleted
> + || reason == svn_wc_conflict_reason_replaced)
> + SVN_ERR_ASSERT(action == svn_wc_conflict_action_edit
> + || action == svn_wc_conflict_action_delete
> + || action == svn_wc_conflict_action_replace);
> + else
> + if (reason == svn_wc_conflict_reason_added)
> + /* When the node did not exist before (it was locally added), then, to
> + * be sane, 'update' can only send svn_wc_conflict_action_add. */
> + SVN_ERR_ASSERT(action == svn_wc_conflict_action_add);
> +
>
> - /* If a conflict was detected, append log commands to the log accumulator
> + /* A conflict was detected. Append log commands to the log accumulator
> * to record it. */
> - if (reason != (svn_wc_conflict_reason_t)(-1))
> - {
> - svn_wc_conflict_description2_t *conflict;
> - const svn_wc_conflict_version_t *src_left_version;
> - const svn_wc_conflict_version_t *src_right_version;
> - const char *repos_url = NULL;
> - const char *path_in_repos = NULL;
> - svn_node_kind_t left_kind = (entry->schedule == svn_wc_schedule_add)
> - ? svn_node_none
> - : (entry->schedule == svn_wc_schedule_delete)
> - ? svn_node_unknown
> - : entry->kind;
> -
> - /* Source-left repository root URL and path in repository.
> - * The Source-right ones will be the same for update.
> - * For switch, only the path in repository will differ, because
> - * a cross-repository switch is not possible. */
> - repos_url = entry->repos;
> - path_in_repos = svn_uri_is_child(repos_url, entry->url, pool);
> - if (path_in_repos == NULL)
> - path_in_repos = "";
> -
> - src_left_version = svn_wc_conflict_version_create(repos_url,
> - path_in_repos,
> - entry->revision,
> - left_kind,
> - pool);
> -
> - /* entry->kind is both base kind and working kind, because schedule
> - * replace-by-different-kind is not supported. */
> - /* ### TODO: but in case the entry is locally removed, entry->kind
> - * is svn_node_none and doesn't reflect the older kind. Then we
> - * need to find out the older kind in a different way! */
> -
> - /* For switch, find out the proper PATH_IN_REPOS for source-right. */
> - if (eb->switch_url != NULL)
> - {
> - if (their_url != NULL)
> - path_in_repos = svn_uri_is_child(repos_url, their_url, pool);
> - else
> - {
> - /* The complete source-right URL is not available, but it
> - * is somewhere below the SWITCH_URL. For now, just go
> - * without it.
> - * ### TODO: Construct a proper THEIR_URL in some of the
> - * delete cases that still pass NULL for THEIR_URL when
> - * calling this function. Do that on the caller's side. */
> - path_in_repos = svn_uri_is_child(repos_url, eb->switch_url,
> - pool);
> - path_in_repos = apr_pstrcat(
> - pool, path_in_repos,
> - "_THIS_IS_INCOMPLETE",
> - NULL);
> - }
> - }
> + {
> + const char *repos_root_url;
> + const char *left_repos_relpath;
> + svn_revnum_t left_revision;
> + svn_node_kind_t left_kind;
> + const char *right_repos_relpath;
> + svn_node_kind_t conflict_node_kind;
> + svn_wc_conflict_version_t *src_left_version;
> + svn_wc_conflict_version_t *src_right_version;
> +
> + /* Get the source-left information, i.e. the local state of the node
> + * before any changes were made to the working copy, i.e. the state the
> + * node would have if it was reverted. */
> + if (reason == svn_wc_conflict_reason_added)
> + {
> + /* Source-left does not exist.
> + * We will still report the URL and revision onto which this node
> + * is locally added. We don't report the locally added node kind,
> + * since that would be 'target', not 'source-left'. */
> + svn_wc__db_status_t added_status;
> +
> + left_kind = svn_node_none;
> +
> + SVN_ERR(svn_wc__db_scan_addition(&added_status, NULL,
> + &left_repos_relpath,
> + &repos_root_url,
> + NULL, NULL, NULL, NULL,
> + &left_revision,
> + eb->db,
> + local_abspath,
> + pool,
> + pool));
> +
> + /* Sanity. */
> + SVN_ERR_ASSERT(added_status == svn_wc__db_status_added
> + || added_status == svn_wc__db_status_obstructed_add
> + || added_status == svn_wc__db_status_copied
> + || added_status == svn_wc__db_status_moved_here);
> + }
> + else
> + {
> + /* A BASE node should exist. */
> + svn_wc__db_kind_t base_kind;
>
> - src_right_version = svn_wc_conflict_version_create(repos_url,
> - path_in_repos,
> - *eb->target_revision,
> - their_node_kind,
> - pool);
> -
> - conflict = svn_wc_conflict_description_create_tree2(
> - local_abspath, entry->kind,
> - eb->switch_url ? svn_wc_operation_switch : svn_wc_operation_update,
> - src_left_version, src_right_version, pool);
> - conflict->action = action;
> - conflict->reason = reason;
> + /* If anything else shows up, then this assertion is probably naive
> + * and that other case should also be handled. */
> + SVN_ERR_ASSERT(reason == svn_wc_conflict_reason_edited
> + || reason == svn_wc_conflict_reason_deleted
> + || reason == svn_wc_conflict_reason_replaced
> + || reason == svn_wc_conflict_reason_obstructed);
> +
> + SVN_ERR(svn_wc__db_base_get_info(NULL, &base_kind,
> + &left_revision,
> + &left_repos_relpath,
> + &repos_root_url,
> + NULL, NULL, NULL, NULL, NULL, NULL,
> + NULL, NULL, NULL, NULL,
> + eb->db,
> + local_abspath,
> + pool,
> + pool));
> + /* Translate the node kind. */
> + if (base_kind == svn_wc__db_kind_file
> + || base_kind == svn_wc__db_kind_symlink)
> + left_kind = svn_node_file;
> + else
> + if (base_kind == svn_wc__db_kind_dir)
> + left_kind = svn_node_dir;
> + else
> + SVN_ERR_MALFUNCTION();
> + }
>
> - *pconflict = conflict;
> - }
> +
> + /* Find the source-right information, i.e. the state in the repository
> + * to which we would like to update. */
> + if (eb->switch_url != NULL)
> + {
> + /* If this is a 'switch' operation, try to construct the switch
> + * target's REPOS_RELPATH. */
> + if (their_url != NULL)
> + right_repos_relpath = svn_uri_is_child(repos_root_url, their_url, pool);
> + else
> + {
> + /* The complete source-right URL is not available, but it
> + * is somewhere below the SWITCH_URL. For now, just go
> + * without it.
> + * ### TODO: Construct a proper THEIR_URL in some of the
> + * delete cases that still pass NULL for THEIR_URL when
> + * calling this function. Do that on the caller's side. */
> + right_repos_relpath = svn_uri_is_child(repos_root_url,
> + eb->switch_url, pool);
> + right_repos_relpath = apr_pstrcat(pool, right_repos_relpath,
> + "_THIS_IS_INCOMPLETE", NULL);
> + }
> + }
> + else
> + {
> + /* This is an 'update', so REPOS_RELPATH is the same as for
> + * source-left. */
> + right_repos_relpath = left_repos_relpath;
> + }
> +
> + /* Determine PCONFLICT's overall node kind. We give it the source-right
> + * revision (THEIR_NODE_KIND) -- unless source-right is deleted and hence
> + * == svn_node_none, in which case we take it from source-left, which has
> + * to be the node kind that was deleted in source-right. */
> + conflict_node_kind = (action == svn_wc_conflict_action_delete ?
> + left_kind : their_node_kind);
> + SVN_ERR_ASSERT(conflict_node_kind == svn_node_file
> + || conflict_node_kind == svn_node_dir);
> +
> +
> + /* Construct the tree conflict info structs. */
> +
> + src_left_version = svn_wc_conflict_version_create(repos_root_url,
> + left_repos_relpath,
> + left_revision,
> + left_kind,
> + pool);
> +
> + src_right_version = svn_wc_conflict_version_create(repos_root_url,
> + right_repos_relpath,
> + *eb->target_revision,
> + their_node_kind,
> + pool);
> +
> + *pconflict = svn_wc_conflict_description_create_tree2(
> + local_abspath, conflict_node_kind,
> + eb->switch_url ?
> + svn_wc_operation_switch : svn_wc_operation_update,
> + src_left_version, src_right_version, pool);
> + (*pconflict)->action = action;
> + (*pconflict)->reason = reason;
> + }
>
> return SVN_NO_ERROR;
> }
> @@ -2092,7 +2219,7 @@
> const svn_wc_entry_t *entry;
> svn_boolean_t already_conflicted;
> svn_stringbuf_t *log_item = svn_stringbuf_create("", pool);
> - svn_wc_conflict_description2_t *tree_conflict;
> + svn_wc_conflict_description2_t *tree_conflict = NULL;
> const char *dir_abspath = svn_dirent_dirname(local_abspath, pool);
> svn_boolean_t hidden;
>
> @@ -2146,13 +2273,15 @@
> /* Is this path the victim of a newly-discovered tree conflict? If so,
> * remember it and notify the client. Then (if it was existing and
> * modified), re-schedule the node to be added back again, as a (modified)
> - * copy of the previous base version.
> - */
> - SVN_ERR(check_tree_conflict(&tree_conflict, eb, local_abspath,
> - svn_wc_conflict_action_delete, svn_node_none,
> - their_url,
> - in_deleted_and_tree_conflicted_subtree,
> - pool));
> + * copy of the previous base version. */
> +
> + /* Check for conflicts only when we haven't already recorded
> + * a tree-conflict on a parent node. */
> + if (!in_deleted_and_tree_conflicted_subtree)
> + SVN_ERR(check_tree_conflict(&tree_conflict, eb, local_abspath,
> + svn_wc_conflict_action_delete, svn_node_none,
> + their_url, pool));
> +
> if (tree_conflict != NULL)
> {
> /* When we raise a tree conflict on a directory, we want to avoid
> @@ -2604,15 +2733,15 @@
> break;
> default:
> {
> - svn_wc_conflict_description2_t *tree_conflict;
> + svn_wc_conflict_description2_t *tree_conflict = NULL;
>
> - /* Raise a tree conflict. */
> - SVN_ERR(check_tree_conflict(
> - &tree_conflict, eb, db->local_abspath,
> - svn_wc_conflict_action_add, svn_node_dir,
> - db->new_URL,
> - db->in_deleted_and_tree_conflicted_subtree,
> - pool));
> + /* Check for conflicts only when we haven't already recorded
> + * a tree-conflict on a parent node. */
> + if (!db->in_deleted_and_tree_conflicted_subtree)
> + SVN_ERR(check_tree_conflict(&tree_conflict, eb,
> + db->local_abspath,
> + svn_wc_conflict_action_add,
> + svn_node_dir, db->new_URL, pool));
>
> if (tree_conflict != NULL)
> {
> @@ -2800,7 +2929,7 @@
> SVN_WC__ENTRY_MODIFY_URL | SVN_WC__ENTRY_MODIFY_INCOMPLETE;
>
> svn_boolean_t already_conflicted;
> - svn_wc_conflict_description2_t *tree_conflict;
> + svn_wc_conflict_description2_t *tree_conflict = NULL;
> svn_wc__db_status_t status;
>
> SVN_ERR(make_dir_baton(&db, path, eb, pb, FALSE, pool));
> @@ -2857,11 +2986,13 @@
>
> /* Is this path a fresh tree conflict victim? If so, skip the tree
> with one notification. */
> - SVN_ERR(check_tree_conflict(&tree_conflict, eb, db->local_abspath,
> - svn_wc_conflict_action_edit,
> - svn_node_dir, db->new_URL,
> - db->in_deleted_and_tree_conflicted_subtree,
> - pool));
> +
> + /* Check for conflicts only when we haven't already recorded
> + * a tree-conflict on a parent node. */
> + if (!db->in_deleted_and_tree_conflicted_subtree)
> + SVN_ERR(check_tree_conflict(&tree_conflict, eb, db->local_abspath,
> + svn_wc_conflict_action_edit, svn_node_dir,
> + db->new_URL, pool));
>
> /* Remember the roots of any locally deleted trees. */
> if (tree_conflict != NULL)
> @@ -3908,14 +4039,16 @@
> break;
> default:
> {
> - svn_wc_conflict_description2_t *tree_conflict;
> + svn_wc_conflict_description2_t *tree_conflict = NULL;
>
> - SVN_ERR(check_tree_conflict(
> - &tree_conflict, eb, fb->local_abspath,
> - svn_wc_conflict_action_add, svn_node_file,
> - fb->new_URL,
> - pb->in_deleted_and_tree_conflicted_subtree,
> - subpool));
> + /* Check for conflicts only when we haven't already recorded
> + * a tree-conflict on a parent node. */
> + if (!pb->in_deleted_and_tree_conflicted_subtree)
> + SVN_ERR(check_tree_conflict(&tree_conflict, eb,
> + fb->local_abspath,
> + svn_wc_conflict_action_add,
> + svn_node_file, fb->new_URL,
> + subpool));
>
> if (tree_conflict != NULL)
> {
> @@ -3969,7 +4102,7 @@
> struct file_baton *fb;
> svn_node_kind_t kind;
> svn_boolean_t already_conflicted;
> - svn_wc_conflict_description2_t *tree_conflict;
> + svn_wc_conflict_description2_t *tree_conflict = NULL;
>
> /* the file_pool can stick around for a *long* time, so we want to use
> a subpool for any temporary allocations. */
> @@ -4026,13 +4159,14 @@
>
> fb->deleted = pb->in_deleted_and_tree_conflicted_subtree;
>
> - /* Is this path the victim of a newly-discovered tree conflict? */
> - SVN_ERR(check_tree_conflict(&tree_conflict, eb, fb->local_abspath,
> - svn_wc_conflict_action_edit, svn_node_file,
> - fb->new_URL,
> - pb->in_deleted_and_tree_conflicted_subtree,
> - pool));
> + /* Check for conflicts only when we haven't already recorded
> + * a tree-conflict on a parent node. */
> + if (!pb->in_deleted_and_tree_conflicted_subtree)
> + SVN_ERR(check_tree_conflict(&tree_conflict, eb, fb->local_abspath,
> + svn_wc_conflict_action_edit, svn_node_file,
> + fb->new_URL, pool));
>
> + /* Is this path the victim of a newly-discovered tree conflict? */
> if (tree_conflict)
> {
> SVN_ERR(svn_wc__loggy_add_tree_conflict(&fb->log_accum, tree_conflict,
>
>

Received on 2010-02-05 03:02:23 CET

This is an archived mail posted to the Subversion Dev mailing list.