cleanup.c revision 289166
156160Sru/* 256160Sru * cleanup.c: handle cleaning up workqueue items 356160Sru * 456160Sru * ==================================================================== 556160Sru * Licensed to the Apache Software Foundation (ASF) under one 656160Sru * or more contributor license agreements. See the NOTICE file 756160Sru * distributed with this work for additional information 856160Sru * regarding copyright ownership. The ASF licenses this file 956160Sru * to you under the Apache License, Version 2.0 (the 1056160Sru * "License"); you may not use this file except in compliance 1156160Sru * with the License. You may obtain a copy of the License at 1256160Sru * 1356160Sru * http://www.apache.org/licenses/LICENSE-2.0 1456160Sru * 1556160Sru * Unless required by applicable law or agreed to in writing, 1656160Sru * software distributed under the License is distributed on an 1756160Sru * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1856160Sru * KIND, either express or implied. See the License for the 1956160Sru * specific language governing permissions and limitations 2056160Sru * under the License. 2156160Sru * ==================================================================== 2256160Sru */ 2356160Sru 2456160Sru 2556160Sru 2656160Sru#include <string.h> 2756160Sru 2856160Sru#include "svn_wc.h" 2956160Sru#include "svn_error.h" 3056160Sru#include "svn_pools.h" 3156160Sru#include "svn_io.h" 3256160Sru#include "svn_dirent_uri.h" 3356160Sru 3456160Sru#include "wc.h" 3556160Sru#include "adm_files.h" 3656160Sru#include "lock.h" 3756160Sru#include "workqueue.h" 3856160Sru 3956160Sru#include "private/svn_wc_private.h" 4056160Sru#include "svn_private_config.h" 4156160Sru 4256160Sru 4356160Sru/*** Recursively do log things. ***/ 4456160Sru 4556160Sru/* */ 4656160Srustatic svn_error_t * 4756160Srucan_be_cleaned(int *wc_format, 4856160Sru svn_wc__db_t *db, 4956160Sru const char *local_abspath, 5056160Sru apr_pool_t *scratch_pool) 5156160Sru{ 5256160Sru SVN_ERR(svn_wc__internal_check_wc(wc_format, db, 5356160Sru local_abspath, FALSE, scratch_pool)); 5456160Sru 5556160Sru /* a "version" of 0 means a non-wc directory */ 5656160Sru if (*wc_format == 0) 5756160Sru return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL, 5856160Sru _("'%s' is not a working copy directory"), 5956160Sru svn_dirent_local_style(local_abspath, 6056160Sru scratch_pool)); 6156160Sru 6256160Sru if (*wc_format < SVN_WC__WC_NG_VERSION) 6356160Sru return svn_error_create(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL, 6456160Sru _("Log format too old, please use " 6556160Sru "Subversion 1.6 or earlier")); 6656160Sru 6756160Sru return SVN_NO_ERROR; 6856160Sru} 6956160Sru 7056160Sru/* Dummy svn_wc_status_func4_t implementation */ 7156160Srustatic svn_error_t * 7256160Srustatus_dummy_callback(void *baton, 7356160Sru const char *local_abspath, 7456160Sru const svn_wc_status3_t *status, 7556160Sru apr_pool_t *scratch_pool) 7656160Sru{ 7756160Sru return SVN_NO_ERROR; 7856160Sru} 7956160Sru 8056160Sru/* */ 8156160Srustatic svn_error_t * 8256160Srucleanup_internal(svn_wc__db_t *db, 8356160Sru const char *dir_abspath, 8456160Sru svn_cancel_func_t cancel_func, 8556160Sru void *cancel_baton, 8656160Sru apr_pool_t *scratch_pool) 8756160Sru{ 8856160Sru int wc_format; 8956160Sru svn_boolean_t is_wcroot; 9056160Sru const char *lock_abspath; 9156160Sru 9256160Sru /* Can we even work with this directory? */ 9356160Sru SVN_ERR(can_be_cleaned(&wc_format, db, dir_abspath, scratch_pool)); 9456160Sru 9556160Sru /* We cannot obtain a lock on a directory that's within a locked 9656160Sru subtree, so always run cleanup from the lock owner. */ 9756160Sru SVN_ERR(svn_wc__db_wclock_find_root(&lock_abspath, db, dir_abspath, 9856160Sru scratch_pool, scratch_pool)); 9956160Sru if (lock_abspath) 10056160Sru dir_abspath = lock_abspath; 10156160Sru SVN_ERR(svn_wc__db_wclock_obtain(db, dir_abspath, -1, TRUE, scratch_pool)); 10256160Sru 10356160Sru /* Run our changes before the subdirectories. We may not have to recurse 10456160Sru if we blow away a subdir. */ 10556160Sru if (wc_format >= SVN_WC__HAS_WORK_QUEUE) 10656160Sru SVN_ERR(svn_wc__wq_run(db, dir_abspath, cancel_func, cancel_baton, 10756160Sru scratch_pool)); 10856160Sru 10956160Sru SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, dir_abspath, scratch_pool)); 11056160Sru 11156160Sru#ifdef SVN_DEBUG 11256160Sru SVN_ERR(svn_wc__db_verify(db, dir_abspath, scratch_pool)); 11356160Sru#endif 11456160Sru 11556160Sru /* Perform these operations if we lock the entire working copy. 11656160Sru Note that we really need to check a wcroot value and not 11756160Sru svn_wc__check_wcroot() as that function, will just return true 11856160Sru once we start sharing databases with externals. 11956160Sru */ 12056160Sru if (is_wcroot) 12156160Sru { 12256160Sru /* Cleanup the tmp area of the admin subdir, if running the log has not 12356160Sru removed it! The logs have been run, so anything left here has no hope 12456160Sru of being useful. */ 12556160Sru SVN_ERR(svn_wc__adm_cleanup_tmp_area(db, dir_abspath, scratch_pool)); 12656160Sru 12756160Sru /* Remove unreferenced pristine texts */ 12856160Sru SVN_ERR(svn_wc__db_pristine_cleanup(db, dir_abspath, scratch_pool)); 12956160Sru } 13056160Sru 13156160Sru /* Instead of implementing a separate repair step here, use the standard 13256160Sru status walker's optimized implementation, which performs repairs when 13356160Sru there is a lock. */ 13456160Sru SVN_ERR(svn_wc__internal_walk_status(db, dir_abspath, svn_depth_infinity, 13556160Sru FALSE /* get_all */, 13656160Sru FALSE /* no_ignore */, 13756160Sru FALSE /* ignore_text_mods */, 13856160Sru NULL /* ignore patterns */, 13956160Sru status_dummy_callback, NULL, 14056160Sru cancel_func, cancel_baton, 14156160Sru scratch_pool)); 14256160Sru 14356160Sru /* All done, toss the lock */ 14456160Sru SVN_ERR(svn_wc__db_wclock_release(db, dir_abspath, scratch_pool)); 14556160Sru 14656160Sru return SVN_NO_ERROR; 14756160Sru} 14856160Sru 14956160Sru 15056160Sru/* ### possibly eliminate the WC_CTX parameter? callers really shouldn't 15156160Sru ### be doing anything *but* running a cleanup, and we need a special 15256160Sru ### DB anyway. ... *shrug* ... consider later. */ 15356160Srusvn_error_t * 15456160Srusvn_wc_cleanup3(svn_wc_context_t *wc_ctx, 15556160Sru const char *local_abspath, 15656160Sru svn_cancel_func_t cancel_func, 15756160Sru void *cancel_baton, 15856160Sru apr_pool_t *scratch_pool) 15956160Sru{ 16056160Sru svn_wc__db_t *db; 16156160Sru 16256160Sru SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath)); 16356160Sru 16456160Sru /* We need a DB that allows a non-empty work queue (though it *will* 16556160Sru auto-upgrade). We'll handle everything manually. */ 16656160Sru SVN_ERR(svn_wc__db_open(&db, 16756160Sru NULL /* ### config */, FALSE, FALSE, 16856160Sru scratch_pool, scratch_pool)); 16956160Sru 17056160Sru SVN_ERR(cleanup_internal(db, local_abspath, cancel_func, cancel_baton, 17156160Sru scratch_pool)); 17256160Sru 17356160Sru /* The DAV cache suffers from flakiness from time to time, and the 17456160Sru pre-1.7 prescribed workarounds aren't as user-friendly in WC-NG. */ 17556160Sru SVN_ERR(svn_wc__db_base_clear_dav_cache_recursive(db, local_abspath, 17656160Sru scratch_pool)); 17756160Sru 17856160Sru SVN_ERR(svn_wc__db_vacuum(db, local_abspath, scratch_pool)); 17956160Sru 18056160Sru /* We're done with this DB, so proactively close it. */ 18156160Sru SVN_ERR(svn_wc__db_close(db)); 18256160Sru 183 return SVN_NO_ERROR; 184} 185