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