Index: subversion/include/svn_client.h =================================================================== --- subversion/include/svn_client.h (revision 7591) +++ subversion/include/svn_client.h (working copy) @@ -918,6 +918,32 @@ apr_pool_t *pool); +/** Restore the pristine version of each working copy named in @a paths, + * effectively undoing any local mods. If any of those paths is a + * directory and @a recursive is @a true, it will be reverted + * recursively. + * + * If @a ctx->notify_func is non-null, then for each item reverted, call + * @a ctx->notify_func with @a ctx->notify_baton and the path of the reverted + * item. + * + * If any path is not found and @a ctx->notify_func is non-null, + * then @a ctx->notify_func will be called with @a ctx->notify_baton + * and each nonexistent path, with kind @a svn_wc_notify_skip. + * Regardless of the state of ctx->notify_func, this will not + * cause an error to be returned and will not prevent processing + * of subsequent paths in the list. + * + * After each path has been processed, @a ctx->cancel_func is called + * with @a ctx->cancel_baton provided @a ctx->cancel_func is non-null. + */ +svn_error_t * +svn_client_revert_list (apr_array_header_t *paths, + svn_boolean_t recursive, + svn_client_ctx_t *ctx, + apr_pool_t *pool); + + /** Remove the 'conflicted' state on a working copy @a path. This will * not semantically resolve conflicts; it just allows @a path to be * committed in the future. The implementation details are opaque. Index: subversion/libsvn_client/revert.c =================================================================== --- subversion/libsvn_client/revert.c (revision 7591) +++ subversion/libsvn_client/revert.c (working copy) @@ -36,11 +36,15 @@ /*** Code. ***/ -svn_error_t * -svn_client_revert (const char *path, - svn_boolean_t recursive, - svn_client_ctx_t *ctx, - apr_pool_t *pool) + +/** The core of svn_client_revert and svn_client_revert_list. + * Reverts a single path. + */ +static svn_error_t * +revert_1 (const char *path, + svn_boolean_t recursive, + svn_client_ctx_t *ctx, + apr_pool_t *pool) { svn_wc_adm_access_t *adm_access; svn_boolean_t wc_root; @@ -107,9 +111,82 @@ out: SVN_ERR (svn_wc_adm_close (adm_access)); + return err; +} + +svn_error_t * +svn_client_revert (const char *path, + svn_boolean_t recursive, + svn_client_ctx_t *ctx, + apr_pool_t *pool) +{ + svn_error_t * err = revert_1 (path, recursive, ctx, pool); + /* Sleep to ensure timestamp integrity. */ svn_sleep_for_timestamps (); return err; } + + +/** Revert a list of paths. The @a pool is private to @a revert_n, + * which may clear it at will. It will be destroyed (by a wrapper + * function) on exit. + */ +static svn_error_t * +revert_n (apr_array_header_t *paths, + svn_boolean_t recursive, + svn_client_ctx_t *ctx, + apr_pool_t *pool) +{ + int i; + + for (i = 0; i < paths->nelts; i++) + { + const char *path = ((const char **) (paths->elts))[i]; + svn_error_t * err; + + svn_pool_clear (pool); + + err = revert_1 (path, recursive, ctx, pool); + + if (err) + { + if (err->apr_err != SVN_ERR_ENTRY_NOT_FOUND) + return err; + + if (ctx->notify_func) + ctx->notify_func (ctx->notify_baton, path, + svn_wc_notify_skip, + svn_node_none, NULL, + svn_wc_notify_state_missing, + svn_wc_notify_state_missing, + SVN_INVALID_REVNUM); + svn_error_clear (err); + } + + if (ctx->cancel_func) + SVN_ERR (ctx->cancel_func (ctx->cancel_baton)); + } + + return SVN_NO_ERROR; +} + + +svn_error_t * +svn_client_revert_list (apr_array_header_t *paths, + svn_boolean_t recursive, + svn_client_ctx_t *ctx, + apr_pool_t *pool) +{ + apr_pool_t * subpool = svn_pool_create (pool); + svn_error_t * err = revert_n (paths, recursive, ctx, subpool); + + svn_pool_destroy (subpool); + + /* Sleep to ensure timestamp integrity. */ + svn_sleep_for_timestamps (); + + return err; +} Index: subversion/clients/cmdline/revert-cmd.c =================================================================== --- subversion/clients/cmdline/revert-cmd.c (revision 7591) +++ subversion/clients/cmdline/revert-cmd.c (working copy) @@ -44,7 +44,6 @@ apr_array_header_t *targets; int i; svn_boolean_t recursive = opt_state->recursive; - apr_pool_t *subpool; SVN_ERR (svn_opt_args_to_target_array (&targets, os, opt_state->targets, @@ -60,31 +59,5 @@ svn_cl__get_notifier (&ctx->notify_func, &ctx->notify_baton, FALSE, FALSE, FALSE, pool); - subpool = svn_pool_create (pool); - for (i = 0; i < targets->nelts; i++) - { - const char *target = ((const char **) (targets->elts))[i]; - svn_error_t *err; - - err = svn_client_revert (target, recursive, ctx, subpool); - if (err) - { - if (err->apr_err == SVN_ERR_ENTRY_NOT_FOUND) - { - if (!opt_state->quiet) - { - svn_handle_warning (stderr, err); - } - continue; - } - else - return err; - } - - SVN_ERR (svn_cl__check_cancel (ctx->cancel_baton)); - svn_pool_clear (subpool); - } - - svn_pool_destroy (subpool); - return SVN_NO_ERROR; + return svn_client_revert_list(targets, recursive, ctx, pool); }