~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to subversion/libsvn_wc/adm_ops.c

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2015-08-07 21:32:47 UTC
  • mfrom: (0.2.15) (4.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20150807213247-ozyewtmgsr6tkewl
Tags: 1.9.0-1
* Upload to unstable
* New upstream release.
  + Security fixes
    - CVE-2015-3184: Mixed anonymous/authenticated path-based authz with
      httpd 2.4
    - CVE-2015-3187: svn_repos_trace_node_locations() reveals paths hidden
      by authz
* Add >= 2.7 requirement for python-all-dev Build-Depends, needed to run
  tests.
* Remove Build-Conflicts against ruby-test-unit.  (Closes: #791844)
* Remove patches/apache_module_dependency in favor of expressing the
  dependencies in authz_svn.load/dav_svn.load.
* Build-Depend on apache2-dev (>= 2.4.16) to ensure ap_some_authn_required()
  is available when building mod_authz_svn and Depend on apache2-bin (>=
  2.4.16) for runtime support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
#include <apr_time.h>
37
37
#include <apr_errno.h>
38
38
 
 
39
#include "svn_private_config.h"
39
40
#include "svn_types.h"
40
41
#include "svn_pools.h"
41
42
#include "svn_string.h"
53
54
#include "conflicts.h"
54
55
#include "workqueue.h"
55
56
 
56
 
#include "svn_private_config.h"
 
57
#include "private/svn_dep_compat.h"
 
58
#include "private/svn_sorts_private.h"
57
59
#include "private/svn_subr_private.h"
58
 
#include "private/svn_dep_compat.h"
59
60
 
60
61
 
61
62
struct svn_wc_committed_queue_t
62
63
{
63
64
  /* The pool in which ->queue is allocated. */
64
65
  apr_pool_t *pool;
65
 
  /* Mapping (const char *) local_abspath to (committed_queue_item_t *). */
66
 
  apr_hash_t *queue;
67
 
  /* Is any item in the queue marked as 'recursive'? */
68
 
  svn_boolean_t have_recursive;
 
66
  /* Mapping (const char *) wcroot_abspath to svn_wc__db_commit_queue_t * */
 
67
  apr_hash_t *wc_queues;
69
68
};
70
69
 
71
70
typedef struct committed_queue_item_t
72
71
{
73
72
  const char *local_abspath;
74
 
  svn_boolean_t recurse;
75
 
  svn_boolean_t no_unlock;
76
 
  svn_boolean_t keep_changelist;
77
 
 
78
 
  /* The pristine text checksum. */
79
 
  const svn_checksum_t *sha1_checksum;
80
 
 
81
 
  apr_hash_t *new_dav_cache;
 
73
  svn_boolean_t recurse; /* Use legacy recursion */
 
74
  svn_boolean_t committed; /* Process the node as committed */
 
75
  svn_boolean_t remove_lock; /* Remove existing lock on node */
 
76
  svn_boolean_t remove_changelist; /* Remove changelist on node */
 
77
 
 
78
  /* The pristine text checksum. NULL if the old value should be kept
 
79
     and for directories */
 
80
  const svn_checksum_t *new_sha1_checksum;
 
81
 
 
82
  apr_hash_t *new_dav_cache; /* New DAV cache for the node */
82
83
} committed_queue_item_t;
83
84
 
84
85
 
88
89
  return queue->pool;
89
90
}
90
91
 
91
 
 
92
 
 
93
 
/*** Finishing updates and commits. ***/
94
 
 
95
 
/* Queue work items that will finish a commit of the file or directory
96
 
 * LOCAL_ABSPATH in DB:
97
 
 *   - queue the removal of any "revert-base" props and text files;
98
 
 *   - queue an update of the DB entry for this node
99
 
 *
100
 
 * ### The Pristine Store equivalent should be:
101
 
 *   - remember the old BASE_NODE and WORKING_NODE pristine text c'sums;
102
 
 *   - queue an update of the DB entry for this node (incl. updating the
103
 
 *       BASE_NODE c'sum and setting the WORKING_NODE c'sum to NULL);
104
 
 *   - queue deletion of the old pristine texts by the remembered checksums.
105
 
 *
106
 
 * CHECKSUM is the checksum of the new text base for LOCAL_ABSPATH, and must
107
 
 * be provided if there is one, else NULL.
108
 
 *
109
 
 * STATUS, KIND, PROP_MODS and OLD_CHECKSUM are the current in-db values of
110
 
 * the node LOCAL_ABSPATH.
111
 
 */
112
 
static svn_error_t *
113
 
process_committed_leaf(svn_wc__db_t *db,
114
 
                       const char *local_abspath,
115
 
                       svn_boolean_t via_recurse,
116
 
                       svn_wc__db_status_t status,
117
 
                       svn_node_kind_t kind,
118
 
                       svn_boolean_t prop_mods,
119
 
                       const svn_checksum_t *old_checksum,
120
 
                       svn_revnum_t new_revnum,
121
 
                       apr_time_t new_changed_date,
122
 
                       const char *new_changed_author,
123
 
                       apr_hash_t *new_dav_cache,
124
 
                       svn_boolean_t no_unlock,
125
 
                       svn_boolean_t keep_changelist,
126
 
                       const svn_checksum_t *checksum,
127
 
                       apr_pool_t *scratch_pool)
128
 
{
129
 
  svn_revnum_t new_changed_rev = new_revnum;
130
 
  svn_skel_t *work_item = NULL;
131
 
 
132
 
  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
133
 
 
134
 
  {
135
 
    const char *adm_abspath;
136
 
 
137
 
    if (kind == svn_node_dir)
138
 
      adm_abspath = local_abspath;
139
 
    else
140
 
      adm_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
141
 
    SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool));
142
 
  }
