blob: e3fffdcaf0db436c295afd98965e0ef348ba07b1 [file] [log] [blame]
/*
* cleanup.c: wrapper around wc cleanup functionality.
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
/* ==================================================================== */
/*** Includes. ***/
#include "svn_time.h"
#include "svn_wc.h"
#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_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)
{
SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
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(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));
return SVN_NO_ERROR;
}