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 */
53struct 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 */
61static svn_error_t *
62traversal_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 */
107static svn_error_t *
108gather_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
154/*** From adm_crawler.c ***/
155
156svn_error_t *
157svn_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
207struct wrap_3to2_report_baton {
208  const svn_ra_reporter2_t *reporter;
209  void *baton;
210};
211
212/* */
213static 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/* */
228static 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/* */
238static 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/* */
254static 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/* */
263static 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
271static 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
279svn_error_t *
280svn_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
307svn_error_t *
308svn_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.  */
339struct 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.  */
349static void
350compat_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
369struct wrap_2to1_report_baton {
370  const svn_ra_reporter_t *reporter;
371  void *baton;
372};
373
374/* */
375static 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/* */
389static 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/* */
399static 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/* */
414static 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/* */
423static 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
431static 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
439svn_error_t *
440svn_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
468svn_error_t *
469svn_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
502svn_error_t *
503svn_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
515svn_error_t *
516svn_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 ***/
542svn_error_t *
543svn_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
568svn_error_t *
569svn_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
581svn_error_t *
582svn_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
591svn_error_t *
592svn_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
604svn_error_t *
605svn_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 ***/
634svn_error_t *
635svn_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
656svn_error_t *
657svn_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
700svn_error_t *
701svn_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
724svn_error_t *
725svn_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
745svn_error_t *
746svn_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
805svn_error_t *
806svn_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
822svn_error_t *
823svn_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
838svn_error_t *
839svn_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
853svn_error_t *
854svn_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
862svn_error_t *
863svn_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
896svn_error_t *
897svn_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
909svn_error_t *
910svn_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
927svn_error_t *
928svn_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
939svn_error_t *
940svn_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
990svn_error_t *
991svn_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
1007svn_error_t *
1008svn_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
1028svn_error_t *
1029svn_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
1059svn_error_t *
1060svn_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
1076svn_error_t *
1077svn_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
1097svn_error_t *
1098svn_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
1127svn_error_t *
1128svn_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
1165svn_error_t *
1166svn_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
1187svn_error_t *
1188svn_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
1207svn_error_t *
1208svn_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
1227svn_error_t *
1228svn_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
1246svn_error_t *
1247svn_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
1265svn_error_t *
1266svn_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
1291svn_error_t *
1292svn_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. */
1320struct 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. */
1326static svn_error_t *
1327wrap_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. */
1361static svn_error_t *
1362wrap_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. */
1394static svn_error_t *
1395wrap_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. */
1419static svn_error_t *
1420wrap_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. */
1436static svn_error_t *
1437wrap_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. */
1452static svn_error_t *
1453wrap_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. */
1472static svn_error_t *
1473wrap_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. */
1487static svn_error_t *
1488wrap_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. */
1506static 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. */
1520struct 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. */
1527static svn_error_t *
1528wrap_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. */
1556static svn_error_t *
1557wrap_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. */
1585static svn_error_t *
1586wrap_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. */
1609static svn_error_t *
1610wrap_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. */
1627static svn_error_t *
1628wrap_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. */
1644static svn_error_t *
1645wrap_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. */
1663static 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. */
1677struct 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
1685static svn_error_t *
1686wrap_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. */
1698static svn_error_t *
1699wrap_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. */
1734static svn_error_t *
1735wrap_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. */
1772static svn_error_t *
1773wrap_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. */
1803static svn_error_t *
1804wrap_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. */
1831static svn_error_t *
1832wrap_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. */
1854static svn_error_t *
1855wrap_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. */
1882static svn_error_t *
1883wrap_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. */
1909static svn_error_t *
1910wrap_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. */
1935static 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
1948svn_error_t *
1949svn_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
1984svn_error_t *
1985svn_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
2037svn_error_t *
2038svn_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
2072svn_error_t *
2073svn_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
2103svn_error_t *
2104svn_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
2128svn_error_t *
2129svn_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
2148svn_error_t *
2149svn_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
2184svn_error_t *
2185svn_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
2202svn_error_t *
2203svn_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
2216svn_error_t *
2217svn_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
2233svn_error_t *
2234svn_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 ***/
2246svn_error_t *
2247svn_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
2264svn_error_t *
2265svn_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
2277svn_error_t *
2278svn_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 ***/
2291svn_error_t *
2292svn_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
2332svn_error_t *
2333svn_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
2360svn_error_t *
2361svn_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
2395svn_error_t *
2396svn_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
2407svn_error_t *
2408svn_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
2417svn_error_t *
2418svn_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
2442svn_error_t *
2443svn_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 */
2471struct 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 */
2479static svn_error_t *
2480conflict_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
2494svn_error_t *
2495svn_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
2552svn_error_t *
2553svn_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
2567svn_error_t *
2568svn_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
2583svn_error_t *
2584svn_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
2604svn_error_t *
2605svn_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
2638struct 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/* */
2648static svn_error_t *
2649status4_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
2673svn_error_t *
2674svn_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
2713svn_error_t *
2714svn_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
2794struct status_editor3_compat_baton
2795{
2796  svn_wc_status_func2_t old_func;
2797  void *old_baton;
2798};
2799
2800/* */
2801static svn_error_t *
2802status_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
2813svn_error_t *
2814svn_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
2845svn_error_t *
2846svn_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. */
2887struct old_status_func_cb_baton
2888{
2889  svn_wc_status_func_t original_func;
2890  void *original_baton;
2891};
2892
2893/* */
2894static 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
2904svn_error_t *
2905svn_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
2935svn_error_t *
2936svn_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
2949static svn_wc_conflict_description_t *
2950conflict_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
2986svn_wc_status2_t *
2987svn_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
3017svn_wc_status_t *
3018svn_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
3034svn_error_t *
3035svn_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
3056svn_error_t *
3057svn_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
3081svn_error_t *
3082svn_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
3118svn_error_t *
3119svn_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
3211svn_error_t *
3212svn_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
3227svn_error_t *
3228svn_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. */
3244svn_error_t *
3245svn_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
3273svn_error_t *
3274svn_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
3312svn_error_t *
3313svn_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
3364svn_error_t *
3365svn_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
3440svn_error_t *
3441svn_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
3466svn_error_t *
3467svn_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
3499svn_error_t *
3500svn_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
3548svn_error_t *
3549svn_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
3623svn_error_t *
3624svn_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
3652svn_error_t *
3653svn_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
3686svn_error_t *
3687svn_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
3694svn_wc_external_item_t *
3695svn_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
3712svn_wc_traversal_info_t *
3713svn_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
3726void
3727svn_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
3736void
3737svn_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 */
3747svn_error_t *
3748svn_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
3759svn_error_t *
3760svn_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
3771svn_error_t *
3772svn_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
3785svn_error_t *
3786svn_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
3797svn_error_t *
3798svn_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
3809svn_error_t *
3810svn_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
3821svn_error_t *
3822svn_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
3830svn_error_t *
3831svn_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
3846svn_error_t *
3847svn_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
3865svn_error_t *
3866svn_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
3879svn_error_t *
3880svn_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
3899svn_error_t *
3900svn_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 ***/
3938svn_error_t *
3939svn_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. */
3967struct compat2_baton {
3968  svn_wc_relocation_validator2_t validator;
3969  void *baton;
3970};
3971
3972/* Compatibility baton and wrapper. */
3973struct compat_baton {
3974  svn_wc_relocation_validator_t validator;
3975  void *baton;
3976};
3977
3978/* This implements svn_wc_relocate_validator3_t. */
3979static svn_error_t *
3980compat2_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. */
3994static svn_error_t *
3995compat_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
4008svn_error_t *
4009svn_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
4027svn_error_t *
4028svn_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
4049svn_error_t *
4050svn_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
4068svn_error_t *
4069svn_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
4081svn_error_t *
4082svn_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
4105svn_error_t *
4106svn_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
4142svn_error_t *
4143svn_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
4186svn_error_t *
4187svn_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 ***/
4208svn_error_t *
4209svn_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
4240svn_error_t *
4241svn_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
4263svn_error_t *
4264svn_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
4306svn_error_t *
4307svn_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
4362svn_error_t *
4363svn_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
4383svn_error_t *
4384svn_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
4406svn_wc_conflict_version_t *
4407svn_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
4417svn_wc_conflict_description_t *
4418svn_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
4434svn_wc_conflict_description_t *
4435svn_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
4452svn_wc_conflict_description_t *
4453svn_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
4478svn_error_t *
4479svn_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 ***/
4501svn_error_t *
4502svn_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
4541svn_error_t *
4542svn_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
4560svn_error_t *
4561svn_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}
4583