Alien-SVN

 view release on metacpan or  search on metacpan

src/subversion/subversion/libsvn_client/copy.c  view on Meta::CPAN

        return svn_error_create
          (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
           _("Source and destination URLs appear not to point to the "
             "same repository."));

      /* Run the history function to get the source's URL and revnum in the
         operational revision. */
      SVN_ERR(svn_ra_reparent(ra_session, pair->src_abspath_or_url, pool));
      SVN_ERR(svn_client__repos_locations(&pair->src_abspath_or_url,
                                          &pair->src_revnum,
                                          NULL, NULL,
                                          ra_session,
                                          pair->src_abspath_or_url,
                                          &pair->src_peg_revision,
                                          &pair->src_op_revision, NULL,
                                          ctx, pool));

      /* Go ahead and grab mergeinfo from the source, too. */
      SVN_ERR(svn_ra_reparent(ra_session, pair->src_abspath_or_url, pool));
      SVN_ERR(svn_client__get_repos_mergeinfo(
                &mergeinfo, ra_session,
                pair->src_abspath_or_url, pair->src_revnum,
                svn_mergeinfo_inherited, TRUE /*squelch_incapable*/, pool));
      if (mergeinfo)
        SVN_ERR(svn_mergeinfo_to_string(&info->mergeinfo, mergeinfo, pool));

      /* Plop an INFO structure onto our array thereof. */
      info->src_url = pair->src_abspath_or_url;
      info->src_revnum = pair->src_revnum;
      info->resurrection = FALSE;
      APR_ARRAY_PUSH(path_infos, path_driver_info_t *) = info;
    }

  /* If this is a move, we have to open our session to the longest
     path common to all SRC_URLS and DST_URLS in the repository so we
     can do existence checks on all paths, and so we can operate on
     all paths in the case of a move.  But if this is *not* a move,
     then opening our session at the longest path common to sources
     *and* destinations might be an optimization when the user is
     authorized to access all that stuff, but could cause the
     operation to fail altogether otherwise.  See issue #3242.  */
  SVN_ERR(get_copy_pair_ancestors(copy_pairs, NULL, &top_url_dst, &top_url_all,
                                  pool));
  top_url = is_move ? top_url_all : top_url_dst;

  /* Check each src/dst pair for resurrection, and verify that TOP_URL
     is anchored high enough to cover all the editor_t activities
     required for this operation.  */
  for (i = 0; i < copy_pairs->nelts; i++)
    {
      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);
      path_driver_info_t *info = APR_ARRAY_IDX(path_infos, i,
                                               path_driver_info_t *);

      /* Source and destination are the same?  It's a resurrection. */
      if (strcmp(pair->src_abspath_or_url, pair->dst_abspath_or_url) == 0)
        info->resurrection = TRUE;

      /* We need to add each dst_URL, and (in a move) we'll need to
         delete each src_URL.  Our selection of TOP_URL so far ensures
         that all our destination URLs (and source URLs, for moves)
         are at least as deep as TOP_URL, but we need to make sure
         that TOP_URL is an *ancestor* of all our to-be-edited paths.

         Issue #683 is demonstrates this scenario.  If you're
         resurrecting a deleted item like this: 'svn cp -rN src_URL
         dst_URL', then src_URL == dst_URL == top_url.  In this
         situation, we want to open an RA session to be at least the
         *parent* of all three. */
      if ((strcmp(top_url, pair->dst_abspath_or_url) == 0)
          && (strcmp(top_url, repos_root) != 0))
        {
          top_url = svn_uri_dirname(top_url, pool);
        }
      if (is_move
          && (strcmp(top_url, pair->src_abspath_or_url) == 0)
          && (strcmp(top_url, repos_root) != 0))
        {
          top_url = svn_uri_dirname(top_url, pool);
        }
    }

  /* Point the RA session to our current TOP_URL. */
  SVN_ERR(svn_ra_reparent(ra_session, top_url, pool));

  /* If we're allowed to create nonexistent parent directories of our
     destinations, then make a list in NEW_DIRS of the parent
     directories of the destination that don't yet exist.  */
  if (make_parents)
    {
      new_dirs = apr_array_make(pool, 0, sizeof(const char *));

      /* If this is a move, TOP_URL is at least the common ancestor of
         all the paths (sources and destinations) involved.  Assuming
         the sources exist (which is fair, because if they don't, this
         whole operation will fail anyway), TOP_URL must also exist.
         So it's the paths between TOP_URL and the destinations which
         we have to check for existence.  But here, we take advantage
         of the knowledge of our caller.  We know that if there are
         multiple copy/move operations being requested, then the
         destinations of the copies/moves will all be siblings of one
         another.  Therefore, we need only to check for the
         nonexistent paths between TOP_URL and *one* of our
         destinations to find nonexistent parents of all of them.  */
      if (is_move)
        {
          /* Imagine a situation where the user tries to copy an
             existing source directory to nonexistent directory with
             --parents options specified:

                svn copy --parents URL/src URL/dst

             where src exists and dst does not.  If the dirname of the
             destination path is equal to TOP_URL,
             do not try to add dst to the NEW_DIRS list since it
             will be added to the commit items array later in this
             function. */
          const char *dir = svn_uri_skip_ancestor(
                              top_url,
                              svn_uri_dirname(first_pair->dst_abspath_or_url,



( run in 0.440 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )