]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/subversion/subversion/libsvn_wc/deprecated.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / subversion / subversion / libsvn_wc / deprecated.c
1 /*
2  * deprecated.c:  holding file for all deprecated APIs.
3  *                "we can't lose 'em, but we can shun 'em!"
4  *
5  * ====================================================================
6  *    Licensed to the Apache Software Foundation (ASF) under one
7  *    or more contributor license agreements.  See the NOTICE file
8  *    distributed with this work for additional information
9  *    regarding copyright ownership.  The ASF licenses this file
10  *    to you under the Apache License, Version 2.0 (the
11  *    "License"); you may not use this file except in compliance
12  *    with the License.  You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  *    Unless required by applicable law or agreed to in writing,
17  *    software distributed under the License is distributed on an
18  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19  *    KIND, either express or implied.  See the License for the
20  *    specific language governing permissions and limitations
21  *    under the License.
22  * ====================================================================
23  */
24
25 /* We define this here to remove any further warnings about the usage of
26    deprecated functions in this file. */
27 #define SVN_DEPRECATED
28
29 #include <apr_md5.h>
30
31 #include "svn_wc.h"
32 #include "svn_subst.h"
33 #include "svn_pools.h"
34 #include "svn_props.h"
35 #include "svn_hash.h"
36 #include "svn_time.h"
37 #include "svn_dirent_uri.h"
38 #include "svn_path.h"
39
40 #include "private/svn_subr_private.h"
41 #include "private/svn_wc_private.h"
42
43 #include "wc.h"
44 #include "entries.h"
45 #include "lock.h"
46 #include "props.h"
47 #include "translate.h"
48 #include "workqueue.h"
49
50 #include "svn_private_config.h"
51
52 /* baton for traversal_info_update */
53 struct traversal_info_update_baton
54 {
55   struct svn_wc_traversal_info_t *traversal;
56   svn_wc__db_t *db;
57 };
58
59 /* Helper for updating svn_wc_traversal_info_t structures
60  * Implements svn_wc_external_update_t */
61 static svn_error_t *
62 traversal_info_update(void *baton,
63                       const char *local_abspath,
64                       const svn_string_t *old_val,
65                       const svn_string_t *new_val,
66                       svn_depth_t depth,
67                       apr_pool_t *scratch_pool)
68 {
69   const char *dup_path;
70   svn_wc_adm_access_t *adm_access;
71   struct traversal_info_update_baton *ub = baton;
72   apr_pool_t *dup_pool = ub->traversal->pool;
73   const char *dup_val = NULL;
74
75   /* We make the abspath relative by retrieving the access baton
76      for the specific directory */
77   adm_access = svn_wc__adm_retrieve_internal2(ub->db, local_abspath,
78                                               scratch_pool);
79
80   if (adm_access)
81     dup_path = apr_pstrdup(dup_pool, svn_wc_adm_access_path(adm_access));
82   else
83     dup_path = apr_pstrdup(dup_pool, local_abspath);
84
85   if (old_val)
86     {
87       dup_val = apr_pstrmemdup(dup_pool, old_val->data, old_val->len);
88
89       svn_hash_sets(ub->traversal->externals_old, dup_path, dup_val);
90     }
91
92   if (new_val)
93     {
94       /* In most cases the value is identical */
95       if (old_val != new_val)
96         dup_val = apr_pstrmemdup(dup_pool, new_val->data, new_val->len);
97
98       svn_hash_sets(ub->traversal->externals_new, dup_path, dup_val);
99     }
100
101   svn_hash_sets(ub->traversal->depths, dup_path, svn_depth_to_word(depth));
102
103   return SVN_NO_ERROR;
104 }
105
106 /* Helper for functions that used to gather traversal_info */
107 static svn_error_t *
108 gather_traversal_info(svn_wc_context_t *wc_ctx,
109                       const char *local_abspath,
110                       const char *path,
111                       svn_depth_t depth,
112                       struct svn_wc_traversal_info_t *traversal_info,
113                       svn_boolean_t gather_as_old,
114                       svn_boolean_t gather_as_new,
115                       apr_pool_t *scratch_pool)
116 {
117   apr_hash_t *externals;
118   apr_hash_t *ambient_depths;
119   apr_hash_index_t *hi;
120
121   SVN_ERR(svn_wc__externals_gather_definitions(&externals, &ambient_depths,
122                                                wc_ctx, local_abspath,
123                                                depth,
124                                                scratch_pool, scratch_pool));
125
126   for (hi = apr_hash_first(scratch_pool, externals);
127        hi;
128        hi = apr_hash_next(hi))
129     {
130       const char *node_abspath = svn__apr_hash_index_key(hi);
131       const char *relpath;
132
133       relpath = svn_dirent_join(path,
134                                 svn_dirent_skip_ancestor(local_abspath,
135                                                          node_abspath),
136                                 traversal_info->pool);
137
138       if (gather_as_old)
139         svn_hash_sets(traversal_info->externals_old, relpath,
140                       svn__apr_hash_index_val(hi));
141
142       if (gather_as_new)
143         svn_hash_sets(traversal_info->externals_new, relpath,
144                       svn__apr_hash_index_val(hi));
145
146       svn_hash_sets(traversal_info->depths, relpath,
147                     svn_hash_gets(ambient_depths, node_abspath));
148     }
149
150   return SVN_NO_ERROR;
151 }
152
153 \f
154 /*** From adm_crawler.c ***/
155
156 svn_error_t *
157 svn_wc_crawl_revisions4(const char *path,
158                         svn_wc_adm_access_t *adm_access,
159                         const svn_ra_reporter3_t *reporter,
160                         void *report_baton,
161                         svn_boolean_t restore_files,
162                         svn_depth_t depth,
163                         svn_boolean_t honor_depth_exclude,
164                         svn_boolean_t depth_compatibility_trick,
165                         svn_boolean_t use_commit_times,
166                         svn_wc_notify_func2_t notify_func,
167                         void *notify_baton,
168                         svn_wc_traversal_info_t *traversal_info,
169                         apr_pool_t *pool)
170 {
171   svn_wc_context_t *wc_ctx;
172   svn_wc__db_t *wc_db = svn_wc__adm_get_db(adm_access);
173   const char *local_abspath;
174
175   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool));
176   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
177
178   SVN_ERR(svn_wc_crawl_revisions5(wc_ctx,
179                                   local_abspath,
180                                   reporter,
181                                   report_baton,
182                                   restore_files,
183                                   depth,
184                                   honor_depth_exclude,
185                                   depth_compatibility_trick,
186                                   use_commit_times,
187                                   NULL /* cancel_func */,
188                                   NULL /* cancel_baton */,
189                                   notify_func,
190                                   notify_baton,
191                                   pool));
192
193   if (traversal_info)
194     SVN_ERR(gather_traversal_info(wc_ctx, local_abspath, path, depth,
195                                   traversal_info, TRUE, FALSE, pool));
196
197   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
198 }
199
200 /*** Compatibility wrapper: turns an svn_ra_reporter2_t into an
201      svn_ra_reporter3_t.
202
203      This code looks like it duplicates code in libsvn_ra/ra_loader.c,
204      but it does not.  That code makes an new thing look like an old
205      thing; this code makes an old thing look like a new thing. ***/
206
207 struct wrap_3to2_report_baton {
208   const svn_ra_reporter2_t *reporter;
209   void *baton;
210 };
211
212 /* */
213 static svn_error_t *wrap_3to2_set_path(void *report_baton,
214                                        const char *path,
215                                        svn_revnum_t revision,
216                                        svn_depth_t depth,
217                                        svn_boolean_t start_empty,
218                                        const char *lock_token,
219                                        apr_pool_t *pool)
220 {
221   struct wrap_3to2_report_baton *wrb = report_baton;
222
223   return wrb->reporter->set_path(wrb->baton, path, revision, start_empty,
224                                  lock_token, pool);
225 }
226
227 /* */
228 static svn_error_t *wrap_3to2_delete_path(void *report_baton,
229                                           const char *path,
230                                           apr_pool_t *pool)
231 {
232   struct wrap_3to2_report_baton *wrb = report_baton;
233
234   return wrb->reporter->delete_path(wrb->baton, path, pool);
235 }
236
237 /* */
238 static svn_error_t *wrap_3to2_link_path(void *report_baton,
239                                         const char *path,
240                                         const char *url,
241                                         svn_revnum_t revision,
242                                         svn_depth_t depth,
243                                         svn_boolean_t start_empty,
244                                         const char *lock_token,
245                                         apr_pool_t *pool)
246 {
247   struct wrap_3to2_report_baton *wrb = report_baton;
248
249   return wrb->reporter->link_path(wrb->baton, path, url, revision,
250                                   start_empty, lock_token, pool);
251 }
252
253 /* */
254 static svn_error_t *wrap_3to2_finish_report(void *report_baton,
255                                             apr_pool_t *pool)
256 {
257   struct wrap_3to2_report_baton *wrb = report_baton;
258
259   return wrb->reporter->finish_report(wrb->baton, pool);
260 }
261
262 /* */
263 static svn_error_t *wrap_3to2_abort_report(void *report_baton,
264                                            apr_pool_t *pool)
265 {
266   struct wrap_3to2_report_baton *wrb = report_baton;
267
268   return wrb->reporter->abort_report(wrb->baton, pool);
269 }
270
271 static const svn_ra_reporter3_t wrap_3to2_reporter = {
272   wrap_3to2_set_path,
273   wrap_3to2_delete_path,
274   wrap_3to2_link_path,
275   wrap_3to2_finish_report,
276   wrap_3to2_abort_report
277 };
278
279 svn_error_t *
280 svn_wc_crawl_revisions3(const char *path,
281                         svn_wc_adm_access_t *adm_access,
282                         const svn_ra_reporter3_t *reporter,
283                         void *report_baton,
284                         svn_boolean_t restore_files,
285                         svn_depth_t depth,
286                         svn_boolean_t depth_compatibility_trick,
287                         svn_boolean_t use_commit_times,
288                         svn_wc_notify_func2_t notify_func,
289                         void *notify_baton,
290                         svn_wc_traversal_info_t *traversal_info,
291                         apr_pool_t *pool)
292 {
293   return svn_wc_crawl_revisions4(path,
294                                  adm_access,
295                                  reporter, report_baton,
296                                  restore_files,
297                                  depth,
298                                  FALSE,
299                                  depth_compatibility_trick,
300                                  use_commit_times,
301                                  notify_func,
302                                  notify_baton,
303                                  traversal_info,
304                                  pool);
305 }
306
307 svn_error_t *
308 svn_wc_crawl_revisions2(const char *path,
309                         svn_wc_adm_access_t *adm_access,
310                         const svn_ra_reporter2_t *reporter,
311                         void *report_baton,
312                         svn_boolean_t restore_files,
313                         svn_boolean_t recurse,
314                         svn_boolean_t use_commit_times,
315                         svn_wc_notify_func2_t notify_func,
316                         void *notify_baton,
317                         svn_wc_traversal_info_t *traversal_info,
318                         apr_pool_t *pool)
319 {
320   struct wrap_3to2_report_baton wrb;
321   wrb.reporter = reporter;
322   wrb.baton = report_baton;
323
324   return svn_wc_crawl_revisions3(path,
325                                  adm_access,
326                                  &wrap_3to2_reporter, &wrb,
327                                  restore_files,
328                                  SVN_DEPTH_INFINITY_OR_FILES(recurse),
329                                  FALSE,
330                                  use_commit_times,
331                                  notify_func,
332                                  notify_baton,
333                                  traversal_info,
334                                  pool);
335 }
336
337
338 /* Baton for compat_call_notify_func below.  */
339 struct compat_notify_baton_t {
340   /* Wrapped func/baton. */
341   svn_wc_notify_func_t func;
342   void *baton;
343 };
344
345
346 /* Implements svn_wc_notify_func2_t.  Call BATON->func (BATON is of type
347    svn_wc__compat_notify_baton_t), passing BATON->baton and the appropriate
348    arguments from NOTIFY.  */
349 static void
350 compat_call_notify_func(void *baton,
351                         const svn_wc_notify_t *n,
352                         apr_pool_t *pool)
353 {
354   struct compat_notify_baton_t *nb = baton;
355
356   if (nb->func)
357     (*nb->func)(nb->baton, n->path, n->action, n->kind, n->mime_type,
358                 n->content_state, n->prop_state, n->revision);
359 }
360
361
362 /*** Compatibility wrapper: turns an svn_ra_reporter_t into an
363      svn_ra_reporter2_t.
364
365      This code looks like it duplicates code in libsvn_ra/ra_loader.c,
366      but it does not.  That code makes an new thing look like an old
367      thing; this code makes an old thing look like a new thing. ***/
368
369 struct wrap_2to1_report_baton {
370   const svn_ra_reporter_t *reporter;
371   void *baton;
372 };
373
374 /* */
375 static svn_error_t *wrap_2to1_set_path(void *report_baton,
376                                        const char *path,
377                                        svn_revnum_t revision,
378                                        svn_boolean_t start_empty,
379                                        const char *lock_token,
380                                        apr_pool_t *pool)
381 {
382   struct wrap_2to1_report_baton *wrb = report_baton;
383
384   return wrb->reporter->set_path(wrb->baton, path, revision, start_empty,
385                                  pool);
386 }
387
388 /* */
389 static svn_error_t *wrap_2to1_delete_path(void *report_baton,
390                                           const char *path,
391                                           apr_pool_t *pool)
392 {
393   struct wrap_2to1_report_baton *wrb = report_baton;
394
395   return wrb->reporter->delete_path(wrb->baton, path, pool);
396 }
397
398 /* */
399 static svn_error_t *wrap_2to1_link_path(void *report_baton,
400                                         const char *path,
401                                         const char *url,
402                                         svn_revnum_t revision,
403                                         svn_boolean_t start_empty,
404                                         const char *lock_token,
405                                         apr_pool_t *pool)
406 {
407   struct wrap_2to1_report_baton *wrb = report_baton;
408
409   return wrb->reporter->link_path(wrb->baton, path, url, revision,
410                                   start_empty, pool);
411 }
412
413 /* */
414 static svn_error_t *wrap_2to1_finish_report(void *report_baton,
415                                             apr_pool_t *pool)
416 {
417   struct wrap_2to1_report_baton *wrb = report_baton;
418
419   return wrb->reporter->finish_report(wrb->baton, pool);
420 }
421
422 /* */
423 static svn_error_t *wrap_2to1_abort_report(void *report_baton,
424                                            apr_pool_t *pool)
425 {
426   struct wrap_2to1_report_baton *wrb = report_baton;
427
428   return wrb->reporter->abort_report(wrb->baton, pool);
429 }
430
431 static const svn_ra_reporter2_t wrap_2to1_reporter = {
432   wrap_2to1_set_path,
433   wrap_2to1_delete_path,
434   wrap_2to1_link_path,
435   wrap_2to1_finish_report,
436   wrap_2to1_abort_report
437 };
438
439 svn_error_t *
440 svn_wc_crawl_revisions(const char *path,
441                        svn_wc_adm_access_t *adm_access,
442                        const svn_ra_reporter_t *reporter,
443                        void *report_baton,
444                        svn_boolean_t restore_files,
445                        svn_boolean_t recurse,
446                        svn_boolean_t use_commit_times,
447                        svn_wc_notify_func_t notify_func,
448                        void *notify_baton,
449                        svn_wc_traversal_info_t *traversal_info,
450                        apr_pool_t *pool)
451 {
452   struct wrap_2to1_report_baton wrb;
453   struct compat_notify_baton_t nb;
454
455   wrb.reporter = reporter;
456   wrb.baton = report_baton;
457
458   nb.func = notify_func;
459   nb.baton = notify_baton;
460
461   return svn_wc_crawl_revisions2(path, adm_access, &wrap_2to1_reporter, &wrb,
462                                  restore_files, recurse, use_commit_times,
463                                  compat_call_notify_func, &nb,
464                                  traversal_info,
465                                  pool);
466 }
467
468 svn_error_t *
469 svn_wc_transmit_text_deltas2(const char **tempfile,
470                              unsigned char digest[],
471                              const char *path,
472                              svn_wc_adm_access_t *adm_access,
473                              svn_boolean_t fulltext,
474                              const svn_delta_editor_t *editor,
475                              void *file_baton,
476                              apr_pool_t *pool)
477 {
478   const char *local_abspath;
479   svn_wc_context_t *wc_ctx;
480   const svn_checksum_t *new_text_base_md5_checksum;
481
482   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
483   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
484                                          svn_wc__adm_get_db(adm_access),
485                                          pool));
486
487   SVN_ERR(svn_wc__internal_transmit_text_deltas(tempfile,
488                                                 (digest
489                                                  ? &new_text_base_md5_checksum
490                                                  : NULL),
491                                                 NULL, wc_ctx->db,
492                                                 local_abspath, fulltext,
493                                                 editor, file_baton,
494                                                 pool, pool));
495
496   if (digest)
497     memcpy(digest, new_text_base_md5_checksum->digest, APR_MD5_DIGESTSIZE);
498
499   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
500 }
501
502 svn_error_t *
503 svn_wc_transmit_text_deltas(const char *path,
504                             svn_wc_adm_access_t *adm_access,
505                             svn_boolean_t fulltext,
506                             const svn_delta_editor_t *editor,
507                             void *file_baton,
508                             const char **tempfile,
509                             apr_pool_t *pool)
510 {
511   return svn_wc_transmit_text_deltas2(tempfile, NULL, path, adm_access,
512                                       fulltext, editor, file_baton, pool);
513 }
514
515 svn_error_t *
516 svn_wc_transmit_prop_deltas(const char *path,
517                             svn_wc_adm_access_t *adm_access,
518                             const svn_wc_entry_t *entry,
519                             const svn_delta_editor_t *editor,
520                             void *baton,
521                             const char **tempfile,
522                             apr_pool_t *pool)
523 {
524   const char *local_abspath;
525   svn_wc_context_t *wc_ctx;
526
527   if (tempfile)
528     *tempfile = NULL;
529
530   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
531   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
532                                          svn_wc__adm_get_db(adm_access),
533                                          pool));
534
535   SVN_ERR(svn_wc_transmit_prop_deltas2(wc_ctx, local_abspath, editor, baton,
536                                        pool));
537
538   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
539 }
540
541 /*** From adm_files.c ***/
542 svn_error_t *
543 svn_wc_ensure_adm3(const char *path,
544                    const char *uuid,
545                    const char *url,
546                    const char *repos,
547                    svn_revnum_t revision,
548                    svn_depth_t depth,
549                    apr_pool_t *pool)
550 {
551   const char *local_abspath;
552   svn_wc_context_t *wc_ctx;
553
554   if (uuid == NULL)
555     return svn_error_create(SVN_ERR_BAD_UUID, NULL, NULL);
556   if (repos == NULL)
557     return svn_error_create(SVN_ERR_BAD_URL, NULL, NULL);
558
559   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
560   SVN_ERR(svn_wc_context_create(&wc_ctx, NULL /* config */, pool, pool));
561
562   SVN_ERR(svn_wc_ensure_adm4(wc_ctx, local_abspath, url, repos, uuid, revision,
563                              depth, pool));
564
565   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
566 }
567
568 svn_error_t *
569 svn_wc_ensure_adm2(const char *path,
570                    const char *uuid,
571                    const char *url,
572                    const char *repos,
573                    svn_revnum_t revision,
574                    apr_pool_t *pool)
575 {
576   return svn_wc_ensure_adm3(path, uuid, url, repos, revision,
577                             svn_depth_infinity, pool);
578 }
579
580
581 svn_error_t *
582 svn_wc_ensure_adm(const char *path,
583                   const char *uuid,
584                   const char *url,
585                   svn_revnum_t revision,
586                   apr_pool_t *pool)
587 {
588   return svn_wc_ensure_adm2(path, uuid, url, NULL, revision, pool);
589 }
590
591 svn_error_t *
592 svn_wc_create_tmp_file(apr_file_t **fp,
593                        const char *path,
594                        svn_boolean_t delete_on_close,
595                        apr_pool_t *pool)
596 {
597   return svn_wc_create_tmp_file2(fp, NULL, path,
598                                  delete_on_close
599                                  ? svn_io_file_del_on_close
600                                  : svn_io_file_del_none,
601                                  pool);
602 }
603
604 svn_error_t *
605 svn_wc_create_tmp_file2(apr_file_t **fp,
606                         const char **new_name,
607                         const char *path,
608                         svn_io_file_del_t delete_when,
609                         apr_pool_t *pool)
610 {
611   svn_wc_context_t *wc_ctx;
612   const char *local_abspath;
613   const char *temp_dir;
614   svn_error_t *err;
615
616   SVN_ERR_ASSERT(fp || new_name);
617
618   SVN_ERR(svn_wc_context_create(&wc_ctx, NULL /* config */, pool, pool));
619
620   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
621   err = svn_wc__get_tmpdir(&temp_dir, wc_ctx, local_abspath, pool, pool);
622   err = svn_error_compose_create(err, svn_wc_context_destroy(wc_ctx));
623   if (err)
624     return svn_error_trace(err);
625
626   SVN_ERR(svn_io_open_unique_file3(fp, new_name, temp_dir,
627                                    delete_when, pool, pool));
628
629   return SVN_NO_ERROR;
630 }
631
632
633 /*** From adm_ops.c ***/
634 svn_error_t *
635 svn_wc_get_pristine_contents(svn_stream_t **contents,
636                              const char *path,
637                              apr_pool_t *result_pool,
638                              apr_pool_t *scratch_pool)
639 {
640   svn_wc_context_t *wc_ctx;
641   const char *local_abspath;
642
643   SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, scratch_pool, scratch_pool));
644   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
645
646   SVN_ERR(svn_wc_get_pristine_contents2(contents,
647                                         wc_ctx,
648                                         local_abspath,
649                                         result_pool,
650                                         scratch_pool));
651
652   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
653 }
654
655
656 svn_error_t *
657 svn_wc_queue_committed2(svn_wc_committed_queue_t *queue,
658                         const char *path,
659                         svn_wc_adm_access_t *adm_access,
660                         svn_boolean_t recurse,
661                         const apr_array_header_t *wcprop_changes,
662                         svn_boolean_t remove_lock,
663                         svn_boolean_t remove_changelist,
664                         const svn_checksum_t *md5_checksum,
665                         apr_pool_t *scratch_pool)
666 {
667   svn_wc_context_t *wc_ctx;
668   const char *local_abspath;
669   const svn_checksum_t *sha1_checksum = NULL;
670
671   SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, scratch_pool, scratch_pool));
672   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
673
674   if (md5_checksum != NULL)
675     {
676       svn_error_t *err;
677       err = svn_wc__db_pristine_get_sha1(&sha1_checksum, wc_ctx->db,
678                                          local_abspath, md5_checksum,
679                                          svn_wc__get_committed_queue_pool(queue),
680                                          scratch_pool);
681
682       /* Don't fail on SHA1 not found */
683       if (err && err->apr_err == SVN_ERR_WC_DB_ERROR)
684         {
685           svn_error_clear(err);
686           sha1_checksum = NULL;
687         }
688       else
689         SVN_ERR(err);
690     }
691
692   SVN_ERR(svn_wc_queue_committed3(queue, wc_ctx, local_abspath, recurse,
693                                   wcprop_changes,
694                                   remove_lock, remove_changelist,
695                                   sha1_checksum, scratch_pool));
696
697   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
698 }
699
700 svn_error_t *
701 svn_wc_queue_committed(svn_wc_committed_queue_t **queue,
702                        const char *path,
703                        svn_wc_adm_access_t *adm_access,
704                        svn_boolean_t recurse,
705                        const apr_array_header_t *wcprop_changes,
706                        svn_boolean_t remove_lock,
707                        svn_boolean_t remove_changelist,
708                        const unsigned char *digest,
709                        apr_pool_t *pool)
710 {
711   const svn_checksum_t *md5_checksum;
712
713   if (digest)
714     md5_checksum = svn_checksum__from_digest_md5(
715                      digest, svn_wc__get_committed_queue_pool(*queue));
716   else
717     md5_checksum = NULL;
718
719   return svn_wc_queue_committed2(*queue, path, adm_access, recurse,
720                                  wcprop_changes, remove_lock,
721                                  remove_changelist, md5_checksum, pool);
722 }
723
724 svn_error_t *
725 svn_wc_process_committed_queue(svn_wc_committed_queue_t *queue,
726                                svn_wc_adm_access_t *adm_access,
727                                svn_revnum_t new_revnum,
728                                const char *rev_date,
729                                const char *rev_author,
730                                apr_pool_t *pool)
731 {
732   svn_wc_context_t *wc_ctx;
733
734   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL,
735                                          svn_wc__adm_get_db(adm_access),
736                                          pool));
737   SVN_ERR(svn_wc_process_committed_queue2(queue, wc_ctx, new_revnum,
738                                           rev_date, rev_author,
739                                           NULL, NULL, pool));
740   SVN_ERR(svn_wc_context_destroy(wc_ctx));
741
742   return SVN_NO_ERROR;
743 }
744
745 svn_error_t *
746 svn_wc_process_committed4(const char *path,
747                           svn_wc_adm_access_t *adm_access,
748                           svn_boolean_t recurse,
749                           svn_revnum_t new_revnum,
750                           const char *rev_date,
751                           const char *rev_author,
752                           const apr_array_header_t *wcprop_changes,
753                           svn_boolean_t remove_lock,
754                           svn_boolean_t remove_changelist,
755                           const unsigned char *digest,
756                           apr_pool_t *pool)
757 {
758   svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
759   const char *local_abspath;
760   const svn_checksum_t *md5_checksum;
761   const svn_checksum_t *sha1_checksum = NULL;
762   apr_time_t new_date;
763   apr_hash_t *wcprop_changes_hash;
764
765   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
766
767   if (rev_date)
768     SVN_ERR(svn_time_from_cstring(&new_date, rev_date, pool));
769   else
770     new_date = 0;
771
772   if (digest)
773     md5_checksum = svn_checksum__from_digest_md5(digest, pool);
774   else
775     md5_checksum = NULL;
776
777   if (md5_checksum != NULL)
778     {
779       svn_error_t *err;
780       err = svn_wc__db_pristine_get_sha1(&sha1_checksum, db,
781                                          local_abspath, md5_checksum,
782                                          pool, pool);
783
784       if (err && err->apr_err == SVN_ERR_WC_DB_ERROR)
785         {
786           svn_error_clear(err);
787           sha1_checksum = NULL;
788         }
789       else
790         SVN_ERR(err);
791     }
792
793   wcprop_changes_hash = svn_wc__prop_array_to_hash(wcprop_changes, pool);
794   SVN_ERR(svn_wc__process_committed_internal(db, local_abspath, recurse, TRUE,
795                                              new_revnum, new_date, rev_author,
796                                              wcprop_changes_hash,
797                                              !remove_lock, !remove_changelist,
798                                              sha1_checksum, NULL, pool));
799
800   /* Run the log file(s) we just created. */
801   return svn_error_trace(svn_wc__wq_run(db, local_abspath, NULL, NULL, pool));
802 }
803
804
805 svn_error_t *
806 svn_wc_process_committed3(const char *path,
807                           svn_wc_adm_access_t *adm_access,
808                           svn_boolean_t recurse,
809                           svn_revnum_t new_revnum,
810                           const char *rev_date,
811                           const char *rev_author,
812                           const apr_array_header_t *wcprop_changes,
813                           svn_boolean_t remove_lock,
814                           const unsigned char *digest,
815                           apr_pool_t *pool)
816 {
817   return svn_wc_process_committed4(path, adm_access, recurse, new_revnum,
818                                    rev_date, rev_author, wcprop_changes,
819                                    remove_lock, FALSE, digest, pool);
820 }
821
822 svn_error_t *
823 svn_wc_process_committed2(const char *path,
824                           svn_wc_adm_access_t *adm_access,
825                           svn_boolean_t recurse,
826                           svn_revnum_t new_revnum,
827                           const char *rev_date,
828                           const char *rev_author,
829                           const apr_array_header_t *wcprop_changes,
830                           svn_boolean_t remove_lock,
831                           apr_pool_t *pool)
832 {
833   return svn_wc_process_committed3(path, adm_access, recurse, new_revnum,
834                                    rev_date, rev_author, wcprop_changes,
835                                    remove_lock, NULL, pool);
836 }
837
838 svn_error_t *
839 svn_wc_process_committed(const char *path,
840                          svn_wc_adm_access_t *adm_access,
841                          svn_boolean_t recurse,
842                          svn_revnum_t new_revnum,
843                          const char *rev_date,
844                          const char *rev_author,
845                          const apr_array_header_t *wcprop_changes,
846                          apr_pool_t *pool)
847 {
848   return svn_wc_process_committed2(path, adm_access, recurse, new_revnum,
849                                    rev_date, rev_author, wcprop_changes,
850                                    FALSE, pool);
851 }
852
853 svn_error_t *
854 svn_wc_maybe_set_repos_root(svn_wc_adm_access_t *adm_access,
855                             const char *path,
856                             const char *repos,
857                             apr_pool_t *pool)
858 {
859   return SVN_NO_ERROR;
860 }
861
862 svn_error_t *
863 svn_wc_delete3(const char *path,
864                svn_wc_adm_access_t *adm_access,
865                svn_cancel_func_t cancel_func,
866                void *cancel_baton,
867                svn_wc_notify_func2_t notify_func,
868                void *notify_baton,
869                svn_boolean_t keep_local,
870                apr_pool_t *pool)
871 {
872   svn_wc_context_t *wc_ctx;
873   svn_wc__db_t *wc_db = svn_wc__adm_get_db(adm_access);
874   svn_wc_adm_access_t *dir_access;
875   const char *local_abspath;
876
877   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool));
878   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
879
880   /* Open access batons for everything below path, because we used to open
881      these before. */
882   SVN_ERR(svn_wc_adm_probe_try3(&dir_access, adm_access, path,
883                                 TRUE, -1, cancel_func, cancel_baton, pool));
884
885   SVN_ERR(svn_wc_delete4(wc_ctx,
886                          local_abspath,
887                          keep_local,
888                          TRUE,
889                          cancel_func, cancel_baton,
890                          notify_func, notify_baton,
891                          pool));
892
893   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
894 }
895
896 svn_error_t *
897 svn_wc_delete2(const char *path,
898                svn_wc_adm_access_t *adm_access,
899                svn_cancel_func_t cancel_func,
900                void *cancel_baton,
901                svn_wc_notify_func2_t notify_func,
902                void *notify_baton,
903                apr_pool_t *pool)
904 {
905   return svn_wc_delete3(path, adm_access, cancel_func, cancel_baton,
906                         notify_func, notify_baton, FALSE, pool);
907 }
908
909 svn_error_t *
910 svn_wc_delete(const char *path,
911               svn_wc_adm_access_t *adm_access,
912               svn_cancel_func_t cancel_func,
913               void *cancel_baton,
914               svn_wc_notify_func_t notify_func,
915               void *notify_baton,
916               apr_pool_t *pool)
917 {
918   struct compat_notify_baton_t nb;
919
920   nb.func = notify_func;
921   nb.baton = notify_baton;
922
923   return svn_wc_delete2(path, adm_access, cancel_func, cancel_baton,
924                         compat_call_notify_func, &nb, pool);
925 }
926
927 svn_error_t *
928 svn_wc_add_from_disk(svn_wc_context_t *wc_ctx,
929                      const char *local_abspath,
930                      svn_wc_notify_func2_t notify_func,
931                      void *notify_baton,
932                      apr_pool_t *scratch_pool)
933 {
934   SVN_ERR(svn_wc_add_from_disk2(wc_ctx, local_abspath, NULL,
935                                  notify_func, notify_baton, scratch_pool));
936   return SVN_NO_ERROR;
937 }
938
939 svn_error_t *
940 svn_wc_add3(const char *path,
941             svn_wc_adm_access_t *parent_access,
942             svn_depth_t depth,
943             const char *copyfrom_url,
944             svn_revnum_t copyfrom_rev,
945             svn_cancel_func_t cancel_func,
946             void *cancel_baton,
947             svn_wc_notify_func2_t notify_func,
948             void *notify_baton,
949             apr_pool_t *pool)
950 {
951   svn_wc_context_t *wc_ctx;
952   svn_wc__db_t *wc_db = svn_wc__adm_get_db(parent_access);
953   const char *local_abspath;
954
955   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool));
956   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
957
958   SVN_ERR(svn_wc_add4(wc_ctx, local_abspath,
959                       depth, copyfrom_url,
960                       copyfrom_rev,
961                       cancel_func, cancel_baton,
962                       notify_func, notify_baton, pool));
963
964   /* Make sure the caller gets the new access baton in the set. */
965   if (svn_wc__adm_retrieve_internal2(wc_db, local_abspath, pool) == NULL)
966     {
967       svn_node_kind_t kind;
968
969       SVN_ERR(svn_wc__db_read_kind(&kind, wc_db, local_abspath,
970                                    FALSE /* allow_missing */,
971                                    TRUE /* show_deleted */,
972                                    FALSE /* show_hidden */, pool));
973       if (kind == svn_node_dir)
974         {
975           svn_wc_adm_access_t *adm_access;
976
977           /* Open the access baton in adm_access' pool to give it the same
978              lifetime */
979           SVN_ERR(svn_wc_adm_open3(&adm_access, parent_access, path, TRUE,
980                                    copyfrom_url ? -1 : 0,
981                                    cancel_func, cancel_baton,
982                                    svn_wc_adm_access_pool(parent_access)));
983         }
984     }
985
986   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
987 }
988
989
990 svn_error_t *
991 svn_wc_add2(const char *path,
992             svn_wc_adm_access_t *parent_access,
993             const char *copyfrom_url,
994             svn_revnum_t copyfrom_rev,
995             svn_cancel_func_t cancel_func,
996             void *cancel_baton,
997             svn_wc_notify_func2_t notify_func,
998             void *notify_baton,
999             apr_pool_t *pool)
1000 {
1001   return svn_wc_add3(path, parent_access, svn_depth_infinity,
1002                      copyfrom_url, copyfrom_rev,
1003                      cancel_func, cancel_baton,
1004                      notify_func, notify_baton, pool);
1005 }
1006
1007 svn_error_t *
1008 svn_wc_add(const char *path,
1009            svn_wc_adm_access_t *parent_access,
1010            const char *copyfrom_url,
1011            svn_revnum_t copyfrom_rev,
1012            svn_cancel_func_t cancel_func,
1013            void *cancel_baton,
1014            svn_wc_notify_func_t notify_func,
1015            void *notify_baton,
1016            apr_pool_t *pool)
1017 {
1018   struct compat_notify_baton_t nb;
1019
1020   nb.func = notify_func;
1021   nb.baton = notify_baton;
1022
1023   return svn_wc_add2(path, parent_access, copyfrom_url, copyfrom_rev,
1024                      cancel_func, cancel_baton,
1025                      compat_call_notify_func, &nb, pool);
1026 }
1027
1028 svn_error_t *
1029 svn_wc_revert3(const char *path,
1030                svn_wc_adm_access_t *parent_access,
1031                svn_depth_t depth,
1032                svn_boolean_t use_commit_times,
1033                const apr_array_header_t *changelist_filter,
1034                svn_cancel_func_t cancel_func,
1035                void *cancel_baton,
1036                svn_wc_notify_func2_t notify_func,
1037                void *notify_baton,
1038                apr_pool_t *pool)
1039 {
1040   svn_wc_context_t *wc_ctx;
1041   svn_wc__db_t *wc_db = svn_wc__adm_get_db(parent_access);
1042   const char *local_abspath;
1043
1044   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool));
1045   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
1046
1047   SVN_ERR(svn_wc_revert4(wc_ctx,
1048                          local_abspath,
1049                          depth,
1050                          use_commit_times,
1051                          changelist_filter,
1052                          cancel_func, cancel_baton,
1053                          notify_func, notify_baton,
1054                          pool));
1055
1056   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
1057 }
1058
1059 svn_error_t *
1060 svn_wc_revert2(const char *path,
1061                svn_wc_adm_access_t *parent_access,
1062                svn_boolean_t recursive,
1063                svn_boolean_t use_commit_times,
1064                svn_cancel_func_t cancel_func,
1065                void *cancel_baton,
1066                svn_wc_notify_func2_t notify_func,
1067                void *notify_baton,
1068                apr_pool_t *pool)
1069 {
1070   return svn_wc_revert3(path, parent_access,
1071                         SVN_DEPTH_INFINITY_OR_EMPTY(recursive),
1072                         use_commit_times, NULL, cancel_func, cancel_baton,
1073                         notify_func, notify_baton, pool);
1074 }
1075
1076 svn_error_t *
1077 svn_wc_revert(const char *path,
1078               svn_wc_adm_access_t *parent_access,
1079               svn_boolean_t recursive,
1080               svn_boolean_t use_commit_times,
1081               svn_cancel_func_t cancel_func,
1082               void *cancel_baton,
1083               svn_wc_notify_func_t notify_func,
1084               void *notify_baton,
1085               apr_pool_t *pool)
1086 {
1087   struct compat_notify_baton_t nb;
1088
1089   nb.func = notify_func;
1090   nb.baton = notify_baton;
1091
1092   return svn_wc_revert2(path, parent_access, recursive, use_commit_times,
1093                         cancel_func, cancel_baton,
1094                         compat_call_notify_func, &nb, pool);
1095 }
1096
1097 svn_error_t *
1098 svn_wc_remove_from_revision_control(svn_wc_adm_access_t *adm_access,
1099                                     const char *name,
1100                                     svn_boolean_t destroy_wf,
1101                                     svn_boolean_t instant_error,
1102                                     svn_cancel_func_t cancel_func,
1103                                     void *cancel_baton,
1104                                     apr_pool_t *pool)
1105 {
1106   svn_wc_context_t *wc_ctx;
1107   svn_wc__db_t *wc_db = svn_wc__adm_get_db(adm_access);
1108   const char *local_abspath = svn_dirent_join(
1109                                     svn_wc__adm_access_abspath(adm_access),
1110                                     name,
1111                                     pool);
1112
1113   /* name must be an entry in adm_access, fail if not */
1114   SVN_ERR_ASSERT(strcmp(svn_dirent_basename(name, NULL), name) == 0);
1115   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool));
1116
1117   SVN_ERR(svn_wc_remove_from_revision_control2(wc_ctx,
1118                                                local_abspath,
1119                                                destroy_wf,
1120                                                instant_error,
1121                                                cancel_func, cancel_baton,
1122                                                pool));
1123
1124   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
1125 }
1126
1127 svn_error_t *
1128 svn_wc_resolved_conflict4(const char *path,
1129                           svn_wc_adm_access_t *adm_access,
1130                           svn_boolean_t resolve_text,
1131                           svn_boolean_t resolve_props,
1132                           svn_boolean_t resolve_tree,
1133                           svn_depth_t depth,
1134                           svn_wc_conflict_choice_t conflict_choice,
1135                           svn_wc_notify_func2_t notify_func,
1136                           void *notify_baton,
1137                           svn_cancel_func_t cancel_func,
1138                           void *cancel_baton,
1139                           apr_pool_t *pool)
1140 {
1141   svn_wc_context_t *wc_ctx;
1142   svn_wc__db_t *wc_db = svn_wc__adm_get_db(adm_access);
1143   const char *local_abspath;
1144
1145   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
1146   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool));
1147
1148   SVN_ERR(svn_wc_resolved_conflict5(wc_ctx,
1149                                     local_abspath,
1150                                     depth,
1151                                     resolve_text,
1152                                     resolve_props ? "" : NULL,
1153                                     resolve_tree,
1154                                     conflict_choice,
1155                                     cancel_func,
1156                                     cancel_baton,
1157                                     notify_func,
1158                                     notify_baton,
1159                                     pool));
1160
1161   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
1162
1163 }
1164
1165 svn_error_t *
1166 svn_wc_resolved_conflict(const char *path,
1167                          svn_wc_adm_access_t *adm_access,
1168                          svn_boolean_t resolve_text,
1169                          svn_boolean_t resolve_props,
1170                          svn_boolean_t recurse,
1171                          svn_wc_notify_func_t notify_func,
1172                          void *notify_baton,
1173                          apr_pool_t *pool)
1174 {
1175   struct compat_notify_baton_t nb;
1176
1177   nb.func = notify_func;
1178   nb.baton = notify_baton;
1179
1180   return svn_wc_resolved_conflict2(path, adm_access,
1181                                    resolve_text, resolve_props, recurse,
1182                                    compat_call_notify_func, &nb,
1183                                    NULL, NULL, pool);
1184
1185 }
1186
1187 svn_error_t *
1188 svn_wc_resolved_conflict2(const char *path,
1189                           svn_wc_adm_access_t *adm_access,
1190                           svn_boolean_t resolve_text,
1191                           svn_boolean_t resolve_props,
1192                           svn_boolean_t recurse,
1193                           svn_wc_notify_func2_t notify_func,
1194                           void *notify_baton,
1195                           svn_cancel_func_t cancel_func,
1196                           void *cancel_baton,
1197                           apr_pool_t *pool)
1198 {
1199   return svn_wc_resolved_conflict3(path, adm_access, resolve_text,
1200                                    resolve_props,
1201                                    SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
1202                                    svn_wc_conflict_choose_merged,
1203                                    notify_func, notify_baton, cancel_func,
1204                                    cancel_baton, pool);
1205 }
1206
1207 svn_error_t *
1208 svn_wc_resolved_conflict3(const char *path,
1209                           svn_wc_adm_access_t *adm_access,
1210                           svn_boolean_t resolve_text,
1211                           svn_boolean_t resolve_props,
1212                           svn_depth_t depth,
1213                           svn_wc_conflict_choice_t conflict_choice,
1214                           svn_wc_notify_func2_t notify_func,
1215                           void *notify_baton,
1216                           svn_cancel_func_t cancel_func,
1217                           void *cancel_baton,
1218                           apr_pool_t *pool)
1219 {
1220   return svn_wc_resolved_conflict4(path, adm_access, resolve_text,
1221                                    resolve_props, FALSE, depth,
1222                                    svn_wc_conflict_choose_merged,
1223                                    notify_func, notify_baton, cancel_func,
1224                                    cancel_baton, pool);
1225 }
1226
1227 svn_error_t *
1228 svn_wc_add_lock(const char *path,
1229                 const svn_lock_t *lock,
1230                 svn_wc_adm_access_t *adm_access,
1231                 apr_pool_t *pool)
1232 {
1233   const char *local_abspath;
1234   svn_wc_context_t *wc_ctx;
1235
1236   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
1237   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
1238                                          svn_wc__adm_get_db(adm_access),
1239                                          pool));
1240
1241   SVN_ERR(svn_wc_add_lock2(wc_ctx, local_abspath, lock, pool));
1242
1243   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
1244 }
1245
1246 svn_error_t *
1247 svn_wc_remove_lock(const char *path,
1248                    svn_wc_adm_access_t *adm_access,
1249                    apr_pool_t *pool)
1250 {
1251   const char *local_abspath;
1252   svn_wc_context_t *wc_ctx;
1253
1254   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
1255   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
1256                                          svn_wc__adm_get_db(adm_access),
1257                                          pool));
1258
1259   SVN_ERR(svn_wc_remove_lock2(wc_ctx, local_abspath, pool));
1260
1261   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
1262
1263 }
1264
1265 svn_error_t *
1266 svn_wc_get_ancestry(char **url,
1267                     svn_revnum_t *rev,
1268                     const char *path,
1269                     svn_wc_adm_access_t *adm_access,
1270                     apr_pool_t *pool)
1271 {
1272   const char *local_abspath;
1273   const svn_wc_entry_t *entry;
1274
1275   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
1276
1277   SVN_ERR(svn_wc__get_entry(&entry, svn_wc__adm_get_db(adm_access),
1278                             local_abspath, FALSE,
1279                             svn_node_unknown,
1280                             pool, pool));
1281
1282   if (url)
1283     *url = apr_pstrdup(pool, entry->url);
1284
1285   if (rev)
1286     *rev = entry->revision;
1287
1288   return SVN_NO_ERROR;
1289 }
1290
1291 svn_error_t *
1292 svn_wc_set_changelist(const char *path,
1293                       const char *changelist,
1294                       svn_wc_adm_access_t *adm_access,
1295                       svn_cancel_func_t cancel_func,
1296                       void *cancel_baton,
1297                       svn_wc_notify_func2_t notify_func,
1298                       void *notify_baton,
1299                       apr_pool_t *pool)
1300 {
1301   const char *local_abspath;
1302   svn_wc_context_t *wc_ctx;
1303
1304   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
1305   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
1306                                          svn_wc__adm_get_db(adm_access),
1307                                          pool));
1308
1309   SVN_ERR(svn_wc_set_changelist2(wc_ctx, local_abspath, changelist,
1310                                  svn_depth_empty, NULL,
1311                                  cancel_func, cancel_baton, notify_func,
1312                                  notify_baton, pool));
1313
1314   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
1315 }
1316
1317
1318 /*** From diff.c ***/
1319 /* Used to wrap svn_wc_diff_callbacks_t. */
1320 struct diff_callbacks_wrapper_baton {
1321   const svn_wc_diff_callbacks_t *callbacks;
1322   void *baton;
1323 };
1324
1325 /* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t. */
1326 static svn_error_t *
1327 wrap_3to1_file_changed(svn_wc_adm_access_t *adm_access,
1328                        svn_wc_notify_state_t *contentstate,
1329                        svn_wc_notify_state_t *propstate,
1330                        svn_boolean_t *tree_conflicted,
1331                        const char *path,
1332                        const char *tmpfile1,
1333                        const char *tmpfile2,
1334                        svn_revnum_t rev1,
1335                        svn_revnum_t rev2,
1336                        const char *mimetype1,
1337                        const char *mimetype2,
1338                        const apr_array_header_t *propchanges,
1339                        apr_hash_t *originalprops,
1340                        void *diff_baton)
1341 {
1342   struct diff_callbacks_wrapper_baton *b = diff_baton;
1343
1344   if (tree_conflicted)
1345     *tree_conflicted = FALSE;
1346
1347   if (tmpfile2 != NULL)
1348     SVN_ERR(b->callbacks->file_changed(adm_access, contentstate, path,
1349                                        tmpfile1, tmpfile2,
1350                                        rev1, rev2, mimetype1, mimetype2,
1351                                        b->baton));
1352   if (propchanges->nelts > 0)
1353     SVN_ERR(b->callbacks->props_changed(adm_access, propstate, path,
1354                                         propchanges, originalprops,
1355                                         b->baton));
1356
1357   return SVN_NO_ERROR;
1358 }
1359
1360 /* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t. */
1361 static svn_error_t *
1362 wrap_3to1_file_added(svn_wc_adm_access_t *adm_access,
1363                      svn_wc_notify_state_t *contentstate,
1364                      svn_wc_notify_state_t *propstate,
1365                      svn_boolean_t *tree_conflicted,
1366                      const char *path,
1367                      const char *tmpfile1,
1368                      const char *tmpfile2,
1369                      svn_revnum_t rev1,
1370                      svn_revnum_t rev2,
1371                      const char *mimetype1,
1372                      const char *mimetype2,
1373                      const apr_array_header_t *propchanges,
1374                      apr_hash_t *originalprops,
1375                      void *diff_baton)
1376 {
1377   struct diff_callbacks_wrapper_baton *b = diff_baton;
1378
1379   if (tree_conflicted)
1380     *tree_conflicted = FALSE;
1381
1382   SVN_ERR(b->callbacks->file_added(adm_access, contentstate, path,
1383                                    tmpfile1, tmpfile2, rev1, rev2,
1384                                    mimetype1, mimetype2, b->baton));
1385   if (propchanges->nelts > 0)
1386     SVN_ERR(b->callbacks->props_changed(adm_access, propstate, path,
1387                                         propchanges, originalprops,
1388                                         b->baton));
1389
1390   return SVN_NO_ERROR;
1391 }
1392
1393 /* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t. */
1394 static svn_error_t *
1395 wrap_3to1_file_deleted(svn_wc_adm_access_t *adm_access,
1396                        svn_wc_notify_state_t *state,
1397                        svn_boolean_t *tree_conflicted,
1398                        const char *path,
1399                        const char *tmpfile1,
1400                        const char *tmpfile2,
1401                        const char *mimetype1,
1402                        const char *mimetype2,
1403                        apr_hash_t *originalprops,
1404                        void *diff_baton)
1405 {
1406   struct diff_callbacks_wrapper_baton *b = diff_baton;
1407
1408   if (tree_conflicted)
1409     *tree_conflicted = FALSE;
1410
1411   SVN_ERR_ASSERT(originalprops);
1412
1413   return b->callbacks->file_deleted(adm_access, state, path,
1414                                     tmpfile1, tmpfile2, mimetype1, mimetype2,
1415                                     b->baton);
1416 }
1417
1418 /* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t. */
1419 static svn_error_t *
1420 wrap_3to1_dir_added(svn_wc_adm_access_t *adm_access,
1421                     svn_wc_notify_state_t *state,
1422                     svn_boolean_t *tree_conflicted,
1423                     const char *path,
1424                     svn_revnum_t rev,
1425                     void *diff_baton)
1426 {
1427   struct diff_callbacks_wrapper_baton *b = diff_baton;
1428
1429   if (tree_conflicted)
1430     *tree_conflicted = FALSE;
1431
1432   return b->callbacks->dir_added(adm_access, state, path, rev, b->baton);
1433 }
1434
1435 /* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t. */
1436 static svn_error_t *
1437 wrap_3to1_dir_deleted(svn_wc_adm_access_t *adm_access,
1438                       svn_wc_notify_state_t *state,
1439                       svn_boolean_t *tree_conflicted,
1440                       const char *path,
1441                       void *diff_baton)
1442 {
1443   struct diff_callbacks_wrapper_baton *b = diff_baton;
1444
1445   if (tree_conflicted)
1446     *tree_conflicted = FALSE;
1447
1448   return b->callbacks->dir_deleted(adm_access, state, path, b->baton);
1449 }
1450
1451 /* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t. */
1452 static svn_error_t *
1453 wrap_3to1_dir_props_changed(svn_wc_adm_access_t *adm_access,
1454                             svn_wc_notify_state_t *state,
1455                             svn_boolean_t *tree_conflicted,
1456                             const char *path,
1457                             const apr_array_header_t *propchanges,
1458                             apr_hash_t *originalprops,
1459                             void *diff_baton)
1460 {
1461   struct diff_callbacks_wrapper_baton *b = diff_baton;
1462
1463   if (tree_conflicted)
1464     *tree_conflicted = FALSE;
1465
1466   return b->callbacks->props_changed(adm_access, state, path, propchanges,
1467                                      originalprops, b->baton);
1468 }
1469
1470 /* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t
1471    and svn_wc_diff_callbacks2_t. */
1472 static svn_error_t *
1473 wrap_3to1or2_dir_opened(svn_wc_adm_access_t *adm_access,
1474                         svn_boolean_t *tree_conflicted,
1475                         const char *path,
1476                         svn_revnum_t rev,
1477                         void *diff_baton)
1478 {
1479   if (tree_conflicted)
1480     *tree_conflicted = FALSE;
1481   /* Do nothing. */
1482   return SVN_NO_ERROR;
1483 }
1484
1485 /* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t
1486    and svn_wc_diff_callbacks2_t. */
1487 static svn_error_t *
1488 wrap_3to1or2_dir_closed(svn_wc_adm_access_t *adm_access,
1489                         svn_wc_notify_state_t *propstate,
1490                         svn_wc_notify_state_t *contentstate,
1491                         svn_boolean_t *tree_conflicted,
1492                         const char *path,
1493                         void *diff_baton)
1494 {
1495   if (contentstate)
1496     *contentstate = svn_wc_notify_state_unknown;
1497   if (propstate)
1498     *propstate = svn_wc_notify_state_unknown;
1499   if (tree_conflicted)
1500     *tree_conflicted = FALSE;
1501   /* Do nothing. */
1502   return SVN_NO_ERROR;
1503 }
1504
1505 /* Used to wrap svn_diff_callbacks_t as an svn_wc_diff_callbacks3_t. */
1506 static struct svn_wc_diff_callbacks3_t diff_callbacks_wrapper = {
1507   wrap_3to1_file_changed,
1508   wrap_3to1_file_added,
1509   wrap_3to1_file_deleted,
1510   wrap_3to1_dir_added,
1511   wrap_3to1_dir_deleted,
1512   wrap_3to1_dir_props_changed,
1513   wrap_3to1or2_dir_opened,
1514   wrap_3to1or2_dir_closed
1515 };
1516
1517
1518
1519 /* Used to wrap svn_wc_diff_callbacks2_t. */
1520 struct diff_callbacks2_wrapper_baton {
1521   const svn_wc_diff_callbacks2_t *callbacks2;
1522   void *baton;
1523 };
1524
1525 /* An svn_wc_diff_callbacks3_t function for wrapping
1526  * svn_wc_diff_callbacks2_t. */
1527 static svn_error_t *
1528 wrap_3to2_file_changed(svn_wc_adm_access_t *adm_access,
1529                        svn_wc_notify_state_t *contentstate,
1530                        svn_wc_notify_state_t *propstate,
1531                        svn_boolean_t *tree_conflicted,
1532                        const char *path,
1533                        const char *tmpfile1,
1534                        const char *tmpfile2,
1535                        svn_revnum_t rev1,
1536                        svn_revnum_t rev2,
1537                        const char *mimetype1,
1538                        const char *mimetype2,
1539                        const apr_array_header_t *propchanges,
1540                        apr_hash_t *originalprops,
1541                        void *diff_baton)
1542 {
1543   struct diff_callbacks2_wrapper_baton *b = diff_baton;
1544
1545   if (tree_conflicted)
1546     *tree_conflicted = FALSE;
1547
1548   return b->callbacks2->file_changed(adm_access, contentstate, propstate,
1549                                      path, tmpfile1, tmpfile2,
1550                                      rev1, rev2, mimetype1, mimetype2,
1551                                      propchanges, originalprops, b->baton);
1552 }
1553
1554 /* An svn_wc_diff_callbacks3_t function for wrapping
1555  * svn_wc_diff_callbacks2_t. */
1556 static svn_error_t *
1557 wrap_3to2_file_added(svn_wc_adm_access_t *adm_access,
1558                      svn_wc_notify_state_t *contentstate,
1559                      svn_wc_notify_state_t *propstate,
1560                      svn_boolean_t *tree_conflicted,
1561                      const char *path,
1562                      const char *tmpfile1,
1563                      const char *tmpfile2,
1564                      svn_revnum_t rev1,
1565                      svn_revnum_t rev2,
1566                      const char *mimetype1,
1567                      const char *mimetype2,
1568                      const apr_array_header_t *propchanges,
1569                      apr_hash_t *originalprops,
1570                      void *diff_baton)
1571 {
1572   struct diff_callbacks2_wrapper_baton *b = diff_baton;
1573
1574   if (tree_conflicted)
1575     *tree_conflicted = FALSE;
1576
1577   return b->callbacks2->file_added(adm_access, contentstate, propstate, path,
1578                                    tmpfile1, tmpfile2, rev1, rev2,
1579                                    mimetype1, mimetype2, propchanges,
1580                                    originalprops, b->baton);
1581 }
1582
1583 /* An svn_wc_diff_callbacks3_t function for wrapping
1584  * svn_wc_diff_callbacks2_t. */
1585 static svn_error_t *
1586 wrap_3to2_file_deleted(svn_wc_adm_access_t *adm_access,
1587                        svn_wc_notify_state_t *state,
1588                        svn_boolean_t *tree_conflicted,
1589                        const char *path,
1590                        const char *tmpfile1,
1591                        const char *tmpfile2,
1592                        const char *mimetype1,
1593                        const char *mimetype2,
1594                        apr_hash_t *originalprops,
1595                        void *diff_baton)
1596 {
1597   struct diff_callbacks2_wrapper_baton *b = diff_baton;
1598
1599   if (tree_conflicted)
1600     *tree_conflicted = FALSE;
1601
1602   return b->callbacks2->file_deleted(adm_access, state, path,
1603                                      tmpfile1, tmpfile2, mimetype1, mimetype2,
1604                                      originalprops, b->baton);
1605 }
1606
1607 /* An svn_wc_diff_callbacks3_t function for wrapping
1608  * svn_wc_diff_callbacks2_t. */
1609 static svn_error_t *
1610 wrap_3to2_dir_added(svn_wc_adm_access_t *adm_access,
1611                     svn_wc_notify_state_t *state,
1612                     svn_boolean_t *tree_conflicted,
1613                     const char *path,
1614                     svn_revnum_t rev,
1615                     void *diff_baton)
1616 {
1617   struct diff_callbacks2_wrapper_baton *b = diff_baton;
1618
1619   if (tree_conflicted)
1620     *tree_conflicted = FALSE;
1621
1622   return b->callbacks2->dir_added(adm_access, state, path, rev, b->baton);
1623 }
1624
1625 /* An svn_wc_diff_callbacks3_t function for wrapping
1626  * svn_wc_diff_callbacks2_t. */
1627 static svn_error_t *
1628 wrap_3to2_dir_deleted(svn_wc_adm_access_t *adm_access,
1629                       svn_wc_notify_state_t *state,
1630                       svn_boolean_t *tree_conflicted,
1631                       const char *path,
1632                       void *diff_baton)
1633 {
1634   struct diff_callbacks2_wrapper_baton *b = diff_baton;
1635
1636   if (tree_conflicted)
1637     *tree_conflicted = FALSE;
1638
1639   return b->callbacks2->dir_deleted(adm_access, state, path, b->baton);
1640 }
1641
1642 /* An svn_wc_diff_callbacks3_t function for wrapping
1643  * svn_wc_diff_callbacks2_t. */
1644 static svn_error_t *
1645 wrap_3to2_dir_props_changed(svn_wc_adm_access_t *adm_access,
1646                             svn_wc_notify_state_t *state,
1647                             svn_boolean_t *tree_conflicted,
1648                             const char *path,
1649                             const apr_array_header_t *propchanges,
1650                             apr_hash_t *originalprops,
1651                             void *diff_baton)
1652 {
1653   struct diff_callbacks2_wrapper_baton *b = diff_baton;
1654
1655   if (tree_conflicted)
1656     *tree_conflicted = FALSE;
1657
1658   return b->callbacks2->dir_props_changed(adm_access, state, path, propchanges,
1659                                           originalprops, b->baton);
1660 }
1661
1662 /* Used to wrap svn_diff_callbacks2_t as an svn_wc_diff_callbacks3_t. */
1663 static struct svn_wc_diff_callbacks3_t diff_callbacks2_wrapper = {
1664   wrap_3to2_file_changed,
1665   wrap_3to2_file_added,
1666   wrap_3to2_file_deleted,
1667   wrap_3to2_dir_added,
1668   wrap_3to2_dir_deleted,
1669   wrap_3to2_dir_props_changed,
1670   wrap_3to1or2_dir_opened,
1671   wrap_3to1or2_dir_closed
1672 };
1673
1674
1675
1676 /* Used to wrap svn_wc_diff_callbacks3_t. */
1677 struct diff_callbacks3_wrapper_baton {
1678   const svn_wc_diff_callbacks3_t *callbacks3;
1679   svn_wc__db_t *db;
1680   void *baton;
1681   const char *anchor;
1682   const char *anchor_abspath;
1683 };
1684
1685 static svn_error_t *
1686 wrap_4to3_file_opened(svn_boolean_t *tree_conflicted,
1687                       svn_boolean_t *skip,
1688                       const char *path,
1689                       svn_revnum_t rev,
1690                       void *diff_baton,
1691                       apr_pool_t *scratch_pool)
1692 {
1693   return SVN_NO_ERROR;
1694 }
1695
1696 /* An svn_wc_diff_callbacks4_t function for wrapping
1697  * svn_wc_diff_callbacks3_t. */
1698 static svn_error_t *
1699 wrap_4to3_file_changed(svn_wc_notify_state_t *contentstate,
1700                        svn_wc_notify_state_t *propstate,
1701                        svn_boolean_t *tree_conflicted,
1702                        const char *path,
1703                        const char *tmpfile1,
1704                        const char *tmpfile2,
1705                        svn_revnum_t rev1,
1706                        svn_revnum_t rev2,
1707                        const char *mimetype1,
1708                        const char *mimetype2,
1709                        const apr_array_header_t *propchanges,
1710                        apr_hash_t *originalprops,
1711                        void *diff_baton,
1712                        apr_pool_t *scratch_pool)
1713 {
1714   struct diff_callbacks3_wrapper_baton *b = diff_baton;
1715   svn_wc_adm_access_t *adm_access;
1716   const char *dir = svn_relpath_dirname(path, scratch_pool);
1717
1718   adm_access = svn_wc__adm_retrieve_internal2(
1719                         b->db,
1720                         svn_dirent_join(b->anchor_abspath, dir, scratch_pool),
1721                         scratch_pool);
1722
1723   return b->callbacks3->file_changed(adm_access, contentstate, propstate,
1724                                      tree_conflicted,
1725                                      svn_dirent_join(b->anchor, path,
1726                                                      scratch_pool),
1727                                      tmpfile1, tmpfile2,
1728                                      rev1, rev2, mimetype1, mimetype2,
1729                                      propchanges, originalprops, b->baton);
1730 }
1731
1732 /* An svn_wc_diff_callbacks4_t function for wrapping
1733  * svn_wc_diff_callbacks3_t. */
1734 static svn_error_t *
1735 wrap_4to3_file_added(svn_wc_notify_state_t *contentstate,
1736                      svn_wc_notify_state_t *propstate,
1737                      svn_boolean_t *tree_conflicted,
1738                      const char *path,
1739                      const char *tmpfile1,
1740                      const char *tmpfile2,
1741                      svn_revnum_t rev1,
1742                      svn_revnum_t rev2,
1743                      const char *mimetype1,
1744                      const char *mimetype2,
1745                      const char *copyfrom_path,
1746                      svn_revnum_t copyfrom_revision,
1747                      const apr_array_header_t *propchanges,
1748                      apr_hash_t *originalprops,
1749                      void *diff_baton,
1750                      apr_pool_t *scratch_pool)
1751 {
1752   struct diff_callbacks3_wrapper_baton *b = diff_baton;
1753   svn_wc_adm_access_t *adm_access;
1754   const char *dir = svn_relpath_dirname(path, scratch_pool);
1755
1756   adm_access = svn_wc__adm_retrieve_internal2(
1757                         b->db,
1758                         svn_dirent_join(b->anchor_abspath, dir, scratch_pool),
1759                         scratch_pool);
1760
1761   return b->callbacks3->file_added(adm_access, contentstate, propstate,
1762                                    tree_conflicted,
1763                                    svn_dirent_join(b->anchor, path,
1764                                                    scratch_pool),
1765                                    tmpfile1, tmpfile2,
1766                                    rev1, rev2, mimetype1, mimetype2,
1767                                    propchanges, originalprops, b->baton);
1768 }
1769
1770 /* An svn_wc_diff_callbacks4_t function for wrapping
1771  * svn_wc_diff_callbacks3_t. */
1772 static svn_error_t *
1773 wrap_4to3_file_deleted(svn_wc_notify_state_t *state,
1774                        svn_boolean_t *tree_conflicted,
1775                        const char *path,
1776                        const char *tmpfile1,
1777                        const char *tmpfile2,
1778                        const char *mimetype1,
1779                        const char *mimetype2,
1780                        apr_hash_t *originalprops,
1781                        void *diff_baton,
1782                        apr_pool_t *scratch_pool)
1783 {
1784   struct diff_callbacks3_wrapper_baton *b = diff_baton;
1785   svn_wc_adm_access_t *adm_access;
1786   const char *dir = svn_relpath_dirname(path, scratch_pool);
1787
1788   adm_access = svn_wc__adm_retrieve_internal2(
1789                         b->db,
1790                         svn_dirent_join(b->anchor_abspath, dir, scratch_pool),
1791                         scratch_pool);
1792
1793   return b->callbacks3->file_deleted(adm_access, state, tree_conflicted,
1794                                      svn_dirent_join(b->anchor, path,
1795                                                      scratch_pool),
1796                                      tmpfile1, tmpfile2,
1797                                      mimetype1, mimetype2, originalprops,
1798                                      b->baton);
1799 }
1800
1801 /* An svn_wc_diff_callbacks4_t function for wrapping
1802  * svn_wc_diff_callbacks3_t. */
1803 static svn_error_t *
1804 wrap_4to3_dir_added(svn_wc_notify_state_t *state,
1805                     svn_boolean_t *tree_conflicted,
1806                     svn_boolean_t *skip,
1807                     svn_boolean_t *skip_children,
1808                     const char *path,
1809                     svn_revnum_t rev,
1810                     const char *copyfrom_path,
1811                     svn_revnum_t copyfrom_revision,
1812                     void *diff_baton,
1813                     apr_pool_t *scratch_pool)
1814 {
1815   struct diff_callbacks3_wrapper_baton *b = diff_baton;
1816   svn_wc_adm_access_t *adm_access;
1817
1818   adm_access = svn_wc__adm_retrieve_internal2(
1819                         b->db,
1820                         svn_dirent_join(b->anchor_abspath, path, scratch_pool),
1821                         scratch_pool);
1822
1823   return b->callbacks3->dir_added(adm_access, state, tree_conflicted,
1824                                   svn_dirent_join(b->anchor, path,
1825                                                      scratch_pool),
1826                                   rev, b->baton);
1827 }
1828
1829 /* An svn_wc_diff_callbacks4_t function for wrapping
1830  * svn_wc_diff_callbacks3_t. */
1831 static svn_error_t *
1832 wrap_4to3_dir_deleted(svn_wc_notify_state_t *state,
1833                       svn_boolean_t *tree_conflicted,
1834                       const char *path,
1835                       void *diff_baton,
1836                       apr_pool_t *scratch_pool)
1837 {
1838   struct diff_callbacks3_wrapper_baton *b = diff_baton;
1839   svn_wc_adm_access_t *adm_access;
1840
1841   adm_access = svn_wc__adm_retrieve_internal2(
1842                         b->db,
1843                         svn_dirent_join(b->anchor_abspath, path, scratch_pool),
1844                         scratch_pool);
1845
1846   return b->callbacks3->dir_deleted(adm_access, state, tree_conflicted,
1847                                     svn_dirent_join(b->anchor, path,
1848                                                      scratch_pool),
1849                                     b->baton);
1850 }
1851
1852 /* An svn_wc_diff_callbacks4_t function for wrapping
1853  * svn_wc_diff_callbacks3_t. */
1854 static svn_error_t *
1855 wrap_4to3_dir_props_changed(svn_wc_notify_state_t *propstate,
1856                             svn_boolean_t *tree_conflicted,
1857                             const char *path,
1858                             svn_boolean_t dir_was_added,
1859                             const apr_array_header_t *propchanges,
1860                             apr_hash_t *original_props,
1861                             void *diff_baton,
1862                             apr_pool_t *scratch_pool)
1863 {
1864   struct diff_callbacks3_wrapper_baton *b = diff_baton;
1865   svn_wc_adm_access_t *adm_access;
1866
1867   adm_access = svn_wc__adm_retrieve_internal2(
1868                         b->db,
1869                         svn_dirent_join(b->anchor_abspath, path, scratch_pool),
1870                         scratch_pool);
1871
1872   return b->callbacks3->dir_props_changed(adm_access, propstate,
1873                                           tree_conflicted,
1874                                           svn_dirent_join(b->anchor, path,
1875                                                      scratch_pool),
1876                                           propchanges, original_props,
1877                                           b->baton);
1878 }
1879
1880 /* An svn_wc_diff_callbacks4_t function for wrapping
1881  * svn_wc_diff_callbacks3_t. */
1882 static svn_error_t *
1883 wrap_4to3_dir_opened(svn_boolean_t *tree_conflicted,
1884                      svn_boolean_t *skip,
1885                      svn_boolean_t *skip_children,
1886                      const char *path,
1887                      svn_revnum_t rev,
1888                      void *diff_baton,
1889                      apr_pool_t *scratch_pool)
1890 {
1891   struct diff_callbacks3_wrapper_baton *b = diff_baton;
1892   svn_wc_adm_access_t *adm_access;
1893
1894   adm_access = svn_wc__adm_retrieve_internal2(
1895                         b->db,
1896                         svn_dirent_join(b->anchor_abspath, path, scratch_pool),
1897                         scratch_pool);
1898   if (skip_children)
1899     *skip_children = FALSE;
1900
1901   return b->callbacks3->dir_opened(adm_access, tree_conflicted,
1902                                    svn_dirent_join(b->anchor, path,
1903                                                      scratch_pool),
1904                                    rev, b->baton);
1905 }
1906
1907 /* An svn_wc_diff_callbacks4_t function for wrapping
1908  * svn_wc_diff_callbacks3_t. */
1909 static svn_error_t *
1910 wrap_4to3_dir_closed(svn_wc_notify_state_t *contentstate,
1911                      svn_wc_notify_state_t *propstate,
1912                      svn_boolean_t *tree_conflicted,
1913                      const char *path,
1914                      svn_boolean_t dir_was_added,
1915                      void *diff_baton,
1916                      apr_pool_t *scratch_pool)
1917 {
1918   struct diff_callbacks3_wrapper_baton *b = diff_baton;
1919   svn_wc_adm_access_t *adm_access;
1920
1921   adm_access = svn_wc__adm_retrieve_internal2(
1922                         b->db,
1923                         svn_dirent_join(b->anchor_abspath, path, scratch_pool),
1924                         scratch_pool);
1925
1926   return b->callbacks3->dir_closed(adm_access, contentstate, propstate,
1927                                    tree_conflicted,
1928                                    svn_dirent_join(b->anchor, path,
1929                                                      scratch_pool),
1930                                    b->baton);
1931 }
1932
1933
1934 /* Used to wrap svn_diff_callbacks3_t as an svn_wc_diff_callbacks4_t. */
1935 static struct svn_wc_diff_callbacks4_t diff_callbacks3_wrapper = {
1936   wrap_4to3_file_opened,
1937   wrap_4to3_file_changed,
1938   wrap_4to3_file_added,
1939   wrap_4to3_file_deleted,
1940   wrap_4to3_dir_deleted,
1941   wrap_4to3_dir_opened,
1942   wrap_4to3_dir_added,
1943   wrap_4to3_dir_props_changed,
1944   wrap_4to3_dir_closed
1945 };
1946
1947
1948 svn_error_t *
1949 svn_wc_get_diff_editor6(const svn_delta_editor_t **editor,
1950                         void **edit_baton,
1951                         svn_wc_context_t *wc_ctx,
1952                         const char *anchor_abspath,
1953                         const char *target,
1954                         svn_depth_t depth,
1955                         svn_boolean_t ignore_ancestry,
1956                         svn_boolean_t show_copies_as_adds,
1957                         svn_boolean_t use_git_diff_format,
1958                         svn_boolean_t use_text_base,
1959                         svn_boolean_t reverse_order,
1960                         svn_boolean_t server_performs_filtering,
1961                         const apr_array_header_t *changelist_filter,
1962                         const svn_wc_diff_callbacks4_t *callbacks,
1963                         void *callback_baton,
1964                         svn_cancel_func_t cancel_func,
1965                         void *cancel_baton,
1966                         apr_pool_t *result_pool,
1967                         apr_pool_t *scratch_pool)
1968 {
1969   return svn_error_trace(
1970     svn_wc__get_diff_editor(editor, edit_baton,
1971                             wc_ctx,
1972                             anchor_abspath, target,
1973                             depth,
1974                             ignore_ancestry, show_copies_as_adds,
1975                             use_git_diff_format, use_text_base,
1976                             reverse_order, server_performs_filtering,
1977                             changelist_filter,
1978                             callbacks, callback_baton,
1979                             cancel_func, cancel_baton,
1980                             result_pool, scratch_pool));
1981 }
1982
1983
1984 svn_error_t *
1985 svn_wc_get_diff_editor5(svn_wc_adm_access_t *anchor,
1986                         const char *target,
1987                         const svn_wc_diff_callbacks3_t *callbacks,
1988                         void *callback_baton,
1989                         svn_depth_t depth,
1990                         svn_boolean_t ignore_ancestry,
1991                         svn_boolean_t use_text_base,
1992                         svn_boolean_t reverse_order,
1993                         svn_cancel_func_t cancel_func,
1994                         void *cancel_baton,
1995                         const apr_array_header_t *changelist_filter,
1996                         const svn_delta_editor_t **editor,
1997                         void **edit_baton,
1998                         apr_pool_t *pool)
1999 {
2000   struct diff_callbacks3_wrapper_baton *b = apr_palloc(pool, sizeof(*b));
2001   svn_wc_context_t *wc_ctx;
2002   svn_wc__db_t *db = svn_wc__adm_get_db(anchor);
2003
2004   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool));
2005
2006   b->callbacks3 = callbacks;
2007   b->baton = callback_baton;
2008   b->db = db;
2009   b->anchor = svn_wc_adm_access_path(anchor);
2010   b->anchor_abspath = svn_wc__adm_access_abspath(anchor);
2011
2012   SVN_ERR(svn_wc_get_diff_editor6(editor,
2013                                    edit_baton,
2014                                    wc_ctx,
2015                                    b->anchor_abspath,
2016                                    target,
2017                                    depth,
2018                                    ignore_ancestry,
2019                                    FALSE,
2020                                    FALSE,
2021                                    use_text_base,
2022                                    reverse_order,
2023                                    FALSE,
2024                                    changelist_filter,
2025                                    &diff_callbacks3_wrapper,
2026                                    b,
2027                                    cancel_func,
2028                                    cancel_baton,
2029                                    pool,
2030                                    pool));
2031
2032   /* Can't destroy wc_ctx. It is used by the diff editor */
2033
2034    return SVN_NO_ERROR;
2035 }
2036
2037 svn_error_t *
2038 svn_wc_get_diff_editor4(svn_wc_adm_access_t *anchor,
2039                         const char *target,
2040                         const svn_wc_diff_callbacks2_t *callbacks,
2041                         void *callback_baton,
2042                         svn_depth_t depth,
2043                         svn_boolean_t ignore_ancestry,
2044                         svn_boolean_t use_text_base,
2045                         svn_boolean_t reverse_order,
2046                         svn_cancel_func_t cancel_func,
2047                         void *cancel_baton,
2048                         const apr_array_header_t *changelist_filter,
2049                         const svn_delta_editor_t **editor,
2050                         void **edit_baton,
2051                         apr_pool_t *pool)
2052 {
2053   struct diff_callbacks2_wrapper_baton *b = apr_palloc(pool, sizeof(*b));
2054   b->callbacks2 = callbacks;
2055   b->baton = callback_baton;
2056   return svn_wc_get_diff_editor5(anchor,
2057                                  target,
2058                                  &diff_callbacks2_wrapper,
2059                                  b,
2060                                  depth,
2061                                  ignore_ancestry,
2062                                  use_text_base,
2063                                  reverse_order,
2064                                  cancel_func,
2065                                  cancel_baton,
2066                                  changelist_filter,
2067                                  editor,
2068                                  edit_baton,
2069                                  pool);
2070 }
2071
2072 svn_error_t *
2073 svn_wc_get_diff_editor3(svn_wc_adm_access_t *anchor,
2074                         const char *target,
2075                         const svn_wc_diff_callbacks2_t *callbacks,
2076                         void *callback_baton,
2077                         svn_boolean_t recurse,
2078                         svn_boolean_t ignore_ancestry,
2079                         svn_boolean_t use_text_base,
2080                         svn_boolean_t reverse_order,
2081                         svn_cancel_func_t cancel_func,
2082                         void *cancel_baton,
2083                         const svn_delta_editor_t **editor,
2084                         void **edit_baton,
2085                         apr_pool_t *pool)
2086 {
2087   return svn_wc_get_diff_editor4(anchor,
2088                                  target,
2089                                  callbacks,
2090                                  callback_baton,
2091                                  SVN_DEPTH_INFINITY_OR_FILES(recurse),
2092                                  ignore_ancestry,
2093                                  use_text_base,
2094                                  reverse_order,
2095                                  cancel_func,
2096                                  cancel_baton,
2097                                  NULL,
2098                                  editor,
2099                                  edit_baton,
2100                                  pool);
2101 }
2102
2103 svn_error_t *
2104 svn_wc_get_diff_editor2(svn_wc_adm_access_t *anchor,
2105                         const char *target,
2106                         const svn_wc_diff_callbacks_t *callbacks,
2107                         void *callback_baton,
2108                         svn_boolean_t recurse,
2109                         svn_boolean_t ignore_ancestry,
2110                         svn_boolean_t use_text_base,
2111                         svn_boolean_t reverse_order,
2112                         svn_cancel_func_t cancel_func,
2113                         void *cancel_baton,
2114                         const svn_delta_editor_t **editor,
2115                         void **edit_baton,
2116                         apr_pool_t *pool)
2117 {
2118   struct diff_callbacks_wrapper_baton *b = apr_palloc(pool, sizeof(*b));
2119   b->callbacks = callbacks;
2120   b->baton = callback_baton;
2121   return svn_wc_get_diff_editor5(anchor, target, &diff_callbacks_wrapper, b,
2122                                  SVN_DEPTH_INFINITY_OR_FILES(recurse),
2123                                  ignore_ancestry, use_text_base,
2124                                  reverse_order, cancel_func, cancel_baton,
2125                                  NULL, editor, edit_baton, pool);
2126 }
2127
2128 svn_error_t *
2129 svn_wc_get_diff_editor(svn_wc_adm_access_t *anchor,
2130                        const char *target,
2131                        const svn_wc_diff_callbacks_t *callbacks,
2132                        void *callback_baton,
2133                        svn_boolean_t recurse,
2134                        svn_boolean_t use_text_base,
2135                        svn_boolean_t reverse_order,
2136                        svn_cancel_func_t cancel_func,
2137                        void *cancel_baton,
2138                        const svn_delta_editor_t **editor,
2139                        void **edit_baton,
2140                        apr_pool_t *pool)
2141 {
2142   return svn_wc_get_diff_editor2(anchor, target, callbacks, callback_baton,
2143                                  recurse, FALSE, use_text_base, reverse_order,
2144                                  cancel_func, cancel_baton,
2145                                  editor, edit_baton, pool);
2146 }
2147
2148 svn_error_t *
2149 svn_wc_diff5(svn_wc_adm_access_t *anchor,
2150              const char *target,
2151              const svn_wc_diff_callbacks3_t *callbacks,
2152              void *callback_baton,
2153              svn_depth_t depth,
2154              svn_boolean_t ignore_ancestry,
2155              const apr_array_header_t *changelist_filter,
2156              apr_pool_t *pool)
2157 {
2158   struct diff_callbacks3_wrapper_baton *b = apr_palloc(pool, sizeof(*b));
2159   svn_wc_context_t *wc_ctx;
2160   svn_wc__db_t *db = svn_wc__adm_get_db(anchor);
2161
2162   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool));
2163
2164   b->callbacks3 = callbacks;
2165   b->baton = callback_baton;
2166   b->anchor = svn_wc_adm_access_path(anchor);
2167   b->anchor_abspath = svn_wc__adm_access_abspath(anchor);
2168
2169   SVN_ERR(svn_wc_diff6(wc_ctx,
2170                        svn_dirent_join(b->anchor_abspath, target, pool),
2171                        &diff_callbacks3_wrapper,
2172                        b,
2173                        depth,
2174                        ignore_ancestry,
2175                        FALSE,
2176                        FALSE,
2177                        changelist_filter,
2178                        NULL, NULL,
2179                        pool));
2180
2181   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
2182 }
2183
2184 svn_error_t *
2185 svn_wc_diff4(svn_wc_adm_access_t *anchor,
2186              const char *target,
2187              const svn_wc_diff_callbacks2_t *callbacks,
2188              void *callback_baton,
2189              svn_depth_t depth,
2190              svn_boolean_t ignore_ancestry,
2191              const apr_array_header_t *changelist_filter,
2192              apr_pool_t *pool)
2193 {
2194   struct diff_callbacks2_wrapper_baton *b = apr_palloc(pool, sizeof(*b));
2195   b->callbacks2 = callbacks;
2196   b->baton = callback_baton;
2197
2198   return svn_wc_diff5(anchor, target, &diff_callbacks2_wrapper, b,
2199                       depth, ignore_ancestry, changelist_filter, pool);
2200 }
2201
2202 svn_error_t *
2203 svn_wc_diff3(svn_wc_adm_access_t *anchor,
2204              const char *target,
2205              const svn_wc_diff_callbacks2_t *callbacks,
2206              void *callback_baton,
2207              svn_boolean_t recurse,
2208              svn_boolean_t ignore_ancestry,
2209              apr_pool_t *pool)
2210 {
2211   return svn_wc_diff4(anchor, target, callbacks, callback_baton,
2212                       SVN_DEPTH_INFINITY_OR_FILES(recurse), ignore_ancestry,
2213                       NULL, pool);
2214 }
2215
2216 svn_error_t *
2217 svn_wc_diff2(svn_wc_adm_access_t *anchor,
2218              const char *target,
2219              const svn_wc_diff_callbacks_t *callbacks,
2220              void *callback_baton,
2221              svn_boolean_t recurse,
2222              svn_boolean_t ignore_ancestry,
2223              apr_pool_t *pool)
2224 {
2225   struct diff_callbacks_wrapper_baton *b = apr_pcalloc(pool, sizeof(*b));
2226   b->callbacks = callbacks;
2227   b->baton = callback_baton;
2228   return svn_wc_diff5(anchor, target, &diff_callbacks_wrapper, b,
2229                       SVN_DEPTH_INFINITY_OR_FILES(recurse), ignore_ancestry,
2230                       NULL, pool);
2231 }
2232
2233 svn_error_t *
2234 svn_wc_diff(svn_wc_adm_access_t *anchor,
2235             const char *target,
2236             const svn_wc_diff_callbacks_t *callbacks,
2237             void *callback_baton,
2238             svn_boolean_t recurse,
2239             apr_pool_t *pool)
2240 {
2241   return svn_wc_diff2(anchor, target, callbacks, callback_baton,
2242                       recurse, FALSE, pool);
2243 }
2244
2245 /*** From entries.c ***/
2246 svn_error_t *
2247 svn_wc_walk_entries2(const char *path,
2248                      svn_wc_adm_access_t *adm_access,
2249                      const svn_wc_entry_callbacks_t *walk_callbacks,
2250                      void *walk_baton,
2251                      svn_boolean_t show_hidden,
2252                      svn_cancel_func_t cancel_func,
2253                      void *cancel_baton,
2254                      apr_pool_t *pool)
2255 {
2256   svn_wc_entry_callbacks2_t walk_cb2 = { 0 };
2257   walk_cb2.found_entry = walk_callbacks->found_entry;
2258   walk_cb2.handle_error = svn_wc__walker_default_error_handler;
2259   return svn_wc_walk_entries3(path, adm_access,
2260                               &walk_cb2, walk_baton, svn_depth_infinity,
2261                               show_hidden, cancel_func, cancel_baton, pool);
2262 }
2263
2264 svn_error_t *
2265 svn_wc_walk_entries(const char *path,
2266                     svn_wc_adm_access_t *adm_access,
2267                     const svn_wc_entry_callbacks_t *walk_callbacks,
2268                     void *walk_baton,
2269                     svn_boolean_t show_hidden,
2270                     apr_pool_t *pool)
2271 {
2272   return svn_wc_walk_entries2(path, adm_access, walk_callbacks,
2273                               walk_baton, show_hidden, NULL, NULL,
2274                               pool);
2275 }
2276
2277 svn_error_t *
2278 svn_wc_mark_missing_deleted(const char *path,
2279                             svn_wc_adm_access_t *parent,
2280                             apr_pool_t *pool)
2281 {
2282   /* With a single DB a node will never be missing */
2283   return svn_error_createf(SVN_ERR_WC_PATH_FOUND, NULL,
2284                            _("Unexpectedly found '%s': "
2285                              "path is marked 'missing'"),
2286                            svn_dirent_local_style(path, pool));
2287 }
2288
2289
2290 /*** From props.c ***/
2291 svn_error_t *
2292 svn_wc_parse_externals_description2(apr_array_header_t **externals_p,
2293                                     const char *parent_directory,
2294                                     const char *desc,
2295                                     apr_pool_t *pool)
2296 {
2297   apr_array_header_t *list;
2298   apr_pool_t *subpool = svn_pool_create(pool);
2299
2300   SVN_ERR(svn_wc_parse_externals_description3(externals_p ? &list : NULL,
2301                                               parent_directory, desc,
2302                                               TRUE, subpool));
2303
2304   if (externals_p)
2305     {
2306       int i;
2307
2308       *externals_p = apr_array_make(pool, list->nelts,
2309                                     sizeof(svn_wc_external_item_t *));
2310       for (i = 0; i < list->nelts; i++)
2311         {
2312           svn_wc_external_item2_t *item2 = APR_ARRAY_IDX(list, i,
2313                                              svn_wc_external_item2_t *);
2314           svn_wc_external_item_t *item = apr_palloc(pool, sizeof (*item));
2315
2316           if (item2->target_dir)
2317             item->target_dir = apr_pstrdup(pool, item2->target_dir);
2318           if (item2->url)
2319             item->url = apr_pstrdup(pool, item2->url);
2320           item->revision = item2->revision;
2321
2322           APR_ARRAY_PUSH(*externals_p, svn_wc_external_item_t *) = item;
2323         }
2324     }
2325
2326   svn_pool_destroy(subpool);
2327
2328   return SVN_NO_ERROR;
2329 }
2330
2331
2332 svn_error_t *
2333 svn_wc_parse_externals_description(apr_hash_t **externals_p,
2334                                    const char *parent_directory,
2335                                    const char *desc,
2336                                    apr_pool_t *pool)
2337 {
2338   apr_array_header_t *list;
2339
2340   SVN_ERR(svn_wc_parse_externals_description2(externals_p ? &list : NULL,
2341                                               parent_directory, desc, pool));
2342
2343   /* Store all of the items into the hash if that was requested. */
2344   if (externals_p)
2345     {
2346       int i;
2347
2348       *externals_p = apr_hash_make(pool);
2349       for (i = 0; i < list->nelts; i++)
2350         {
2351           svn_wc_external_item_t *item;
2352           item = APR_ARRAY_IDX(list, i, svn_wc_external_item_t *);
2353
2354           svn_hash_sets(*externals_p, item->target_dir, item);
2355         }
2356     }
2357   return SVN_NO_ERROR;
2358 }
2359
2360 svn_error_t *
2361 svn_wc_prop_set3(const char *name,
2362                  const svn_string_t *value,
2363                  const char *path,
2364                  svn_wc_adm_access_t *adm_access,
2365                  svn_boolean_t skip_checks,
2366                  svn_wc_notify_func2_t notify_func,
2367                  void *notify_baton,
2368                  apr_pool_t *pool)
2369 {
2370   svn_wc_context_t *wc_ctx;
2371   const char *local_abspath;
2372   svn_error_t *err;
2373
2374   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
2375   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
2376                                          svn_wc__adm_get_db(adm_access),
2377                                          pool));
2378
2379   err = svn_wc_prop_set4(wc_ctx, local_abspath,
2380                          name, value,
2381                          svn_depth_empty,
2382                          skip_checks, NULL /* changelist_filter */,
2383                          NULL, NULL /* cancellation */,
2384                          notify_func, notify_baton,
2385                          pool);
2386
2387   if (err && err->apr_err == SVN_ERR_WC_INVALID_SCHEDULE)
2388     svn_error_clear(err);
2389   else
2390     SVN_ERR(err);
2391
2392   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
2393 }
2394
2395 svn_error_t *
2396 svn_wc_prop_set2(const char *name,
2397                  const svn_string_t *value,
2398                  const char *path,
2399                  svn_wc_adm_access_t *adm_access,
2400                  svn_boolean_t skip_checks,
2401                  apr_pool_t *pool)
2402 {
2403   return svn_wc_prop_set3(name, value, path, adm_access, skip_checks,
2404                           NULL, NULL, pool);
2405 }
2406
2407 svn_error_t *
2408 svn_wc_prop_set(const char *name,
2409                 const svn_string_t *value,
2410                 const char *path,
2411                 svn_wc_adm_access_t *adm_access,
2412                 apr_pool_t *pool)
2413 {
2414   return svn_wc_prop_set2(name, value, path, adm_access, FALSE, pool);
2415 }
2416
2417 svn_error_t *
2418 svn_wc_prop_list(apr_hash_t **props,
2419                  const char *path,
2420                  svn_wc_adm_access_t *adm_access,
2421                  apr_pool_t *pool)
2422 {
2423   svn_wc_context_t *wc_ctx;
2424   const char *local_abspath;
2425   svn_error_t *err;
2426
2427   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
2428   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
2429                                          svn_wc__adm_get_db(adm_access), pool));
2430
2431   err = svn_wc_prop_list2(props, wc_ctx, local_abspath, pool, pool);
2432   if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
2433     {
2434       *props = apr_hash_make(pool);
2435       svn_error_clear(err);
2436       err = NULL;
2437     }
2438
2439   return svn_error_compose_create(err, svn_wc_context_destroy(wc_ctx));
2440 }
2441
2442 svn_error_t *
2443 svn_wc_prop_get(const svn_string_t **value,
2444                 const char *name,
2445                 const char *path,
2446                 svn_wc_adm_access_t *adm_access,
2447                 apr_pool_t *pool)
2448 {
2449
2450   svn_wc_context_t *wc_ctx;
2451   const char *local_abspath;
2452   svn_error_t *err;
2453
2454   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
2455   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
2456                                          svn_wc__adm_get_db(adm_access), pool));
2457
2458   err = svn_wc_prop_get2(value, wc_ctx, local_abspath, name, pool, pool);
2459
2460   if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
2461     {
2462       *value = NULL;
2463       svn_error_clear(err);
2464       err = NULL;
2465     }
2466
2467   return svn_error_compose_create(err, svn_wc_context_destroy(wc_ctx));
2468 }
2469
2470 /* baton for conflict_func_1to2_wrapper */
2471 struct conflict_func_1to2_baton
2472 {
2473   svn_wc_conflict_resolver_func_t inner_func;
2474   void *inner_baton;
2475 };
2476
2477
2478 /* Implements svn_wc_conflict_resolver_func2_t */
2479 static svn_error_t *
2480 conflict_func_1to2_wrapper(svn_wc_conflict_result_t **result,
2481                            const svn_wc_conflict_description2_t *conflict,
2482                            void *baton,
2483                            apr_pool_t *result_pool,
2484                            apr_pool_t *scratch_pool)
2485 {
2486   struct conflict_func_1to2_baton *btn = baton;
2487   svn_wc_conflict_description_t *cd = svn_wc__cd2_to_cd(conflict,
2488                                                         scratch_pool);
2489
2490   return svn_error_trace(btn->inner_func(result, cd, btn->inner_baton,
2491                                          result_pool));
2492 }
2493
2494 svn_error_t *
2495 svn_wc_merge_props2(svn_wc_notify_state_t *state,
2496                     const char *path,
2497                     svn_wc_adm_access_t *adm_access,
2498                     apr_hash_t *baseprops,
2499                     const apr_array_header_t *propchanges,
2500                     svn_boolean_t base_merge,
2501                     svn_boolean_t dry_run,
2502                     svn_wc_conflict_resolver_func_t conflict_func,
2503                     void *conflict_baton,
2504                     apr_pool_t *scratch_pool)
2505 {
2506   const char *local_abspath;
2507   svn_error_t *err;
2508   svn_wc_context_t *wc_ctx;
2509   struct conflict_func_1to2_baton conflict_wrapper;
2510
2511   if (base_merge && !dry_run)
2512     return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
2513                             U_("base_merge=TRUE is no longer supported; "
2514                                "see notes/api-errata/1.7/wc006.txt"));
2515
2516   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
2517
2518   conflict_wrapper.inner_func = conflict_func;
2519   conflict_wrapper.inner_baton = conflict_baton;
2520
2521   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL,
2522                                          svn_wc__adm_get_db(adm_access),
2523                                          scratch_pool));
2524
2525   err = svn_wc_merge_props3(state,
2526                             wc_ctx,
2527                             local_abspath,
2528                             NULL /* left_version */,
2529                             NULL /* right_version */,
2530                             baseprops,
2531                             propchanges,
2532                             dry_run,
2533                             conflict_func ? conflict_func_1to2_wrapper
2534                                           : NULL,
2535                             &conflict_wrapper,
2536                             NULL, NULL,
2537                             scratch_pool);
2538
2539   if (err)
2540     switch(err->apr_err)
2541       {
2542         case SVN_ERR_WC_PATH_NOT_FOUND:
2543         case SVN_ERR_WC_PATH_UNEXPECTED_STATUS:
2544           err->apr_err = SVN_ERR_UNVERSIONED_RESOURCE;
2545           break;
2546       }
2547   return svn_error_trace(
2548             svn_error_compose_create(err,
2549                                      svn_wc_context_destroy(wc_ctx)));
2550 }
2551
2552 svn_error_t *
2553 svn_wc_merge_props(svn_wc_notify_state_t *state,
2554                    const char *path,
2555                    svn_wc_adm_access_t *adm_access,
2556                    apr_hash_t *baseprops,
2557                    const apr_array_header_t *propchanges,
2558                    svn_boolean_t base_merge,
2559                    svn_boolean_t dry_run,
2560                    apr_pool_t *pool)
2561 {
2562   return svn_wc_merge_props2(state, path, adm_access, baseprops, propchanges,
2563                              base_merge, dry_run, NULL, NULL, pool);
2564 }
2565
2566
2567 svn_error_t *
2568 svn_wc_merge_prop_diffs(svn_wc_notify_state_t *state,
2569                         const char *path,
2570                         svn_wc_adm_access_t *adm_access,
2571                         const apr_array_header_t *propchanges,
2572                         svn_boolean_t base_merge,
2573                         svn_boolean_t dry_run,
2574                         apr_pool_t *pool)
2575 {
2576   /* NOTE: Here, we use implementation knowledge.  The public
2577      svn_wc_merge_props2 doesn't allow NULL as baseprops argument, but we know
2578      that it works. */
2579   return svn_wc_merge_props2(state, path, adm_access, NULL, propchanges,
2580                              base_merge, dry_run, NULL, NULL, pool);
2581 }
2582
2583 svn_error_t *
2584 svn_wc_get_prop_diffs(apr_array_header_t **propchanges,
2585                       apr_hash_t **original_props,
2586                       const char *path,
2587                       svn_wc_adm_access_t *adm_access,
2588                       apr_pool_t *pool)
2589 {
2590   svn_wc_context_t *wc_ctx;
2591   const char *local_abspath;
2592
2593   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
2594   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
2595                                          svn_wc__adm_get_db(adm_access), pool));
2596
2597   SVN_ERR(svn_wc_get_prop_diffs2(propchanges, original_props, wc_ctx,
2598                                  local_abspath, pool, pool));
2599
2600   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
2601 }
2602
2603
2604 svn_error_t *
2605 svn_wc_props_modified_p(svn_boolean_t *modified_p,
2606                         const char *path,
2607                         svn_wc_adm_access_t *adm_access,
2608                         apr_pool_t *pool)
2609 {
2610   svn_wc_context_t *wc_ctx;
2611   const char *local_abspath;
2612   svn_error_t *err;
2613
2614   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
2615   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
2616                                          svn_wc__adm_get_db(adm_access), pool));
2617
2618   err = svn_wc_props_modified_p2(modified_p,
2619                                  wc_ctx,
2620                                  local_abspath,
2621                                  pool);
2622
2623   if (err)
2624     {
2625       if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
2626         return svn_error_trace(err);
2627
2628       svn_error_clear(err);
2629       *modified_p = FALSE;
2630     }
2631
2632   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
2633 }
2634
2635
2636 /*** From status.c ***/
2637
2638 struct status4_wrapper_baton
2639 {
2640   svn_wc_status_func3_t old_func;
2641   void *old_baton;
2642   const char *anchor_abspath;
2643   const char *anchor_relpath;
2644   svn_wc_context_t *wc_ctx;
2645 };
2646
2647 /* */
2648 static svn_error_t *
2649 status4_wrapper_func(void *baton,
2650                      const char *local_abspath,
2651                      const svn_wc_status3_t *status,
2652                      apr_pool_t *scratch_pool)
2653 {
2654   struct status4_wrapper_baton *swb = baton;
2655   svn_wc_status2_t *dup;
2656   const char *path = local_abspath;
2657
2658   SVN_ERR(svn_wc__status2_from_3(&dup, status, swb->wc_ctx, local_abspath,
2659                                  scratch_pool, scratch_pool));
2660
2661   if (swb->anchor_abspath != NULL)
2662     {
2663       path = svn_dirent_join(
2664                 swb->anchor_relpath,
2665                 svn_dirent_skip_ancestor(swb->anchor_abspath, local_abspath),
2666                 scratch_pool);
2667     }
2668
2669   return (*swb->old_func)(swb->old_baton, path, dup, scratch_pool);
2670 }
2671
2672
2673 svn_error_t *
2674 svn_wc_get_status_editor5(const svn_delta_editor_t **editor,
2675                           void **edit_baton,
2676                           void **set_locks_baton,
2677                           svn_revnum_t *edit_revision,
2678                           svn_wc_context_t *wc_ctx,
2679                           const char *anchor_abspath,
2680                           const char *target_basename,
2681                           svn_depth_t depth,
2682                           svn_boolean_t get_all,
2683                           svn_boolean_t no_ignore,
2684                           svn_boolean_t depth_as_sticky,
2685                           svn_boolean_t server_performs_filtering,
2686                           const apr_array_header_t *ignore_patterns,
2687                           svn_wc_status_func4_t status_func,
2688                           void *status_baton,
2689                           svn_cancel_func_t cancel_func,
2690                           void *cancel_baton,
2691                           apr_pool_t *result_pool,
2692                           apr_pool_t *scratch_pool)
2693 {
2694   return svn_error_trace(
2695     svn_wc__get_status_editor(editor, edit_baton,
2696                               set_locks_baton,
2697                               edit_revision,
2698                               wc_ctx,
2699                               anchor_abspath,
2700                               target_basename,
2701                               depth,
2702                               get_all, no_ignore,
2703                               depth_as_sticky,
2704                               server_performs_filtering,
2705                               ignore_patterns,
2706                               status_func, status_baton,
2707                               cancel_func, cancel_baton,
2708                               result_pool,
2709                               scratch_pool));
2710 }
2711
2712
2713 svn_error_t *
2714 svn_wc_get_status_editor4(const svn_delta_editor_t **editor,
2715                           void **edit_baton,
2716                           void **set_locks_baton,
2717                           svn_revnum_t *edit_revision,
2718                           svn_wc_adm_access_t *anchor,
2719                           const char *target,
2720                           svn_depth_t depth,
2721                           svn_boolean_t get_all,
2722                           svn_boolean_t no_ignore,
2723                           const apr_array_header_t *ignore_patterns,
2724                           svn_wc_status_func3_t status_func,
2725                           void *status_baton,
2726                           svn_cancel_func_t cancel_func,
2727                           void *cancel_baton,
2728                           svn_wc_traversal_info_t *traversal_info,
2729                           apr_pool_t *pool)
2730 {
2731   struct status4_wrapper_baton *swb = apr_palloc(pool, sizeof(*swb));
2732   svn_wc__db_t *wc_db;
2733   svn_wc_context_t *wc_ctx;
2734   const char *anchor_abspath;
2735
2736   swb->old_func = status_func;
2737   swb->old_baton = status_baton;
2738
2739   wc_db = svn_wc__adm_get_db(anchor);
2740
2741   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
2742                                          wc_db, pool));
2743
2744   swb->wc_ctx = wc_ctx;
2745
2746   anchor_abspath = svn_wc__adm_access_abspath(anchor);
2747
2748   if (!svn_dirent_is_absolute(svn_wc_adm_access_path(anchor)))
2749     {
2750       swb->anchor_abspath = anchor_abspath;
2751       swb->anchor_relpath = svn_wc_adm_access_path(anchor);
2752     }
2753   else
2754     {
2755       swb->anchor_abspath = NULL;
2756       swb->anchor_relpath = NULL;
2757     }
2758
2759   /* Before subversion 1.7 status always handled depth as sticky. 1.7 made
2760      the output of svn status by default match the result of what would be
2761      updated by a similar svn update. (Following the documentation) */
2762
2763   SVN_ERR(svn_wc_get_status_editor5(editor, edit_baton, set_locks_baton,
2764                                     edit_revision, wc_ctx, anchor_abspath,
2765                                     target, depth, get_all,
2766                                     no_ignore,
2767                                     (depth != svn_depth_unknown) /*as_sticky*/,
2768                                     FALSE /* server_performs_filtering */,
2769                                     ignore_patterns,
2770                                     status4_wrapper_func, swb,
2771                                     cancel_func, cancel_baton,
2772                                     pool, pool));
2773
2774   if (traversal_info)
2775     {
2776       const char *local_path = svn_wc_adm_access_path(anchor);
2777       const char *local_abspath = anchor_abspath;
2778       if (*target)
2779         {
2780           local_path = svn_dirent_join(local_path, target, pool);
2781           local_abspath = svn_dirent_join(local_abspath, target, pool);
2782         }
2783
2784       SVN_ERR(gather_traversal_info(wc_ctx, local_abspath, local_path, depth,
2785                                     traversal_info, TRUE, TRUE,
2786                                     pool));
2787     }
2788
2789   /* We can't destroy wc_ctx here, because the editor needs it while it's
2790      driven. */
2791   return SVN_NO_ERROR;
2792 }
2793
2794 struct status_editor3_compat_baton
2795 {
2796   svn_wc_status_func2_t old_func;
2797   void *old_baton;
2798 };
2799
2800 /* */
2801 static svn_error_t *
2802 status_editor3_compat_func(void *baton,
2803                            const char *path,
2804                            svn_wc_status2_t *status,
2805                            apr_pool_t *pool)
2806 {
2807   struct status_editor3_compat_baton *secb = baton;
2808
2809   secb->old_func(secb->old_baton, path, status);
2810   return SVN_NO_ERROR;
2811 }
2812
2813 svn_error_t *
2814 svn_wc_get_status_editor3(const svn_delta_editor_t **editor,
2815                           void **edit_baton,
2816                           void **set_locks_baton,
2817                           svn_revnum_t *edit_revision,
2818                           svn_wc_adm_access_t *anchor,
2819                           const char *target,
2820                           svn_depth_t depth,
2821                           svn_boolean_t get_all,
2822                           svn_boolean_t no_ignore,
2823                           const apr_array_header_t *ignore_patterns,
2824                           svn_wc_status_func2_t status_func,
2825                           void *status_baton,
2826                           svn_cancel_func_t cancel_func,
2827                           void *cancel_baton,
2828                           svn_wc_traversal_info_t *traversal_info,
2829                           apr_pool_t *pool)
2830 {
2831   /* This baton must live beyond this function. Alloc on heap.  */
2832   struct status_editor3_compat_baton *secb = apr_palloc(pool, sizeof(*secb));
2833
2834   secb->old_func = status_func;
2835   secb->old_baton = status_baton;
2836
2837   return svn_wc_get_status_editor4(editor, edit_baton, set_locks_baton,
2838                                    edit_revision, anchor, target, depth,
2839                                    get_all, no_ignore, ignore_patterns,
2840                                    status_editor3_compat_func, secb,
2841                                    cancel_func, cancel_baton, traversal_info,
2842                                    pool);
2843 }
2844
2845 svn_error_t *
2846 svn_wc_get_status_editor2(const svn_delta_editor_t **editor,
2847                           void **edit_baton,
2848                           void **set_locks_baton,
2849                           svn_revnum_t *edit_revision,
2850                           svn_wc_adm_access_t *anchor,
2851                           const char *target,
2852                           apr_hash_t *config,
2853                           svn_boolean_t recurse,
2854                           svn_boolean_t get_all,
2855                           svn_boolean_t no_ignore,
2856                           svn_wc_status_func2_t status_func,
2857                           void *status_baton,
2858                           svn_cancel_func_t cancel_func,
2859                           void *cancel_baton,
2860                           svn_wc_traversal_info_t *traversal_info,
2861                           apr_pool_t *pool)
2862 {
2863   apr_array_header_t *ignores;
2864
2865   SVN_ERR(svn_wc_get_default_ignores(&ignores, config, pool));
2866   return svn_wc_get_status_editor3(editor,
2867                                    edit_baton,
2868                                    set_locks_baton,
2869                                    edit_revision,
2870                                    anchor,
2871                                    target,
2872                                    SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
2873                                    get_all,
2874                                    no_ignore,
2875                                    ignores,
2876                                    status_func,
2877                                    status_baton,
2878                                    cancel_func,
2879                                    cancel_baton,
2880                                    traversal_info,
2881                                    pool);
2882 }
2883
2884
2885 /* Helpers for deprecated svn_wc_status_editor(), of type
2886    svn_wc_status_func2_t. */
2887 struct old_status_func_cb_baton
2888 {
2889   svn_wc_status_func_t original_func;
2890   void *original_baton;
2891 };
2892
2893 /* */
2894 static void old_status_func_cb(void *baton,
2895                                const char *path,
2896                                svn_wc_status2_t *status)
2897 {
2898   struct old_status_func_cb_baton *b = baton;
2899   svn_wc_status_t *stat = (svn_wc_status_t *) status;
2900
2901   b->original_func(b->original_baton, path, stat);
2902 }
2903
2904 svn_error_t *
2905 svn_wc_get_status_editor(const svn_delta_editor_t **editor,
2906                          void **edit_baton,
2907                          svn_revnum_t *edit_revision,
2908                          svn_wc_adm_access_t *anchor,
2909                          const char *target,
2910                          apr_hash_t *config,
2911                          svn_boolean_t recurse,
2912                          svn_boolean_t get_all,
2913                          svn_boolean_t no_ignore,
2914                          svn_wc_status_func_t status_func,
2915                          void *status_baton,
2916                          svn_cancel_func_t cancel_func,
2917                          void *cancel_baton,
2918                          svn_wc_traversal_info_t *traversal_info,
2919                          apr_pool_t *pool)
2920 {
2921   struct old_status_func_cb_baton *b = apr_pcalloc(pool, sizeof(*b));
2922   apr_array_header_t *ignores;
2923   b->original_func = status_func;
2924   b->original_baton = status_baton;
2925   SVN_ERR(svn_wc_get_default_ignores(&ignores, config, pool));
2926   return svn_wc_get_status_editor3(editor, edit_baton, NULL, edit_revision,
2927                                    anchor, target,
2928                                    SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
2929                                    get_all, no_ignore, ignores,
2930                                    old_status_func_cb, b,
2931                                    cancel_func, cancel_baton,
2932                                    traversal_info, pool);
2933 }
2934
2935 svn_error_t *
2936 svn_wc_status(svn_wc_status_t **status,
2937               const char *path,
2938               svn_wc_adm_access_t *adm_access,
2939               apr_pool_t *pool)
2940 {
2941   svn_wc_status2_t *stat2;
2942
2943   SVN_ERR(svn_wc_status2(&stat2, path, adm_access, pool));
2944   *status = (svn_wc_status_t *) stat2;
2945   return SVN_NO_ERROR;
2946 }
2947
2948
2949 static svn_wc_conflict_description_t *
2950 conflict_description_dup(const svn_wc_conflict_description_t *conflict,
2951                          apr_pool_t *pool)
2952 {
2953   svn_wc_conflict_description_t *new_conflict;
2954
2955   new_conflict = apr_pcalloc(pool, sizeof(*new_conflict));
2956
2957   /* Shallow copy all members. */
2958   *new_conflict = *conflict;
2959
2960   if (conflict->path)
2961     new_conflict->path = apr_pstrdup(pool, conflict->path);
2962   if (conflict->property_name)
2963     new_conflict->property_name = apr_pstrdup(pool, conflict->property_name);
2964   if (conflict->mime_type)
2965     new_conflict->mime_type = apr_pstrdup(pool, conflict->mime_type);
2966   /* NOTE: We cannot make a deep copy of adm_access. */
2967   if (conflict->base_file)
2968     new_conflict->base_file = apr_pstrdup(pool, conflict->base_file);
2969   if (conflict->their_file)
2970     new_conflict->their_file = apr_pstrdup(pool, conflict->their_file);
2971   if (conflict->my_file)
2972     new_conflict->my_file = apr_pstrdup(pool, conflict->my_file);
2973   if (conflict->merged_file)
2974     new_conflict->merged_file = apr_pstrdup(pool, conflict->merged_file);
2975   if (conflict->src_left_version)
2976     new_conflict->src_left_version =
2977       svn_wc_conflict_version_dup(conflict->src_left_version, pool);
2978   if (conflict->src_right_version)
2979     new_conflict->src_right_version =
2980       svn_wc_conflict_version_dup(conflict->src_right_version, pool);
2981
2982   return new_conflict;
2983 }
2984
2985
2986 svn_wc_status2_t *
2987 svn_wc_dup_status2(const svn_wc_status2_t *orig_stat,
2988                    apr_pool_t *pool)
2989 {
2990   svn_wc_status2_t *new_stat = apr_palloc(pool, sizeof(*new_stat));
2991
2992   /* Shallow copy all members. */
2993   *new_stat = *orig_stat;
2994
2995   /* Now go back and dup the deep items into this pool. */
2996   if (orig_stat->entry)
2997     new_stat->entry = svn_wc_entry_dup(orig_stat->entry, pool);
2998
2999   if (orig_stat->repos_lock)
3000     new_stat->repos_lock = svn_lock_dup(orig_stat->repos_lock, pool);
3001
3002   if (orig_stat->url)
3003     new_stat->url = apr_pstrdup(pool, orig_stat->url);
3004
3005   if (orig_stat->ood_last_cmt_author)
3006     new_stat->ood_last_cmt_author
3007       = apr_pstrdup(pool, orig_stat->ood_last_cmt_author);
3008
3009   if (orig_stat->tree_conflict)
3010     new_stat->tree_conflict
3011       = conflict_description_dup(orig_stat->tree_conflict, pool);
3012
3013   /* Return the new hotness. */
3014   return new_stat;
3015 }
3016
3017 svn_wc_status_t *
3018 svn_wc_dup_status(const svn_wc_status_t *orig_stat,
3019                   apr_pool_t *pool)
3020 {
3021   svn_wc_status_t *new_stat = apr_palloc(pool, sizeof(*new_stat));
3022
3023   /* Shallow copy all members. */
3024   *new_stat = *orig_stat;
3025
3026   /* Now go back and dup the deep item into this pool. */
3027   if (orig_stat->entry)
3028     new_stat->entry = svn_wc_entry_dup(orig_stat->entry, pool);
3029
3030   /* Return the new hotness. */
3031   return new_stat;
3032 }
3033
3034 svn_error_t *
3035 svn_wc_get_ignores(apr_array_header_t **patterns,
3036                    apr_hash_t *config,
3037                    svn_wc_adm_access_t *adm_access,
3038                    apr_pool_t *pool)
3039 {
3040   svn_wc_context_t *wc_ctx;
3041   const char *local_abspath;
3042
3043   SVN_ERR(svn_dirent_get_absolute(&local_abspath,
3044                                   svn_wc_adm_access_path(adm_access), pool));
3045
3046   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
3047                                          svn_wc__adm_get_db(adm_access),
3048                                          pool));
3049
3050   SVN_ERR(svn_wc_get_ignores2(patterns, wc_ctx, local_abspath, config, pool,
3051                               pool));
3052
3053   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
3054 }
3055
3056 svn_error_t *
3057 svn_wc_status2(svn_wc_status2_t **status,
3058                const char *path,
3059                svn_wc_adm_access_t *adm_access,
3060                apr_pool_t *pool)
3061 {
3062   const char *local_abspath;
3063   svn_wc_context_t *wc_ctx;
3064   svn_wc_status3_t *stat3;
3065
3066   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
3067   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
3068                                          svn_wc__adm_get_db(adm_access),
3069                                          pool));
3070
3071   SVN_ERR(svn_wc_status3(&stat3, wc_ctx, local_abspath, pool, pool));
3072   SVN_ERR(svn_wc__status2_from_3(status, stat3, wc_ctx, local_abspath,
3073                                  pool, pool));
3074
3075   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
3076 }
3077
3078
3079 /*** From update_editor.c ***/
3080
3081 svn_error_t *
3082 svn_wc_add_repos_file3(const char *dst_path,
3083                        svn_wc_adm_access_t *adm_access,
3084                        svn_stream_t *new_base_contents,
3085                        svn_stream_t *new_contents,
3086                        apr_hash_t *new_base_props,
3087                        apr_hash_t *new_props,
3088                        const char *copyfrom_url,
3089                        svn_revnum_t copyfrom_rev,
3090                        svn_cancel_func_t cancel_func,
3091                        void *cancel_baton,
3092                        svn_wc_notify_func2_t notify_func,
3093                        void *notify_baton,
3094                        apr_pool_t *pool)
3095 {
3096   const char *local_abspath;
3097   svn_wc_context_t *wc_ctx;
3098
3099   SVN_ERR(svn_dirent_get_absolute(&local_abspath, dst_path, pool));
3100   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
3101                                          svn_wc__adm_get_db(adm_access),
3102                                          pool));
3103
3104   SVN_ERR(svn_wc_add_repos_file4(wc_ctx,
3105                                  local_abspath,
3106                                  new_base_contents,
3107                                  new_contents,
3108                                  new_base_props,
3109                                  new_props,
3110                                  copyfrom_url,
3111                                  copyfrom_rev,
3112                                  cancel_func, cancel_baton,
3113                                  pool));
3114
3115   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
3116 }
3117
3118 svn_error_t *
3119 svn_wc_add_repos_file2(const char *dst_path,
3120                        svn_wc_adm_access_t *adm_access,
3121                        const char *new_text_base_path,
3122                        const char *new_text_path,
3123                        apr_hash_t *new_base_props,
3124                        apr_hash_t *new_props,
3125                        const char *copyfrom_url,
3126                        svn_revnum_t copyfrom_rev,
3127                        apr_pool_t *pool)
3128 {
3129   svn_stream_t *new_base_contents;
3130   svn_stream_t *new_contents = NULL;
3131
3132   SVN_ERR(svn_stream_open_readonly(&new_base_contents, new_text_base_path,
3133                                    pool, pool));
3134
3135   if (new_text_path)
3136     {
3137       /* NOTE: the specified path may *not* be under version control.
3138          It is most likely sitting in .svn/tmp/. Thus, we cannot use the
3139          typical WC functions to access "special", "keywords" or "EOL"
3140          information. We need to look at the properties given to us. */
3141
3142       /* If the new file is special, then we can simply open the given
3143          contents since it is already in normal form. */
3144       if (svn_hash_gets(new_props, SVN_PROP_SPECIAL) != NULL)
3145         {
3146           SVN_ERR(svn_stream_open_readonly(&new_contents, new_text_path,
3147                                            pool, pool));
3148         }
3149       else
3150         {
3151           /* The new text contents need to be detrans'd into normal form. */
3152           svn_subst_eol_style_t eol_style;
3153           const char *eol_str;
3154           apr_hash_t *keywords = NULL;
3155           svn_string_t *list;
3156
3157           list = svn_hash_gets(new_props, SVN_PROP_KEYWORDS);
3158           if (list != NULL)
3159             {
3160               /* Since we are detranslating, all of the keyword values
3161                  can be "". */
3162               SVN_ERR(svn_subst_build_keywords2(&keywords,
3163                                                 list->data,
3164                                                 "", "", 0, "",
3165                                                 pool));
3166               if (apr_hash_count(keywords) == 0)
3167                 keywords = NULL;
3168             }
3169
3170           svn_subst_eol_style_from_value(&eol_style, &eol_str,
3171                                          svn_hash_gets(new_props,
3172                                                        SVN_PROP_EOL_STYLE));
3173
3174           if (svn_subst_translation_required(eol_style, eol_str, keywords,
3175                                              FALSE, FALSE))
3176             {
3177               SVN_ERR(svn_subst_stream_detranslated(&new_contents,
3178                                                     new_text_path,
3179                                                     eol_style, eol_str,
3180                                                     FALSE,
3181                                                     keywords,
3182                                                     FALSE,
3183                                                     pool));
3184             }
3185           else
3186             {
3187               SVN_ERR(svn_stream_open_readonly(&new_contents, new_text_path,
3188                                                pool, pool));
3189             }
3190         }
3191     }
3192
3193   SVN_ERR(svn_wc_add_repos_file3(dst_path, adm_access,
3194                                  new_base_contents, new_contents,
3195                                  new_base_props, new_props,
3196                                  copyfrom_url, copyfrom_rev,
3197                                  NULL, NULL, NULL, NULL,
3198                                  pool));
3199
3200   /* The API contract states that the text files will be removed upon
3201      successful completion. add_repos_file3() does not remove the files
3202      since it only has streams on them. Toss 'em now. */
3203   svn_error_clear(svn_io_remove_file(new_text_base_path, pool));
3204   if (new_text_path)
3205     svn_error_clear(svn_io_remove_file(new_text_path, pool));
3206
3207   return SVN_NO_ERROR;
3208 }
3209
3210
3211 svn_error_t *
3212 svn_wc_add_repos_file(const char *dst_path,
3213                       svn_wc_adm_access_t *adm_access,
3214                       const char *new_text_path,
3215                       apr_hash_t *new_props,
3216                       const char *copyfrom_url,
3217                       svn_revnum_t copyfrom_rev,
3218                       apr_pool_t *pool)
3219 {
3220   return svn_wc_add_repos_file2(dst_path, adm_access,
3221                                 new_text_path, NULL,
3222                                 new_props, NULL,
3223                                 copyfrom_url, copyfrom_rev,
3224                                 pool);
3225 }
3226
3227 svn_error_t *
3228 svn_wc_get_actual_target(const char *path,
3229                          const char **anchor,
3230                          const char **target,
3231                          apr_pool_t *pool)
3232 {
3233   svn_wc_context_t *wc_ctx;
3234
3235   SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool));
3236   SVN_ERR(svn_wc_get_actual_target2(anchor, target, wc_ctx, path, pool, pool));
3237
3238   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
3239 }
3240
3241 /* This function has no internal variant as its behavior on switched
3242    non-directories is not what you would expect. But this happens to
3243    be the legacy behavior of this function. */
3244 svn_error_t *
3245 svn_wc_is_wc_root2(svn_boolean_t *wc_root,
3246                    svn_wc_context_t *wc_ctx,
3247                    const char *local_abspath,
3248                    apr_pool_t *scratch_pool)
3249 {
3250   svn_boolean_t is_root;
3251   svn_boolean_t is_switched;
3252   svn_node_kind_t kind;
3253   svn_error_t *err;
3254   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
3255
3256   err = svn_wc__db_is_switched(&is_root, &is_switched, &kind,
3257                                wc_ctx->db, local_abspath, scratch_pool);
3258
3259   if (err)
3260     {
3261       if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND &&
3262           err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
3263         return svn_error_trace(err);
3264
3265       return svn_error_create(SVN_ERR_ENTRY_NOT_FOUND, err, err->message);
3266     }
3267
3268   *wc_root = is_root || (kind == svn_node_dir && is_switched);
3269
3270   return SVN_NO_ERROR;
3271 }
3272
3273 svn_error_t *
3274 svn_wc_is_wc_root(svn_boolean_t *wc_root,
3275                   const char *path,
3276                   svn_wc_adm_access_t *adm_access,
3277                   apr_pool_t *pool)
3278 {
3279   svn_wc_context_t *wc_ctx;
3280   const char *local_abspath;
3281   svn_error_t *err;
3282
3283   /* Subversion <= 1.6 said that '.' or a drive root is a WC root. */
3284   if (svn_path_is_empty(path) || svn_dirent_is_root(path, strlen(path)))
3285     {
3286       *wc_root = TRUE;
3287       return SVN_NO_ERROR;
3288     }
3289
3290   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
3291   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
3292                                          svn_wc__adm_get_db(adm_access),
3293                                          pool));
3294
3295   err = svn_wc_is_wc_root2(wc_root, wc_ctx, local_abspath, pool);
3296
3297   if (err
3298       && (err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY
3299           || err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND))
3300     {
3301       /* Subversion <= 1.6 said that an unversioned path is a WC root. */
3302       svn_error_clear(err);
3303       *wc_root = TRUE;
3304     }
3305   else
3306     SVN_ERR(err);
3307
3308   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
3309 }
3310
3311
3312 svn_error_t *
3313 svn_wc_get_update_editor4(const svn_delta_editor_t **editor,
3314                           void **edit_baton,
3315                           svn_revnum_t *target_revision,
3316                           svn_wc_context_t *wc_ctx,
3317                           const char *anchor_abspath,
3318                           const char *target_basename,
3319                           svn_boolean_t use_commit_times,
3320                           svn_depth_t depth,
3321                           svn_boolean_t depth_is_sticky,
3322                           svn_boolean_t allow_unver_obstructions,
3323                           svn_boolean_t adds_as_modification,
3324                           svn_boolean_t server_performs_filtering,
3325                           svn_boolean_t clean_checkout,
3326                           const char *diff3_cmd,
3327                           const apr_array_header_t *preserved_exts,
3328                           svn_wc_dirents_func_t fetch_dirents_func,
3329                           void *fetch_dirents_baton,
3330                           svn_wc_conflict_resolver_func2_t conflict_func,
3331                           void *conflict_baton,
3332                           svn_wc_external_update_t external_func,
3333                           void *external_baton,
3334                           svn_cancel_func_t cancel_func,
3335                           void *cancel_baton,
3336                           svn_wc_notify_func2_t notify_func,
3337                           void *notify_baton,
3338                           apr_pool_t *result_pool,
3339                           apr_pool_t *scratch_pool)
3340 {
3341   return svn_error_trace(
3342     svn_wc__get_update_editor(editor, edit_baton,
3343                               target_revision,
3344                               wc_ctx,
3345                               anchor_abspath,
3346                               target_basename, NULL,
3347                               use_commit_times,
3348                               depth, depth_is_sticky,
3349                               allow_unver_obstructions,
3350                               adds_as_modification,
3351                               server_performs_filtering,
3352                               clean_checkout,
3353                               diff3_cmd,
3354                               preserved_exts,
3355                               fetch_dirents_func, fetch_dirents_baton,
3356                               conflict_func, conflict_baton,
3357                               external_func, external_baton,
3358                               cancel_func, cancel_baton,
3359                               notify_func, notify_baton,
3360                               result_pool, scratch_pool));
3361 }
3362
3363
3364 svn_error_t *
3365 svn_wc_get_update_editor3(svn_revnum_t *target_revision,
3366                           svn_wc_adm_access_t *anchor,
3367                           const char *target,
3368                           svn_boolean_t use_commit_times,
3369                           svn_depth_t depth,
3370                           svn_boolean_t depth_is_sticky,
3371                           svn_boolean_t allow_unver_obstructions,
3372                           svn_wc_notify_func2_t notify_func,
3373                           void *notify_baton,
3374                           svn_cancel_func_t cancel_func,
3375                           void *cancel_baton,
3376                           svn_wc_conflict_resolver_func_t conflict_func,
3377                           void *conflict_baton,
3378                           svn_wc_get_file_t fetch_func,
3379                           void *fetch_baton,
3380                           const char *diff3_cmd,
3381                           const apr_array_header_t *preserved_exts,
3382                           const svn_delta_editor_t **editor,
3383                           void **edit_baton,
3384                           svn_wc_traversal_info_t *traversal_info,
3385                           apr_pool_t *pool)
3386 {
3387   svn_wc_context_t *wc_ctx;
3388   svn_wc__db_t *db = svn_wc__adm_get_db(anchor);
3389   svn_wc_external_update_t external_func = NULL;
3390   struct traversal_info_update_baton *eb = NULL;
3391   struct conflict_func_1to2_baton *cfw = NULL;
3392
3393   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool));
3394
3395   if (traversal_info)
3396     {
3397       eb = apr_palloc(pool, sizeof(*eb));
3398       eb->db = db;
3399       eb->traversal = traversal_info;
3400       external_func = traversal_info_update;
3401     }
3402
3403   if (conflict_func)
3404     {
3405       cfw = apr_pcalloc(pool, sizeof(*cfw));
3406       cfw->inner_func = conflict_func;
3407       cfw->inner_baton = conflict_baton;
3408     }
3409
3410   if (diff3_cmd)
3411     SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, pool));
3412
3413   SVN_ERR(svn_wc_get_update_editor4(editor, edit_baton,
3414                                     target_revision,
3415                                     wc_ctx,
3416                                     svn_wc__adm_access_abspath(anchor),
3417                                     target,
3418                                     use_commit_times,
3419                                     depth, depth_is_sticky,
3420                                     allow_unver_obstructions,
3421                                     TRUE /* adds_as_modification */,
3422                                     FALSE /* server_performs_filtering */,
3423                                     FALSE /* clean_checkout */,
3424                                     diff3_cmd,
3425                                     preserved_exts,
3426                                     NULL, NULL, /* fetch_dirents_func, baton */
3427                                     conflict_func ? conflict_func_1to2_wrapper
3428                                                   : NULL,
3429                                     cfw,
3430                                     external_func, eb,
3431                                     cancel_func, cancel_baton,
3432                                     notify_func, notify_baton,
3433                                     pool, pool));
3434
3435   /* We can't destroy wc_ctx here, because the editor needs it while it's
3436      driven. */
3437   return SVN_NO_ERROR;
3438 }
3439
3440 svn_error_t *
3441 svn_wc_get_update_editor2(svn_revnum_t *target_revision,
3442                           svn_wc_adm_access_t *anchor,
3443                           const char *target,
3444                           svn_boolean_t use_commit_times,
3445                           svn_boolean_t recurse,
3446                           svn_wc_notify_func2_t notify_func,
3447                           void *notify_baton,
3448                           svn_cancel_func_t cancel_func,
3449                           void *cancel_baton,
3450                           const char *diff3_cmd,
3451                           const svn_delta_editor_t **editor,
3452                           void **edit_baton,
3453                           svn_wc_traversal_info_t *traversal_info,
3454                           apr_pool_t *pool)
3455 {
3456   return svn_wc_get_update_editor3(target_revision, anchor, target,
3457                                    use_commit_times,
3458                                    SVN_DEPTH_INFINITY_OR_FILES(recurse), FALSE,
3459                                    FALSE, notify_func, notify_baton,
3460                                    cancel_func, cancel_baton, NULL, NULL,
3461                                    NULL, NULL,
3462                                    diff3_cmd, NULL, editor, edit_baton,
3463                                    traversal_info, pool);
3464 }
3465
3466 svn_error_t *
3467 svn_wc_get_update_editor(svn_revnum_t *target_revision,
3468                          svn_wc_adm_access_t *anchor,
3469                          const char *target,
3470                          svn_boolean_t use_commit_times,
3471                          svn_boolean_t recurse,
3472                          svn_wc_notify_func_t notify_func,
3473                          void *notify_baton,
3474                          svn_cancel_func_t cancel_func,
3475                          void *cancel_baton,
3476                          const char *diff3_cmd,
3477                          const svn_delta_editor_t **editor,
3478                          void **edit_baton,
3479                          svn_wc_traversal_info_t *traversal_info,
3480                          apr_pool_t *pool)
3481 {
3482   /* This baton must live beyond this function. Alloc on heap.  */
3483   struct compat_notify_baton_t *nb = apr_palloc(pool, sizeof(*nb));
3484
3485   nb->func = notify_func;
3486   nb->baton = notify_baton;
3487
3488   return svn_wc_get_update_editor3(target_revision, anchor, target,
3489                                    use_commit_times,
3490                                    SVN_DEPTH_INFINITY_OR_FILES(recurse), FALSE,
3491                                    FALSE, compat_call_notify_func, nb,
3492                                    cancel_func, cancel_baton, NULL, NULL,
3493                                    NULL, NULL,
3494                                    diff3_cmd, NULL, editor, edit_baton,
3495                                    traversal_info, pool);
3496 }
3497
3498
3499 svn_error_t *
3500 svn_wc_get_switch_editor4(const svn_delta_editor_t **editor,
3501                           void **edit_baton,
3502                           svn_revnum_t *target_revision,
3503                           svn_wc_context_t *wc_ctx,
3504                           const char *anchor_abspath,
3505                           const char *target_basename,
3506                           const char *switch_url,
3507                           svn_boolean_t use_commit_times,
3508                           svn_depth_t depth,
3509                           svn_boolean_t depth_is_sticky,
3510                           svn_boolean_t allow_unver_obstructions,
3511                           svn_boolean_t server_performs_filtering,
3512                           const char *diff3_cmd,
3513                           const apr_array_header_t *preserved_exts,
3514                           svn_wc_dirents_func_t fetch_dirents_func,
3515                           void *fetch_dirents_baton,
3516                           svn_wc_conflict_resolver_func2_t conflict_func,
3517                           void *conflict_baton,
3518                           svn_wc_external_update_t external_func,
3519                           void *external_baton,
3520                           svn_cancel_func_t cancel_func,
3521                           void *cancel_baton,
3522                           svn_wc_notify_func2_t notify_func,
3523                           void *notify_baton,
3524                           apr_pool_t *result_pool,
3525                           apr_pool_t *scratch_pool)
3526 {
3527   return svn_error_trace(
3528     svn_wc__get_switch_editor(editor, edit_baton,
3529                               target_revision,
3530                               wc_ctx,
3531                               anchor_abspath, target_basename,
3532                               switch_url, NULL,
3533                               use_commit_times,
3534                               depth, depth_is_sticky,
3535                               allow_unver_obstructions,
3536                               server_performs_filtering,
3537                               diff3_cmd,
3538                               preserved_exts,
3539                               fetch_dirents_func, fetch_dirents_baton,
3540                               conflict_func, conflict_baton,
3541                               external_func, external_baton,
3542                               cancel_func, cancel_baton,
3543                               notify_func, notify_baton,
3544                               result_pool, scratch_pool));
3545 }
3546
3547
3548 svn_error_t *
3549 svn_wc_get_switch_editor3(svn_revnum_t *target_revision,
3550                           svn_wc_adm_access_t *anchor,
3551                           const char *target,
3552                           const char *switch_url,
3553                           svn_boolean_t use_commit_times,
3554                           svn_depth_t depth,
3555                           svn_boolean_t depth_is_sticky,
3556                           svn_boolean_t allow_unver_obstructions,
3557                           svn_wc_notify_func2_t notify_func,
3558                           void *notify_baton,
3559                           svn_cancel_func_t cancel_func,
3560                           void *cancel_baton,
3561                           svn_wc_conflict_resolver_func_t conflict_func,
3562                           void *conflict_baton,
3563                           const char *diff3_cmd,
3564                           const apr_array_header_t *preserved_exts,
3565                           const svn_delta_editor_t **editor,
3566                           void **edit_baton,
3567                           svn_wc_traversal_info_t *traversal_info,
3568                           apr_pool_t *pool)
3569 {
3570   svn_wc_context_t *wc_ctx;
3571   svn_wc__db_t *db = svn_wc__adm_get_db(anchor);
3572   svn_wc_external_update_t external_func = NULL;
3573   struct traversal_info_update_baton *eb = NULL;
3574   struct conflict_func_1to2_baton *cfw = NULL;
3575
3576   SVN_ERR_ASSERT(switch_url && svn_uri_is_canonical(switch_url, pool));
3577
3578   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool));
3579
3580   if (traversal_info)
3581     {
3582       eb = apr_palloc(pool, sizeof(*eb));
3583       eb->db = db;
3584       eb->traversal = traversal_info;
3585       external_func = traversal_info_update;
3586     }
3587
3588   if (conflict_func)
3589     {
3590       cfw = apr_pcalloc(pool, sizeof(*cfw));
3591       cfw->inner_func = conflict_func;
3592       cfw->inner_baton = conflict_baton;
3593     }
3594
3595   if (diff3_cmd)
3596     SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, pool));
3597
3598   SVN_ERR(svn_wc_get_switch_editor4(editor, edit_baton,
3599                                     target_revision,
3600                                     wc_ctx,
3601                                     svn_wc__adm_access_abspath(anchor),
3602                                     target, switch_url,
3603                                     use_commit_times,
3604                                     depth, depth_is_sticky,
3605                                     allow_unver_obstructions,
3606                                     FALSE /* server_performs_filtering */,
3607                                     diff3_cmd,
3608                                     preserved_exts,
3609                                     NULL, NULL, /* fetch_dirents_func, baton */
3610                                     conflict_func ? conflict_func_1to2_wrapper
3611                                                   : NULL,
3612                                     cfw,
3613                                     external_func, eb,
3614                                     cancel_func, cancel_baton,
3615                                     notify_func, notify_baton,
3616                                     pool, pool));
3617
3618   /* We can't destroy wc_ctx here, because the editor needs it while it's
3619      driven. */
3620   return SVN_NO_ERROR;
3621 }
3622
3623 svn_error_t *
3624 svn_wc_get_switch_editor2(svn_revnum_t *target_revision,
3625                           svn_wc_adm_access_t *anchor,
3626                           const char *target,
3627                           const char *switch_url,
3628                           svn_boolean_t use_commit_times,
3629                           svn_boolean_t recurse,
3630                           svn_wc_notify_func2_t notify_func,
3631                           void *notify_baton,
3632                           svn_cancel_func_t cancel_func,
3633                           void *cancel_baton,
3634                           const char *diff3_cmd,
3635                           const svn_delta_editor_t **editor,
3636                           void **edit_baton,
3637                           svn_wc_traversal_info_t *traversal_info,
3638                           apr_pool_t *pool)
3639 {
3640   SVN_ERR_ASSERT(switch_url);
3641
3642   return svn_wc_get_switch_editor3(target_revision, anchor, target,
3643                                    switch_url, use_commit_times,
3644                                    SVN_DEPTH_INFINITY_OR_FILES(recurse), FALSE,
3645                                    FALSE, notify_func, notify_baton,
3646                                    cancel_func, cancel_baton,
3647                                    NULL, NULL, diff3_cmd,
3648                                    NULL, editor, edit_baton, traversal_info,
3649                                    pool);
3650 }
3651
3652 svn_error_t *
3653 svn_wc_get_switch_editor(svn_revnum_t *target_revision,
3654                          svn_wc_adm_access_t *anchor,
3655                          const char *target,
3656                          const char *switch_url,
3657                          svn_boolean_t use_commit_times,
3658                          svn_boolean_t recurse,
3659                          svn_wc_notify_func_t notify_func,
3660                          void *notify_baton,
3661                          svn_cancel_func_t cancel_func,
3662                          void *cancel_baton,
3663                          const char *diff3_cmd,
3664                          const svn_delta_editor_t **editor,
3665                          void **edit_baton,
3666                          svn_wc_traversal_info_t *traversal_info,
3667                          apr_pool_t *pool)
3668 {
3669   /* This baton must live beyond this function. Alloc on heap.  */
3670   struct compat_notify_baton_t *nb = apr_palloc(pool, sizeof(*nb));
3671
3672   nb->func = notify_func;
3673   nb->baton = notify_baton;
3674
3675   return svn_wc_get_switch_editor3(target_revision, anchor, target,
3676                                    switch_url, use_commit_times,
3677                                    SVN_DEPTH_INFINITY_OR_FILES(recurse), FALSE,
3678                                    FALSE, compat_call_notify_func, nb,
3679                                    cancel_func, cancel_baton,
3680                                    NULL, NULL, diff3_cmd,
3681                                    NULL, editor, edit_baton, traversal_info,
3682                                    pool);
3683 }
3684
3685
3686 svn_error_t *
3687 svn_wc_external_item_create(const svn_wc_external_item2_t **item,
3688                             apr_pool_t *pool)
3689 {
3690   *item = apr_pcalloc(pool, sizeof(svn_wc_external_item2_t));
3691   return SVN_NO_ERROR;
3692 }
3693
3694 svn_wc_external_item_t *
3695 svn_wc_external_item_dup(const svn_wc_external_item_t *item,
3696                          apr_pool_t *pool)
3697 {
3698   svn_wc_external_item_t *new_item = apr_palloc(pool, sizeof(*new_item));
3699
3700   *new_item = *item;
3701
3702   if (new_item->target_dir)
3703     new_item->target_dir = apr_pstrdup(pool, new_item->target_dir);
3704
3705   if (new_item->url)
3706     new_item->url = apr_pstrdup(pool, new_item->url);
3707
3708   return new_item;
3709 }
3710
3711
3712 svn_wc_traversal_info_t *
3713 svn_wc_init_traversal_info(apr_pool_t *pool)
3714 {
3715   svn_wc_traversal_info_t *ti = apr_palloc(pool, sizeof(*ti));
3716
3717   ti->pool           = pool;
3718   ti->externals_old  = apr_hash_make(pool);
3719   ti->externals_new  = apr_hash_make(pool);
3720   ti->depths         = apr_hash_make(pool);
3721
3722   return ti;
3723 }
3724
3725
3726 void
3727 svn_wc_edited_externals(apr_hash_t **externals_old,
3728                         apr_hash_t **externals_new,
3729                         svn_wc_traversal_info_t *traversal_info)
3730 {
3731   *externals_old = traversal_info->externals_old;
3732   *externals_new = traversal_info->externals_new;
3733 }
3734
3735
3736 void
3737 svn_wc_traversed_depths(apr_hash_t **depths,
3738                         svn_wc_traversal_info_t *traversal_info)
3739 {
3740   *depths = traversal_info->depths;
3741 }
3742
3743
3744 /*** From lock.c ***/
3745
3746 /* To preserve API compatibility with Subversion 1.0.0 */
3747 svn_error_t *
3748 svn_wc_adm_open(svn_wc_adm_access_t **adm_access,
3749                 svn_wc_adm_access_t *associated,
3750                 const char *path,
3751                 svn_boolean_t write_lock,
3752                 svn_boolean_t tree_lock,
3753                 apr_pool_t *pool)
3754 {
3755   return svn_wc_adm_open3(adm_access, associated, path, write_lock,
3756                           (tree_lock ? -1 : 0), NULL, NULL, pool);
3757 }
3758
3759 svn_error_t *
3760 svn_wc_adm_open2(svn_wc_adm_access_t **adm_access,
3761                  svn_wc_adm_access_t *associated,
3762                  const char *path,
3763                  svn_boolean_t write_lock,
3764                  int levels_to_lock,
3765                  apr_pool_t *pool)
3766 {
3767   return svn_wc_adm_open3(adm_access, associated, path, write_lock,
3768                           levels_to_lock, NULL, NULL, pool);
3769 }
3770
3771 svn_error_t *
3772 svn_wc_adm_probe_open(svn_wc_adm_access_t **adm_access,
3773                       svn_wc_adm_access_t *associated,
3774                       const char *path,
3775                       svn_boolean_t write_lock,
3776                       svn_boolean_t tree_lock,
3777                       apr_pool_t *pool)
3778 {
3779   return svn_wc_adm_probe_open3(adm_access, associated, path,
3780                                 write_lock, (tree_lock ? -1 : 0),
3781                                 NULL, NULL, pool);
3782 }
3783
3784
3785 svn_error_t *
3786 svn_wc_adm_probe_open2(svn_wc_adm_access_t **adm_access,
3787                        svn_wc_adm_access_t *associated,
3788                        const char *path,
3789                        svn_boolean_t write_lock,
3790                        int levels_to_lock,
3791                        apr_pool_t *pool)
3792 {
3793   return svn_wc_adm_probe_open3(adm_access, associated, path, write_lock,
3794                                 levels_to_lock, NULL, NULL, pool);
3795 }
3796
3797 svn_error_t *
3798 svn_wc_adm_probe_try2(svn_wc_adm_access_t **adm_access,
3799                       svn_wc_adm_access_t *associated,
3800                       const char *path,
3801                       svn_boolean_t write_lock,
3802                       int levels_to_lock,
3803                       apr_pool_t *pool)
3804 {
3805   return svn_wc_adm_probe_try3(adm_access, associated, path, write_lock,
3806                                levels_to_lock, NULL, NULL, pool);
3807 }
3808
3809 svn_error_t *
3810 svn_wc_adm_probe_try(svn_wc_adm_access_t **adm_access,
3811                      svn_wc_adm_access_t *associated,
3812                      const char *path,
3813                      svn_boolean_t write_lock,
3814                      svn_boolean_t tree_lock,
3815                      apr_pool_t *pool)
3816 {
3817   return svn_wc_adm_probe_try3(adm_access, associated, path, write_lock,
3818                                (tree_lock ? -1 : 0), NULL, NULL, pool);
3819 }
3820
3821 svn_error_t *
3822 svn_wc_adm_close(svn_wc_adm_access_t *adm_access)
3823 {
3824   /* This is the only pool we have access to. */
3825   apr_pool_t *scratch_pool = svn_wc_adm_access_pool(adm_access);
3826
3827   return svn_wc_adm_close2(adm_access, scratch_pool);
3828 }
3829
3830 svn_error_t *
3831 svn_wc_locked(svn_boolean_t *locked,
3832               const char *path,
3833               apr_pool_t *pool)
3834 {
3835   svn_wc_context_t *wc_ctx;
3836   const char *local_abspath;
3837
3838   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
3839   SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool));
3840
3841   SVN_ERR(svn_wc_locked2(NULL, locked, wc_ctx, local_abspath, pool));
3842
3843   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
3844 }
3845
3846 svn_error_t *
3847 svn_wc_check_wc(const char *path,
3848                 int *wc_format,
3849                 apr_pool_t *pool)
3850 {
3851   svn_wc_context_t *wc_ctx;
3852   const char *local_abspath;
3853
3854   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
3855   SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool));
3856
3857   SVN_ERR(svn_wc_check_wc2(wc_format, wc_ctx, local_abspath, pool));
3858
3859   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
3860 }
3861
3862
3863 /*** From translate.c ***/
3864
3865 svn_error_t *
3866 svn_wc_translated_file(const char **xlated_p,
3867                        const char *vfile,
3868                        svn_wc_adm_access_t *adm_access,
3869                        svn_boolean_t force_repair,
3870                        apr_pool_t *pool)
3871 {
3872   return svn_wc_translated_file2(xlated_p, vfile, vfile, adm_access,
3873                                  SVN_WC_TRANSLATE_TO_NF
3874                                  | (force_repair ?
3875                                     SVN_WC_TRANSLATE_FORCE_EOL_REPAIR : 0),
3876                                  pool);
3877 }
3878
3879 svn_error_t *
3880 svn_wc_translated_stream(svn_stream_t **stream,
3881                          const char *path,
3882                          const char *versioned_file,
3883                          svn_wc_adm_access_t *adm_access,
3884                          apr_uint32_t flags,
3885                          apr_pool_t *pool)
3886 {
3887   const char *local_abspath;
3888   const char *versioned_abspath;
3889
3890   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
3891   SVN_ERR(svn_dirent_get_absolute(&versioned_abspath, versioned_file, pool));
3892
3893   return svn_error_trace(
3894     svn_wc__internal_translated_stream(stream, svn_wc__adm_get_db(adm_access),
3895                                        local_abspath, versioned_abspath, flags,
3896                                        pool, pool));
3897 }
3898
3899 svn_error_t *
3900 svn_wc_translated_file2(const char **xlated_path,
3901                         const char *src,
3902                         const char *versioned_file,
3903                         svn_wc_adm_access_t *adm_access,
3904                         apr_uint32_t flags,
3905                         apr_pool_t *pool)
3906 {
3907   const char *versioned_abspath;
3908   const char *root;
3909   const char *tmp_root;
3910   const char *src_abspath;
3911
3912   SVN_ERR(svn_dirent_get_absolute(&versioned_abspath, versioned_file, pool));
3913   SVN_ERR(svn_dirent_get_absolute(&src_abspath, src, pool));
3914
3915   SVN_ERR(svn_wc__internal_translated_file(xlated_path, src_abspath,
3916                                            svn_wc__adm_get_db(adm_access),
3917                                            versioned_abspath,
3918                                            flags, NULL, NULL, pool, pool));
3919
3920   if (strcmp(*xlated_path, src_abspath) == 0)
3921     *xlated_path = src;
3922   else if (! svn_dirent_is_absolute(versioned_file))
3923     {
3924       SVN_ERR(svn_io_temp_dir(&tmp_root, pool));
3925       if (! svn_dirent_is_child(tmp_root, *xlated_path, pool))
3926         {
3927           SVN_ERR(svn_dirent_get_absolute(&root, "", pool));
3928
3929           if (svn_dirent_is_child(root, *xlated_path, pool))
3930             *xlated_path = svn_dirent_is_child(root, *xlated_path, pool);
3931         }
3932     }
3933
3934   return SVN_NO_ERROR;
3935 }
3936
3937 /*** From relocate.c ***/
3938 svn_error_t *
3939 svn_wc_relocate3(const char *path,
3940                  svn_wc_adm_access_t *adm_access,
3941                  const char *from,
3942                  const char *to,
3943                  svn_boolean_t recurse,
3944                  svn_wc_relocation_validator3_t validator,
3945                  void *validator_baton,
3946                  apr_pool_t *pool)
3947 {
3948   const char *local_abspath;
3949   svn_wc_context_t *wc_ctx;
3950
3951   if (! recurse)
3952     SVN_ERR(svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
3953                              _("Non-recursive relocation not supported")));
3954
3955   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
3956   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
3957                                          svn_wc__adm_get_db(adm_access),
3958                                          pool));
3959
3960   SVN_ERR(svn_wc_relocate4(wc_ctx, local_abspath, from, to,
3961                            validator, validator_baton, pool));
3962
3963   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
3964 }
3965
3966 /* Compatibility baton and wrapper. */
3967 struct compat2_baton {
3968   svn_wc_relocation_validator2_t validator;
3969   void *baton;
3970 };
3971
3972 /* Compatibility baton and wrapper. */
3973 struct compat_baton {
3974   svn_wc_relocation_validator_t validator;
3975   void *baton;
3976 };
3977
3978 /* This implements svn_wc_relocate_validator3_t. */
3979 static svn_error_t *
3980 compat2_validator(void *baton,
3981                   const char *uuid,
3982                   const char *url,
3983                   const char *root_url,
3984                   apr_pool_t *pool)
3985 {
3986   struct compat2_baton *cb = baton;
3987   /* The old callback type doesn't set root_url. */
3988   return cb->validator(cb->baton, uuid,
3989                        (root_url ? root_url : url), (root_url != NULL),
3990                        pool);
3991 }
3992
3993 /* This implements svn_wc_relocate_validator3_t. */
3994 static svn_error_t *
3995 compat_validator(void *baton,
3996                  const char *uuid,
3997                  const char *url,
3998                  const char *root_url,
3999                  apr_pool_t *pool)
4000 {
4001   struct compat_baton *cb = baton;
4002   /* The old callback type doesn't allow uuid to be NULL. */
4003   if (uuid)
4004     return cb->validator(cb->baton, uuid, url);
4005   return SVN_NO_ERROR;
4006 }
4007
4008 svn_error_t *
4009 svn_wc_relocate2(const char *path,
4010                  svn_wc_adm_access_t *adm_access,
4011                  const char *from,
4012                  const char *to,
4013                  svn_boolean_t recurse,
4014                  svn_wc_relocation_validator2_t validator,
4015                  void *validator_baton,
4016                  apr_pool_t *pool)
4017 {
4018   struct compat2_baton cb;
4019
4020   cb.validator = validator;
4021   cb.baton = validator_baton;
4022
4023   return svn_wc_relocate3(path, adm_access, from, to, recurse,
4024                           compat2_validator, &cb, pool);
4025 }
4026
4027 svn_error_t *
4028 svn_wc_relocate(const char *path,
4029                 svn_wc_adm_access_t *adm_access,
4030                 const char *from,
4031                 const char *to,
4032                 svn_boolean_t recurse,
4033                 svn_wc_relocation_validator_t validator,
4034                 void *validator_baton,
4035                 apr_pool_t *pool)
4036 {
4037   struct compat_baton cb;
4038
4039   cb.validator = validator;
4040   cb.baton = validator_baton;
4041
4042   return svn_wc_relocate3(path, adm_access, from, to, recurse,
4043                           compat_validator, &cb, pool);
4044 }
4045
4046
4047 /*** From log.c ***/
4048
4049 svn_error_t *
4050 svn_wc_cleanup2(const char *path,
4051                 const char *diff3_cmd,
4052                 svn_cancel_func_t cancel_func,
4053                 void *cancel_baton,
4054                 apr_pool_t *pool)
4055 {
4056   svn_wc_context_t *wc_ctx;
4057   const char *local_abspath;
4058
4059   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
4060   SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool));
4061
4062   SVN_ERR(svn_wc_cleanup3(wc_ctx, local_abspath, cancel_func,
4063                           cancel_baton, pool));
4064
4065   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
4066 }
4067
4068 svn_error_t *
4069 svn_wc_cleanup(const char *path,
4070                svn_wc_adm_access_t *optional_adm_access,
4071                const char *diff3_cmd,
4072                svn_cancel_func_t cancel_func,
4073                void *cancel_baton,
4074                apr_pool_t *pool)
4075 {
4076   return svn_wc_cleanup2(path, diff3_cmd, cancel_func, cancel_baton, pool);
4077 }
4078
4079 /*** From questions.c ***/
4080
4081 svn_error_t *
4082 svn_wc_has_binary_prop(svn_boolean_t *has_binary_prop,
4083                        const char *path,
4084                        svn_wc_adm_access_t *adm_access,
4085                        apr_pool_t *pool)
4086 {
4087   svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
4088   const char *local_abspath;
4089   const svn_string_t *value;
4090
4091   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
4092
4093   SVN_ERR(svn_wc__internal_propget(&value, db, local_abspath,
4094                                    SVN_PROP_MIME_TYPE,
4095                                    pool, pool));
4096
4097   if (value && (svn_mime_type_is_binary(value->data)))
4098     *has_binary_prop = TRUE;
4099   else
4100     *has_binary_prop = FALSE;
4101
4102   return SVN_NO_ERROR;
4103 }
4104
4105 svn_error_t *
4106 svn_wc_conflicted_p2(svn_boolean_t *text_conflicted_p,
4107                      svn_boolean_t *prop_conflicted_p,
4108                      svn_boolean_t *tree_conflicted_p,
4109                      const char *path,
4110                      svn_wc_adm_access_t *adm_access,
4111                      apr_pool_t *pool)
4112 {
4113   const char *local_abspath;
4114   svn_wc_context_t *wc_ctx;
4115   svn_error_t *err;
4116
4117   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
4118   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
4119                                          svn_wc__adm_get_db(adm_access),
4120                                          pool));
4121
4122   err = svn_wc_conflicted_p3(text_conflicted_p, prop_conflicted_p,
4123                              tree_conflicted_p, wc_ctx, local_abspath, pool);
4124
4125   if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
4126     {
4127       svn_error_clear(err);
4128
4129       if (text_conflicted_p)
4130         *text_conflicted_p = FALSE;
4131       if (prop_conflicted_p)
4132         *prop_conflicted_p = FALSE;
4133       if (tree_conflicted_p)
4134         *tree_conflicted_p = FALSE;
4135     }
4136   else if (err)
4137     return err;
4138
4139   return SVN_NO_ERROR;
4140 }
4141
4142 svn_error_t *
4143 svn_wc_conflicted_p(svn_boolean_t *text_conflicted_p,
4144                     svn_boolean_t *prop_conflicted_p,
4145                     const char *dir_path,
4146                     const svn_wc_entry_t *entry,
4147                     apr_pool_t *pool)
4148 {
4149   svn_node_kind_t kind;
4150   const char *path;
4151
4152   *text_conflicted_p = FALSE;
4153   *prop_conflicted_p = FALSE;
4154
4155   if (entry->conflict_old)
4156     {
4157       path = svn_dirent_join(dir_path, entry->conflict_old, pool);
4158       SVN_ERR(svn_io_check_path(path, &kind, pool));
4159       *text_conflicted_p = (kind == svn_node_file);
4160     }
4161
4162   if ((! *text_conflicted_p) && (entry->conflict_new))
4163     {
4164       path = svn_dirent_join(dir_path, entry->conflict_new, pool);
4165       SVN_ERR(svn_io_check_path(path, &kind, pool));
4166       *text_conflicted_p = (kind == svn_node_file);
4167     }
4168
4169   if ((! *text_conflicted_p) && (entry->conflict_wrk))
4170     {
4171       path = svn_dirent_join(dir_path, entry->conflict_wrk, pool);
4172       SVN_ERR(svn_io_check_path(path, &kind, pool));
4173       *text_conflicted_p = (kind == svn_node_file);
4174     }
4175
4176   if (entry->prejfile)
4177     {
4178       path = svn_dirent_join(dir_path, entry->prejfile, pool);
4179       SVN_ERR(svn_io_check_path(path, &kind, pool));
4180       *prop_conflicted_p = (kind == svn_node_file);
4181     }
4182
4183   return SVN_NO_ERROR;
4184 }
4185
4186 svn_error_t *
4187 svn_wc_text_modified_p(svn_boolean_t *modified_p,
4188                        const char *filename,
4189                        svn_boolean_t force_comparison,
4190                        svn_wc_adm_access_t *adm_access,
4191                        apr_pool_t *pool)
4192 {
4193   svn_wc_context_t *wc_ctx;
4194   svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
4195   const char *local_abspath;
4196
4197   SVN_ERR(svn_dirent_get_absolute(&local_abspath, filename, pool));
4198   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool));
4199
4200   SVN_ERR(svn_wc_text_modified_p2(modified_p, wc_ctx, local_abspath,
4201                                   force_comparison, pool));
4202
4203   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
4204 }
4205
4206
4207 /*** From copy.c ***/
4208 svn_error_t *
4209 svn_wc_copy2(const char *src,
4210              svn_wc_adm_access_t *dst_parent,
4211              const char *dst_basename,
4212              svn_cancel_func_t cancel_func,
4213              void *cancel_baton,
4214              svn_wc_notify_func2_t notify_func,
4215              void *notify_baton,
4216              apr_pool_t *pool)
4217 {
4218   svn_wc_context_t *wc_ctx;
4219   svn_wc__db_t *wc_db = svn_wc__adm_get_db(dst_parent);
4220   const char *src_abspath;
4221   const char *dst_abspath;
4222
4223   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool));
4224   SVN_ERR(svn_dirent_get_absolute(&src_abspath, src, pool));
4225
4226   dst_abspath = svn_dirent_join(svn_wc__adm_access_abspath(dst_parent),
4227                                 dst_basename, pool);
4228
4229   SVN_ERR(svn_wc_copy3(wc_ctx,
4230                        src_abspath,
4231                        dst_abspath,
4232                        FALSE /* metadata_only */,
4233                        cancel_func, cancel_baton,
4234                        notify_func, notify_baton,
4235                        pool));
4236
4237   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
4238 }
4239
4240 svn_error_t *
4241 svn_wc_copy(const char *src_path,
4242             svn_wc_adm_access_t *dst_parent,
4243             const char *dst_basename,
4244             svn_cancel_func_t cancel_func,
4245             void *cancel_baton,
4246             svn_wc_notify_func_t notify_func,
4247             void *notify_baton,
4248             apr_pool_t *pool)
4249 {
4250   struct compat_notify_baton_t nb;
4251
4252   nb.func = notify_func;
4253   nb.baton = notify_baton;
4254
4255   return svn_wc_copy2(src_path, dst_parent, dst_basename, cancel_func,
4256                       cancel_baton, compat_call_notify_func,
4257                       &nb, pool);
4258 }
4259
4260
4261 /*** From merge.c ***/
4262
4263 svn_error_t *
4264 svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome,
4265               svn_wc_context_t *wc_ctx,
4266               const char *left_abspath,
4267               const char *right_abspath,
4268               const char *target_abspath,
4269               const char *left_label,
4270               const char *right_label,
4271               const char *target_label,
4272               const svn_wc_conflict_version_t *left_version,
4273               const svn_wc_conflict_version_t *right_version,
4274               svn_boolean_t dry_run,
4275               const char *diff3_cmd,
4276               const apr_array_header_t *merge_options,
4277               const apr_array_header_t *prop_diff,
4278               svn_wc_conflict_resolver_func2_t conflict_func,
4279               void *conflict_baton,
4280               svn_cancel_func_t cancel_func,
4281               void *cancel_baton,
4282               apr_pool_t *scratch_pool)
4283 {
4284   return svn_error_trace(
4285             svn_wc_merge5(merge_outcome,
4286                           NULL /* merge_props_outcome */,
4287                           wc_ctx,
4288                           left_abspath,
4289                           right_abspath,
4290                           target_abspath,
4291                           left_label,
4292                           right_label,
4293                           target_label,
4294                           left_version,
4295                           right_version,
4296                           dry_run,
4297                           diff3_cmd,
4298                           merge_options,
4299                           NULL /* original_props */,
4300                           prop_diff,
4301                           conflict_func, conflict_baton,
4302                           cancel_func, cancel_baton,
4303                           scratch_pool));
4304 }
4305
4306 svn_error_t *
4307 svn_wc_merge3(enum svn_wc_merge_outcome_t *merge_outcome,
4308               const char *left,
4309               const char *right,
4310               const char *merge_target,
4311               svn_wc_adm_access_t *adm_access,
4312               const char *left_label,
4313               const char *right_label,
4314               const char *target_label,
4315               svn_boolean_t dry_run,
4316               const char *diff3_cmd,
4317               const apr_array_header_t *merge_options,
4318               const apr_array_header_t *prop_diff,
4319               svn_wc_conflict_resolver_func_t conflict_func,
4320               void *conflict_baton,
4321               apr_pool_t *pool)
4322 {
4323   svn_wc_context_t *wc_ctx;
4324   svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
4325   const char *left_abspath, *right_abspath, *target_abspath;
4326   struct conflict_func_1to2_baton cfw;
4327
4328   SVN_ERR(svn_dirent_get_absolute(&left_abspath, left, pool));
4329   SVN_ERR(svn_dirent_get_absolute(&right_abspath, right, pool));
4330   SVN_ERR(svn_dirent_get_absolute(&target_abspath, merge_target, pool));
4331
4332   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, db, pool));
4333
4334   cfw.inner_func = conflict_func;
4335   cfw.inner_baton = conflict_baton;
4336
4337   if (diff3_cmd)
4338     SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, pool));
4339
4340   SVN_ERR(svn_wc_merge4(merge_outcome,
4341                         wc_ctx,
4342                         left_abspath,
4343                         right_abspath,
4344                         target_abspath,
4345                         left_label,
4346                         right_label,
4347                         target_label,
4348                         NULL,
4349                         NULL,
4350                         dry_run,
4351                         diff3_cmd,
4352                         merge_options,
4353                         prop_diff,
4354                         conflict_func ? conflict_func_1to2_wrapper : NULL,
4355                         &cfw,
4356                         NULL, NULL,
4357                         pool));
4358
4359   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
4360 }
4361
4362 svn_error_t *
4363 svn_wc_merge2(enum svn_wc_merge_outcome_t *merge_outcome,
4364               const char *left,
4365               const char *right,
4366               const char *merge_target,
4367               svn_wc_adm_access_t *adm_access,
4368               const char *left_label,
4369               const char *right_label,
4370               const char *target_label,
4371               svn_boolean_t dry_run,
4372               const char *diff3_cmd,
4373               const apr_array_header_t *merge_options,
4374               apr_pool_t *pool)
4375 {
4376   return svn_wc_merge3(merge_outcome,
4377                        left, right, merge_target, adm_access,
4378                        left_label, right_label, target_label,
4379                        dry_run, diff3_cmd, merge_options, NULL,
4380                        NULL, NULL, pool);
4381 }
4382
4383 svn_error_t *
4384 svn_wc_merge(const char *left,
4385              const char *right,
4386              const char *merge_target,
4387              svn_wc_adm_access_t *adm_access,
4388              const char *left_label,
4389              const char *right_label,
4390              const char *target_label,
4391              svn_boolean_t dry_run,
4392              enum svn_wc_merge_outcome_t *merge_outcome,
4393              const char *diff3_cmd,
4394              apr_pool_t *pool)
4395 {
4396   return svn_wc_merge3(merge_outcome,
4397                        left, right, merge_target, adm_access,
4398                        left_label, right_label, target_label,
4399                        dry_run, diff3_cmd, NULL, NULL, NULL,
4400                        NULL, pool);
4401 }
4402
4403
4404 /*** From util.c ***/
4405
4406 svn_wc_conflict_version_t *
4407 svn_wc_conflict_version_create(const char *repos_url,
4408                                const char *path_in_repos,
4409                                svn_revnum_t peg_rev,
4410                                svn_node_kind_t node_kind,
4411                                apr_pool_t *pool)
4412 {
4413   return svn_wc_conflict_version_create2(repos_url, NULL, path_in_repos,
4414                                          peg_rev, node_kind, pool);
4415 }
4416
4417 svn_wc_conflict_description_t *
4418 svn_wc_conflict_description_create_text(const char *path,
4419                                         svn_wc_adm_access_t *adm_access,
4420                                         apr_pool_t *pool)
4421 {
4422   svn_wc_conflict_description_t *conflict;
4423
4424   conflict = apr_pcalloc(pool, sizeof(*conflict));
4425   conflict->path = path;
4426   conflict->node_kind = svn_node_file;
4427   conflict->kind = svn_wc_conflict_kind_text;
4428   conflict->access = adm_access;
4429   conflict->action = svn_wc_conflict_action_edit;
4430   conflict->reason = svn_wc_conflict_reason_edited;
4431   return conflict;
4432 }
4433
4434 svn_wc_conflict_description_t *
4435 svn_wc_conflict_description_create_prop(const char *path,
4436                                         svn_wc_adm_access_t *adm_access,
4437                                         svn_node_kind_t node_kind,
4438                                         const char *property_name,
4439                                         apr_pool_t *pool)
4440 {
4441   svn_wc_conflict_description_t *conflict;
4442
4443   conflict = apr_pcalloc(pool, sizeof(*conflict));
4444   conflict->path = path;
4445   conflict->node_kind = node_kind;
4446   conflict->kind = svn_wc_conflict_kind_property;
4447   conflict->access = adm_access;
4448   conflict->property_name = property_name;
4449   return conflict;
4450 }
4451
4452 svn_wc_conflict_description_t *
4453 svn_wc_conflict_description_create_tree(
4454                             const char *path,
4455                             svn_wc_adm_access_t *adm_access,
4456                             svn_node_kind_t node_kind,
4457                             svn_wc_operation_t operation,
4458                             svn_wc_conflict_version_t *src_left_version,
4459                             svn_wc_conflict_version_t *src_right_version,
4460                             apr_pool_t *pool)
4461 {
4462   svn_wc_conflict_description_t *conflict;
4463
4464   conflict = apr_pcalloc(pool, sizeof(*conflict));
4465   conflict->path = path;
4466   conflict->node_kind = node_kind;
4467   conflict->kind = svn_wc_conflict_kind_tree;
4468   conflict->access = adm_access;
4469   conflict->operation = operation;
4470   conflict->src_left_version = src_left_version;
4471   conflict->src_right_version = src_right_version;
4472   return conflict;
4473 }
4474
4475
4476 /*** From revision_status.c ***/
4477
4478 svn_error_t *
4479 svn_wc_revision_status(svn_wc_revision_status_t **result_p,
4480                        const char *wc_path,
4481                        const char *trail_url,
4482                        svn_boolean_t committed,
4483                        svn_cancel_func_t cancel_func,
4484                        void *cancel_baton,
4485                        apr_pool_t *pool)
4486 {
4487   svn_wc_context_t *wc_ctx;
4488   const char *local_abspath;
4489
4490   SVN_ERR(svn_dirent_get_absolute(&local_abspath, wc_path, pool));
4491   SVN_ERR(svn_wc_context_create(&wc_ctx, NULL /* config */, pool, pool));
4492
4493   SVN_ERR(svn_wc_revision_status2(result_p, wc_ctx, local_abspath, trail_url,
4494                                   committed, cancel_func, cancel_baton, pool,
4495                                   pool));
4496
4497   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
4498 }
4499
4500 /*** From crop.c ***/
4501 svn_error_t *
4502 svn_wc_crop_tree(svn_wc_adm_access_t *anchor,
4503                  const char *target,
4504                  svn_depth_t depth,
4505                  svn_wc_notify_func2_t notify_func,
4506                  void *notify_baton,
4507                  svn_cancel_func_t cancel_func,
4508                  void *cancel_baton,
4509                  apr_pool_t *pool)
4510 {
4511   svn_wc_context_t *wc_ctx;
4512   svn_wc__db_t *db = svn_wc__adm_get_db(anchor);
4513   const char *local_abspath;
4514
4515   local_abspath = svn_dirent_join(svn_wc__adm_access_abspath(anchor),
4516                                   target, pool);
4517
4518   SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool));
4519
4520   if (depth == svn_depth_exclude)
4521     {
4522       SVN_ERR(svn_wc_exclude(wc_ctx,
4523                              local_abspath,
4524                              cancel_func, cancel_baton,
4525                              notify_func, notify_baton,
4526                              pool));
4527     }
4528   else
4529     {
4530       SVN_ERR(svn_wc_crop_tree2(wc_ctx,
4531                                 local_abspath,
4532                                 depth,
4533                                 cancel_func, cancel_baton,
4534                                 notify_func, notify_baton,
4535                                 pool));
4536     }
4537
4538   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
4539 }
4540
4541 svn_error_t *
4542 svn_wc_move(svn_wc_context_t *wc_ctx,
4543             const char *src_abspath,
4544             const char *dst_abspath,
4545             svn_boolean_t metadata_only,
4546             svn_cancel_func_t cancel_func,
4547             void *cancel_baton,
4548             svn_wc_notify_func2_t notify_func,
4549             void *notify_baton,
4550             apr_pool_t *scratch_pool)
4551 {
4552   return svn_error_trace(svn_wc__move2(wc_ctx, src_abspath, dst_abspath,
4553                                        metadata_only,
4554                                        TRUE, /* allow_mixed_revisions */
4555                                        cancel_func, cancel_baton,
4556                                        notify_func, notify_baton,
4557                                        scratch_pool));
4558 }
4559
4560 svn_error_t *
4561 svn_wc_read_kind(svn_node_kind_t *kind,
4562                  svn_wc_context_t *wc_ctx,
4563                  const char *abspath,
4564                  svn_boolean_t show_hidden,
4565                  apr_pool_t *scratch_pool)
4566 {
4567   return svn_error_trace(
4568           svn_wc_read_kind2(kind,
4569                             wc_ctx, abspath,
4570                             TRUE /* show_deleted */,
4571                             show_hidden,
4572                             scratch_pool));
4573
4574   /*if (db_kind == svn_node_dir)
4575     *kind = svn_node_dir;
4576   else if (db_kind == svn_node_file || db_kind == svn_node_symlink)
4577     *kind = svn_node_file;
4578   else
4579     *kind = svn_node_none;*/
4580
4581   return SVN_NO_ERROR;
4582 }