You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by David Glasser <gl...@davidglasser.net> on 2008/04/17 19:05:04 UTC

Re: svn commit: r30644 - trunk/subversion/libsvn_client

This makes merge_tests #22 crash over ra_local (at least) for me.

--dave

On Wed, Apr 16, 2008 at 4:09 PM,  <pb...@tigris.org> wrote:
> Author: pburba
>  Date: Wed Apr 16 16:09:29 2008
>  New Revision: 30644
>
>  Log:
>  Make --record-only merges record and elide mergeinfo on subtrees.
>
>  Previously --record-only merges only set mergeinfo on the merge target,
>  ignored subtrees with explicit mergeinfo, and did not attempt any elision.
>  With this change (paraphrasing cmpilato) --record-only is now effectively
>  a --dry-run merge but with live mergeinfo recording and elision.
>
>  * subversion/libsvn_client/merge.c
>   (populate_remaining_ranges): Expect that this code may now be invoked
>   during --record-only merges and in that case follow the same code path
>   we do when not honoring mergeinfo, i.e. the requested range *is* the
>   remaining range, no filtering needed.
>   (record_mergeinfo_for_record_only_merge): Delete, a few minor tweaks to
>   do_file_merge(), do_directory_merge(), and their helpers is adequate to
>   replace this while also implementing the new --record-only functionality.
>   (do_file_merge, do_directory_merge): Expect that this code may now be
>   invoked during --record-only merges; if it is, *skip* the actual
>   merging, but *do* record the merge in mergeinfo.
>   (do_merge): Remove call to record_mergeinfo_for_record_only_merge().
>
>  Modified:
>    trunk/subversion/libsvn_client/merge.c
>
>  Modified: trunk/subversion/libsvn_client/merge.c
>  URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_client/merge.c?pathrev=30644&r1=30643&r2=30644
>  ==============================================================================
>  --- trunk/subversion/libsvn_client/merge.c      Wed Apr 16 13:38:40 2008        (r30643)
>  +++ trunk/subversion/libsvn_client/merge.c      Wed Apr 16 16:09:29 2008        (r30644)
>  @@ -1817,9 +1817,10 @@ populate_remaining_ranges(apr_array_head
>    pool = children_with_mergeinfo->pool;
>    iterpool = svn_pool_create(pool);
>
>  -  /* If we aren't honoring mergeinfo, we'll make quick work of this by
>  -     simply adding dummy REVISION1:REVISION2 ranges for all children. */
>  -  if (! honor_mergeinfo)
>  +  /* If we aren't honoring mergeinfo or this is a --record-only merge,
>  +     we'll make quick work of this by simply adding dummy REVISION1:REVISION2
>  +     ranges for all children. */
>  +  if (! honor_mergeinfo || merge_b->record_only)
>      {
>        for (i = 0; i < children_with_mergeinfo->nelts; i++)
>          {
>  @@ -2539,54 +2540,6 @@ remove_first_range_from_remaining_ranges
>      }
>   }
>
>  -
>  -/* Blindly record the range specified by the user (rather than refining it
>  -   as we do for actual merges) for the merge source URL. */
>  -static svn_error_t *
>  -record_mergeinfo_for_record_only_merge(const char *url,
>  -                                       svn_merge_range_t *range,
>  -                                       const svn_wc_entry_t *entry,
>  -                                       svn_wc_adm_access_t *adm_access,
>  -                                       merge_cmd_baton_t *merge_b,
>  -                                       apr_pool_t *pool)
>  -{
>  -  apr_array_header_t *rangelist;
>  -  const char *rel_path;
>  -  svn_mergeinfo_t target_mergeinfo;
>  -  svn_boolean_t indirect;
>  -  apr_hash_t *merges = apr_hash_make(pool);
>  -  const char *old_url = NULL;
>  -  svn_boolean_t is_rollback = (range->start > range->end);
>  -
>  -  /* Temporarily reparent ra_session to WC target URL. */
>  -  SVN_ERR(svn_client__ensure_ra_session_url(&old_url, merge_b->ra_session1,
>  -                                            entry->url, pool));
>  -  SVN_ERR(svn_client__get_wc_or_repos_mergeinfo(&target_mergeinfo, entry,
>  -                                                &indirect, FALSE,
>  -                                                svn_mergeinfo_inherited,
>  -                                                merge_b->ra_session1,
>  -                                                merge_b->target,
>  -                                                adm_access, merge_b->ctx,
>  -                                                pool));
>  -  if (old_url)
>  -    SVN_ERR(svn_ra_reparent(merge_b->ra_session1, url, pool));
>  -
>  -  SVN_ERR(svn_client__path_relative_to_root(&rel_path, url, NULL, TRUE,
>  -                                            merge_b->ra_session1,
>  -                                            adm_access, pool));
>  -  rangelist = apr_array_make(pool, 1, sizeof(range));
>  -  APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = range;
>  -  apr_hash_set(merges, merge_b->target, APR_HASH_KEY_STRING, rangelist);
>  -
>  -  /* If merge target has indirect mergeinfo set it. */
>  -  if (indirect)
>  -    SVN_ERR(svn_client__record_wc_mergeinfo(merge_b->target, target_mergeinfo,
>  -                                            adm_access, pool));
>  -
>  -  return update_wc_mergeinfo(merge_b->target, entry, rel_path, merges,
>  -                             is_rollback, adm_access, merge_b->ctx, pool);
>  -}
>  -
>   /* Marks 'inheritable' RANGE to TARGET_WCPATH by wiping off the
>     corresponding 'non-inheritable' RANGE from TARGET_MERGEINFO for the
>     merge source REL_PATH.  It does such marking only for same URLs
>  @@ -3959,7 +3912,7 @@ do_file_merge(const char *url1,
>    range.start = revision1;
>    range.end = revision2;
>    range.inheritable = TRUE;
>  -  if (honor_mergeinfo)
>  +  if (honor_mergeinfo && !merge_b->record_only)
>      {
>        const char *source_root_url;
>        svn_mergeinfo_t implicit_mergeinfo;
>  @@ -3997,122 +3950,125 @@ do_file_merge(const char *url1,
>
>    subpool = svn_pool_create(pool);
>
>  -  for (i = 0; i < remaining_ranges->nelts; i++)
>  +  if (!merge_b->record_only)
>      {
>  -      svn_wc_notify_t *n;
>  -      svn_boolean_t header_sent = FALSE;
>  -      svn_error_t *err = SVN_NO_ERROR;
>  -
>  -      /* When using this merge range, account for the exclusivity of
>  -         its low value (which is indicated by this operation being a
>  -         merge vs. revert). */
>  -      svn_merge_range_t *r = APR_ARRAY_IDX(remaining_ranges, i,
>  -                                           svn_merge_range_t *);
>  -
>  -      svn_pool_clear(subpool);
>  -
>  -      n = svn_wc_create_notify(target_wcpath,
>  -                               merge_b->same_repos
>  -                                 ? svn_wc_notify_merge_begin
>  -                                 : svn_wc_notify_foreign_merge_begin,
>  -                               subpool);
>  -      if (merge_b->sources_ancestral)
>  -        n->merge_range = r;
>  -
>  -      /* While we currently don't allow it, in theory we could be
>  -         fetching two fulltexts from two different repositories here. */
>  -      SVN_ERR(single_file_merge_get_file(&tmpfile1, merge_b->ra_session1,
>  -                                         &props1, r->start, target_wcpath,
>  -                                         subpool));
>  -      SVN_ERR(single_file_merge_get_file(&tmpfile2, merge_b->ra_session2,
>  -                                         &props2, r->end, target_wcpath,
>  -                                         subpool));
>  -
>  -      /* Discover any svn:mime-type values in the proplists */
>  -      pval = apr_hash_get(props1, SVN_PROP_MIME_TYPE,
>  -                          strlen(SVN_PROP_MIME_TYPE));
>  -      mimetype1 = pval ? pval->data : NULL;
>  -
>  -      pval = apr_hash_get(props2, SVN_PROP_MIME_TYPE,
>  -                          strlen(SVN_PROP_MIME_TYPE));
>  -      mimetype2 = pval ? pval->data : NULL;
>  -
>  -      /* Deduce property diffs. */
>  -      SVN_ERR(svn_prop_diffs(&propchanges, props2, props1, subpool));
>  -
>  -      /* If we aren't ignoring ancestry, then we've already done
>  -         ancestry relatedness checks.  If we are ignoring ancestry, or
>  -         our sources are known to be related, then we can do
>  -         text-n-props merge; otherwise, we have to do a delete-n-add
>  -         merge.  */
>  -      if (! (merge_b->ignore_ancestry || sources_related))
>  -        {
>  -          /* Delete... */
>  -          SVN_ERR(merge_file_deleted(adm_access,
>  -                                     &text_state,
>  -                                     target_wcpath,
>  -                                     NULL,
>  -                                     NULL,
>  -                                     mimetype1, mimetype2,
>  -                                     props1,
>  -                                     merge_b));
>  -          single_file_merge_notify(notify_b, target_wcpath,
>  -                                   svn_wc_notify_update_delete, text_state,
>  -                                   svn_wc_notify_state_unknown, n,
>  -                                   &header_sent, subpool);
>  -
>  -          /* ...plus add... */
>  -          SVN_ERR(merge_file_added(adm_access,
>  -                                   &text_state, &prop_state,
>  -                                   target_wcpath,
>  -                                   tmpfile1,
>  -                                   tmpfile2,
>  -                                   r->start,
>  -                                   r->end,
>  -                                   mimetype1, mimetype2,
>  -                                   propchanges, props1,
>  -                                   merge_b));
>  -          single_file_merge_notify(notify_b, target_wcpath,
>  -                                   svn_wc_notify_update_add, text_state,
>  -                                   prop_state, n, &header_sent, subpool);
>  -          /* ... equals replace. */
>  -        }
>  -      else
>  +      for (i = 0; i < remaining_ranges->nelts; i++)
>          {
>  -          SVN_ERR(merge_file_changed(adm_access,
>  -                                     &text_state, &prop_state,
>  -                                     target_wcpath,
>  -                                     tmpfile1,
>  -                                     tmpfile2,
>  -                                     r->start,
>  -                                     r->end,
>  -                                     mimetype1, mimetype2,
>  -                                     propchanges, props1,
>  -                                     merge_b));
>  -          single_file_merge_notify(notify_b, target_wcpath,
>  -                                   svn_wc_notify_update_update, text_state,
>  -                                   prop_state, n, &header_sent, subpool);
>  -        }
>  -
>  -      /* Ignore if temporary file not found. It may have been renamed. */
>  -      /* (This is where we complain about missing Lisp, or better yet,
>  -         Python...) */
>  -      err = svn_io_remove_file(tmpfile1, subpool);
>  -      if (err && ! APR_STATUS_IS_ENOENT(err->apr_err))
>  -        return err;
>  -      svn_error_clear(err);
>  -      err = svn_io_remove_file(tmpfile2, subpool);
>  -      if (err && ! APR_STATUS_IS_ENOENT(err->apr_err))
>  -        return err;
>  -      svn_error_clear(err);
>  +          svn_wc_notify_t *n;
>  +          svn_boolean_t header_sent = FALSE;
>  +          svn_error_t *err = SVN_NO_ERROR;
>  +
>  +          /* When using this merge range, account for the exclusivity of
>  +             its low value (which is indicated by this operation being a
>  +             merge vs. revert). */
>  +          svn_merge_range_t *r = APR_ARRAY_IDX(remaining_ranges, i,
>  +                                               svn_merge_range_t *);
>  +
>  +          svn_pool_clear(subpool);
>  +
>  +          n = svn_wc_create_notify(target_wcpath,
>  +                                   merge_b->same_repos
>  +                                     ? svn_wc_notify_merge_begin
>  +                                     : svn_wc_notify_foreign_merge_begin,
>  +                                   subpool);
>  +          if (merge_b->sources_ancestral)
>  +            n->merge_range = r;
>  +
>  +          /* While we currently don't allow it, in theory we could be
>  +             fetching two fulltexts from two different repositories here. */
>  +          SVN_ERR(single_file_merge_get_file(&tmpfile1, merge_b->ra_session1,
>  +                                             &props1, r->start, target_wcpath,
>  +                                             subpool));
>  +          SVN_ERR(single_file_merge_get_file(&tmpfile2, merge_b->ra_session2,
>  +                                             &props2, r->end, target_wcpath,
>  +                                             subpool));
>  +
>  +          /* Discover any svn:mime-type values in the proplists */
>  +          pval = apr_hash_get(props1, SVN_PROP_MIME_TYPE,
>  +                              strlen(SVN_PROP_MIME_TYPE));
>  +          mimetype1 = pval ? pval->data : NULL;
>  +
>  +          pval = apr_hash_get(props2, SVN_PROP_MIME_TYPE,
>  +                              strlen(SVN_PROP_MIME_TYPE));
>  +          mimetype2 = pval ? pval->data : NULL;
>  +
>  +          /* Deduce property diffs. */
>  +          SVN_ERR(svn_prop_diffs(&propchanges, props2, props1, subpool));
>  +
>  +          /* If we aren't ignoring ancestry, then we've already done
>  +             ancestry relatedness checks.  If we are ignoring ancestry, or
>  +             our sources are known to be related, then we can do
>  +             text-n-props merge; otherwise, we have to do a delete-n-add
>  +             merge.  */
>  +          if (! (merge_b->ignore_ancestry || sources_related))
>  +            {
>  +              /* Delete... */
>  +              SVN_ERR(merge_file_deleted(adm_access,
>  +                                         &text_state,
>  +                                         target_wcpath,
>  +                                         NULL,
>  +                                         NULL,
>  +                                         mimetype1, mimetype2,
>  +                                         props1,
>  +                                         merge_b));
>  +              single_file_merge_notify(notify_b, target_wcpath,
>  +                                       svn_wc_notify_update_delete, text_state,
>  +                                       svn_wc_notify_state_unknown, n,
>  +                                       &header_sent, subpool);
>  +
>  +              /* ...plus add... */
>  +              SVN_ERR(merge_file_added(adm_access,
>  +                                       &text_state, &prop_state,
>  +                                       target_wcpath,
>  +                                       tmpfile1,
>  +                                       tmpfile2,
>  +                                       r->start,
>  +                                       r->end,
>  +                                       mimetype1, mimetype2,
>  +                                       propchanges, props1,
>  +                                       merge_b));
>  +              single_file_merge_notify(notify_b, target_wcpath,
>  +                                       svn_wc_notify_update_add, text_state,
>  +                                       prop_state, n, &header_sent, subpool);
>  +              /* ... equals replace. */
>  +            }
>  +          else
>  +            {
>  +              SVN_ERR(merge_file_changed(adm_access,
>  +                                         &text_state, &prop_state,
>  +                                         target_wcpath,
>  +                                         tmpfile1,
>  +                                         tmpfile2,
>  +                                         r->start,
>  +                                         r->end,
>  +                                         mimetype1, mimetype2,
>  +                                         propchanges, props1,
>  +                                         merge_b));
>  +              single_file_merge_notify(notify_b, target_wcpath,
>  +                                       svn_wc_notify_update_update, text_state,
>  +                                       prop_state, n, &header_sent, subpool);
>  +            }
>  +
>  +          /* Ignore if temporary file not found. It may have been renamed. */
>  +          /* (This is where we complain about missing Lisp, or better yet,
>  +             Python...) */
>  +          err = svn_io_remove_file(tmpfile1, subpool);
>  +          if (err && ! APR_STATUS_IS_ENOENT(err->apr_err))
>  +            return err;
>  +          svn_error_clear(err);
>  +          err = svn_io_remove_file(tmpfile2, subpool);
>  +          if (err && ! APR_STATUS_IS_ENOENT(err->apr_err))
>  +            return err;
>  +          svn_error_clear(err);
>
>  -      if ((i < (remaining_ranges->nelts - 1))
>  -          && is_path_conflicted_by_merge(merge_b))
>  -        {
>  -          conflicted_range = r;
>  -          break;
>  +          if ((i < (remaining_ranges->nelts - 1))
>  +              && is_path_conflicted_by_merge(merge_b))
>  +            {
>  +              conflicted_range = r;
>  +              break;
>  +            }
>          }
>  -    }
>  +    } /* !merge_b->record_only */
>
>    /* Record updated WC mergeinfo to account for our new merges, minus
>       any unresolved conflicts and skips. */
>  @@ -4285,7 +4241,7 @@ do_directory_merge(const char *url1,
>                                      ra_session, mergeinfo_path,
>                                      adm_access, merge_b));
>
>  -  if (honor_mergeinfo)
>  +  if (honor_mergeinfo && !merge_b->record_only)
>      {
>        svn_revnum_t start_rev, end_rev;
>
>  @@ -4407,17 +4363,20 @@ do_directory_merge(const char *url1,
>        range.end = revision2;
>        range.inheritable = inheritable;
>
>  -      /* Reset cur_ancestor_index to -1 so that subsequent cherry
>  -         picked revision ranges will be notified upon subsequent
>  -         operative merge. */
>  -      notify_b->cur_ancestor_index = -1;
>  -
>  -      SVN_ERR(drive_merge_report_editor(merge_b->target,
>  -                                        url1, revision1, url2, revision2,
>  -                                        NULL, is_rollback,
>  -                                        depth, notify_b, adm_access,
>  -                                        &merge_callbacks, merge_b,
>  -                                        pool));
>  +      if (!merge_b->record_only)
>  +        {
>  +          /* Reset cur_ancestor_index to -1 so that subsequent cherry
>  +             picked revision ranges will be notified upon subsequent
>  +             operative merge. */
>  +          notify_b->cur_ancestor_index = -1;
>  +
>  +          SVN_ERR(drive_merge_report_editor(merge_b->target,
>  +                                            url1, revision1, url2, revision2,
>  +                                            NULL, is_rollback,
>  +                                            depth, notify_b, adm_access,
>  +                                            &merge_callbacks, merge_b,
>  +                                            pool));
>  +        }
>      }
>
>    /* Record mergeinfo where appropriate.*/
>  @@ -4779,25 +4738,6 @@ do_merge(apr_array_header_t *merge_sourc
>            checked_mergeinfo_capability = TRUE;
>          }
>
>  -      /* If this is a record-only merge and our sources are from the
>  -         same repository as our target, just do the record and move on. */
>  -      if (same_repos && record_only)
>  -        {
>  -          const char *merge_source_url = (rev1 < rev2) ? url2 : url1;
>  -          svn_merge_range_t range;
>  -          range.start = rev1;
>  -          range.end = rev2;
>  -          range.inheritable = TRUE;
>  -          SVN_ERR(record_mergeinfo_for_record_only_merge(merge_source_url,
>  -                                                         &range,
>  -                                                         target_entry,
>  -                                                         adm_access,
>  -                                                         &merge_cmd_baton,
>  -                                                         subpool));
>  -
>  -          continue;
>  -        }
>  -
>        /* Call our merge helpers based on entry kind. */
>        if (target_entry->kind == svn_node_file)
>          {
>
>  ---------------------------------------------------------------------
>  To unsubscribe, e-mail: svn-unsubscribe@subversion.tigris.org
>  For additional commands, e-mail: svn-help@subversion.tigris.org
>
>



-- 
David Glasser | glasser@davidglasser.net | http://www.davidglasser.net/

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org