2 * cleanup.c: handle cleaning up workqueue items
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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
21 * ====================================================================
29 #include "svn_error.h"
30 #include "svn_pools.h"
32 #include "svn_dirent_uri.h"
35 #include "adm_files.h"
37 #include "workqueue.h"
39 #include "private/svn_wc_private.h"
40 #include "svn_private_config.h"
43 /*** Recursively do log things. ***/
47 can_be_cleaned(int *wc_format,
49 const char *local_abspath,
50 apr_pool_t *scratch_pool)
52 SVN_ERR(svn_wc__internal_check_wc(wc_format, db,
53 local_abspath, FALSE, scratch_pool));
55 /* a "version" of 0 means a non-wc directory */
57 return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
58 _("'%s' is not a working copy directory"),
59 svn_dirent_local_style(local_abspath,
62 if (*wc_format < SVN_WC__WC_NG_VERSION)
63 return svn_error_create(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
64 _("Log format too old, please use "
65 "Subversion 1.6 or earlier"));
70 /* Do a modifed check for LOCAL_ABSPATH, and all working children, to force
73 repair_timestamps(svn_wc__db_t *db,
74 const char *local_abspath,
75 svn_cancel_func_t cancel_func,
77 apr_pool_t *scratch_pool)
80 svn_wc__db_status_t status;
83 SVN_ERR(cancel_func(cancel_baton));
85 SVN_ERR(svn_wc__db_read_info(&status, &kind,
86 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
87 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
88 NULL, NULL, NULL, NULL, NULL, NULL,
90 db, local_abspath, scratch_pool, scratch_pool));
92 if (status == svn_wc__db_status_server_excluded
93 || status == svn_wc__db_status_deleted
94 || status == svn_wc__db_status_excluded
95 || status == svn_wc__db_status_not_present)
98 if (kind == svn_node_file
99 || kind == svn_node_symlink)
101 svn_boolean_t modified;
102 SVN_ERR(svn_wc__internal_file_modified_p(&modified,
103 db, local_abspath, FALSE,
106 else if (kind == svn_node_dir)
108 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
109 const apr_array_header_t *children;
112 SVN_ERR(svn_wc__db_read_children_of_working_node(&children, db,
116 for (i = 0; i < children->nelts; ++i)
118 const char *child_abspath;
120 svn_pool_clear(iterpool);
122 child_abspath = svn_dirent_join(local_abspath,
123 APR_ARRAY_IDX(children, i,
127 SVN_ERR(repair_timestamps(db, child_abspath,
128 cancel_func, cancel_baton, iterpool));
130 svn_pool_destroy(iterpool);
138 cleanup_internal(svn_wc__db_t *db,
139 const char *dir_abspath,
140 svn_cancel_func_t cancel_func,
142 apr_pool_t *scratch_pool)
145 svn_boolean_t is_wcroot;
146 const char *lock_abspath;
148 /* Can we even work with this directory? */
149 SVN_ERR(can_be_cleaned(&wc_format, db, dir_abspath, scratch_pool));
151 /* We cannot obtain a lock on a directory that's within a locked
152 subtree, so always run cleanup from the lock owner. */
153 SVN_ERR(svn_wc__db_wclock_find_root(&lock_abspath, db, dir_abspath,
154 scratch_pool, scratch_pool));
156 dir_abspath = lock_abspath;
157 SVN_ERR(svn_wc__db_wclock_obtain(db, dir_abspath, -1, TRUE, scratch_pool));
159 /* Run our changes before the subdirectories. We may not have to recurse
160 if we blow away a subdir. */
161 if (wc_format >= SVN_WC__HAS_WORK_QUEUE)
162 SVN_ERR(svn_wc__wq_run(db, dir_abspath, cancel_func, cancel_baton,
165 SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, dir_abspath, scratch_pool));
168 SVN_ERR(svn_wc__db_verify(db, dir_abspath, scratch_pool));
171 /* Perform these operations if we lock the entire working copy.
172 Note that we really need to check a wcroot value and not
173 svn_wc__check_wcroot() as that function, will just return true
174 once we start sharing databases with externals.
178 /* Cleanup the tmp area of the admin subdir, if running the log has not
179 removed it! The logs have been run, so anything left here has no hope
181 SVN_ERR(svn_wc__adm_cleanup_tmp_area(db, dir_abspath, scratch_pool));
183 /* Remove unreferenced pristine texts */
184 SVN_ERR(svn_wc__db_pristine_cleanup(db, dir_abspath, scratch_pool));
187 SVN_ERR(repair_timestamps(db, dir_abspath, cancel_func, cancel_baton,
190 /* All done, toss the lock */
191 SVN_ERR(svn_wc__db_wclock_release(db, dir_abspath, scratch_pool));
197 /* ### possibly eliminate the WC_CTX parameter? callers really shouldn't
198 ### be doing anything *but* running a cleanup, and we need a special
199 ### DB anyway. ... *shrug* ... consider later. */
201 svn_wc_cleanup3(svn_wc_context_t *wc_ctx,
202 const char *local_abspath,
203 svn_cancel_func_t cancel_func,
205 apr_pool_t *scratch_pool)
209 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
211 /* We need a DB that allows a non-empty work queue (though it *will*
212 auto-upgrade). We'll handle everything manually. */
213 SVN_ERR(svn_wc__db_open(&db,
214 NULL /* ### config */, FALSE, FALSE,
215 scratch_pool, scratch_pool));
217 SVN_ERR(cleanup_internal(db, local_abspath, cancel_func, cancel_baton,
220 /* The DAV cache suffers from flakiness from time to time, and the
221 pre-1.7 prescribed workarounds aren't as user-friendly in WC-NG. */
222 SVN_ERR(svn_wc__db_base_clear_dav_cache_recursive(db, local_abspath,
225 SVN_ERR(svn_wc__db_vacuum(db, local_abspath, scratch_pool));
227 /* We're done with this DB, so proactively close it. */
228 SVN_ERR(svn_wc__db_close(db));