]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - contrib/subversion/subversion/libsvn_wc/cleanup.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / contrib / subversion / subversion / libsvn_wc / cleanup.c
1 /*
2  * cleanup.c:  handle cleaning up workqueue items
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 \f
26 #include <string.h>
27
28 #include "svn_wc.h"
29 #include "svn_error.h"
30 #include "svn_pools.h"
31 #include "svn_io.h"
32 #include "svn_dirent_uri.h"
33
34 #include "wc.h"
35 #include "adm_files.h"
36 #include "lock.h"
37 #include "workqueue.h"
38
39 #include "private/svn_wc_private.h"
40 #include "svn_private_config.h"
41
42 \f
43 /*** Recursively do log things. ***/
44
45 /* */
46 static svn_error_t *
47 can_be_cleaned(int *wc_format,
48                svn_wc__db_t *db,
49                const char *local_abspath,
50                apr_pool_t *scratch_pool)
51 {
52   SVN_ERR(svn_wc__internal_check_wc(wc_format, db,
53                                     local_abspath, FALSE, scratch_pool));
54
55   /* a "version" of 0 means a non-wc directory */
56   if (*wc_format == 0)
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,
60                                                     scratch_pool));
61
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"));
66
67   return SVN_NO_ERROR;
68 }
69
70 /* Dummy svn_wc_status_func4_t implementation */
71 static svn_error_t *
72 status_dummy_callback(void *baton,
73                       const char *local_abspath,
74                       const svn_wc_status3_t *status,
75                       apr_pool_t *scratch_pool)
76 {
77   return SVN_NO_ERROR;
78 }
79
80 /* */
81 static svn_error_t *
82 cleanup_internal(svn_wc__db_t *db,
83                  const char *dir_abspath,
84                  svn_cancel_func_t cancel_func,
85                  void *cancel_baton,
86                  apr_pool_t *scratch_pool)
87 {
88   int wc_format;
89   svn_boolean_t is_wcroot;
90   const char *lock_abspath;
91
92   /* Can we even work with this directory?  */
93   SVN_ERR(can_be_cleaned(&wc_format, db, dir_abspath, scratch_pool));
94
95   /* We cannot obtain a lock on a directory that's within a locked
96      subtree, so always run cleanup from the lock owner. */
97   SVN_ERR(svn_wc__db_wclock_find_root(&lock_abspath, db, dir_abspath,
98                                       scratch_pool, scratch_pool));
99   if (lock_abspath)
100     dir_abspath = lock_abspath;
101   SVN_ERR(svn_wc__db_wclock_obtain(db, dir_abspath, -1, TRUE, scratch_pool));
102
103   /* Run our changes before the subdirectories. We may not have to recurse
104      if we blow away a subdir.  */
105   if (wc_format >= SVN_WC__HAS_WORK_QUEUE)
106     SVN_ERR(svn_wc__wq_run(db, dir_abspath, cancel_func, cancel_baton,
107                            scratch_pool));
108
109   SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, dir_abspath, scratch_pool));
110
111 #ifdef SVN_DEBUG
112   SVN_ERR(svn_wc__db_verify(db, dir_abspath, scratch_pool));
113 #endif
114
115   /* Perform these operations if we lock the entire working copy.
116      Note that we really need to check a wcroot value and not
117      svn_wc__check_wcroot() as that function, will just return true
118      once we start sharing databases with externals.
119    */
120   if (is_wcroot)
121     {
122     /* Cleanup the tmp area of the admin subdir, if running the log has not
123        removed it!  The logs have been run, so anything left here has no hope
124        of being useful. */
125       SVN_ERR(svn_wc__adm_cleanup_tmp_area(db, dir_abspath, scratch_pool));
126
127       /* Remove unreferenced pristine texts */
128       SVN_ERR(svn_wc__db_pristine_cleanup(db, dir_abspath, scratch_pool));
129     }
130
131   /* Instead of implementing a separate repair step here, use the standard
132      status walker's optimized implementation, which performs repairs when
133      there is a lock. */
134   SVN_ERR(svn_wc__internal_walk_status(db, dir_abspath, svn_depth_infinity,
135                                        FALSE /* get_all */,
136                                        FALSE /* no_ignore */,
137                                        FALSE /* ignore_text_mods */,
138                                        NULL /* ignore patterns */,
139                                        status_dummy_callback, NULL,
140                                        cancel_func, cancel_baton,
141                                        scratch_pool));
142
143   /* All done, toss the lock */
144   SVN_ERR(svn_wc__db_wclock_release(db, dir_abspath, scratch_pool));
145
146   return SVN_NO_ERROR;
147 }
148
149
150 /* ### possibly eliminate the WC_CTX parameter? callers really shouldn't
151    ### be doing anything *but* running a cleanup, and we need a special
152    ### DB anyway. ... *shrug* ... consider later.  */
153 svn_error_t *
154 svn_wc_cleanup3(svn_wc_context_t *wc_ctx,
155                 const char *local_abspath,
156                 svn_cancel_func_t cancel_func,
157                 void *cancel_baton,
158                 apr_pool_t *scratch_pool)
159 {
160   svn_wc__db_t *db;
161
162   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
163
164   /* We need a DB that allows a non-empty work queue (though it *will*
165      auto-upgrade). We'll handle everything manually.  */
166   SVN_ERR(svn_wc__db_open(&db,
167                           NULL /* ### config */, FALSE, FALSE,
168                           scratch_pool, scratch_pool));
169
170   SVN_ERR(cleanup_internal(db, local_abspath, cancel_func, cancel_baton,
171                            scratch_pool));
172
173   /* The DAV cache suffers from flakiness from time to time, and the
174      pre-1.7 prescribed workarounds aren't as user-friendly in WC-NG. */
175   SVN_ERR(svn_wc__db_base_clear_dav_cache_recursive(db, local_abspath,
176                                                     scratch_pool));
177
178   SVN_ERR(svn_wc__db_vacuum(db, local_abspath, scratch_pool));
179
180   /* We're done with this DB, so proactively close it.  */
181   SVN_ERR(svn_wc__db_close(db));
182
183   return SVN_NO_ERROR;
184 }