143
 
 
144
 
  if (status == svn_wc__db_status_deleted)
145
 
    {
146
 
      return svn_error_trace(
147
 
                svn_wc__db_base_remove(
148
 
                                db, local_abspath,
149
 
                                FALSE /* keep_as_working */,
150
 
                                FALSE /* queue_deletes */,
151
 
                                TRUE  /* remove_locks */,
152
 
                                (! via_recurse)
153
 
                                    ? new_revnum : SVN_INVALID_REVNUM,
154
 
                                NULL, NULL,
155
 
                                scratch_pool));
156
 
    }
157
 
  else if (status == svn_wc__db_status_not_present)
158
 
    {
159
 
      /* We are committing the leaf of a copy operation.
160
 
         We leave the not-present marker to allow pulling in excluded
161
 
         children of a copy.
162
 
 
163
 
         The next update will remove the not-present marker. */
164
 
 
165
 
      return SVN_NO_ERROR;
166
 
    }
167
 
 
168
 
  SVN_ERR_ASSERT(status == svn_wc__db_status_normal
169
 
                 || status == svn_wc__db_status_incomplete
170
 
                 || status == svn_wc__db_status_added);
171
 
 
172
 
  if (kind != svn_node_dir)
173
 
    {
174
 
      /* If we sent a delta (meaning: post-copy modification),
175
 
         then this file will appear in the queue and so we should have
176
 
         its checksum already. */
177
 
      if (checksum == NULL)
178
 
        {
179
 
          /* It was copied and not modified. We must have a text
180
 
             base for it. And the node should have a checksum. */
181
 
          SVN_ERR_ASSERT(old_checksum != NULL);
182
 
 
183
 
          checksum = old_checksum;
184
 
 
185
 
          /* Is the node completely unmodified and are we recursing? */
186
 
          if (via_recurse && !prop_mods)
187
 
            {
188
 
              /* If a copied node itself is not modified, but the op_root of
189
 
                 the copy is committed we have to make sure that changed_rev,
190
 
                 changed_date and changed_author don't change or the working
191
 
                 copy used for committing will show different last modified
192
 
                 information then a clean checkout of exactly the same
193
 
                 revisions. (Issue #3676) */
194
 
 
195
 
              SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL,
196
 
                                           NULL, &new_changed_rev,
197
 
                                           &new_changed_date,
198
 
                                           &new_changed_author, NULL, NULL,
199
 
                                           NULL, NULL, NULL, NULL, NULL,
200
 
                                           NULL, NULL, NULL, NULL,
201
 
                                           NULL, NULL, NULL, NULL,
202
 
                                           NULL, NULL, NULL,
203
 
                                           db, local_abspath,
204
 
                                           scratch_pool, scratch_pool));
205
 
            }
