diff options
Diffstat (limited to 'subversion/libsvn_client/cleanup.c')
-rw-r--r-- | subversion/libsvn_client/cleanup.c | 228 |
1 files changed, 215 insertions, 13 deletions
diff --git a/subversion/libsvn_client/cleanup.c b/subversion/libsvn_client/cleanup.c index b15e824d3490..e3fffdcaf0db 100644 --- a/subversion/libsvn_client/cleanup.c +++ b/subversion/libsvn_client/cleanup.c @@ -32,32 +32,234 @@ #include "svn_client.h" #include "svn_config.h" #include "svn_dirent_uri.h" +#include "svn_hash.h" #include "svn_path.h" #include "svn_pools.h" #include "client.h" #include "svn_props.h" #include "svn_private_config.h" +#include "private/svn_wc_private.h" /*** Code. ***/ +struct cleanup_status_walk_baton +{ + svn_boolean_t break_locks; + svn_boolean_t fix_timestamps; + svn_boolean_t clear_dav_cache; + svn_boolean_t vacuum_pristines; + svn_boolean_t remove_unversioned_items; + svn_boolean_t remove_ignored_items; + svn_boolean_t include_externals; + svn_client_ctx_t *ctx; +}; + +/* Forward declararion. */ +static svn_error_t * +cleanup_status_walk(void *baton, + const char *local_abspath, + const svn_wc_status3_t *status, + apr_pool_t *scratch_pool); + +static svn_error_t * +do_cleanup(const char *local_abspath, + svn_boolean_t break_locks, + svn_boolean_t fix_timestamps, + svn_boolean_t clear_dav_cache, + svn_boolean_t vacuum_pristines, + svn_boolean_t remove_unversioned_items, + svn_boolean_t remove_ignored_items, + svn_boolean_t include_externals, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool) +{ + SVN_ERR(svn_wc_cleanup4(ctx->wc_ctx, + local_abspath, + break_locks, + fix_timestamps, + clear_dav_cache, + vacuum_pristines, + ctx->cancel_func, ctx->cancel_baton, + ctx->notify_func2, ctx->notify_baton2, + scratch_pool)); + + if (fix_timestamps) + svn_io_sleep_for_timestamps(local_abspath, scratch_pool); + + if (remove_unversioned_items || remove_ignored_items || include_externals) + { + struct cleanup_status_walk_baton b; + apr_array_header_t *ignores; + + b.break_locks = break_locks; + b.fix_timestamps = fix_timestamps; + b.clear_dav_cache = clear_dav_cache; + b.vacuum_pristines = vacuum_pristines; + b.remove_unversioned_items = remove_unversioned_items; + b.remove_ignored_items = remove_ignored_items; + b.include_externals = include_externals; + b.ctx = ctx; + + SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, scratch_pool)); + + SVN_WC__CALL_WITH_WRITE_LOCK( + svn_wc_walk_status(ctx->wc_ctx, local_abspath, + svn_depth_infinity, + TRUE, /* get all */ + remove_ignored_items, + TRUE, /* ignore textmods */ + ignores, + cleanup_status_walk, &b, + ctx->cancel_func, + ctx->cancel_baton, + scratch_pool), + ctx->wc_ctx, + local_abspath, + FALSE /* lock_anchor */, + scratch_pool); + } + + return SVN_NO_ERROR; +} + + +/* An implementation of svn_wc_status_func4_t. */ +static svn_error_t * +cleanup_status_walk(void *baton, + const char *local_abspath, + const svn_wc_status3_t *status, + apr_pool_t *scratch_pool) +{ + struct cleanup_status_walk_baton *b = baton; + svn_node_kind_t kind_on_disk; + svn_wc_notify_t *notify; + + if (status->node_status == svn_wc_status_external && b->include_externals) + { + svn_error_t *err; + + SVN_ERR(svn_io_check_path(local_abspath, &kind_on_disk, scratch_pool)); + if (kind_on_disk == svn_node_dir) + { + if (b->ctx->notify_func2) + { + notify = svn_wc_create_notify(local_abspath, + svn_wc_notify_cleanup_external, + scratch_pool); + b->ctx->notify_func2(b->ctx->notify_baton2, notify, + scratch_pool); + } + + err = do_cleanup(local_abspath, + b->break_locks, + b->fix_timestamps, + b->clear_dav_cache, + b->vacuum_pristines, + b->remove_unversioned_items, + b->remove_ignored_items, + TRUE /* include_externals */, + b->ctx, scratch_pool); + if (err && err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY) + { + svn_error_clear(err); + return SVN_NO_ERROR; + } + else + SVN_ERR(err); + } + + return SVN_NO_ERROR; + } + + if (status->node_status == svn_wc_status_ignored) + { + if (!b->remove_ignored_items) + return SVN_NO_ERROR; + } + else if (status->node_status == svn_wc_status_unversioned) + { + if (!b->remove_unversioned_items) + return SVN_NO_ERROR; + } + else + return SVN_NO_ERROR; + + SVN_ERR(svn_io_check_path(local_abspath, &kind_on_disk, scratch_pool)); + switch (kind_on_disk) + { + case svn_node_file: + case svn_node_symlink: + SVN_ERR(svn_io_remove_file2(local_abspath, FALSE, scratch_pool)); + break; + case svn_node_dir: + SVN_ERR(svn_io_remove_dir2(local_abspath, FALSE, + b->ctx->cancel_func, b->ctx->cancel_baton, + scratch_pool)); + break; + case svn_node_none: + default: + return SVN_NO_ERROR; + } + + if (b->ctx->notify_func2) + { + notify = svn_wc_create_notify(local_abspath, svn_wc_notify_delete, + scratch_pool); + notify->kind = kind_on_disk; + b->ctx->notify_func2(b->ctx->notify_baton2, notify, scratch_pool); + } + + return SVN_NO_ERROR; +} + svn_error_t * -svn_client_cleanup(const char *path, - svn_client_ctx_t *ctx, - apr_pool_t *scratch_pool) +svn_client_cleanup2(const char *dir_abspath, + svn_boolean_t break_locks, + svn_boolean_t fix_recorded_timestamps, + svn_boolean_t clear_dav_cache, + svn_boolean_t vacuum_pristines, + svn_boolean_t include_externals, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool) { - const char *local_abspath; - svn_error_t *err; + SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath)); - if (svn_path_is_url(path)) - return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL, - _("'%s' is not a local path"), path); + SVN_ERR(do_cleanup(dir_abspath, + break_locks, + fix_recorded_timestamps, + clear_dav_cache, + vacuum_pristines, + FALSE /* remove_unversioned_items */, + FALSE /* remove_ignored_items */, + include_externals, + ctx, scratch_pool)); + + return SVN_NO_ERROR; +} + +svn_error_t * +svn_client_vacuum(const char *dir_abspath, + svn_boolean_t remove_unversioned_items, + svn_boolean_t remove_ignored_items, + svn_boolean_t fix_recorded_timestamps, + svn_boolean_t vacuum_pristines, + svn_boolean_t include_externals, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool) +{ + SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath)); - SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool)); + SVN_ERR(do_cleanup(dir_abspath, + FALSE /* break_locks */, + fix_recorded_timestamps, + FALSE /* clear_dav_cache */, + vacuum_pristines, + remove_unversioned_items, + remove_ignored_items, + include_externals, + ctx, scratch_pool)); - err = svn_wc_cleanup3(ctx->wc_ctx, local_abspath, ctx->cancel_func, - ctx->cancel_baton, scratch_pool); - svn_io_sleep_for_timestamps(path, scratch_pool); - return svn_error_trace(err); + return SVN_NO_ERROR; } |