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