206
 
        }
207
 
 
208
 
      SVN_ERR(svn_wc__wq_build_file_commit(&work_item,
209
 
                                           db, local_abspath,
210
 
                                           prop_mods,
211
 
                                           scratch_pool, scratch_pool));
212
 
    }
213
 
 
214
 
  /* The new text base will be found in the pristine store by its checksum. */
215
 
  SVN_ERR(svn_wc__db_global_commit(db, local_abspath,
216
 
                                   new_revnum, new_changed_rev,
217
 
                                   new_changed_date, new_changed_author,
218
 
                                   checksum,
219
 
                                   NULL /* new_children */,
220
 
                                   new_dav_cache,
221
 
                                   keep_changelist,
222
 
                                   no_unlock,
223
 
                                   work_item,
224
 
                                   scratch_pool));
225
 
 
226
 
  return SVN_NO_ERROR;
227
 
}
228
 
 
229
 
 
230
 
svn_error_t *
231
 
svn_wc__process_committed_internal(svn_wc__db_t *db,
232
 
                                   const char *local_abspath,
233
 
                                   svn_boolean_t recurse,
234
 
                                   svn_boolean_t top_of_recurse,
235
 
                                   svn_revnum_t new_revnum,
236
 
                                   apr_time_t new_date,
237
 
                                   const char *rev_author,
238
 
                                   apr_hash_t *new_dav_cache,
239
 
                                   svn_boolean_t no_unlock,
240
 
                                   svn_boolean_t keep_changelist,
241
 
                                   const svn_checksum_t *sha1_checksum,
242
 
                                   const svn_wc_committed_queue_t *queue,
243
 
                                   apr_pool_t *scratch_pool)
244
 
{
245
 
  svn_wc__db_status_t status;
246
 
  svn_node_kind_t kind;
247
 
  const svn_checksum_t *old_checksum;
248
 
  svn_boolean_t prop_mods;
249
 
 
250
 
  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
251
 
                               NULL, NULL, NULL, &old_checksum, NULL, NULL,
252
 
                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
253
 
                               NULL, NULL, &prop_mods, NULL, NULL, NULL,
254
 
                               db, local_abspath,
255
 
                               scratch_pool, scratch_pool));
256
 
 
257
 
  /* NOTE: be wary of making crazy semantic changes in this function, since
258
 
     svn_wc_process_committed4() calls this.  */
259
 
 
260
 
  SVN_ERR(process_committed_leaf(db, local_abspath, !top_of_recurse,
261
 
                                 status, kind, prop_mods, old_checksum,
262
 
                                 new_revnum, new_date, rev_author,
263
 
                                 new_dav_cache,
264
 
                                 no_unlock, keep_changelist,
265
 
                                 sha1_checksum,
266
 
                                 scratch_pool));
267
 
 
268
 
  /* Only check for recursion on nodes that have children */
269
 
  if (kind != svn_node_file
270
 
      || status == svn_wc__db_status_not_present
271
 
      || status == svn_wc__db_status_excluded
272
 
      || status == svn_wc__db_status_server_excluded
273
 
      /* Node deleted -> then no longer a directory */
274
 
      || status == svn_wc__db_status_deleted)
275
 
    {
276
 
      return SVN_NO_ERROR;
277
 
    }
278
 
 
279
 
  if (recurse)
280
 
    {
281
 
      const apr_array_header_t *children;
282
 
      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
283
 
      int i;
284
 
 
285
 
      /* Read PATH's entries;  this is the absolute path. */
286
 
      SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath,
287
 
                                       scratch_pool, iterpool));
288
 
 
289
 
      /* Recursively loop over all children. */
290
 
      for (i = 0; i < children->nelts; i++)
