You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/12/19 19:49:43 UTC
svn commit: r1220893 [3/19] - in /subversion/branches/fs-py: ./ build/
build/ac-macros/ build/generator/ build/generator/templates/ build/win32/
contrib/client-side/emacs/ contrib/server-side/mod_dontdothat/ notes/
subversion/bindings/javahl/native/ su...
Modified: subversion/branches/fs-py/subversion/libsvn_client/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/blame.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/blame.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/blame.c Mon Dec 19 18:49:34 2011
@@ -592,7 +592,6 @@ svn_client_blame5(const char *target,
{
struct file_rev_baton frb;
svn_ra_session_t *ra_session;
- const char *url;
svn_revnum_t start_revnum, end_revnum;
struct blame *walk, *walk_merged = NULL;
apr_pool_t *iterpool;
@@ -611,9 +610,8 @@ svn_client_blame5(const char *target,
SVN_ERR(svn_dirent_get_absolute(&target_abspath_or_url, target, pool));
/* Get an RA plugin for this filesystem object. */
- SVN_ERR(svn_client__ra_session_from_path(&ra_session, &end_revnum,
- &url, target, NULL,
- peg_revision, end,
+ SVN_ERR(svn_client__ra_session_from_path(&ra_session, &end_revnum, NULL,
+ target, NULL, peg_revision, end,
ctx, pool));
SVN_ERR(svn_client__get_revision_number(&start_revnum, NULL, ctx->wc_ctx,
Modified: subversion/branches/fs-py/subversion/libsvn_client/cleanup.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/cleanup.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/cleanup.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/cleanup.c Mon Dec 19 18:49:34 2011
@@ -88,7 +88,7 @@ fetch_repos_info(const char **repos_root
svn_ra_session_t *ra_session;
/* The same info is likely to retrieved multiple times (e.g. externals) */
- if (ri->last_repos && svn_uri__is_child(ri->last_repos, url, scratch_pool))
+ if (ri->last_repos && svn_uri__is_ancestor(ri->last_repos, url))
{
*repos_root = apr_pstrdup(result_pool, ri->last_repos);
*repos_uuid = apr_pstrdup(result_pool, ri->last_uuid);
Modified: subversion/branches/fs-py/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/client.h?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/client.h (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/client.h Mon Dec 19 18:49:34 2011
@@ -105,6 +105,7 @@ svn_error_t *svn_client__get_copy_source
specify the point(s) of interest (typically the revisions referred
to as the "operative range" for a given operation) along that history.
+ START_REVISION and/or END_REVISION may be NULL if not wanted.
END may be NULL or of kind svn_opt_revision_unspecified (in either case
END_URL and END_REVISION are not touched by the function);
START and REVISION may not.
@@ -131,9 +132,9 @@ svn_error_t *svn_client__get_copy_source
Use POOL for all allocations. */
svn_error_t *
svn_client__repos_locations(const char **start_url,
- svn_opt_revision_t **start_revision,
+ svn_revnum_t *start_revision,
const char **end_url,
- svn_opt_revision_t **end_revision,
+ svn_revnum_t *end_revision,
svn_ra_session_t *ra_session,
const char *path,
const svn_opt_revision_t *revision,
@@ -142,6 +143,22 @@ svn_client__repos_locations(const char *
svn_client_ctx_t *ctx,
apr_pool_t *pool);
+/* Trace a line of history of a particular versioned resource back to a
+ * specific revision.
+ *
+ * Set *OP_URL to the URL that the object PEG_URL@PEG_REVNUM had in
+ * revision OP_REVNUM.
+ * RA_SESSION is required. */
+svn_error_t *
+svn_client__repos_location(const char **start_url,
+ svn_ra_session_t *ra_session,
+ const char *peg_url,
+ svn_revnum_t peg_revnum,
+ svn_revnum_t op_revnum,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/* Set *SEGMENTS to an array of svn_location_segment_t * objects, each
representing a reposition location segment for the history of PATH
@@ -168,19 +185,30 @@ svn_client__repos_location_segments(apr_
apr_pool_t *pool);
-/* Set *ANCESTOR_PATH and *ANCESTOR_REVISION to the youngest common
- ancestor path (a path relative to the root of the repository) and
- revision, respectively, of the two locations identified as
- PATH_OR_URL1@REV1 and PATH_OR_URL2@REV1. Use the authentication
- baton cached in CTX to authenticate against the repository.
- This function assumes that PATH_OR_URL1@REV1 and PATH_OR_URL2@REV1
- both refer to the same repository. Use POOL for all allocations. */
+/* Find the common ancestor of two locations in a repository.
+ Ancestry is determined by the 'copy-from' relationship and the normal
+ successor relationship.
+
+ Set *ANCESTOR_RELPATH, *ANCESTOR_URL, and *ANCESTOR_REVISION to the
+ path (relative to the root of the repository, with no leading '/'),
+ URL, and revision, respectively, of the youngest common ancestor of
+ the two locations URL1@REV1 and URL2@REV2. Set *ANCESTOR_RELPATH and
+ *ANCESTOR_URL to NULL and *ANCESTOR_REVISION to SVN_INVALID_REVNUM if
+ they have no common ancestor. This function assumes that URL1@REV1
+ and URL2@REV2 both refer to the same repository.
+
+ Use the authentication baton cached in CTX to authenticate against
+ the repository. Use POOL for all allocations.
+
+ See also svn_client__youngest_common_ancestor().
+*/
svn_error_t *
-svn_client__get_youngest_common_ancestor(const char **ancestor_path,
+svn_client__get_youngest_common_ancestor(const char **ancestor_relpath,
+ const char **ancestor_url,
svn_revnum_t *ancestor_revision,
- const char *path_or_url1,
+ const char *url1,
svn_revnum_t rev1,
- const char *path_or_url2,
+ const char *url2,
svn_revnum_t rev2,
svn_client_ctx_t *ctx,
apr_pool_t *pool);
@@ -197,12 +225,13 @@ svn_client__get_youngest_common_ancestor
and should only be used if PATH_OR_URL is a url
### else NULL? what's it for?
- If PEG_REVISION's kind is svn_opt_revision_unspecified, it is
- interpreted as "head" for a URL or "working" for a working-copy path.
+ If PEG_REVISION->kind is 'unspecified', the peg revision is 'head'
+ for a URL or 'working' for a WC path. If REVISION->kind is
+ 'unspecified', the operative revision is the peg revision.
Store the resulting ra_session in *RA_SESSION_P. Store the actual
revision number of the object in *REV_P, and the final resulting
- URL in *URL_P.
+ URL in *URL_P. REV_P and/or URL_P may be NULL if not wanted.
Use authentication baton cached in CTX to authenticate against the
repository.
@@ -248,30 +277,13 @@ svn_client__ensure_ra_session_url(const
const char *session_url,
apr_pool_t *pool);
-/* Set *REPOS_ROOT and *REPOS_UUID, to the URL and UUID that represent
- the root of the repository in with ABSPATH_OR_URL is versioned.
- Use the authentication baton and working copy context cached in CTX as
- necessary. REPOS_ROOT and/or REPOS_UUID may be NULL if not wanted.
-
- Allocate *REPOS_ROOT and *REPOS_UUID in RESULT_POOL.
- Use SCRATCH_POOL for temporary allocations. */
-svn_error_t *
-svn_client__get_repos_root(const char **repos_root,
- const char **repos_uuid,
- const char *abspath_or_url,
- svn_client_ctx_t *ctx,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
-
/* Return the path of ABSPATH_OR_URL relative to the repository root
- (REPOS_ROOT) in REL_PATH (URI-decoded), both allocated in RESULT_POOL.
+ in REL_PATH (URI-decoded), allocated in RESULT_POOL.
If INCLUDE_LEADING_SLASH is set, the returned result will have a leading
slash; otherwise, it will not.
- The remaining parameters are used to procure the repository root.
- Either REPOS_ROOT or RA_SESSION -- but not both -- may be NULL.
- REPOS_ROOT should be passed when available as an optimization (in
- that order of preference).
+ REPOS_ROOT and RA_SESSION may be NULL if ABSPATH_OR_URL is a WC path,
+ otherwise at least one of them must be non-null.
CAUTION: While having a leading slash on a so-called relative path
might work out well for functionality that interacts with
@@ -401,6 +413,19 @@ svn_error_t * svn_client__wc_delete(cons
svn_client_ctx_t *ctx,
apr_pool_t *pool);
+
+/* Like svn_client__wc_delete(), but deletes mulitple TARGETS efficiently. */
+svn_error_t *
+svn_client__wc_delete_many(const apr_array_header_t *targets,
+ svn_boolean_t force,
+ svn_boolean_t dry_run,
+ svn_boolean_t keep_local,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+
/* Make PATH and add it to the working copy, optionally making all the
intermediate parent directories if MAKE_PARENTS is TRUE. */
svn_error_t *
Modified: subversion/branches/fs-py/subversion/libsvn_client/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/cmdline.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/cmdline.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/cmdline.c Mon Dec 19 18:49:34 2011
@@ -114,8 +114,8 @@ check_root_url_of_target(const char **ro
if (!svn_path_is_url(truepath))
SVN_ERR(svn_dirent_get_absolute(&truepath, truepath, pool));
- err = svn_client__get_repos_root(&tmp_root_url, NULL, truepath,
- ctx, pool, pool);
+ err = svn_client_get_repos_root(&tmp_root_url, NULL, truepath,
+ ctx, pool, pool);
if (err)
{
@@ -347,7 +347,11 @@ svn_client_args_to_target_array2(apr_arr
*/
if (root_url == NULL)
{
- err = svn_client_root_url_from_path(&root_url, "", ctx, pool);
+ const char *current_abspath;
+
+ SVN_ERR(svn_dirent_get_absolute(¤t_abspath, "", pool));
+ err = svn_client_get_repos_root(&root_url, NULL /* uuid */,
+ current_abspath, ctx, pool, pool);
if (err || root_url == NULL)
return svn_error_create(SVN_ERR_WC_NOT_WORKING_COPY, err,
_("Resolving '^/': no repository root "
Modified: subversion/branches/fs-py/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/commit.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/commit.c Mon Dec 19 18:49:34 2011
@@ -145,19 +145,22 @@ send_file_contents(const char *path,
if (svn_subst_translation_required(eol_style, eol, keywords,
FALSE, TRUE))
{
- svn_boolean_t repair = FALSE;
+ if (eol_style == svn_subst_eol_style_unknown)
+ return svn_error_createf(SVN_ERR_IO_UNKNOWN_EOL, NULL,
+ _("%s property on '%s' contains "
+ "unrecognized EOL-style '%s'"),
+ SVN_PROP_EOL_STYLE, path,
+ eol_style_val->data);
+ /* We're importing, so translate files with 'native' eol-style to
+ * repository-normal form, not to this platform's native EOL. */
if (eol_style == svn_subst_eol_style_native)
eol = SVN_SUBST_NATIVE_EOL_STR;
- else if (eol_style == svn_subst_eol_style_fixed)
- repair = TRUE;
- else if (eol_style != svn_subst_eol_style_none)
- return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL, NULL, NULL);
/* Wrap the working copy stream with a filter to detranslate it. */
contents = svn_subst_stream_translated(contents,
eol,
- repair,
+ TRUE /* repair */,
keywords,
FALSE /* expand */,
pool);
@@ -822,7 +825,7 @@ svn_client_import4(const char *path,
ignore_unknown_node_types, ctx, subpool)))
{
svn_error_clear(editor->abort_edit(edit_baton, subpool));
- return err;
+ return svn_error_trace(err);
}
svn_pool_destroy(subpool);
@@ -901,12 +904,11 @@ collect_lock_tokens(apr_hash_t **result,
{
const char *url = svn__apr_hash_index_key(hi);
const char *token = svn__apr_hash_index_val(hi);
+ const char *relpath = svn_uri_skip_ancestor(base_url, url, pool);
- if (svn_uri__is_ancestor(base_url, url))
+ if (relpath)
{
- url = svn_uri_skip_ancestor(base_url, url, pool);
-
- apr_hash_set(*result, url, APR_HASH_KEY_STRING, token);
+ apr_hash_set(*result, relpath, APR_HASH_KEY_STRING, token);
}
}
@@ -1168,12 +1170,113 @@ check_url_kind(void *baton,
kind, scratch_pool));
}
+/* Recurse into every target in REL_TARGETS, finding committable externals
+ * nested within. Append these to REL_TARGETS itself. The paths in REL_TARGETS
+ * are assumed to be / will be created relative to BASE_ABSPATH. The remaining
+ * arguments correspond to those of svn_client_commit6(). */
+static svn_error_t*
+append_externals_as_explicit_targets(apr_array_header_t *rel_targets,
+ const char *base_abspath,
+ svn_boolean_t include_file_externals,
+ svn_boolean_t include_dir_externals,
+ svn_depth_t depth,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ int rel_targets_nelts_fixed;
+ int i;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ /* Easy part of applying DEPTH to externals. */
+ if (depth == svn_depth_empty)
+ {
+ /* Don't recurse. */
+ return SVN_NO_ERROR;
+ }
+ else if (depth != svn_depth_infinity)
+ {
+ include_dir_externals = FALSE;
+ /* We slip in dir externals as explicit targets. When we do that,
+ * depth_immediates should become depth_empty for dir externals targets.
+ * But adding the dir external to the list of targets makes it get
+ * handled with depth_immediates itself, and thus will also include the
+ * immediate children of the dir external. So do dir externals only with
+ * depth_infinity or not at all.
+ * ### TODO: Maybe rework this (and svn_client_commit6()) into separate
+ * ### target lists, "duplicating" REL_TARGETS: one for the user's
+ * ### targets and one for the overlayed externals targets, and pass an
+ * ### appropriate depth for the externals targets in a separate call to
+ * ### svn_client__harvest_committables(). The only gain is correct
+ * ### handling of this very specific case: during 'svn commit
+ * ### --depth=immediates --include-externals', commit dir externals
+ * ### (only immediate children of a target) with depth_empty instead of
+ * ### not at all. No other effect. So not doing that for now. */
+ }
+
+ if (! (include_file_externals || include_dir_externals))
+ return SVN_NO_ERROR;
+
+ /* Iterate *and* grow REL_TARGETS at the same time. */
+ rel_targets_nelts_fixed = rel_targets->nelts;
+
+ for (i = 0; i < rel_targets_nelts_fixed; i++)
+ {
+ int j;
+ const char *target;
+ apr_array_header_t *externals = NULL;
+
+ svn_pool_clear(iterpool);
+
+ target = svn_dirent_join(base_abspath,
+ APR_ARRAY_IDX(rel_targets, i, const char *),
+ iterpool);
+
+ /* ### TODO: Possible optimization: No need to do this for file targets.
+ * ### But what's cheaper, stat'ing the file system or querying the db?
+ * ### --> future. */
+
+ SVN_ERR(svn_wc__committable_externals_below(&externals, ctx->wc_ctx,
+ target, depth,
+ iterpool, iterpool));
+
+ if (externals != NULL)
+ {
+ const char *rel_target;
+
+ for (j = 0; j < externals->nelts; j++)
+ {
+ svn_wc__committable_external_info_t *xinfo =
+ APR_ARRAY_IDX(externals, j,
+ svn_wc__committable_external_info_t *);
+
+ if ((xinfo->kind == svn_kind_file && ! include_file_externals)
+ || (xinfo->kind == svn_kind_dir && ! include_dir_externals))
+ continue;
+
+ rel_target = svn_dirent_skip_ancestor(base_abspath,
+ xinfo->local_abspath);
+
+ SVN_ERR_ASSERT(rel_target != NULL && *rel_target != '\0');
+
+ APR_ARRAY_PUSH(rel_targets, const char *) =
+ apr_pstrdup(result_pool, rel_target);
+ }
+ }
+ }
+
+ svn_pool_destroy(iterpool);
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
-svn_client_commit5(const apr_array_header_t *targets,
+svn_client_commit6(const apr_array_header_t *targets,
svn_depth_t depth,
svn_boolean_t keep_locks,
svn_boolean_t keep_changelists,
svn_boolean_t commit_as_operations,
+ svn_boolean_t include_file_externals,
+ svn_boolean_t include_dir_externals,
const apr_array_header_t *changelists,
const apr_hash_t *revprop_table,
svn_commit_callback2_t commit_callback,
@@ -1233,6 +1336,12 @@ svn_client_commit5(const apr_array_heade
if (rel_targets->nelts == 0)
APR_ARRAY_PUSH(rel_targets, const char *) = "";
+ SVN_ERR(append_externals_as_explicit_targets(rel_targets, base_abspath,
+ include_file_externals,
+ include_dir_externals,
+ depth, ctx,
+ pool, pool));
+
SVN_ERR(determine_lock_targets(&lock_targets, ctx->wc_ctx, base_abspath,
rel_targets, pool, iterpool));
@@ -1603,3 +1712,25 @@ svn_client_commit5(const apr_array_heade
return svn_error_trace(reconcile_errors(cmt_err, unlock_err, bump_err,
pool));
}
+
+svn_error_t *
+svn_client_commit5(const apr_array_header_t *targets,
+ svn_depth_t depth,
+ svn_boolean_t keep_locks,
+ svn_boolean_t keep_changelists,
+ svn_boolean_t commit_as_operations,
+ const apr_array_header_t *changelists,
+ const apr_hash_t *revprop_table,
+ svn_commit_callback2_t commit_callback,
+ void *commit_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ return svn_client_commit6(targets, depth, keep_locks, keep_changelists,
+ commit_as_operations,
+ TRUE, /* include_file_externals */
+ FALSE, /* include_dir_externals */
+ changelists, revprop_table, commit_callback,
+ commit_baton, ctx, pool);
+}
+
Modified: subversion/branches/fs-py/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/commit_util.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/commit_util.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/commit_util.c Mon Dec 19 18:49:34 2011
@@ -410,6 +410,12 @@ bail_on_tree_conflicted_ancestor(svn_wc_
when harvesting committables; that is, don't add a path to
COMMITTABLES unless it's a member of one of those changelists.
+ IS_EXPLICIT_TARGET should always be passed as TRUE, except when
+ harvest_committables() calls itself in recursion. This provides a way to
+ tell whether LOCAL_ABSPATH was an original target or whether it was reached
+ by recursing deeper into a dir target. (This is used to skip all file
+ externals that aren't explicit commit targets.)
+
If CANCEL_FUNC is non-null, call it with CANCEL_BATON to see
if the user has cancelled the operation.
@@ -428,6 +434,7 @@ harvest_committables(svn_wc_context_t *w
apr_hash_t *changelists,
svn_boolean_t skip_files,
svn_boolean_t skip_dirs,
+ svn_boolean_t is_explicit_target,
svn_client__check_url_kind_t check_url_func,
void *check_url_baton,
svn_cancel_func_t cancel_func,
@@ -543,10 +550,24 @@ harvest_committables(svn_wc_context_t *w
svn_dirent_local_style(local_abspath, scratch_pool));
}
- /* ### in need of comment */
- if (copy_mode
- && is_update_root
- && db_kind == svn_node_file)
+ /* Handle file externals.
+ * (IS_UPDATE_ROOT is more generally defined, but at the moment this
+ * condition matches only file externals.)
+ *
+ * Don't copy files that svn:externals brought into the WC. So in copy_mode,
+ * even explicit targets are skipped.
+ *
+ * Exclude file externals from recursion. Hande file externals only when
+ * passed as explicit target. Note that svn_client_commit6() passes all
+ * committable externals in as explicit targets iff they count.
+ *
+ * Also note that dir externals will never be reached recursively by this
+ * function, since svn_wc__node_get_children_of_working_node() (used below
+ * to recurse) does not return switched subdirs. */
+ if (is_update_root
+ && db_kind == svn_node_file
+ && (copy_mode
+ || ! is_explicit_target))
{
return SVN_NO_ERROR;
}
@@ -841,6 +862,7 @@ harvest_committables(svn_wc_context_t *w
changelists,
(depth < svn_depth_files),
(depth < svn_depth_immediates),
+ FALSE, /* IS_EXPLICIT_TARGET */
check_url_func, check_url_baton,
cancel_func, cancel_baton,
notify_func, notify_baton,
@@ -1125,6 +1147,7 @@ svn_client__harvest_committables(svn_cli
FALSE /* COPY_MODE_ROOT */,
depth, just_locked, changelist_hash,
FALSE, FALSE,
+ TRUE /* IS_EXPLICIT_TARGET */,
check_url_func, check_url_baton,
ctx->cancel_func, ctx->cancel_baton,
ctx->notify_func2, ctx->notify_baton2,
@@ -1218,6 +1241,7 @@ harvest_copy_committables(void *baton, v
FALSE, /* JUST_LOCKED */
NULL,
FALSE, FALSE, /* skip files, dirs */
+ TRUE, /* IS_EXPLICIT_TARGET (don't care) */
btn->check_url_func,
btn->check_url_baton,
btn->ctx->cancel_func,
Modified: subversion/branches/fs-py/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/copy.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/copy.c Mon Dec 19 18:49:34 2011
@@ -121,7 +121,7 @@ calculate_target_mergeinfo(svn_ra_sessio
const char *old_session_url = NULL;
SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
ra_session, src_url, pool));
- SVN_ERR(svn_client__get_repos_mergeinfo(ra_session, &src_mergeinfo,
+ SVN_ERR(svn_client__get_repos_mergeinfo(&src_mergeinfo, ra_session,
"", src_revnum,
svn_mergeinfo_inherited,
TRUE, pool));
@@ -150,7 +150,7 @@ extend_wc_mergeinfo(const char *target_a
/* Combine the provided mergeinfo with any mergeinfo from the WC. */
if (wc_mergeinfo && mergeinfo)
- SVN_ERR(svn_mergeinfo_merge(wc_mergeinfo, mergeinfo, pool));
+ SVN_ERR(svn_mergeinfo_merge2(wc_mergeinfo, mergeinfo, pool, pool));
else if (! wc_mergeinfo)
wc_mergeinfo = mergeinfo;
@@ -240,47 +240,41 @@ get_copy_pair_ancestors(const apr_array_
}
-struct do_wc_to_wc_copies_with_write_lock_baton {
- const apr_array_header_t *copy_pairs;
- svn_client_ctx_t *ctx;
- const char *dst_parent;
-};
-
/* The guts of do_wc_to_wc_copies */
static svn_error_t *
-do_wc_to_wc_copies_with_write_lock(void *baton,
- apr_pool_t *result_pool,
+do_wc_to_wc_copies_with_write_lock(const apr_array_header_t *copy_pairs,
+ const char *dst_parent,
+ svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
{
- struct do_wc_to_wc_copies_with_write_lock_baton *b = baton;
int i;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
svn_error_t *err = SVN_NO_ERROR;
- for (i = 0; i < b->copy_pairs->nelts; i++)
+ for (i = 0; i < copy_pairs->nelts; i++)
{
const char *dst_abspath;
- svn_client__copy_pair_t *pair = APR_ARRAY_IDX(b->copy_pairs, i,
+ svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
svn_client__copy_pair_t *);
svn_pool_clear(iterpool);
/* Check for cancellation */
- if (b->ctx->cancel_func)
- SVN_ERR(b->ctx->cancel_func(b->ctx->cancel_baton));
+ if (ctx->cancel_func)
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
/* Perform the copy */
dst_abspath = svn_dirent_join(pair->dst_parent_abspath, pair->base_name,
iterpool);
- err = svn_wc_copy3(b->ctx->wc_ctx, pair->src_abspath_or_url, dst_abspath,
+ err = svn_wc_copy3(ctx->wc_ctx, pair->src_abspath_or_url, dst_abspath,
FALSE /* metadata_only */,
- b->ctx->cancel_func, b->ctx->cancel_baton,
- b->ctx->notify_func2, b->ctx->notify_baton2, iterpool);
+ ctx->cancel_func, ctx->cancel_baton,
+ ctx->notify_func2, ctx->notify_baton2, iterpool);
if (err)
break;
}
svn_pool_destroy(iterpool);
- svn_io_sleep_for_timestamps(b->dst_parent, scratch_pool);
+ svn_io_sleep_for_timestamps(dst_parent, scratch_pool);
SVN_ERR(err);
return SVN_NO_ERROR;
}
@@ -293,7 +287,6 @@ do_wc_to_wc_copies(const apr_array_heade
apr_pool_t *pool)
{
const char *dst_parent, *dst_parent_abspath;
- struct do_wc_to_wc_copies_with_write_lock_baton baton;
SVN_ERR(get_copy_pair_ancestors(copy_pairs, NULL, &dst_parent, NULL, pool));
if (copy_pairs->nelts == 1)
@@ -301,40 +294,31 @@ do_wc_to_wc_copies(const apr_array_heade
SVN_ERR(svn_dirent_get_absolute(&dst_parent_abspath, dst_parent, pool));
- baton.copy_pairs = copy_pairs;
- baton.ctx = ctx;
- baton.dst_parent = dst_parent;
- SVN_ERR(svn_wc__call_with_write_lock(do_wc_to_wc_copies_with_write_lock,
- &baton, ctx->wc_ctx, dst_parent_abspath,
- FALSE, pool, pool));
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ do_wc_to_wc_copies_with_write_lock(copy_pairs, dst_parent, ctx, pool),
+ ctx->wc_ctx, dst_parent_abspath, FALSE, pool);
return SVN_NO_ERROR;
}
-struct do_wc_to_wc_moves_with_locks_baton {
- svn_client_ctx_t *ctx;
- svn_client__copy_pair_t *pair;
- const char *dst_parent_abspath;
- svn_boolean_t lock_src;
- svn_boolean_t lock_dst;
-};
-
/* The locked bit of do_wc_to_wc_moves. */
static svn_error_t *
-do_wc_to_wc_moves_with_locks2(void *baton,
- apr_pool_t *result_pool,
+do_wc_to_wc_moves_with_locks2(svn_client__copy_pair_t *pair,
+ const char *dst_parent_abspath,
+ svn_boolean_t lock_src,
+ svn_boolean_t lock_dst,
+ svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
{
- struct do_wc_to_wc_moves_with_locks_baton *b = baton;
const char *dst_abspath;
- dst_abspath = svn_dirent_join(b->dst_parent_abspath, b->pair->base_name,
+ dst_abspath = svn_dirent_join(dst_parent_abspath, pair->base_name,
scratch_pool);
- SVN_ERR(svn_wc_move(b->ctx->wc_ctx, b->pair->src_abspath_or_url,
+ SVN_ERR(svn_wc_move(ctx->wc_ctx, pair->src_abspath_or_url,
dst_abspath, FALSE /* metadata_only */,
- b->ctx->cancel_func, b->ctx->cancel_baton,
- b->ctx->notify_func2, b->ctx->notify_baton2,
+ ctx->cancel_func, ctx->cancel_baton,
+ ctx->notify_func2, ctx->notify_baton2,
scratch_pool));
return SVN_NO_ERROR;
@@ -342,18 +326,21 @@ do_wc_to_wc_moves_with_locks2(void *bato
/* Wrapper to add an optional second lock */
static svn_error_t *
-do_wc_to_wc_moves_with_locks1(void *baton,
- apr_pool_t *result_pool,
+do_wc_to_wc_moves_with_locks1(svn_client__copy_pair_t *pair,
+ const char *dst_parent_abspath,
+ svn_boolean_t lock_src,
+ svn_boolean_t lock_dst,
+ svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
{
- struct do_wc_to_wc_moves_with_locks_baton *b = baton;
-
- if (b->lock_dst)
- SVN_ERR(svn_wc__call_with_write_lock(do_wc_to_wc_moves_with_locks2, b,
- b->ctx->wc_ctx, b->dst_parent_abspath,
- FALSE, result_pool, scratch_pool));
+ if (lock_dst)
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ do_wc_to_wc_moves_with_locks2(pair, dst_parent_abspath, lock_src,
+ lock_dst, ctx, scratch_pool),
+ ctx->wc_ctx, dst_parent_abspath, FALSE, scratch_pool);
else
- SVN_ERR(do_wc_to_wc_moves_with_locks2(b, result_pool, scratch_pool));
+ SVN_ERR(do_wc_to_wc_moves_with_locks2(pair, dst_parent_abspath, lock_src,
+ lock_dst, ctx, scratch_pool));
return SVN_NO_ERROR;
}
@@ -373,7 +360,7 @@ do_wc_to_wc_moves(const apr_array_header
for (i = 0; i < copy_pairs->nelts; i++)
{
const char *src_parent_abspath;
- struct do_wc_to_wc_moves_with_locks_baton baton;
+ svn_boolean_t lock_src, lock_dst;
svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
svn_client__copy_pair_t *);
@@ -397,32 +384,31 @@ do_wc_to_wc_moves(const apr_array_header
|| svn_dirent_is_child(src_parent_abspath, pair->dst_parent_abspath,
iterpool))
{
- baton.lock_src = TRUE;
- baton.lock_dst = FALSE;
+ lock_src = TRUE;
+ lock_dst = FALSE;
}
else if (svn_dirent_is_child(pair->dst_parent_abspath, src_parent_abspath,
iterpool))
{
- baton.lock_src = FALSE;
- baton.lock_dst = TRUE;
+ lock_src = FALSE;
+ lock_dst = TRUE;
}
else
{
- baton.lock_src = TRUE;
- baton.lock_dst = TRUE;
+ lock_src = TRUE;
+ lock_dst = TRUE;
}
/* Perform the copy and then the delete. */
- baton.ctx = ctx;
- baton.pair = pair;
- baton.dst_parent_abspath = pair->dst_parent_abspath;
- if (baton.lock_src)
- SVN_ERR(svn_wc__call_with_write_lock(do_wc_to_wc_moves_with_locks1,
- &baton,
- ctx->wc_ctx, src_parent_abspath,
- FALSE, iterpool, iterpool));
+ if (lock_src)
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ do_wc_to_wc_moves_with_locks1(pair, pair->dst_parent_abspath,
+ lock_src, lock_dst, ctx, iterpool),
+ ctx->wc_ctx, src_parent_abspath,
+ FALSE, iterpool);
else
- SVN_ERR(do_wc_to_wc_moves_with_locks1(&baton, iterpool, iterpool));
+ SVN_ERR(do_wc_to_wc_moves_with_locks1(pair, pair->dst_parent_abspath,
+ lock_src, lock_dst, ctx, iterpool));
}
svn_pool_destroy(iterpool);
@@ -795,7 +781,6 @@ repos_to_repos_copy(const apr_array_head
svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
svn_client__copy_pair_t *);
apr_hash_t *mergeinfo;
- svn_opt_revision_t *src_rev;
/* Are the source and destination URLs at or under REPOS_ROOT? */
if (! (svn_uri__is_ancestor(repos_root, pair->src_abspath_or_url)
@@ -805,18 +790,11 @@ repos_to_repos_copy(const apr_array_head
_("Source and destination URLs appear not to point to the "
"same repository."));
- /* Resolve revision keywords and such into real revision number,
- passing NULL for the path (to ensure error if trying to get a
- revision based on the working copy). */
- SVN_ERR(svn_client__get_revision_number(&pair->src_revnum, &youngest,
- ctx->wc_ctx, NULL,
- ra_session,
- &pair->src_op_revision, pool));
-
- /* Run the history function to get the source's URL in the
+ /* 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, &src_rev,
+ SVN_ERR(svn_client__repos_locations(&pair->src_abspath_or_url,
+ &pair->src_revnum,
NULL, NULL,
ra_session,
pair->src_abspath_or_url,
@@ -897,8 +875,6 @@ repos_to_repos_copy(const apr_array_head
directories of the destination that don't yet exist. */
if (make_parents)
{
- const char *dir;
-
new_dirs = apr_array_make(pool, 0, sizeof(const char *));
/* If this is a move, TOP_URL is at least the common ancestor of
@@ -921,17 +897,17 @@ repos_to_repos_copy(const apr_array_head
svn copy --parents URL/src URL/dst
- where src exists and dst does not. The svn_uri_dirname()
- call above will produce a string equivalent to TOP_URL,
- which means svn_uri_is_child() will return NULL. In this
- case, do not try to add dst to the NEW_DIRS list since it
+ 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. */
- dir = svn_uri__is_child(
- top_url,
- svn_uri_dirname(first_pair->dst_abspath_or_url, pool),
- pool);
- if (dir)
+ const char *dir = svn_uri_skip_ancestor(
+ top_url,
+ svn_uri_dirname(first_pair->dst_abspath_or_url,
+ pool),
+ pool);
+ if (dir && *dir)
SVN_ERR(find_absent_parents1(ra_session, dir, new_dirs, pool));
}
/* If, however, this is *not* a move, TOP_URL only points to the
@@ -950,8 +926,9 @@ repos_to_repos_copy(const apr_array_head
for (i = 0; i < new_urls->nelts; i++)
{
const char *new_url = APR_ARRAY_IDX(new_urls, i, const char *);
- dir = svn_uri__is_child(top_url, new_url, pool);
- APR_ARRAY_PUSH(new_dirs, const char *) = dir ? dir : "";
+ const char *dir = svn_uri_skip_ancestor(top_url, new_url, pool);
+
+ APR_ARRAY_PUSH(new_dirs, const char *) = dir;
}
}
}
@@ -967,10 +944,12 @@ repos_to_repos_copy(const apr_array_head
svn_client__copy_pair_t *);
path_driver_info_t *info = APR_ARRAY_IDX(path_infos, i,
path_driver_info_t *);
+ const char *relpath = svn_uri_skip_ancestor(pair->dst_abspath_or_url,
+ pair->src_abspath_or_url,
+ pool);
if ((strcmp(pair->dst_abspath_or_url, repos_root) != 0)
- && (svn_uri__is_child(pair->dst_abspath_or_url,
- pair->src_abspath_or_url, pool) != NULL))
+ && (relpath != NULL && *relpath != '\0'))
{
info->resurrection = TRUE;
top_url = svn_uri_dirname(top_url, pool);
@@ -1021,9 +1000,7 @@ repos_to_repos_copy(const apr_array_head
/* Figure out the basename that will result from this operation,
and ensure that we aren't trying to overwrite existing paths. */
- dst_rel = svn_uri__is_child(top_url, pair->dst_abspath_or_url, pool);
- if (! dst_rel)
- dst_rel = "";
+ dst_rel = svn_uri_skip_ancestor(top_url, pair->dst_abspath_or_url, pool);
SVN_ERR(svn_ra_check_path(ra_session, dst_rel, youngest,
&dst_kind, pool));
if (dst_kind != svn_node_none)
@@ -1277,9 +1254,8 @@ wc_to_repos_copy(const apr_array_header_
APR_ARRAY_IDX(copy_pairs, i, svn_client__copy_pair_t *);
svn_pool_clear(iterpool);
- dst_rel = svn_uri__is_child(top_dst_url,
- pair->dst_abspath_or_url,
- iterpool);
+ dst_rel = svn_uri_skip_ancestor(top_dst_url, pair->dst_abspath_or_url,
+ iterpool);
SVN_ERR(svn_ra_check_path(ra_session, dst_rel, SVN_INVALID_REVNUM,
&dst_kind, iterpool));
if (dst_kind != svn_node_none)
@@ -1400,7 +1376,8 @@ wc_to_repos_copy(const apr_array_header_
pair->src_abspath_or_url,
iterpool, iterpool));
if (wc_mergeinfo && mergeinfo)
- SVN_ERR(svn_mergeinfo_merge(mergeinfo, wc_mergeinfo, iterpool));
+ SVN_ERR(svn_mergeinfo_merge2(mergeinfo, wc_mergeinfo, iterpool,
+ iterpool));
else if (! mergeinfo)
mergeinfo = wc_mergeinfo;
if (mergeinfo)
@@ -1745,8 +1722,9 @@ repos_to_wc_copy_locked(const apr_array_
parent = top_dst_path;
SVN_ERR(svn_dirent_get_absolute(&parent_abspath, parent, scratch_pool));
- dst_err = svn_client_uuid_from_path2(&dst_uuid, parent_abspath, ctx,
- scratch_pool, scratch_pool);
+ dst_err = svn_client_get_repos_root(NULL /* root_url */, &dst_uuid,
+ parent_abspath, ctx,
+ scratch_pool, scratch_pool);
if (dst_err && dst_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)
return dst_err;
@@ -1781,29 +1759,6 @@ repos_to_wc_copy_locked(const apr_array_
return SVN_NO_ERROR;
}
-struct repos_to_wc_copy_baton {
- const apr_array_header_t *copy_pairs;
- const char *top_dst_path;
- svn_boolean_t ignore_externals;
- svn_ra_session_t *ra_session;
- svn_client_ctx_t *ctx;
-};
-
-/* Implements svn_wc__with_write_lock_func_t. */
-static svn_error_t *
-repos_to_wc_copy_cb(void *baton,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- struct repos_to_wc_copy_baton *b = baton;
-
- SVN_ERR(repos_to_wc_copy_locked(b->copy_pairs, b->top_dst_path,
- b->ignore_externals, b->ra_session,
- b->ctx, scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
static svn_error_t *
repos_to_wc_copy(const apr_array_header_t *copy_pairs,
svn_boolean_t make_parents,
@@ -1815,7 +1770,6 @@ repos_to_wc_copy(const apr_array_header_
const char *top_src_url, *top_dst_path;
apr_pool_t *iterpool = svn_pool_create(pool);
const char *lock_abspath;
- struct repos_to_wc_copy_baton baton;
int i;
/* Get the real path for the source, based upon its peg revision. */
@@ -1824,11 +1778,10 @@ repos_to_wc_copy(const apr_array_header_
svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
svn_client__copy_pair_t *);
const char *src;
- svn_opt_revision_t *new_rev;
svn_pool_clear(iterpool);
- SVN_ERR(svn_client__repos_locations(&src, &new_rev, NULL, NULL,
+ SVN_ERR(svn_client__repos_locations(&src, &pair->src_revnum, NULL, NULL,
NULL,
pair->src_abspath_or_url,
&pair->src_peg_revision,
@@ -1855,18 +1808,6 @@ repos_to_wc_copy(const apr_array_header_
NULL, NULL, FALSE, TRUE,
ctx, pool));
- /* Pass null for the path, to ensure error if trying to get a
- revision based on the working copy. */
- 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 *);
-
- SVN_ERR(svn_client__get_revision_number(&pair->src_revnum, NULL,
- ctx->wc_ctx, NULL, ra_session,
- &pair->src_op_revision, pool));
- }
-
/* Get the correct src path for the peg revision used, and verify that we
aren't overwriting an existing path. */
for (i = 0; i < copy_pairs->nelts; i++)
@@ -1928,15 +1869,10 @@ repos_to_wc_copy(const apr_array_header_
}
svn_pool_destroy(iterpool);
- baton.copy_pairs = copy_pairs;
- baton.top_dst_path = top_dst_path;
- baton.ignore_externals = ignore_externals;
- baton.ra_session = ra_session;
- baton.ctx = ctx;
-
- SVN_ERR(svn_wc__call_with_write_lock(repos_to_wc_copy_cb, &baton,
- ctx->wc_ctx, lock_abspath,
- FALSE, pool, pool));
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ repos_to_wc_copy_locked(copy_pairs, top_dst_path, ignore_externals,
+ ra_session, ctx, pool),
+ ctx->wc_ctx, lock_abspath, FALSE, pool);
return SVN_NO_ERROR;
}
Modified: subversion/branches/fs-py/subversion/libsvn_client/delete.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/delete.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/delete.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/delete.c Mon Dec 19 18:49:34 2011
@@ -237,7 +237,7 @@ delete_urls_multi_repos(const apr_array_
for (hi = apr_hash_first(pool, sessions); hi; hi = apr_hash_next(hi))
{
repos_root = svn__apr_hash_index_key(hi);
- repos_relpath = svn_uri__is_child(repos_root, uri, pool);
+ repos_relpath = svn_uri_skip_ancestor(repos_root, uri, pool);
if (repos_relpath)
{
@@ -264,7 +264,7 @@ delete_urls_multi_repos(const apr_array_
SVN_ERR(svn_ra_reparent(ra_session, repos_root, pool));
apr_hash_set(sessions, repos_root, APR_HASH_KEY_STRING, ra_session);
- repos_relpath = svn_uri__is_child(repos_root, uri, pool);
+ repos_relpath = svn_uri_skip_ancestor(repos_root, uri, pool);
relpaths_list = apr_array_make(pool, 1, sizeof(const char *));
apr_hash_set(relpaths, repos_root, APR_HASH_KEY_STRING,
@@ -272,6 +272,12 @@ delete_urls_multi_repos(const apr_array_
APR_ARRAY_PUSH(relpaths_list, const char *) = repos_relpath;
}
+ /* Check we identified a non-root relpath. Return an RA error
+ code for 1.6 compatibility. */
+ if (!repos_relpath || !*repos_relpath)
+ return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+ "URL '%s' not within a repository", uri);
+
/* Now, test to see if the thing actually exists. */
SVN_ERR(svn_ra_check_path(ra_session, repos_relpath, SVN_INVALID_REVNUM,
&kind, pool));
@@ -329,29 +335,43 @@ svn_client__wc_delete(const char *path,
return SVN_NO_ERROR;
}
-/* Callback baton for delete_with_write_lock_baton. */
-struct delete_with_write_lock_baton
-{
- const char *path;
- svn_boolean_t force;
- svn_boolean_t keep_local;
- svn_client_ctx_t *ctx;
-};
-
-/* Implements svn_wc__with_write_lock_func_t. */
-static svn_error_t *
-delete_with_write_lock_func(void *baton,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_error_t *
+svn_client__wc_delete_many(const apr_array_header_t *targets,
+ svn_boolean_t force,
+ svn_boolean_t dry_run,
+ svn_boolean_t keep_local,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
{
- struct delete_with_write_lock_baton *args = baton;
+ int i;
+ apr_array_header_t *abs_targets;
+
+ abs_targets = apr_array_make(pool, targets->nelts, sizeof(const char *));
+ for (i = 0; i < targets->nelts; i++)
+ {
+ const char *path = APR_ARRAY_IDX(targets, i, const char *);
+ const char *local_abspath;
+
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
+ APR_ARRAY_PUSH(abs_targets, const char *) = local_abspath;
+
+ if (!force && !keep_local)
+ /* Verify that there are no "awkward" files */
+ SVN_ERR(svn_client__can_delete(local_abspath, ctx, pool));
+ }
+
+ if (!dry_run)
+ /* Mark the entry for commit deletion and perform wc deletion */
+ return svn_error_trace(svn_wc__delete_many(ctx->wc_ctx, abs_targets,
+ keep_local, TRUE,
+ ctx->cancel_func,
+ ctx->cancel_baton,
+ notify_func, notify_baton,
+ pool));
- /* Let the working copy library handle the PATH. */
- return svn_client__wc_delete(args->path, args->force,
- FALSE, args->keep_local,
- args->ctx->notify_func2,
- args->ctx->notify_baton2,
- args->ctx, scratch_pool);
+ return SVN_NO_ERROR;
}
svn_error_t *
@@ -379,32 +399,75 @@ svn_client_delete4(const apr_array_heade
}
else
{
- apr_pool_t *subpool = svn_pool_create(pool);
+ const char *local_abspath;
+ apr_hash_t *wcroots;
+ apr_hash_index_t *hi;
int i;
-
+ int j;
+ apr_pool_t *iterpool;
+ svn_boolean_t is_new_target;
+
+ /* Build a map of wcroots and targets within them. */
+ wcroots = apr_hash_make(pool);
+ iterpool = svn_pool_create(pool);
for (i = 0; i < paths->nelts; i++)
{
- struct delete_with_write_lock_baton dwwlb;
- const char *path = APR_ARRAY_IDX(paths, i, const char *);
- const char *local_abspath;
+ const char *wcroot_abspath;
+ apr_array_header_t *targets;
- svn_pool_clear(subpool);
+ svn_pool_clear(iterpool);
/* See if the user wants us to stop. */
if (ctx->cancel_func)
SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, subpool));
- dwwlb.path = path;
- dwwlb.force = force;
- dwwlb.keep_local = keep_local;
- dwwlb.ctx = ctx;
- SVN_ERR(svn_wc__call_with_write_lock(delete_with_write_lock_func,
- &dwwlb, ctx->wc_ctx,
- local_abspath, TRUE,
- pool, subpool));
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath,
+ APR_ARRAY_IDX(paths, i,
+ const char *),
+ pool));
+ SVN_ERR(svn_wc__get_wc_root(&wcroot_abspath, ctx->wc_ctx,
+ local_abspath, pool, iterpool));
+ targets = apr_hash_get(wcroots, wcroot_abspath,
+ APR_HASH_KEY_STRING);
+ if (targets == NULL)
+ {
+ targets = apr_array_make(pool, 1, sizeof(const char *));
+ apr_hash_set(wcroots, wcroot_abspath, APR_HASH_KEY_STRING,
+ targets);
+ }
+
+ /* Make sure targets are unique. */
+ is_new_target = TRUE;
+ for (j = 0; j < targets->nelts; j++)
+ {
+ if (strcmp(APR_ARRAY_IDX(targets, j, const char *),
+ local_abspath) == 0)
+ {
+ is_new_target = FALSE;
+ break;
+ }
+ }
+
+ if (is_new_target)
+ APR_ARRAY_PUSH(targets, const char *) = local_abspath;
+ }
+
+ /* Delete the targets from each working copy in turn. */
+ for (hi = apr_hash_first(pool, wcroots); hi; hi = apr_hash_next(hi))
+ {
+ const char *wcroot_abspath = svn__apr_hash_index_key(hi);
+ const apr_array_header_t *targets = svn__apr_hash_index_val(hi);
+
+ svn_pool_clear(iterpool);
+
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ svn_client__wc_delete_many(targets, force, FALSE, keep_local,
+ ctx->notify_func2, ctx->notify_baton2,
+ ctx, iterpool),
+ ctx->wc_ctx, wcroot_abspath, TRUE /* lock_anchor */,
+ iterpool);
}
- svn_pool_destroy(subpool);
+ svn_pool_destroy(iterpool);
}
return SVN_NO_ERROR;
Modified: subversion/branches/fs-py/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/deprecated.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/deprecated.c Mon Dec 19 18:49:34 2011
@@ -39,10 +39,12 @@
#include "svn_props.h"
#include "svn_utf.h"
#include "svn_string.h"
+#include "svn_pools.h"
#include "client.h"
#include "mergeinfo.h"
+#include "private/svn_opt_private.h"
#include "private/svn_wc_private.h"
#include "svn_private_config.h"
@@ -1361,16 +1363,11 @@ svn_client_log4(const apr_array_header_t
apr_pool_t *pool)
{
apr_array_header_t *revision_ranges;
- svn_opt_revision_range_t *range;
-
- range = apr_palloc(pool, sizeof(svn_opt_revision_range_t));
- range->start = *start;
- range->end = *end;
revision_ranges = apr_array_make(pool, 1,
sizeof(svn_opt_revision_range_t *));
-
- APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *) = range;
+ APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
+ = svn_opt__revision_range_create(start, end, pool);
return svn_client_log5(targets, peg_revision, revision_ranges, limit,
discover_changed_paths, strict_node_history,
@@ -1576,13 +1573,11 @@ svn_client_merge_peg2(const char *source
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- svn_opt_revision_range_t range;
apr_array_header_t *ranges_to_merge =
apr_array_make(pool, 1, sizeof(svn_opt_revision_range_t *));
- range.start = *revision1;
- range.end = *revision2;
- APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *) = ⦥
+ APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *)
+ = svn_opt__revision_range_create(revision1, revision2, pool);
return svn_client_merge_peg3(source, ranges_to_merge,
peg_revision,
target_wcpath,
@@ -2464,6 +2459,41 @@ svn_client_revert(const apr_array_header
/*** From ra.c ***/
svn_error_t *
+svn_client_uuid_from_url(const char **uuid,
+ const char *url,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ svn_ra_session_t *ra_session;
+ apr_pool_t *subpool = svn_pool_create(pool);
+
+ /* use subpool to create a temporary RA session */
+ SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL, url,
+ NULL, /* no base dir */
+ NULL, FALSE, TRUE,
+ ctx, subpool));
+
+ SVN_ERR(svn_ra_get_uuid2(ra_session, uuid, pool));
+
+ /* destroy the RA session */
+ svn_pool_destroy(subpool);
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_uuid_from_path2(const char **uuid,
+ const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_trace(
+ svn_wc__node_get_repos_info(NULL, uuid, ctx->wc_ctx, local_abspath,
+ result_pool, scratch_pool));
+}
+
+svn_error_t *
svn_client_uuid_from_path(const char **uuid,
const char *path,
svn_wc_adm_access_t *adm_access,
@@ -2479,6 +2509,20 @@ svn_client_uuid_from_path(const char **u
/*** From url.c ***/
svn_error_t *
+svn_client_root_url_from_path(const char **url,
+ const char *path_or_url,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ if (!svn_path_is_url(path_or_url))
+ SVN_ERR(svn_dirent_get_absolute(&path_or_url, path_or_url, pool));
+
+ return svn_error_trace(
+ svn_client_get_repos_root(url, NULL, path_or_url,
+ ctx, pool, pool));
+}
+
+svn_error_t *
svn_client_url_from_path(const char **url,
const char *path_or_url,
apr_pool_t *pool)