Author: hwright
Date: Tue Apr 19 20:33:21 2011
New Revision: 1095195
URL: http://svn.apache.org/viewvc?rev=1095195&view=rev
Log:
Make the libsvn_client propset API operate on an array of targets, rather than
just one.
Note: This will probably choke the JavaHL bindings.
* subversion/svn/propdel-cmd.c
(svn_cl__propdel): Don't iterate over the targets, just pass 'em down.
* subversion/svn/propset-cmd.c
(svn_cl__propset): Same.
* subversion/svn/propedit-cmd.c
(svn_cl__propedit): Wrap the single target in an array.
* subversion/libsvn_client/deprecated.c
(svn_client_propset3): Same.
* subversion/include/svn_client.h
(svn_client_propset4): Update targets param to be an array. Update docs.
* subversion/libsvn_client/prop_commands.c
(svn_client_propset4): Take an array of targets, and verify they are
homogeneous. Loop over them for either ra or working copy mods.
Modified:
subversion/trunk/subversion/include/svn_client.h
subversion/trunk/subversion/libsvn_client/deprecated.c
subversion/trunk/subversion/libsvn_client/prop_commands.c
subversion/trunk/subversion/svn/propdel-cmd.c
subversion/trunk/subversion/svn/propedit-cmd.c
subversion/trunk/subversion/svn/propset-cmd.c
Modified: subversion/trunk/subversion/include/svn_client.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1095195&r1=1095194&r2=1095195&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Tue Apr 19 20:33:21 2011
@@ -4115,20 +4115,21 @@ svn_client_move(svn_client_commit_info_t
/**
- * Set @a propname to @a propval on @a target.
+ * Set @a propname to @a propval on @a targets.
* A @a propval of @c NULL will delete the property.
*
- * If @a depth is #svn_depth_empty, set the property on @a target
- * only; if #svn_depth_files, set it on @a target and its file
- * children (if any); if #svn_depth_immediates, on @a target and all
- * of its immediate children (both files and directories); if
- * #svn_depth_infinity, on @a target and everything beneath it.
+ * If @a depth is #svn_depth_empty, set the property on each member of
+ * @a targets only; if #svn_depth_files, set it on @a targets and their file
+ * children (if any); if #svn_depth_immediates, on @a targets and all
+ * of their immediate children (both files and directories); if
+ * #svn_depth_infinity, on @a targets and everything beneath them.
*
- * The @a target may only be an URL if @a base_revision_for_url is not
+ * Targets must either be all working copy paths or URLs. The @a targets may
+ * only be an URL if @a base_revision_for_url is not
* #SVN_INVALID_REVNUM; in this case, the property will only be set
* if it has not changed since revision @a base_revision_for_url.
- * @a base_revision_for_url must be #SVN_INVALID_REVNUM if @a target
- * is not an URL. @a depth deeper than #svn_depth_empty is not
+ * @a base_revision_for_url must be #SVN_INVALID_REVNUM if @a targets
+ * are not URLs. @a depth deeper than #svn_depth_empty is not
* supported on URLs. The authentication baton in @a ctx and @a
* ctx->log_msg_func3/@a ctx->log_msg_baton3 will be used to
* immediately attempt to commit the property change in the
@@ -4140,8 +4141,8 @@ svn_client_move(svn_client_commit_info_t
*
* If @a skip_checks is TRUE, do no validity checking. But if @a
* skip_checks is FALSE, and @a propname is not a valid property for @a
- * target, return an error, either #SVN_ERR_ILLEGAL_TARGET (if the
- * property is not appropriate for @a target), or
+ * targets, return an error, either #SVN_ERR_ILLEGAL_TARGET (if the
+ * property is not appropriate for @a targets), or
* #SVN_ERR_BAD_MIME_TYPE (if @a propname is "svn:mime-type", but @a
* propval is not a valid mime-type).
*
@@ -4171,7 +4172,7 @@ svn_client_move(svn_client_commit_info_t
svn_error_t *
svn_client_propset4(const char *propname,
const svn_string_t *propval,
- const char *target,
+ const apr_array_header_t *targets,
svn_depth_t depth,
svn_boolean_t skip_checks,
svn_revnum_t base_revision_for_url,
Modified: subversion/trunk/subversion/libsvn_client/deprecated.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/deprecated.c?rev=1095195&r1=1095194&r2=1095195&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_client/deprecated.c Tue Apr 19 20:33:21
2011
@@ -1536,11 +1536,14 @@ svn_client_propset3(svn_commit_info_t **
apr_pool_t *pool)
{
struct capture_baton_t cb;
+ apr_array_header_t *targets = apr_array_make(pool, 1, sizeof(const char *));
+
+ APR_ARRAY_PUSH(targets, const char *) = target;
cb.info = commit_info_p;
cb.pool = pool;
- return svn_client_propset4(propname, propval, target, depth, skip_checks,
+ return svn_client_propset4(propname, propval, targets, depth, skip_checks,
base_revision_for_url, changelists, revprop_table,
capture_commit_info, &cb, ctx, pool);
}
Modified: subversion/trunk/subversion/libsvn_client/prop_commands.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/prop_commands.c?rev=1095195&r1=1095194&r2=1095195&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/prop_commands.c (original)
+++ subversion/trunk/subversion/libsvn_client/prop_commands.c Tue Apr 19
20:33:21 2011
@@ -343,7 +343,7 @@ set_props_cb(void *baton,
svn_error_t *
svn_client_propset4(const char *propname,
const svn_string_t *propval,
- const char *target,
+ const apr_array_header_t *targets,
svn_depth_t depth,
svn_boolean_t skip_checks,
svn_revnum_t base_revision_for_url,
@@ -354,6 +354,23 @@ svn_client_propset4(const char *propname
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
+ svn_boolean_t targets_are_urls;
+ int i;
+
+ if (targets->nelts == 0)
+ return SVN_NO_ERROR;
+
+ /* Check for homogeneity among our targets. */
+ targets_are_urls = svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *));
+ for (i = 1; i < targets->nelts; i++)
+ {
+ const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+ if (svn_path_is_url(target) != targets_are_urls)
+ return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+ _("Cannot mix repository and working copy paths"));
+ }
+
/* Since Subversion controls the "svn:" property namespace, we
don't honor the 'skip_checks' flag here. Unusual property
combinations, like svn:eol-style with a non-text svn:mime-type,
@@ -370,21 +387,21 @@ svn_client_propset4(const char *propname
return svn_error_createf(SVN_ERR_CLIENT_PROPERTY_NAME, NULL,
_("Bad property name: '%s'"), propname);
- if (svn_path_is_url(target))
+ if (targets_are_urls)
{
/* The rationale for requiring the base_revision_for_url
argument is that without it, it's too easy to possibly
overwrite someone else's change without noticing. (See also
tools/examples/svnput.c). */
if (! SVN_IS_VALID_REVNUM(base_revision_for_url))
- return svn_error_createf(SVN_ERR_CLIENT_BAD_REVISION, NULL,
- _("Setting property on non-local target '%s' "
- "needs a base revision"), target);
+ return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL,
+ _("Setting property on non-local targets "
+ "needs a base revision"));
if (depth > svn_depth_empty)
- return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
- _("Setting property recursively on non-local "
- "target '%s' is not supported"), target);
+ return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+ _("Setting property recursively on non-local "
+ "targets is not supported"));
/* ### When you set svn:eol-style or svn:keywords on a wc file,
### Subversion sends a textdelta at commit time to properly
@@ -398,54 +415,81 @@ svn_client_propset4(const char *propname
if ((strcmp(propname, SVN_PROP_EOL_STYLE) == 0) ||
(strcmp(propname, SVN_PROP_KEYWORDS) == 0))
return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
- _("Setting property '%s' on non-local target "
- "'%s' is not supported"), propname, target);
+ _("Setting property '%s' on non-local "
+ "targets is not supported"), propname);
+
+ for (i = 0; i < targets->nelts; i++)
+ {
+ const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+ SVN_ERR(propset_on_url(propname, propval, target, skip_checks,
+ base_revision_for_url, revprop_table,
+ commit_callback, commit_baton, ctx, pool));
+ }
- return propset_on_url(propname, propval, target, skip_checks,
- base_revision_for_url, revprop_table,
- commit_callback, commit_baton, ctx, pool);
+ return SVN_NO_ERROR;
}
else
{
- svn_node_kind_t kind;
apr_hash_t *changelist_hash = NULL;
- const char *target_abspath;
- svn_error_t *err;
- struct set_props_baton baton;
-
- SVN_ERR(svn_dirent_get_absolute(&target_abspath, target, pool));
+ apr_pool_t *iterpool = svn_pool_create(pool);
if (changelists && changelists->nelts)
SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash,
changelists, pool));
- err = svn_wc_read_kind(&kind, ctx->wc_ctx, target_abspath, FALSE, pool);
-
- if ((err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
- || kind == svn_node_unknown || kind == svn_node_none)
+ for (i = 0; i < targets->nelts; i++)
{
- /* svn uses SVN_ERR_UNVERSIONED_RESOURCE as warning only
- for this function. */
- return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, err,
- _("'%s' is not under version control"),
- svn_dirent_local_style(target_abspath,
- pool));
- }
- else
- SVN_ERR(err);
+ svn_node_kind_t kind;
+ const char *target_abspath;
+ svn_error_t *err;
+ struct set_props_baton baton;
+ const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+ svn_pool_clear(iterpool);
+
+ /* Check for cancellation */
+ if (ctx->cancel_func)
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
- baton.ctx = ctx;
- baton.local_abspath = target_abspath;
- baton.depth = depth;
- baton.kind = kind;
- baton.propname = propname;
- baton.propval = propval;
- baton.skip_checks = skip_checks;
- baton.changelist_hash = changelist_hash;
-
- SVN_ERR(svn_wc__call_with_write_lock(set_props_cb, &baton,
- ctx->wc_ctx, target_abspath, FALSE,
- pool, pool));
+ SVN_ERR(svn_dirent_get_absolute(&target_abspath, target, iterpool));
+
+ err = svn_wc_read_kind(&kind, ctx->wc_ctx, target_abspath, FALSE,
+ iterpool);
+
+ if ((err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ || kind == svn_node_unknown || kind == svn_node_none)
+ {
+ if (ctx->notify_func2)
+ {
+ svn_wc_notify_t *notify = svn_wc_create_notify(
+ target_abspath,
+ svn_wc_notify_warning,
+ iterpool);
+
+ notify->err = err;
+ ctx->notify_func2(ctx->notify_baton2, notify, iterpool);
+ }
+
+ svn_error_clear(err);
+ }
+ else
+ SVN_ERR(err);
+
+ baton.ctx = ctx;
+ baton.local_abspath = target_abspath;
+ baton.depth = depth;
+ baton.kind = kind;
+ baton.propname = propname;
+ baton.propval = propval;
+ baton.skip_checks = skip_checks;
+ baton.changelist_hash = changelist_hash;
+
+ SVN_ERR(svn_wc__call_with_write_lock(set_props_cb, &baton,
+ ctx->wc_ctx, target_abspath,
+ FALSE, iterpool, iterpool));
+ }
+ svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/svn/propdel-cmd.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/propdel-cmd.c?rev=1095195&r1=1095194&r2=1095195&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/propdel-cmd.c (original)
+++ subversion/trunk/subversion/svn/propdel-cmd.c Tue Apr 19 20:33:21 2011
@@ -90,36 +90,17 @@ svn_cl__propdel(apr_getopt_t *os,
}
else /* operate on a normal, versioned property (not a revprop) */
{
- apr_pool_t *subpool = svn_pool_create(pool);
- int i;
-
if (opt_state->depth == svn_depth_unknown)
opt_state->depth = svn_depth_empty;
/* For each target, remove the property PNAME. */
- for (i = 0; i < targets->nelts; i++)
- {
- const char *target = APR_ARRAY_IDX(targets, i, const char *);
-
- svn_pool_clear(subpool);
- SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
-
- /* Pass FALSE for 'skip_checks' because it doesn't matter here,
- and opt_state->force doesn't apply to this command anyway. */
- SVN_ERR(svn_cl__try(svn_client_propset4(
- pname_utf8,
- NULL, target,
- opt_state->depth,
- FALSE, SVN_INVALID_REVNUM,
- opt_state->changelists, NULL,
- svn_cl__print_commit_info, NULL,
- ctx, subpool),
- NULL, opt_state->quiet,
- SVN_ERR_UNVERSIONED_RESOURCE,
- SVN_ERR_ENTRY_NOT_FOUND,
- SVN_NO_ERROR));
- }
- svn_pool_destroy(subpool);
+ SVN_ERR(svn_client_propset4(pname_utf8,
+ NULL, targets,
+ opt_state->depth,
+ FALSE, SVN_INVALID_REVNUM,
+ opt_state->changelists, NULL,
+ svn_cl__print_commit_info, NULL,
+ ctx, pool));
}
return SVN_NO_ERROR;
Modified: subversion/trunk/subversion/svn/propedit-cmd.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/propedit-cmd.c?rev=1095195&r1=1095194&r2=1095195&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/propedit-cmd.c (original)
+++ subversion/trunk/subversion/svn/propedit-cmd.c Tue Apr 19 20:33:21 2011
@@ -287,6 +287,8 @@ svn_cl__propedit(apr_getopt_t *os,
if (edited_propval && !svn_string_compare(propval, edited_propval))
{
svn_error_t *err = SVN_NO_ERROR;
+ apr_array_header_t *targs = apr_array_make(subpool, 1,
+ sizeof(const char *));
svn_cl__check_boolean_prop_val(pname_utf8, edited_propval->data,
subpool);
@@ -296,7 +298,8 @@ svn_cl__propedit(apr_getopt_t *os,
opt_state, NULL,
ctx->config,
subpool));
- err = svn_client_propset4(pname_utf8, edited_propval, target,
+ APR_ARRAY_PUSH(targs, const char *) = target;
+ err = svn_client_propset4(pname_utf8, edited_propval, targs,
svn_depth_empty, opt_state->force,
base_rev, NULL,
opt_state->revprop_table,
commit_info_handler, &cib,
Modified: subversion/trunk/subversion/svn/propset-cmd.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/propset-cmd.c?rev=1095195&r1=1095194&r2=1095195&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/propset-cmd.c (original)
+++ subversion/trunk/subversion/svn/propset-cmd.c Tue Apr 19 20:33:21 2011
@@ -130,7 +130,6 @@ svn_cl__propset(apr_getopt_t *os,
}
else /* operate on a normal, versioned property (not a revprop) */
{
- apr_pool_t *iterpool;
int i;
if (opt_state->depth == svn_depth_unknown)
@@ -172,43 +171,20 @@ svn_cl__propset(apr_getopt_t *os,
}
}
- iterpool = svn_pool_create(scratch_pool);
+ SVN_ERR(svn_client_propset4(pname_utf8, propval, targets,
+ opt_state->depth, opt_state->force,
+ SVN_INVALID_REVNUM, opt_state->changelists,
+ NULL, svn_cl__print_commit_info, NULL, ctx,
+ scratch_pool));
+
for (i = 0; i < targets->nelts; i++)
{
const char *target = APR_ARRAY_IDX(targets, i, const char *);
- svn_error_t *err;
-
- svn_pool_clear(iterpool);
- SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
-
- err = svn_client_propset4(
- pname_utf8, propval, target,
- opt_state->depth, opt_state->force,
- SVN_INVALID_REVNUM, opt_state->changelists,
- NULL, svn_cl__print_commit_info, NULL, ctx,
- iterpool);
- if (err && (err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE
- || err->apr_err == SVN_ERR_ENTRY_NOT_FOUND) )
- {
- if (! opt_state->quiet)
- {
- svn_wc_notify_t *notify = svn_wc_create_notify(NULL,
- svn_wc_notify_warning,
- iterpool);
-
- notify->err = err;
- ctx->notify_func2(ctx->notify_baton, notify, iterpool);
- }
-
- svn_error_clear(err);
- }
- else if (err)
- return err;
if (! opt_state->quiet)
- svn_cl__check_boolean_prop_val(pname_utf8, propval->data,
iterpool);
+ svn_cl__check_boolean_prop_val(pname_utf8, propval->data,
+ scratch_pool);
}
- svn_pool_destroy(iterpool);
}
return SVN_NO_ERROR;