291
 
        {
292
 
          const char *name = APR_ARRAY_IDX(children, i, const char *);
293
 
          const char *this_abspath;
294
 
          const committed_queue_item_t *cqi;
295
 
 
296
 
          svn_pool_clear(iterpool);
297
 
 
298
 
          this_abspath = svn_dirent_join(local_abspath, name, iterpool);
299
 
 
300
 
          sha1_checksum = NULL;
301
 
          cqi = svn_hash_gets(queue->queue, this_abspath);
302
 
 
303
 
          if (cqi != NULL)
304
 
            sha1_checksum = cqi->sha1_checksum;
305
 
 
306
 
          /* Recurse.  Pass NULL for NEW_DAV_CACHE, because the
307
 
             ones present in the current call are only applicable to
308
 
             this one committed item. */
309
 
          SVN_ERR(svn_wc__process_committed_internal(
310
 
                    db, this_abspath,
311
 
                    TRUE /* recurse */,
312
 
                    FALSE /* top_of_recurse */,
313
 
                    new_revnum, new_date,
314
 
                    rev_author,
315
 
                    NULL /* new_dav_cache */,
316
 
                    TRUE /* no_unlock */,
317
 
                    keep_changelist,
318
 
                    sha1_checksum,
319
 
                    queue,
320
 
                    iterpool));
321
 
        }
322
 
 
323
 
      svn_pool_destroy(iterpool);
324
 
    }
325
 
 
326
 
  return SVN_NO_ERROR;
327
 
}
328
 
 
329
 
 
330
92
apr_hash_t *
331
93
svn_wc__prop_array_to_hash(const apr_array_header_t *props,
332
94
                           apr_pool_t *result_pool)
357
119
 
358
120
  q = apr_palloc(pool, sizeof(*q));
359
121
  q->pool = pool;
360
 
  q->queue = apr_hash_make(pool);
361
 
  q->have_recursive = FALSE;
 
122
  q->wc_queues = apr_hash_make(pool);
362
123
 
363
124
  return q;
364
125
}
365
126
 
366
127
 
367
128
svn_error_t *
368
 
svn_wc_queue_committed3(svn_wc_committed_queue_t *queue,
 
129
svn_wc_queue_committed4(svn_wc_committed_queue_t *queue,
369
130
                        svn_wc_context_t *wc_ctx,
370
131
                        const char *local_abspath,
371
132
                        svn_boolean_t recurse,
 
133
                        svn_boolean_t is_committed,
372
134
                        const apr_array_header_t *wcprop_changes,
373
135
                        svn_boolean_t remove_lock,
374
136
                        svn_boolean_t remove_changelist,
375
137
                        const svn_checksum_t *sha1_checksum,
376
138
                        apr_pool_t *scratch_pool)
377
139
{
378
 
  committed_queue_item_t *cqi;
 
140
  const char *wcroot_abspath;
 
141
  svn_wc__db_commit_queue_t *db_queue;
379
142
 
380
143
  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
381
144
 
382
 
  queue->have_recursive |= recurse;
383
 
 
384
145
  /* Use the same pool as the one QUEUE was allocated in,
385
146
     to prevent lifetime issues.  Intermediate operations
386
147
     should use SCRATCH_POOL. */
387
148
 
388
 
  /* Add to the array with paths and options */
389
 
  cqi = apr_palloc(queue->pool, sizeof(*cqi));
390
 
  cqi->local_abspath = local_abspath;
391
 
  cqi->recurse = recurse;
392
 
  cqi->no_unlock = !remove_lock;
393
 
  cqi->keep_changelist = !remove_changelist;
394
 
  cqi->sha1_checksum = sha1_checksum;
395
 
  cqi->new_dav_cache = svn_wc__prop_array_to_hash(wcprop_changes, queue->pool);
396
 
 
397
 
  svn_hash_sets(queue->queue, local_abspath, cqi);
398
 
 
399
 
  return SVN_NO_ERROR;
400
 
}
401
 
 
402
 
 
403
 
/* Return TRUE if any item of QUEUE is a parent of ITEM and will be
404
 
   processed recursively, return FALSE otherwise.
405
 
 
406
 
   The algorithmic complexity of this search implementation is O(queue
407
 
   length), but it's quite quick.
408
 
*/
409
 
static svn_boolean_t
410
 
have_recursive_parent(apr_hash_t *queue,
411
 
                      const committed_queue_item_t *item,
412
 
                      apr_pool_t *scratch_pool)
413
 
{
414
 
  apr_hash_index_t *hi;
415
 
  const char *local_abspath = item->local_abspath;
416
 
 
417
 
  for (hi = apr_hash_first(scratch_pool, queue); hi; hi = apr_hash_next(hi))
 
149
  SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath,
 
150
                                wc_ctx->db, local_abspath,
 
151
                                scratch_pool, scratch_pool));
 
