> Author: cmpilato

> URL: http://svn.apache.org/viewvc?rev=1414880&view=rev
> Log:
> After consultation with pburba, restore the 'added_path' merge context
> baton member and related functionality removed in r1414810, using it
> as a preferred sourch of information about added parent directories,
> and only falling back to the more expensive consultation of the
> 'dry_run_added' hash when we have to.  Though, rather than a *precise*
> reintroduction of that baton member, call its restored form
> 'dry_run_last_added_dir' and position it alongside the 
> 'dry_run_added'
> baton member.
> 
> * subversion/libsvn_client/merge.c
>   (merge_cmd_baton_t): Add new 'dry_run_last_added_dir' member.
>   (dry_run_added_parent_p): Add 'local_abspath' parameter, and rename
>     'edit_relpath' to 'local_relpath'.  Now check the incoming 
> paths
>     against the merge baton's 'dry_run_last_added_dir' as an
>     optimization before consulting the 'dry_run_added' hash.
>   (merge_file_added): Update call to dry_run_added_parent_p().
>   (merge_dir_added): Manage the state of the new 
> 'dry_run_last_added_dir'
>     baton member.  Update call to dry_run_added_parent_p().
>   (do_merge): Reset the new 'dry_run_last_added_dir' context baton 
> member, too.

> Modified: subversion/trunk/subversion/libsvn_client/merge.c
> ==============================================================================

> @@ -286,9 +286,10 @@ typedef struct merge_cmd_baton_t {
> 
> -  /* The list of paths for entries we've added, used only when in
> -     dry_run mode. */
> +  /* The list of paths for entries we've added and the most
> +     recently added directory.  (Used only when in dry_run mode.) */
>    apr_hash_t *dry_run_added;
> +  const char *dry_run_last_added_dir;

> @@ -487,32 +488,45 @@ dry_run_added_p(const merge_cmd_baton_t 
>                         APR_HASH_KEY_STRING) != NULL);
> }
> 
> -/* Return true iff we're in dry-run mode and a parent of EDIT_RELPATH
> -   would have been added by now if we weren't in dry-run mode.
> -   Used to avoid spurious notifications (e.g. conflicts) from a merge
> -   attempt into an existing target which would have been deleted if we
> -   weren't in dry_run mode (issue #2584).  Assumes that WCPATH is
> -   still versioned (e.g. has an associated entry). */
> +/* Return true iff we're in dry-run mode and a parent of
> +   LOCAL_RELPATH/LOCAL_ABSPATH would have been added by now if we
> +   weren't in dry-run mode.  Used to avoid spurious notifications
> +   (e.g. conflicts) from a merge attempt into an existing target which
> +   would have been deleted if we weren't in dry_run mode (issue
> +   #2584).  Assumes that WCPATH is still versioned (e.g. has an
> +   associated entry). */
> static svn_boolean_t
> dry_run_added_parent_p(const merge_cmd_baton_t *merge_b,
> -                       const char *edit_relpath,
> +                       const char *local_relpath,
> +                       const char *local_abspath,
>                         apr_pool_t *scratch_pool)
> {
> +  const char *abspath = local_abspath;
>    int i;
> -  const char *abspath;
> 
>    if (!merge_b->dry_run)
>      return FALSE;
> 
> -  abspath = svn_dirent_join(merge_b->target->abspath, edit_relpath,
> -                            scratch_pool);
> -  for (i = 0; i < (svn_path_component_count(edit_relpath) - 1); i++)
> +  /* See if LOCAL_ABSPATH is a child of the most recently added
> +     directory.  This is an optimization over searching through
> +     dry_run_added that plays to the strengths of the editor's drive
> +     ordering constraints.  In fact, we need the fallback approach
> +     below only because of ra_serf's insufficiencies in this area.  */
> +  if (merge_b->dry_run_last_added_dir
> +      && svn_dirent_is_child(merge_b->dry_run_last_added_dir,
> +                             local_abspath, NULL))
> +    return TRUE;
> +
> +  /* The fallback:  see if any of LOCAL_ABSPATH's parents have been
> +     added in this merge so far. */
> +  for (i = 0; i < (svn_path_component_count(local_relpath) - 1); i++)
>      {
>        abspath = svn_dirent_dirname(abspath, scratch_pool);
>        if (apr_hash_get(merge_b->dry_run_added, abspath,
>                         APR_HASH_KEY_STRING))
>          return TRUE;
>      }
> +
>    return FALSE;
> }
> 

> @@ -2386,10 +2402,10 @@ merge_dir_added(svn_wc_notify_state_t *s
>        /* Unversioned or schedule-delete */
>        if (merge_b->dry_run)
>          {
> -          const char *added_path = apr_pstrdup(merge_b->pool,
> -                                               local_abspath);
> -          apr_hash_set(merge_b->dry_run_added, added_path,
> -                       APR_HASH_KEY_STRING, added_path);
> +          merge_b->dry_run_last_added_dir =
> +            apr_pstrdup(merge_b->pool, local_abspath);
> +          apr_hash_set(merge_b->dry_run_added, 
> merge_b->dry_run_last_added_dir,
> +                       APR_HASH_KEY_STRING, 
> merge_b->dry_run_last_added_dir);
>          }
>        else
>          {
> @@ -2425,10 +2441,8 @@ merge_dir_added(svn_wc_notify_state_t *s
>              }
>            else
>              {
> -              const char *added_path = apr_pstrdup(merge_b->pool,
> -                                                   local_abspath);
> -              apr_hash_set(merge_b->dry_run_added, added_path,
> -                           APR_HASH_KEY_STRING, added_path);
> +              merge_b->dry_run_last_added_dir =
> +                apr_pstrdup(merge_b->pool, local_abspath);

Oops -- no longer setting the hash here.  Maybe use a macro or function to 
encapsulate both parts of the "registration".

>              }
>            if (state)
>              *state = svn_wc_notify_state_changed;
> @@ -2467,6 +2481,9 @@ merge_dir_added(svn_wc_notify_state_t *s
>          }
>        break;
>      case svn_node_file:
> +      if (merge_b->dry_run)
> +        merge_b->dry_run_last_added_dir = NULL;

Clearing that path is just an optimization, right?  (Also below.)

>        if (is_versioned && dry_run_deleted_p(merge_b, local_abspath))
>          {
>            /* ### TODO: Retain record of this dir being added to
> @@ -2488,6 +2505,8 @@ merge_dir_added(svn_wc_notify_state_t *s
>          }
>        break;
>      default:
> +      if (merge_b->dry_run)
> +        merge_b->dry_run_last_added_dir = NULL;
>        if (state)
>          *state = svn_wc_notify_state_unknown;
>        break;
> @@ -9199,6 +9218,7 @@ do_merge(apr_hash_t **modified_subtrees,
>          dry_run ? apr_hash_make(iterpool) : NULL;
>        merge_cmd_baton.dry_run_added =
>          dry_run ? apr_hash_make(iterpool) : NULL;
> +      merge_cmd_baton.dry_run_last_added_dir = NULL;
>        merge_cmd_baton.conflicted_paths = NULL;
>        merge_cmd_baton.paths_with_new_mergeinfo = NULL;
>        merge_cmd_baton.paths_with_deleted_mergeinfo = NULL;
>

Reply via email to