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 )