152
 
 
153
  db_queue = svn_hash_gets(queue->wc_queues, wcroot_abspath);
 
154
  if (! db_queue)
418
155
    {
419
 
      const committed_queue_item_t *qi = svn__apr_hash_index_val(hi);
420
 
 
421
 
      if (qi == item)
422
 
        continue;
423
 
 
424
 
      if (qi->recurse && svn_dirent_is_child(qi->local_abspath, local_abspath,
425
 
                                             NULL))
426
 
        return TRUE;
 
156
      wcroot_abspath = apr_pstrdup(queue->pool, wcroot_abspath);
 
157
 
 
158
      SVN_ERR(svn_wc__db_create_commit_queue(&db_queue,
 
159
                                             wc_ctx->db, wcroot_abspath,
 
160
                                             queue->pool, scratch_pool));
 
161
 
 
162
      svn_hash_sets(queue->wc_queues, wcroot_abspath, db_queue);
427
163
    }
428
164
 
429
 
  return FALSE;
 
165
  return svn_error_trace(
 
166
          svn_wc__db_commit_queue_add(db_queue, local_abspath, recurse,
 
167
                                      is_committed, remove_lock,
 
168
                                      remove_changelist, sha1_checksum,
 
169
                                      svn_wc__prop_array_to_hash(wcprop_changes,
 
170
                                                                 queue->pool),
 
171
                                      queue->pool, scratch_pool));
430
172
}
431
173
 
432
174
 
440
182
                                void *cancel_baton,
441
183
                                apr_pool_t *scratch_pool)
442
184
{
443
 
  apr_array_header_t *sorted_queue;
 
185
  apr_array_header_t *wcs;
444
186
  int i;
445
187
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
446
188
  apr_time_t new_date;
447
 
  apr_hash_t *run_wqs = apr_hash_make(scratch_pool);
448
 
  apr_hash_index_t *hi;
449
189
 
450
190
  if (rev_date)
451
191
    SVN_ERR(svn_time_from_cstring(&new_date, rev_date, iterpool));
452
192
  else
453
193
    new_date = 0;
454
194
 
455
 
  /* Process the queued items in order of their paths.  (The requirement is
456
 
   * probably just that a directory must be processed before its children.) */
457
 
  sorted_queue = svn_sort__hash(queue->queue, svn_sort_compare_items_as_paths,
458
 
                                scratch_pool);
459
 
  for (i = 0; i < sorted_queue->nelts; i++)
 
195
  /* Process the wc's in order of their paths. */
 
196
  wcs = svn_sort__hash(queue->wc_queues, svn_sort_compare_items_as_paths,
 
197
                       scratch_pool);
 
198
  for (i = 0; i < wcs->nelts; i++)
460
199
    {
461
200
      const svn_sort__item_t *sort_item
462
 
        = &APR_ARRAY_IDX(sorted_queue, i, svn_sort__item_t);
463
 
      const committed_queue_item_t *cqi = sort_item->value;
464
 
      const char *wcroot_abspath;
 
201
                                = &APR_ARRAY_IDX(wcs, i, svn_sort__item_t);
 
202
      svn_wc__db_commit_queue_t *db_queue = sort_item->value;
465
203
 
466
204
      svn_pool_clear(iterpool);
467
205
 
468
 
      /* Skip this item if it is a child of a recursive item, because it has
469
 
         been (or will be) accounted for when that recursive item was (or
470
 
         will be) processed. */
471
 
      if (queue->have_recursive && have_recursive_parent(queue->queue, cqi,
472
 
                                                         iterpool))
473
 
        continue;
474
 
 
475
 
      SVN_ERR(svn_wc__process_committed_internal(
476
 
                wc_ctx->db, cqi->local_abspath,
477
 
                cqi->recurse,
478
 
                TRUE /* top_of_recurse */,
479
 
                new_revnum, new_date, rev_author,
480
 
                cqi->new_dav_cache,
481
 
                cqi->no_unlock,
482
 
                cqi->keep_changelist,
483
 
                cqi->sha1_checksum, queue,
484
 
                iterpool));
485
 
 
486
 
      /* Don't run the wq now, but remember that we must call it for this
487
 
         working copy */
488
 
      SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath,
489
 
                                    wc_ctx->db, cqi->local_abspath,
490
 
                                    iterpool, iterpool));
