1/* 2 * cleanup.c: wrapper around wc cleanup functionality. 3 * 4 * ==================================================================== 5 * Licensed to the Apache Software Foundation (ASF) under one 6 * or more contributor license agreements. See the NOTICE file 7 * distributed with this work for additional information 8 * regarding copyright ownership. The ASF licenses this file 9 * to you under the Apache License, Version 2.0 (the 10 * "License"); you may not use this file except in compliance 11 * with the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, 16 * software distributed under the License is distributed on an 17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18 * KIND, either express or implied. See the License for the 19 * specific language governing permissions and limitations 20 * under the License. 21 * ==================================================================== 22 */ 23 24/* ==================================================================== */ 25 26 27 28/*** Includes. ***/ 29 30#include "svn_time.h" 31#include "svn_wc.h" 32#include "svn_client.h" 33#include "svn_config.h" 34#include "svn_dirent_uri.h" 35#include "svn_hash.h" 36#include "svn_path.h" 37#include "svn_pools.h" 38#include "client.h" 39#include "svn_props.h" 40 41#include "svn_private_config.h" 42#include "private/svn_wc_private.h" 43 44 45/*** Code. ***/ 46 47struct cleanup_status_walk_baton 48{ 49 svn_boolean_t break_locks; 50 svn_boolean_t fix_timestamps; 51 svn_boolean_t clear_dav_cache; 52 svn_boolean_t vacuum_pristines; 53 svn_boolean_t remove_unversioned_items; 54 svn_boolean_t remove_ignored_items; 55 svn_boolean_t include_externals; 56 svn_client_ctx_t *ctx; 57}; 58 59/* Forward declararion. */ 60static svn_error_t * 61cleanup_status_walk(void *baton, 62 const char *local_abspath, 63 const svn_wc_status3_t *status, 64 apr_pool_t *scratch_pool); 65 66static svn_error_t * 67do_cleanup(const char *local_abspath, 68 svn_boolean_t break_locks, 69 svn_boolean_t fix_timestamps, 70 svn_boolean_t clear_dav_cache, 71 svn_boolean_t vacuum_pristines, 72 svn_boolean_t remove_unversioned_items, 73 svn_boolean_t remove_ignored_items, 74 svn_boolean_t include_externals, 75 svn_client_ctx_t *ctx, 76 apr_pool_t *scratch_pool) 77{ 78 SVN_ERR(svn_wc_cleanup4(ctx->wc_ctx, 79 local_abspath, 80 break_locks, 81 fix_timestamps, 82 clear_dav_cache, 83 vacuum_pristines, 84 ctx->cancel_func, ctx->cancel_baton, 85 ctx->notify_func2, ctx->notify_baton2, 86 scratch_pool)); 87 88 if (fix_timestamps) 89 svn_io_sleep_for_timestamps(local_abspath, scratch_pool); 90 91 if (remove_unversioned_items || remove_ignored_items || include_externals) 92 { 93 struct cleanup_status_walk_baton b; 94 apr_array_header_t *ignores; 95 96 b.break_locks = break_locks; 97 b.fix_timestamps = fix_timestamps; 98 b.clear_dav_cache = clear_dav_cache; 99 b.vacuum_pristines = vacuum_pristines; 100 b.remove_unversioned_items = remove_unversioned_items; 101 b.remove_ignored_items = remove_ignored_items; 102 b.include_externals = include_externals; 103 b.ctx = ctx; 104 105 SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, scratch_pool)); 106 107 SVN_WC__CALL_WITH_WRITE_LOCK( 108 svn_wc_walk_status(ctx->wc_ctx, local_abspath, 109 svn_depth_infinity, 110 TRUE, /* get all */ 111 remove_ignored_items, 112 TRUE, /* ignore textmods */ 113 ignores, 114 cleanup_status_walk, &b, 115 ctx->cancel_func, 116 ctx->cancel_baton, 117 scratch_pool), 118 ctx->wc_ctx, 119 local_abspath, 120 FALSE /* lock_anchor */, 121 scratch_pool); 122 } 123 124 return SVN_NO_ERROR; 125} 126 127 128/* An implementation of svn_wc_status_func4_t. */ 129static svn_error_t * 130cleanup_status_walk(void *baton, 131 const char *local_abspath, 132 const svn_wc_status3_t *status, 133 apr_pool_t *scratch_pool) 134{ 135 struct cleanup_status_walk_baton *b = baton; 136 svn_node_kind_t kind_on_disk; 137 svn_wc_notify_t *notify; 138 139 if (status->node_status == svn_wc_status_external && b->include_externals) 140 { 141 svn_error_t *err; 142 143 SVN_ERR(svn_io_check_path(local_abspath, &kind_on_disk, scratch_pool)); 144 if (kind_on_disk == svn_node_dir) 145 { 146 if (b->ctx->notify_func2) 147 { 148 notify = svn_wc_create_notify(local_abspath, 149 svn_wc_notify_cleanup_external, 150 scratch_pool); 151 b->ctx->notify_func2(b->ctx->notify_baton2, notify, 152 scratch_pool); 153 } 154 155 err = do_cleanup(local_abspath, 156 b->break_locks, 157 b->fix_timestamps, 158 b->clear_dav_cache, 159 b->vacuum_pristines, 160 b->remove_unversioned_items, 161 b->remove_ignored_items, 162 TRUE /* include_externals */, 163 b->ctx, scratch_pool); 164 if (err && err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY) 165 { 166 svn_error_clear(err); 167 return SVN_NO_ERROR; 168 } 169 else 170 SVN_ERR(err); 171 } 172 173 return SVN_NO_ERROR; 174 } 175 176 if (status->node_status == svn_wc_status_ignored) 177 { 178 if (!b->remove_ignored_items) 179 return SVN_NO_ERROR; 180 } 181 else if (status->node_status == svn_wc_status_unversioned) 182 { 183 if (!b->remove_unversioned_items) 184 return SVN_NO_ERROR; 185 } 186 else 187 return SVN_NO_ERROR; 188 189 SVN_ERR(svn_io_check_path(local_abspath, &kind_on_disk, scratch_pool)); 190 switch (kind_on_disk) 191 { 192 case svn_node_file: 193 case svn_node_symlink: 194 SVN_ERR(svn_io_remove_file2(local_abspath, FALSE, scratch_pool)); 195 break; 196 case svn_node_dir: 197 SVN_ERR(svn_io_remove_dir2(local_abspath, FALSE, 198 b->ctx->cancel_func, b->ctx->cancel_baton, 199 scratch_pool)); 200 break; 201 case svn_node_none: 202 default: 203 return SVN_NO_ERROR; 204 } 205 206 if (b->ctx->notify_func2) 207 { 208 notify = svn_wc_create_notify(local_abspath, svn_wc_notify_delete, 209 scratch_pool); 210 notify->kind = kind_on_disk; 211 b->ctx->notify_func2(b->ctx->notify_baton2, notify, scratch_pool); 212 } 213 214 return SVN_NO_ERROR; 215} 216 217svn_error_t * 218svn_client_cleanup2(const char *dir_abspath, 219 svn_boolean_t break_locks, 220 svn_boolean_t fix_recorded_timestamps, 221 svn_boolean_t clear_dav_cache, 222 svn_boolean_t vacuum_pristines, 223 svn_boolean_t include_externals, 224 svn_client_ctx_t *ctx, 225 apr_pool_t *scratch_pool) 226{ 227 SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath)); 228 229 SVN_ERR(do_cleanup(dir_abspath, 230 break_locks, 231 fix_recorded_timestamps, 232 clear_dav_cache, 233 vacuum_pristines, 234 FALSE /* remove_unversioned_items */, 235 FALSE /* remove_ignored_items */, 236 include_externals, 237 ctx, scratch_pool)); 238 239 return SVN_NO_ERROR; 240} 241 242svn_error_t * 243svn_client_vacuum(const char *dir_abspath, 244 svn_boolean_t remove_unversioned_items, 245 svn_boolean_t remove_ignored_items, 246 svn_boolean_t fix_recorded_timestamps, 247 svn_boolean_t vacuum_pristines, 248 svn_boolean_t include_externals, 249 svn_client_ctx_t *ctx, 250 apr_pool_t *scratch_pool) 251{ 252 SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath)); 253 254 SVN_ERR(do_cleanup(dir_abspath, 255 FALSE /* break_locks */, 256 fix_recorded_timestamps, 257 FALSE /* clear_dav_cache */, 258 vacuum_pristines, 259 remove_unversioned_items, 260 remove_ignored_items, 261 include_externals, 262 ctx, scratch_pool)); 263 264 return SVN_NO_ERROR; 265} 266