491
 
 
492
 
      if (! svn_hash_gets(run_wqs, wcroot_abspath))
493
 
        {
494
 
          wcroot_abspath = apr_pstrdup(scratch_pool, wcroot_abspath);
495
 
          svn_hash_sets(run_wqs, wcroot_abspath, wcroot_abspath);
496
 
        }
 
206
      SVN_ERR(svn_wc__db_process_commit_queue(wc_ctx->db, db_queue,
 
207
                                              new_revnum, new_date, rev_author,
 
208
                                              iterpool));
497
209
    }
498
210
 
499
211
  /* Make sure nothing happens if this function is called again.  */
500
 
  apr_hash_clear(queue->queue);
 
212
  apr_hash_clear(queue->wc_queues);
501
213
 
502
214
  /* Ok; everything is committed now. Now we can start calling callbacks */
503
 
 
504
215
  if (cancel_func)
505
216
    SVN_ERR(cancel_func(cancel_baton));
506
217
 
507
 
  for (hi = apr_hash_first(scratch_pool, run_wqs);
508
 
       hi;
509
 
       hi = apr_hash_next(hi))
 
218
  for (i = 0; i < wcs->nelts; i++)
510
219
    {
511
 
      const char *wcroot_abspath = svn__apr_hash_index_key(hi);
 
220
      const svn_sort__item_t *sort_item
 
221
          = &APR_ARRAY_IDX(wcs, i, svn_sort__item_t);
 
222
      const char *wcroot_abspath = sort_item->key;
512
223
 
513
224
      svn_pool_clear(iterpool);
514
225
 
631
342
                                         db, parent_abspath,
632
343
                                         result_pool, scratch_pool));
633
344
      else
634
 
        SVN_ERR(svn_wc__db_scan_base_repos(NULL,
635
 
                                           repos_root_url, repos_uuid,
636
 
                                           db, parent_abspath,
637
 
                                           result_pool, scratch_pool));
 
345
        SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL,
 
346
                                         repos_root_url, repos_uuid, NULL,
 
347
                                         NULL, NULL, NULL, NULL, NULL, NULL,
 
348
                                         NULL, NULL, NULL,
 
349
                                         db, parent_abspath,
 
350
                                         result_pool, scratch_pool));
638
351
    }
639
352
 
640
353
  return SVN_NO_ERROR;
887
600
      const char *repos_relpath, *inner_repos_root_url, *inner_repos_uuid;
888
601
      const char *inner_url;
889
602
 
890
 
      SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath,
891
 
                                         &inner_repos_root_url,
892
 
                                         &inner_repos_uuid,
893
 
                                         db, local_abspath,
894
 
                                         scratch_pool, scratch_pool));
 
603
      SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, &repos_relpath,
 
604
                                       &inner_repos_root_url,
 
605
                                       &inner_repos_uuid, NULL, NULL, NULL,
 
606
                                       NULL, NULL, NULL, NULL, NULL, NULL,
 
607
                                       NULL,
 
608
                                       db, local_abspath,
 
609
                                       scratch_pool, scratch_pool));
895
610
 
896
611
      if (strcmp(inner_repos_uuid, repos_uuid)
897
612
          || strcmp(repos_root_url, inner_repos_root_url))
993
708
 
994
709
 
995
710
svn_error_t *
996
 
svn_wc_add_from_disk2(svn_wc_context_t *wc_ctx,
 
711
svn_wc_add_from_disk3(svn_wc_context_t *wc_ctx,
997
712
                      const char *local_abspath,
998
713
                      const apr_hash_t *props,
 
714
                      svn_boolean_t skip_checks,
999
715
                      svn_wc_notify_func2_t notify_func,
1000
716
                      void *notify_baton,
1001
717
                      apr_pool_t *scratch_pool)
1014
730
 
1015
731
      SVN_ERR(svn_wc__canonicalize_props(
1016
732
                &new_props,
1017
 
                local_abspath, kind, props, FALSE /* skip_some_checks */,
 
733
                local_abspath, kind, props, skip_checks,
1018
734
                scratch_pool, scratch_pool));
1019
735
      props = new_props;
1020
736
    }
1177
893
 
1178
894
  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
1179
895
 
1180
 
  /* ### Enable after fixing callers */
1181
 
  /*SVN_ERR(svn_wc__write_check(wc_ctx->db,
 
896
  SVN_ERR(svn_wc__write_check(wc_ctx->db,
1182
897
                              svn_dirent_dirname(local_abspath, scratch_pool),
1183
 
                              scratch_pool));*/
 
898
                              scratch_pool));
1184
899
 
1185
900
  db_lock.token = lock->token;
1186
901
  db_lock.owner = lock->owner;
1227
942
                    apr_pool_t *scratch_pool)
1228
943
{
1229
944
  svn_error_t *err;
1230
 
  const svn_string_t *needs_lock;
 
945
  svn_skel_t *work_item;
1231
946
 
1232
947
  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
1233
948
 
1234
 
  /* ### Enable after fixing callers */
1235
 
  /*SVN_ERR(svn_wc__write_check(wc_ctx->db,
 
949
  SVN_ERR(svn_wc__write_check(wc_ctx->db,
1236
950
                              svn_dirent_dirname(local_abspath, scratch_pool),
1237
 
                              scratch_pool));*/
1238
 
 
1239
 
  err = svn_wc__db_lock_remove(wc_ctx->db, local_abspath, scratch_pool);
 
951
                              scratch_pool));
 
952
 
 
953
  SVN_ERR(svn_wc__wq_build_sync_file_flags(&work_item,
 
954
                                           wc_ctx->db, local_abspath,
 
955
                                           scratch_pool, scratch_pool));
 
956
 
 
957
  err = svn_wc__db_lock_remove(wc_ctx->db, local_abspath, work_item,
 
958
                               scratch_pool);
1240
959
  if (err)
1241
960
    {
1242
961
      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
1250
969
                                                      scratch_pool));
1251
970
    }
1252
971
 
1253
 
  /* if svn:needs-lock is present, then make the file read-only. */
1254
 
  err = svn_wc__internal_propget(&needs_lock, wc_ctx->db, local_abspath,
1255
 
                                 SVN_PROP_NEEDS_LOCK, scratch_pool,
1256
 
                                 scratch_pool);
1257
 
  if (err)
1258
 
    {
1259
 
      if (err->apr_err != SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
1260
 
        return svn_error_trace(err);
1261
 
 
1262
 
      svn_error_clear(err);
1263
 
      return SVN_NO_ERROR; /* Node is shadowed and/or deleted,
1264
 
                              so we shouldn't apply its lock */
1265
 
    }
1266
 
 
1267
 
  if (needs_lock)
1268
 
    SVN_ERR(svn_io_set_file_read_only(local_abspath, FALSE, scratch_pool));
1269
 
 
1270
 
  return SVN_NO_ERROR;
 
972
  return svn_error_trace(svn_wc__wq_run(wc_ctx->db, local_abspath,
 
973
                                        NULL, NULL /* cancel*/,
 
974
                                        scratch_pool));
1271
975
}
1272
976
 
1273
977
 
1321
1025
                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1322
1026
                               b->db, local_abspath,
1323
1027
                               scratch_pool, scratch_pool));
1324
 
 
1325
 
  if (svn_wc__internal_changelist_match(b->db, local_abspath, b->clhash,
1326
 
                                        scratch_pool))
 
1028
  if (!b->clhash
 
1029
      || (changelist && svn_hash_gets(b->clhash, changelist) != NULL))
1327
1030
    SVN_ERR(b->callback_func(b->callback_baton, local_abspath,
1328
1031
                             changelist, scratch_pool));
1329
1032