1251881Speter/*
2251881Speter * deprecated.c:  holding file for all deprecated APIs.
3251881Speter *                "we can't lose 'em, but we can shun 'em!"
4251881Speter *
5251881Speter * ====================================================================
6251881Speter *    Licensed to the Apache Software Foundation (ASF) under one
7251881Speter *    or more contributor license agreements.  See the NOTICE file
8251881Speter *    distributed with this work for additional information
9251881Speter *    regarding copyright ownership.  The ASF licenses this file
10251881Speter *    to you under the Apache License, Version 2.0 (the
11251881Speter *    "License"); you may not use this file except in compliance
12251881Speter *    with the License.  You may obtain a copy of the License at
13251881Speter *
14251881Speter *      http://www.apache.org/licenses/LICENSE-2.0
15251881Speter *
16251881Speter *    Unless required by applicable law or agreed to in writing,
17251881Speter *    software distributed under the License is distributed on an
18251881Speter *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19251881Speter *    KIND, either express or implied.  See the License for the
20251881Speter *    specific language governing permissions and limitations
21251881Speter *    under the License.
22251881Speter * ====================================================================
23251881Speter */
24251881Speter
25251881Speter/* ==================================================================== */
26251881Speter
27251881Speter
28251881Speter
29251881Speter/*** Includes. ***/
30251881Speter
31251881Speter/* We define this here to remove any further warnings about the usage of
32251881Speter   deprecated functions in this file. */
33251881Speter#define SVN_DEPRECATED
34251881Speter
35251881Speter#include <string.h>
36251881Speter#include "svn_client.h"
37251881Speter#include "svn_path.h"
38251881Speter#include "svn_compat.h"
39251881Speter#include "svn_hash.h"
40251881Speter#include "svn_props.h"
41251881Speter#include "svn_utf.h"
42251881Speter#include "svn_string.h"
43251881Speter#include "svn_pools.h"
44251881Speter
45251881Speter#include "client.h"
46251881Speter#include "mergeinfo.h"
47251881Speter
48251881Speter#include "private/svn_opt_private.h"
49251881Speter#include "private/svn_wc_private.h"
50251881Speter#include "svn_private_config.h"
51251881Speter
52251881Speter
53251881Speter
54251881Speter
55251881Speter/*** Code. ***/
56251881Speter
57251881Speter
58251881Speter/* Baton for capture_commit_info() */
59251881Speterstruct capture_baton_t {
60251881Speter  svn_commit_info_t **info;
61251881Speter  apr_pool_t *pool;
62251881Speter};
63251881Speter
64251881Speter
65251881Speter/* Callback which implements svn_commit_callback2_t for use with some
66251881Speter   backward compat functions. */
67251881Speterstatic svn_error_t *
68251881Spetercapture_commit_info(const svn_commit_info_t *commit_info,
69251881Speter                    void *baton,
70251881Speter                    apr_pool_t *pool)
71251881Speter{
72251881Speter  struct capture_baton_t *cb = baton;
73251881Speter
74251881Speter  *(cb->info) = svn_commit_info_dup(commit_info, cb->pool);
75251881Speter
76251881Speter  return SVN_NO_ERROR;
77251881Speter}
78251881Speter
79251881Speter
80251881Speter/*** From add.c ***/
81251881Spetersvn_error_t *
82251881Spetersvn_client_add4(const char *path,
83251881Speter                svn_depth_t depth,
84251881Speter                svn_boolean_t force,
85251881Speter                svn_boolean_t no_ignore,
86251881Speter                svn_boolean_t add_parents,
87251881Speter                svn_client_ctx_t *ctx,
88251881Speter                apr_pool_t *pool)
89251881Speter{
90251881Speter  return svn_client_add5(path, depth, force, no_ignore, FALSE, add_parents,
91251881Speter                         ctx, pool);
92251881Speter}
93251881Speter
94251881Spetersvn_error_t *
95251881Spetersvn_client_add3(const char *path,
96251881Speter                svn_boolean_t recursive,
97251881Speter                svn_boolean_t force,
98251881Speter                svn_boolean_t no_ignore,
99251881Speter                svn_client_ctx_t *ctx,
100251881Speter                apr_pool_t *pool)
101251881Speter{
102251881Speter  return svn_client_add4(path, SVN_DEPTH_INFINITY_OR_EMPTY(recursive),
103251881Speter                         force, no_ignore, FALSE, ctx,
104251881Speter                         pool);
105251881Speter}
106251881Speter
107251881Spetersvn_error_t *
108251881Spetersvn_client_add2(const char *path,
109251881Speter                svn_boolean_t recursive,
110251881Speter                svn_boolean_t force,
111251881Speter                svn_client_ctx_t *ctx,
112251881Speter                apr_pool_t *pool)
113251881Speter{
114251881Speter  return svn_client_add3(path, recursive, force, FALSE, ctx, pool);
115251881Speter}
116251881Speter
117251881Spetersvn_error_t *
118251881Spetersvn_client_add(const char *path,
119251881Speter               svn_boolean_t recursive,
120251881Speter               svn_client_ctx_t *ctx,
121251881Speter               apr_pool_t *pool)
122251881Speter{
123251881Speter  return svn_client_add3(path, recursive, FALSE, FALSE, ctx, pool);
124251881Speter}
125251881Speter
126251881Spetersvn_error_t *
127251881Spetersvn_client_mkdir3(svn_commit_info_t **commit_info_p,
128251881Speter                  const apr_array_header_t *paths,
129251881Speter                  svn_boolean_t make_parents,
130251881Speter                  const apr_hash_t *revprop_table,
131251881Speter                  svn_client_ctx_t *ctx,
132251881Speter                  apr_pool_t *pool)
133251881Speter{
134251881Speter  struct capture_baton_t cb;
135251881Speter
136251881Speter  cb.info = commit_info_p;
137251881Speter  cb.pool = pool;
138251881Speter
139251881Speter  return svn_client_mkdir4(paths, make_parents, revprop_table,
140251881Speter                           capture_commit_info, &cb, ctx, pool);
141251881Speter}
142251881Speter
143251881Spetersvn_error_t *
144251881Spetersvn_client_mkdir2(svn_commit_info_t **commit_info_p,
145251881Speter                  const apr_array_header_t *paths,
146251881Speter                  svn_client_ctx_t *ctx,
147251881Speter                  apr_pool_t *pool)
148251881Speter{
149251881Speter  return svn_client_mkdir3(commit_info_p, paths, FALSE, NULL, ctx, pool);
150251881Speter}
151251881Speter
152251881Speter
153251881Spetersvn_error_t *
154251881Spetersvn_client_mkdir(svn_client_commit_info_t **commit_info_p,
155251881Speter                 const apr_array_header_t *paths,
156251881Speter                 svn_client_ctx_t *ctx,
157251881Speter                 apr_pool_t *pool)
158251881Speter{
159251881Speter  svn_commit_info_t *commit_info = NULL;
160251881Speter  svn_error_t *err;
161251881Speter
162251881Speter  err = svn_client_mkdir2(&commit_info, paths, ctx, pool);
163251881Speter  /* These structs have the same layout for the common fields. */
164251881Speter  *commit_info_p = (svn_client_commit_info_t *) commit_info;
165251881Speter  return svn_error_trace(err);
166251881Speter}
167251881Speter
168251881Speter/*** From blame.c ***/
169251881Speter
170251881Speterstruct blame_receiver_wrapper_baton2 {
171251881Speter  void *baton;
172251881Speter  svn_client_blame_receiver2_t receiver;
173251881Speter};
174251881Speter
175251881Speterstatic svn_error_t *
176251881Speterblame_wrapper_receiver2(void *baton,
177251881Speter   svn_revnum_t start_revnum,
178251881Speter   svn_revnum_t end_revnum,
179251881Speter   apr_int64_t line_no,
180251881Speter   svn_revnum_t revision,
181251881Speter   apr_hash_t *rev_props,
182251881Speter   svn_revnum_t merged_revision,
183251881Speter   apr_hash_t *merged_rev_props,
184251881Speter   const char *merged_path,
185251881Speter   const char *line,
186251881Speter   svn_boolean_t local_change,
187251881Speter   apr_pool_t *pool)
188251881Speter{
189251881Speter  struct blame_receiver_wrapper_baton2 *brwb = baton;
190251881Speter  const char *author = NULL;
191251881Speter  const char *date = NULL;
192251881Speter  const char *merged_author = NULL;
193251881Speter  const char *merged_date = NULL;
194251881Speter
195251881Speter  if (rev_props != NULL)
196251881Speter    {
197251881Speter      author = svn_prop_get_value(rev_props, SVN_PROP_REVISION_AUTHOR);
198251881Speter      date = svn_prop_get_value(rev_props, SVN_PROP_REVISION_DATE);
199251881Speter    }
200251881Speter  if (merged_rev_props != NULL)
201251881Speter    {
202251881Speter      merged_author = svn_prop_get_value(merged_rev_props,
203251881Speter                                         SVN_PROP_REVISION_AUTHOR);
204251881Speter      merged_date = svn_prop_get_value(merged_rev_props,
205251881Speter                                       SVN_PROP_REVISION_DATE);
206251881Speter    }
207251881Speter
208251881Speter  if (brwb->receiver)
209251881Speter    return brwb->receiver(brwb->baton, line_no, revision, author, date,
210251881Speter                          merged_revision, merged_author, merged_date,
211251881Speter                          merged_path, line, pool);
212251881Speter
213251881Speter  return SVN_NO_ERROR;
214251881Speter}
215251881Speter
216251881Spetersvn_error_t *
217251881Spetersvn_client_blame4(const char *target,
218251881Speter                  const svn_opt_revision_t *peg_revision,
219251881Speter                  const svn_opt_revision_t *start,
220251881Speter                  const svn_opt_revision_t *end,
221251881Speter                  const svn_diff_file_options_t *diff_options,
222251881Speter                  svn_boolean_t ignore_mime_type,
223251881Speter                  svn_boolean_t include_merged_revisions,
224251881Speter                  svn_client_blame_receiver2_t receiver,
225251881Speter                  void *receiver_baton,
226251881Speter                  svn_client_ctx_t *ctx,
227251881Speter                  apr_pool_t *pool)
228251881Speter{
229251881Speter  struct blame_receiver_wrapper_baton2 baton;
230251881Speter
231251881Speter  baton.receiver = receiver;
232251881Speter  baton.baton = receiver_baton;
233251881Speter
234251881Speter  return svn_client_blame5(target, peg_revision, start, end, diff_options,
235251881Speter                           ignore_mime_type, include_merged_revisions,
236251881Speter                           blame_wrapper_receiver2, &baton, ctx, pool);
237251881Speter}
238251881Speter
239251881Speter
240251881Speter/* Baton for use with wrap_blame_receiver */
241251881Speterstruct blame_receiver_wrapper_baton {
242251881Speter  void *baton;
243251881Speter  svn_client_blame_receiver_t receiver;
244251881Speter};
245251881Speter
246251881Speter/* This implements svn_client_blame_receiver2_t */
247251881Speterstatic svn_error_t *
248251881Speterblame_wrapper_receiver(void *baton,
249251881Speter                       apr_int64_t line_no,
250251881Speter                       svn_revnum_t revision,
251251881Speter                       const char *author,
252251881Speter                       const char *date,
253251881Speter                       svn_revnum_t merged_revision,
254251881Speter                       const char *merged_author,
255251881Speter                       const char *merged_date,
256251881Speter                       const char *merged_path,
257251881Speter                       const char *line,
258251881Speter                       apr_pool_t *pool)
259251881Speter{
260251881Speter  struct blame_receiver_wrapper_baton *brwb = baton;
261251881Speter
262251881Speter  if (brwb->receiver)
263251881Speter    return brwb->receiver(brwb->baton,
264251881Speter                          line_no, revision, author, date, line, pool);
265251881Speter
266251881Speter  return SVN_NO_ERROR;
267251881Speter}
268251881Speter
269251881Speterstatic void
270251881Speterwrap_blame_receiver(svn_client_blame_receiver2_t *receiver2,
271251881Speter                    void **receiver2_baton,
272251881Speter                    svn_client_blame_receiver_t receiver,
273251881Speter                    void *receiver_baton,
274251881Speter                    apr_pool_t *pool)
275251881Speter{
276251881Speter  struct blame_receiver_wrapper_baton *brwb = apr_palloc(pool, sizeof(*brwb));
277251881Speter
278251881Speter  /* Set the user provided old format callback in the baton. */
279251881Speter  brwb->baton = receiver_baton;
280251881Speter  brwb->receiver = receiver;
281251881Speter
282251881Speter  *receiver2_baton = brwb;
283251881Speter  *receiver2 = blame_wrapper_receiver;
284251881Speter}
285251881Speter
286251881Spetersvn_error_t *
287251881Spetersvn_client_blame3(const char *target,
288251881Speter                  const svn_opt_revision_t *peg_revision,
289251881Speter                  const svn_opt_revision_t *start,
290251881Speter                  const svn_opt_revision_t *end,
291251881Speter                  const svn_diff_file_options_t *diff_options,
292251881Speter                  svn_boolean_t ignore_mime_type,
293251881Speter                  svn_client_blame_receiver_t receiver,
294251881Speter                  void *receiver_baton,
295251881Speter                  svn_client_ctx_t *ctx,
296251881Speter                  apr_pool_t *pool)
297251881Speter{
298251881Speter  svn_client_blame_receiver2_t receiver2;
299251881Speter  void *receiver2_baton;
300251881Speter
301251881Speter  wrap_blame_receiver(&receiver2, &receiver2_baton, receiver, receiver_baton,
302251881Speter                      pool);
303251881Speter
304251881Speter  return svn_client_blame4(target, peg_revision, start, end, diff_options,
305251881Speter                           ignore_mime_type, FALSE, receiver2, receiver2_baton,
306251881Speter                           ctx, pool);
307251881Speter}
308251881Speter
309251881Speter/* svn_client_blame3 guarantees 'no EOL chars' as part of the receiver
310251881Speter   LINE argument.  Older versions depend on the fact that if a CR is
311251881Speter   required, that CR is already part of the LINE data.
312251881Speter
313251881Speter   Because of this difference, we need to trap old receivers and append
314251881Speter   a CR to LINE before passing it on to the actual receiver on platforms
315251881Speter   which want CRLF line termination.
316251881Speter
317251881Speter*/
318251881Speter
319251881Speterstruct wrapped_receiver_baton_s
320251881Speter{
321251881Speter  svn_client_blame_receiver_t orig_receiver;
322251881Speter  void *orig_baton;
323251881Speter};
324251881Speter
325251881Speterstatic svn_error_t *
326251881Speterwrapped_receiver(void *baton,
327251881Speter                 apr_int64_t line_no,
328251881Speter                 svn_revnum_t revision,
329251881Speter                 const char *author,
330251881Speter                 const char *date,
331251881Speter                 const char *line,
332251881Speter                 apr_pool_t *pool)
333251881Speter{
334251881Speter  struct wrapped_receiver_baton_s *b = baton;
335251881Speter  svn_stringbuf_t *expanded_line = svn_stringbuf_create(line, pool);
336251881Speter
337251881Speter  svn_stringbuf_appendbyte(expanded_line, '\r');
338251881Speter
339251881Speter  return b->orig_receiver(b->orig_baton, line_no, revision, author,
340251881Speter                          date, expanded_line->data, pool);
341251881Speter}
342251881Speter
343251881Speterstatic void
344251881Speterwrap_pre_blame3_receiver(svn_client_blame_receiver_t *receiver,
345251881Speter                         void **receiver_baton,
346251881Speter                         apr_pool_t *pool)
347251881Speter{
348251881Speter  if (sizeof(APR_EOL_STR) == 3)
349251881Speter    {
350251881Speter      struct wrapped_receiver_baton_s *b = apr_palloc(pool,sizeof(*b));
351251881Speter
352251881Speter      b->orig_receiver = *receiver;
353251881Speter      b->orig_baton = *receiver_baton;
354251881Speter
355251881Speter      *receiver_baton = b;
356251881Speter      *receiver = wrapped_receiver;
357251881Speter    }
358251881Speter}
359251881Speter
360251881Spetersvn_error_t *
361251881Spetersvn_client_blame2(const char *target,
362251881Speter                  const svn_opt_revision_t *peg_revision,
363251881Speter                  const svn_opt_revision_t *start,
364251881Speter                  const svn_opt_revision_t *end,
365251881Speter                  svn_client_blame_receiver_t receiver,
366251881Speter                  void *receiver_baton,
367251881Speter                  svn_client_ctx_t *ctx,
368251881Speter                  apr_pool_t *pool)
369251881Speter{
370251881Speter  wrap_pre_blame3_receiver(&receiver, &receiver_baton, pool);
371251881Speter  return svn_client_blame3(target, peg_revision, start, end,
372251881Speter                           svn_diff_file_options_create(pool), FALSE,
373251881Speter                           receiver, receiver_baton, ctx, pool);
374251881Speter}
375251881Spetersvn_error_t *
376251881Spetersvn_client_blame(const char *target,
377251881Speter                 const svn_opt_revision_t *start,
378251881Speter                 const svn_opt_revision_t *end,
379251881Speter                 svn_client_blame_receiver_t receiver,
380251881Speter                 void *receiver_baton,
381251881Speter                 svn_client_ctx_t *ctx,
382251881Speter                 apr_pool_t *pool)
383251881Speter{
384251881Speter  wrap_pre_blame3_receiver(&receiver, &receiver_baton, pool);
385251881Speter  return svn_client_blame2(target, end, start, end,
386251881Speter                           receiver, receiver_baton, ctx, pool);
387251881Speter}
388251881Speter
389251881Speter/*** From cmdline.c ***/
390251881Spetersvn_error_t *
391251881Spetersvn_client_args_to_target_array(apr_array_header_t **targets_p,
392251881Speter                                apr_getopt_t *os,
393251881Speter                                const apr_array_header_t *known_targets,
394251881Speter                                svn_client_ctx_t *ctx,
395251881Speter                                apr_pool_t *pool)
396251881Speter{
397251881Speter  return svn_client_args_to_target_array2(targets_p, os, known_targets, ctx,
398251881Speter                                          FALSE, pool);
399251881Speter}
400251881Speter
401251881Speter/*** From commit.c ***/
402251881Spetersvn_error_t *
403251881Spetersvn_client_import4(const char *path,
404251881Speter                   const char *url,
405251881Speter                   svn_depth_t depth,
406251881Speter                   svn_boolean_t no_ignore,
407251881Speter                   svn_boolean_t ignore_unknown_node_types,
408251881Speter                   const apr_hash_t *revprop_table,
409251881Speter                   svn_commit_callback2_t commit_callback,
410251881Speter                   void *commit_baton,
411251881Speter                   svn_client_ctx_t *ctx,
412251881Speter                   apr_pool_t *pool)
413251881Speter{
414251881Speter  return svn_error_trace(svn_client_import5(path, url, depth, no_ignore,
415251881Speter                                            FALSE, ignore_unknown_node_types,
416251881Speter                                            revprop_table,
417251881Speter                                            NULL, NULL,
418251881Speter                                            commit_callback, commit_baton,
419251881Speter                                            ctx, pool));
420251881Speter}
421251881Speter
422251881Speter
423251881Spetersvn_error_t *
424251881Spetersvn_client_import3(svn_commit_info_t **commit_info_p,
425251881Speter                   const char *path,
426251881Speter                   const char *url,
427251881Speter                   svn_depth_t depth,
428251881Speter                   svn_boolean_t no_ignore,
429251881Speter                   svn_boolean_t ignore_unknown_node_types,
430251881Speter                   const apr_hash_t *revprop_table,
431251881Speter                   svn_client_ctx_t *ctx,
432251881Speter                   apr_pool_t *pool)
433251881Speter{
434251881Speter  struct capture_baton_t cb;
435251881Speter
436251881Speter  cb.info = commit_info_p;
437251881Speter  cb.pool = pool;
438251881Speter
439251881Speter  return svn_client_import4(path, url, depth, no_ignore,
440251881Speter                            ignore_unknown_node_types, revprop_table,
441251881Speter                            capture_commit_info, &cb, ctx, pool);
442251881Speter}
443251881Speter
444251881Spetersvn_error_t *
445251881Spetersvn_client_import2(svn_commit_info_t **commit_info_p,
446251881Speter                   const char *path,
447251881Speter                   const char *url,
448251881Speter                   svn_boolean_t nonrecursive,
449251881Speter                   svn_boolean_t no_ignore,
450251881Speter                   svn_client_ctx_t *ctx,
451251881Speter                   apr_pool_t *pool)
452251881Speter{
453251881Speter  return svn_client_import3(commit_info_p,
454251881Speter                            path, url,
455251881Speter                            SVN_DEPTH_INFINITY_OR_FILES(! nonrecursive),
456251881Speter                            no_ignore, FALSE, NULL, ctx, pool);
457251881Speter}
458251881Speter
459251881Spetersvn_error_t *
460251881Spetersvn_client_import(svn_client_commit_info_t **commit_info_p,
461251881Speter                  const char *path,
462251881Speter                  const char *url,
463251881Speter                  svn_boolean_t nonrecursive,
464251881Speter                  svn_client_ctx_t *ctx,
465251881Speter                  apr_pool_t *pool)
466251881Speter{
467251881Speter  svn_commit_info_t *commit_info = NULL;
468251881Speter  svn_error_t *err;
469251881Speter
470251881Speter  err = svn_client_import2(&commit_info,
471251881Speter                           path, url, nonrecursive,
472251881Speter                           FALSE, ctx, pool);
473251881Speter  /* These structs have the same layout for the common fields. */
474251881Speter  *commit_info_p = (svn_client_commit_info_t *) commit_info;
475251881Speter  return svn_error_trace(err);
476251881Speter}
477251881Speter
478251881Speter
479251881Speter/* Wrapper notify_func2 function and baton for downgrading
480251881Speter   svn_wc_notify_commit_copied and svn_wc_notify_commit_copied_replaced
481251881Speter   to svn_wc_notify_commit_added and svn_wc_notify_commit_replaced,
482251881Speter   respectively. */
483251881Speterstruct downgrade_commit_copied_notify_baton
484251881Speter{
485251881Speter  svn_wc_notify_func2_t orig_notify_func2;
486251881Speter  void *orig_notify_baton2;
487251881Speter};
488251881Speter
489251881Speterstatic void
490251881Speterdowngrade_commit_copied_notify_func(void *baton,
491251881Speter                                    const svn_wc_notify_t *notify,
492251881Speter                                    apr_pool_t *pool)
493251881Speter{
494251881Speter  struct downgrade_commit_copied_notify_baton *b = baton;
495251881Speter
496251881Speter  if (notify->action == svn_wc_notify_commit_copied)
497251881Speter    {
498251881Speter      svn_wc_notify_t *my_notify = svn_wc_dup_notify(notify, pool);
499251881Speter      my_notify->action = svn_wc_notify_commit_added;
500251881Speter      notify = my_notify;
501251881Speter    }
502251881Speter  else if (notify->action == svn_wc_notify_commit_copied_replaced)
503251881Speter    {
504251881Speter      svn_wc_notify_t *my_notify = svn_wc_dup_notify(notify, pool);
505251881Speter      my_notify->action = svn_wc_notify_commit_replaced;
506251881Speter      notify = my_notify;
507251881Speter    }
508251881Speter
509251881Speter  /* Call the wrapped notification system (if any) with MY_NOTIFY,
510251881Speter     which is either the original NOTIFY object, or a tweaked deep
511251881Speter     copy thereof. */
512251881Speter  if (b->orig_notify_func2)
513251881Speter    b->orig_notify_func2(b->orig_notify_baton2, notify, pool);
514251881Speter}
515251881Speter
516251881Spetersvn_error_t *
517251881Spetersvn_client_commit5(const apr_array_header_t *targets,
518251881Speter                   svn_depth_t depth,
519251881Speter                   svn_boolean_t keep_locks,
520251881Speter                   svn_boolean_t keep_changelists,
521251881Speter                   svn_boolean_t commit_as_operations,
522251881Speter                   const apr_array_header_t *changelists,
523251881Speter                   const apr_hash_t *revprop_table,
524251881Speter                   svn_commit_callback2_t commit_callback,
525251881Speter                   void *commit_baton,
526251881Speter                   svn_client_ctx_t *ctx,
527251881Speter                   apr_pool_t *pool)
528251881Speter{
529251881Speter  return svn_client_commit6(targets, depth, keep_locks, keep_changelists,
530251881Speter                            commit_as_operations,
531251881Speter                            FALSE,  /* include_file_externals */
532251881Speter                            FALSE, /* include_dir_externals */
533251881Speter                            changelists, revprop_table, commit_callback,
534251881Speter                            commit_baton, ctx, pool);
535251881Speter}
536251881Speter
537251881Spetersvn_error_t *
538251881Spetersvn_client_commit4(svn_commit_info_t **commit_info_p,
539251881Speter                   const apr_array_header_t *targets,
540251881Speter                   svn_depth_t depth,
541251881Speter                   svn_boolean_t keep_locks,
542251881Speter                   svn_boolean_t keep_changelists,
543251881Speter                   const apr_array_header_t *changelists,
544251881Speter                   const apr_hash_t *revprop_table,
545251881Speter                   svn_client_ctx_t *ctx,
546251881Speter                   apr_pool_t *pool)
547251881Speter{
548251881Speter  struct capture_baton_t cb;
549251881Speter  struct downgrade_commit_copied_notify_baton notify_baton;
550251881Speter  svn_error_t *err;
551251881Speter
552251881Speter  notify_baton.orig_notify_func2 = ctx->notify_func2;
553251881Speter  notify_baton.orig_notify_baton2 = ctx->notify_baton2;
554251881Speter
555251881Speter  *commit_info_p = NULL;
556251881Speter  cb.info = commit_info_p;
557251881Speter  cb.pool = pool;
558251881Speter
559251881Speter  /* Swap out the notification system (if any) with a thin filtering
560251881Speter     wrapper. */
561251881Speter  if (ctx->notify_func2)
562251881Speter    {
563251881Speter      ctx->notify_func2 = downgrade_commit_copied_notify_func;
564251881Speter      ctx->notify_baton2 = &notify_baton;
565251881Speter    }
566251881Speter
567251881Speter  err = svn_client_commit5(targets, depth, keep_locks, keep_changelists, FALSE,
568251881Speter                           changelists, revprop_table,
569251881Speter                           capture_commit_info, &cb, ctx, pool);
570251881Speter
571251881Speter  /* Ensure that the original notification system is in place. */
572251881Speter  ctx->notify_func2 = notify_baton.orig_notify_func2;
573251881Speter  ctx->notify_baton2 = notify_baton.orig_notify_baton2;
574251881Speter
575251881Speter  SVN_ERR(err);
576251881Speter
577251881Speter  if (! *commit_info_p)
578251881Speter    *commit_info_p = svn_create_commit_info(pool);
579251881Speter
580251881Speter  return SVN_NO_ERROR;
581251881Speter}
582251881Speter
583251881Spetersvn_error_t *
584251881Spetersvn_client_commit3(svn_commit_info_t **commit_info_p,
585251881Speter                   const apr_array_header_t *targets,
586251881Speter                   svn_boolean_t recurse,
587251881Speter                   svn_boolean_t keep_locks,
588251881Speter                   svn_client_ctx_t *ctx,
589251881Speter                   apr_pool_t *pool)
590251881Speter{
591251881Speter  svn_depth_t depth = SVN_DEPTH_INFINITY_OR_EMPTY(recurse);
592251881Speter
593251881Speter  return svn_client_commit4(commit_info_p, targets, depth, keep_locks,
594251881Speter                            FALSE, NULL, NULL, ctx, pool);
595251881Speter}
596251881Speter
597251881Spetersvn_error_t *
598251881Spetersvn_client_commit2(svn_client_commit_info_t **commit_info_p,
599251881Speter                   const apr_array_header_t *targets,
600251881Speter                   svn_boolean_t recurse,
601251881Speter                   svn_boolean_t keep_locks,
602251881Speter                   svn_client_ctx_t *ctx,
603251881Speter                   apr_pool_t *pool)
604251881Speter{
605251881Speter  svn_commit_info_t *commit_info = NULL;
606251881Speter  svn_error_t *err;
607251881Speter
608251881Speter  err = svn_client_commit3(&commit_info, targets, recurse, keep_locks,
609251881Speter                           ctx, pool);
610251881Speter  /* These structs have the same layout for the common fields. */
611251881Speter  *commit_info_p = (svn_client_commit_info_t *) commit_info;
612251881Speter  return svn_error_trace(err);
613251881Speter}
614251881Speter
615251881Spetersvn_error_t *
616251881Spetersvn_client_commit(svn_client_commit_info_t **commit_info_p,
617251881Speter                  const apr_array_header_t *targets,
618251881Speter                  svn_boolean_t nonrecursive,
619251881Speter                  svn_client_ctx_t *ctx,
620251881Speter                  apr_pool_t *pool)
621251881Speter{
622251881Speter  return svn_client_commit2(commit_info_p, targets,
623251881Speter                            ! nonrecursive,
624251881Speter                            TRUE,
625251881Speter                            ctx, pool);
626251881Speter}
627251881Speter
628251881Speter/*** From copy.c ***/
629251881Spetersvn_error_t *
630299742Sdimsvn_client_copy6(const apr_array_header_t *sources,
631299742Sdim                 const char *dst_path,
632299742Sdim                 svn_boolean_t copy_as_child,
633299742Sdim                 svn_boolean_t make_parents,
634299742Sdim                 svn_boolean_t ignore_externals,
635299742Sdim                 const apr_hash_t *revprop_table,
636299742Sdim                 svn_commit_callback2_t commit_callback,
637299742Sdim                 void *commit_baton,
638299742Sdim                 svn_client_ctx_t *ctx,
639299742Sdim                 apr_pool_t *pool)
640299742Sdim{
641299742Sdim  return svn_error_trace(svn_client_copy7(sources, dst_path, copy_as_child,
642299742Sdim                                          make_parents, ignore_externals,
643299742Sdim                                          FALSE /* metadata_only */,
644299742Sdim                                          FALSE /* pin_externals */,
645299742Sdim                                          NULL /* externals_to_pin */,
646299742Sdim                                          revprop_table,
647299742Sdim                                          commit_callback, commit_baton,
648299742Sdim                                          ctx, pool));
649299742Sdim}
650299742Sdim
651299742Sdimsvn_error_t *
652251881Spetersvn_client_copy5(svn_commit_info_t **commit_info_p,
653251881Speter                 const apr_array_header_t *sources,
654251881Speter                 const char *dst_path,
655251881Speter                 svn_boolean_t copy_as_child,
656251881Speter                 svn_boolean_t make_parents,
657251881Speter                 svn_boolean_t ignore_externals,
658251881Speter                 const apr_hash_t *revprop_table,
659251881Speter                 svn_client_ctx_t *ctx,
660251881Speter                 apr_pool_t *pool)
661251881Speter{
662251881Speter  struct capture_baton_t cb;
663251881Speter
664251881Speter  cb.info = commit_info_p;
665251881Speter  cb.pool = pool;
666251881Speter
667251881Speter  return svn_client_copy6(sources, dst_path, copy_as_child, make_parents,
668251881Speter                          ignore_externals, revprop_table,
669251881Speter                          capture_commit_info, &cb, ctx, pool);
670251881Speter}
671251881Speter
672251881Spetersvn_error_t *
673251881Spetersvn_client_copy4(svn_commit_info_t **commit_info_p,
674251881Speter                 const apr_array_header_t *sources,
675251881Speter                 const char *dst_path,
676251881Speter                 svn_boolean_t copy_as_child,
677251881Speter                 svn_boolean_t make_parents,
678251881Speter                 const apr_hash_t *revprop_table,
679251881Speter                 svn_client_ctx_t *ctx,
680251881Speter                 apr_pool_t *pool)
681251881Speter{
682251881Speter  return svn_client_copy5(commit_info_p, sources, dst_path, copy_as_child,
683251881Speter                          make_parents, FALSE, revprop_table, ctx, pool);
684251881Speter}
685251881Speter
686251881Spetersvn_error_t *
687251881Spetersvn_client_copy3(svn_commit_info_t **commit_info_p,
688251881Speter                 const char *src_path,
689251881Speter                 const svn_opt_revision_t *src_revision,
690251881Speter                 const char *dst_path,
691251881Speter                 svn_client_ctx_t *ctx,
692251881Speter                 apr_pool_t *pool)
693251881Speter{
694251881Speter  apr_array_header_t *sources = apr_array_make(pool, 1,
695251881Speter                                  sizeof(const svn_client_copy_source_t *));
696251881Speter  svn_client_copy_source_t copy_source;
697251881Speter
698251881Speter  copy_source.path = src_path;
699251881Speter  copy_source.revision = src_revision;
700251881Speter  copy_source.peg_revision = src_revision;
701251881Speter
702251881Speter  APR_ARRAY_PUSH(sources, const svn_client_copy_source_t *) = &copy_source;
703251881Speter
704251881Speter  return svn_client_copy4(commit_info_p, sources, dst_path, FALSE, FALSE,
705251881Speter                          NULL, ctx, pool);
706251881Speter}
707251881Speter
708251881Spetersvn_error_t *
709251881Spetersvn_client_copy2(svn_commit_info_t **commit_info_p,
710251881Speter                 const char *src_path,
711251881Speter                 const svn_opt_revision_t *src_revision,
712251881Speter                 const char *dst_path,
713251881Speter                 svn_client_ctx_t *ctx,
714251881Speter                 apr_pool_t *pool)
715251881Speter{
716251881Speter  svn_error_t *err;
717251881Speter
718251881Speter  err = svn_client_copy3(commit_info_p, src_path, src_revision,
719251881Speter                         dst_path, ctx, pool);
720251881Speter
721251881Speter  /* If the target exists, try to copy the source as a child of the target.
722251881Speter     This will obviously fail if target is not a directory, but that's exactly
723251881Speter     what we want. */
724251881Speter  if (err && (err->apr_err == SVN_ERR_ENTRY_EXISTS
725251881Speter              || err->apr_err == SVN_ERR_FS_ALREADY_EXISTS))
726251881Speter    {
727251881Speter      const char *src_basename = svn_path_basename(src_path, pool);
728251881Speter
729251881Speter      svn_error_clear(err);
730251881Speter
731251881Speter      return svn_client_copy3(commit_info_p, src_path, src_revision,
732251881Speter                              svn_path_join(dst_path, src_basename, pool),
733251881Speter                              ctx, pool);
734251881Speter    }
735251881Speter
736251881Speter  return svn_error_trace(err);
737251881Speter}
738251881Speter
739251881Spetersvn_error_t *
740251881Spetersvn_client_copy(svn_client_commit_info_t **commit_info_p,
741251881Speter                const char *src_path,
742251881Speter                const svn_opt_revision_t *src_revision,
743251881Speter                const char *dst_path,
744251881Speter                svn_client_ctx_t *ctx,
745251881Speter                apr_pool_t *pool)
746251881Speter{
747251881Speter  svn_commit_info_t *commit_info = NULL;
748251881Speter  svn_error_t *err;
749251881Speter
750251881Speter  err = svn_client_copy2(&commit_info, src_path, src_revision, dst_path,
751251881Speter                         ctx, pool);
752251881Speter  /* These structs have the same layout for the common fields. */
753251881Speter  *commit_info_p = (svn_client_commit_info_t *) commit_info;
754251881Speter  return svn_error_trace(err);
755251881Speter}
756251881Speter
757251881Spetersvn_error_t *
758251881Spetersvn_client_move6(const apr_array_header_t *src_paths,
759251881Speter                 const char *dst_path,
760251881Speter                 svn_boolean_t move_as_child,
761251881Speter                 svn_boolean_t make_parents,
762251881Speter                 const apr_hash_t *revprop_table,
763251881Speter                 svn_commit_callback2_t commit_callback,
764251881Speter                 void *commit_baton,
765251881Speter                 svn_client_ctx_t *ctx,
766251881Speter                 apr_pool_t *pool)
767251881Speter{
768251881Speter  return svn_error_trace(svn_client_move7(src_paths, dst_path,
769251881Speter                                          move_as_child, make_parents,
770251881Speter                                          TRUE /* allow_mixed_revisions */,
771251881Speter                                          FALSE /* metadata_only */,
772251881Speter                                          revprop_table,
773251881Speter                                          commit_callback, commit_baton,
774251881Speter                                          ctx, pool));
775251881Speter}
776251881Speter
777251881Spetersvn_error_t *
778251881Spetersvn_client_move5(svn_commit_info_t **commit_info_p,
779251881Speter                 const apr_array_header_t *src_paths,
780251881Speter                 const char *dst_path,
781251881Speter                 svn_boolean_t force,
782251881Speter                 svn_boolean_t move_as_child,
783251881Speter                 svn_boolean_t make_parents,
784251881Speter                 const apr_hash_t *revprop_table,
785251881Speter                 svn_client_ctx_t *ctx,
786251881Speter                 apr_pool_t *pool)
787251881Speter{
788251881Speter  struct capture_baton_t cb;
789251881Speter
790251881Speter  cb.info = commit_info_p;
791251881Speter  cb.pool = pool;
792251881Speter
793251881Speter  return svn_client_move6(src_paths, dst_path, move_as_child,
794251881Speter                          make_parents, revprop_table,
795251881Speter                          capture_commit_info, &cb, ctx, pool);
796251881Speter}
797251881Speter
798251881Spetersvn_error_t *
799251881Spetersvn_client_move4(svn_commit_info_t **commit_info_p,
800251881Speter                 const char *src_path,
801251881Speter                 const char *dst_path,
802251881Speter                 svn_boolean_t force,
803251881Speter                 svn_client_ctx_t *ctx,
804251881Speter                 apr_pool_t *pool)
805251881Speter{
806251881Speter  apr_array_header_t *src_paths =
807251881Speter    apr_array_make(pool, 1, sizeof(const char *));
808251881Speter  APR_ARRAY_PUSH(src_paths, const char *) = src_path;
809251881Speter
810251881Speter
811251881Speter  return svn_client_move5(commit_info_p, src_paths, dst_path, force, FALSE,
812251881Speter                          FALSE, NULL, ctx, pool);
813251881Speter}
814251881Speter
815251881Spetersvn_error_t *
816251881Spetersvn_client_move3(svn_commit_info_t **commit_info_p,
817251881Speter                 const char *src_path,
818251881Speter                 const char *dst_path,
819251881Speter                 svn_boolean_t force,
820251881Speter                 svn_client_ctx_t *ctx,
821251881Speter                 apr_pool_t *pool)
822251881Speter{
823251881Speter  svn_error_t *err;
824251881Speter
825251881Speter  err = svn_client_move4(commit_info_p, src_path, dst_path, force, ctx, pool);
826251881Speter
827251881Speter  /* If the target exists, try to move the source as a child of the target.
828251881Speter     This will obviously fail if target is not a directory, but that's exactly
829251881Speter     what we want. */
830251881Speter  if (err && (err->apr_err == SVN_ERR_ENTRY_EXISTS
831251881Speter              || err->apr_err == SVN_ERR_FS_ALREADY_EXISTS))
832251881Speter    {
833251881Speter      const char *src_basename = svn_path_basename(src_path, pool);
834251881Speter
835251881Speter      svn_error_clear(err);
836251881Speter
837251881Speter      return svn_client_move4(commit_info_p, src_path,
838251881Speter                              svn_path_join(dst_path, src_basename, pool),
839251881Speter                              force, ctx, pool);
840251881Speter    }
841251881Speter
842251881Speter  return svn_error_trace(err);
843251881Speter}
844251881Speter
845251881Spetersvn_error_t *
846251881Spetersvn_client_move2(svn_client_commit_info_t **commit_info_p,
847251881Speter                 const char *src_path,
848251881Speter                 const char *dst_path,
849251881Speter                 svn_boolean_t force,
850251881Speter                 svn_client_ctx_t *ctx,
851251881Speter                 apr_pool_t *pool)
852251881Speter{
853251881Speter  svn_commit_info_t *commit_info = NULL;
854251881Speter  svn_error_t *err;
855251881Speter
856251881Speter  err = svn_client_move3(&commit_info, src_path, dst_path, force, ctx, pool);
857251881Speter  /* These structs have the same layout for the common fields. */
858251881Speter  *commit_info_p = (svn_client_commit_info_t *) commit_info;
859251881Speter  return svn_error_trace(err);
860251881Speter}
861251881Speter
862251881Speter
863251881Spetersvn_error_t *
864251881Spetersvn_client_move(svn_client_commit_info_t **commit_info_p,
865251881Speter                const char *src_path,
866251881Speter                const svn_opt_revision_t *src_revision,
867251881Speter                const char *dst_path,
868251881Speter                svn_boolean_t force,
869251881Speter                svn_client_ctx_t *ctx,
870251881Speter                apr_pool_t *pool)
871251881Speter{
872251881Speter  /* It doesn't make sense to specify revisions in a move. */
873251881Speter
874251881Speter  /* ### todo: this check could fail wrongly.  For example,
875251881Speter     someone could pass in an svn_opt_revision_number that just
876251881Speter     happens to be the HEAD.  It's fair enough to punt then, IMHO,
877251881Speter     and just demand that the user not specify a revision at all;
878251881Speter     beats mucking up this function with RA calls and such. */
879251881Speter  if (src_revision->kind != svn_opt_revision_unspecified
880251881Speter      && src_revision->kind != svn_opt_revision_head)
881251881Speter    {
882251881Speter      return svn_error_create
883251881Speter        (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
884251881Speter         _("Cannot specify revisions (except HEAD) with move operations"));
885251881Speter    }
886251881Speter
887251881Speter  return svn_client_move2(commit_info_p, src_path, dst_path, force, ctx, pool);
888251881Speter}
889251881Speter
890251881Speter/*** From delete.c ***/
891251881Spetersvn_error_t *
892251881Spetersvn_client_delete3(svn_commit_info_t **commit_info_p,
893251881Speter                   const apr_array_header_t *paths,
894251881Speter                   svn_boolean_t force,
895251881Speter                   svn_boolean_t keep_local,
896251881Speter                   const apr_hash_t *revprop_table,
897251881Speter                   svn_client_ctx_t *ctx,
898251881Speter                   apr_pool_t *pool)
899251881Speter{
900251881Speter  struct capture_baton_t cb;
901251881Speter
902251881Speter  cb.info = commit_info_p;
903251881Speter  cb.pool = pool;
904251881Speter
905251881Speter  return svn_client_delete4(paths, force, keep_local, revprop_table,
906251881Speter                            capture_commit_info, &cb, ctx, pool);
907251881Speter}
908251881Speter
909251881Spetersvn_error_t *
910251881Spetersvn_client_delete2(svn_commit_info_t **commit_info_p,
911251881Speter                   const apr_array_header_t *paths,
912251881Speter                   svn_boolean_t force,
913251881Speter                   svn_client_ctx_t *ctx,
914251881Speter                   apr_pool_t *pool)
915251881Speter{
916251881Speter  return svn_client_delete3(commit_info_p, paths, force, FALSE, NULL,
917251881Speter                            ctx, pool);
918251881Speter}
919251881Speter
920251881Spetersvn_error_t *
921251881Spetersvn_client_delete(svn_client_commit_info_t **commit_info_p,
922251881Speter                  const apr_array_header_t *paths,
923251881Speter                  svn_boolean_t force,
924251881Speter                  svn_client_ctx_t *ctx,
925251881Speter                  apr_pool_t *pool)
926251881Speter{
927251881Speter  svn_commit_info_t *commit_info = NULL;
928251881Speter  svn_error_t *err = NULL;
929251881Speter
930251881Speter  err = svn_client_delete2(&commit_info, paths, force, ctx, pool);
931251881Speter  /* These structs have the same layout for the common fields. */
932251881Speter  *commit_info_p = (svn_client_commit_info_t *) commit_info;
933251881Speter  return svn_error_trace(err);
934251881Speter}
935251881Speter
936251881Speter/*** From diff.c ***/
937251881Speter
938251881Spetersvn_error_t *
939251881Spetersvn_client_diff5(const apr_array_header_t *diff_options,
940251881Speter                 const char *path1,
941251881Speter                 const svn_opt_revision_t *revision1,
942251881Speter                 const char *path2,
943251881Speter                 const svn_opt_revision_t *revision2,
944251881Speter                 const char *relative_to_dir,
945251881Speter                 svn_depth_t depth,
946251881Speter                 svn_boolean_t ignore_ancestry,
947251881Speter                 svn_boolean_t no_diff_deleted,
948251881Speter                 svn_boolean_t show_copies_as_adds,
949251881Speter                 svn_boolean_t ignore_content_type,
950251881Speter                 svn_boolean_t use_git_diff_format,
951251881Speter                 const char *header_encoding,
952251881Speter                 apr_file_t *outfile,
953251881Speter                 apr_file_t *errfile,
954251881Speter                 const apr_array_header_t *changelists,
955251881Speter                 svn_client_ctx_t *ctx,
956251881Speter                 apr_pool_t *pool)
957251881Speter{
958251881Speter  svn_stream_t *outstream = svn_stream_from_aprfile2(outfile, TRUE, pool);
959251881Speter  svn_stream_t *errstream = svn_stream_from_aprfile2(errfile, TRUE, pool);
960251881Speter
961251881Speter  return svn_client_diff6(diff_options, path1, revision1, path2,
962251881Speter                          revision2, relative_to_dir, depth,
963251881Speter                          ignore_ancestry, FALSE /* no_diff_added */,
964251881Speter                          no_diff_deleted, show_copies_as_adds,
965251881Speter                          ignore_content_type, FALSE /* ignore_properties */,
966251881Speter                          FALSE /* properties_only */, use_git_diff_format,
967251881Speter                          header_encoding,
968251881Speter                          outstream, errstream, changelists, ctx, pool);
969251881Speter}
970251881Speter
971251881Spetersvn_error_t *
972251881Spetersvn_client_diff4(const apr_array_header_t *options,
973251881Speter                 const char *path1,
974251881Speter                 const svn_opt_revision_t *revision1,
975251881Speter                 const char *path2,
976251881Speter                 const svn_opt_revision_t *revision2,
977251881Speter                 const char *relative_to_dir,
978251881Speter                 svn_depth_t depth,
979251881Speter                 svn_boolean_t ignore_ancestry,
980251881Speter                 svn_boolean_t no_diff_deleted,
981251881Speter                 svn_boolean_t ignore_content_type,
982251881Speter                 const char *header_encoding,
983251881Speter                 apr_file_t *outfile,
984251881Speter                 apr_file_t *errfile,
985251881Speter                 const apr_array_header_t *changelists,
986251881Speter                 svn_client_ctx_t *ctx,
987251881Speter                 apr_pool_t *pool)
988251881Speter{
989251881Speter  return svn_client_diff5(options, path1, revision1, path2,
990251881Speter                          revision2, relative_to_dir, depth,
991251881Speter                          ignore_ancestry, no_diff_deleted, FALSE,
992251881Speter                          ignore_content_type, FALSE, header_encoding,
993251881Speter                          outfile, errfile, changelists, ctx, pool);
994251881Speter}
995251881Speter
996251881Spetersvn_error_t *
997251881Spetersvn_client_diff3(const apr_array_header_t *options,
998251881Speter                 const char *path1,
999251881Speter                 const svn_opt_revision_t *revision1,
1000251881Speter                 const char *path2,
1001251881Speter                 const svn_opt_revision_t *revision2,
1002251881Speter                 svn_boolean_t recurse,
1003251881Speter                 svn_boolean_t ignore_ancestry,
1004251881Speter                 svn_boolean_t no_diff_deleted,
1005251881Speter                 svn_boolean_t ignore_content_type,
1006251881Speter                 const char *header_encoding,
1007251881Speter                 apr_file_t *outfile,
1008251881Speter                 apr_file_t *errfile,
1009251881Speter                 svn_client_ctx_t *ctx,
1010251881Speter                 apr_pool_t *pool)
1011251881Speter{
1012251881Speter  return svn_client_diff4(options, path1, revision1, path2,
1013251881Speter                          revision2, NULL,
1014251881Speter                          SVN_DEPTH_INFINITY_OR_FILES(recurse),
1015251881Speter                          ignore_ancestry, no_diff_deleted,
1016251881Speter                          ignore_content_type, header_encoding,
1017251881Speter                          outfile, errfile, NULL, ctx, pool);
1018251881Speter}
1019251881Speter
1020251881Spetersvn_error_t *
1021251881Spetersvn_client_diff2(const apr_array_header_t *options,
1022251881Speter                 const char *path1,
1023251881Speter                 const svn_opt_revision_t *revision1,
1024251881Speter                 const char *path2,
1025251881Speter                 const svn_opt_revision_t *revision2,
1026251881Speter                 svn_boolean_t recurse,
1027251881Speter                 svn_boolean_t ignore_ancestry,
1028251881Speter                 svn_boolean_t no_diff_deleted,
1029251881Speter                 svn_boolean_t ignore_content_type,
1030251881Speter                 apr_file_t *outfile,
1031251881Speter                 apr_file_t *errfile,
1032251881Speter                 svn_client_ctx_t *ctx,
1033251881Speter                 apr_pool_t *pool)
1034251881Speter{
1035251881Speter  return svn_client_diff3(options, path1, revision1, path2, revision2,
1036251881Speter                          recurse, ignore_ancestry, no_diff_deleted,
1037251881Speter                          ignore_content_type, SVN_APR_LOCALE_CHARSET,
1038251881Speter                          outfile, errfile, ctx, pool);
1039251881Speter}
1040251881Speter
1041251881Spetersvn_error_t *
1042251881Spetersvn_client_diff(const apr_array_header_t *options,
1043251881Speter                const char *path1,
1044251881Speter                const svn_opt_revision_t *revision1,
1045251881Speter                const char *path2,
1046251881Speter                const svn_opt_revision_t *revision2,
1047251881Speter                svn_boolean_t recurse,
1048251881Speter                svn_boolean_t ignore_ancestry,
1049251881Speter                svn_boolean_t no_diff_deleted,
1050251881Speter                apr_file_t *outfile,
1051251881Speter                apr_file_t *errfile,
1052251881Speter                svn_client_ctx_t *ctx,
1053251881Speter                apr_pool_t *pool)
1054251881Speter{
1055251881Speter  return svn_client_diff2(options, path1, revision1, path2, revision2,
1056251881Speter                          recurse, ignore_ancestry, no_diff_deleted, FALSE,
1057251881Speter                          outfile, errfile, ctx, pool);
1058251881Speter}
1059251881Speter
1060251881Spetersvn_error_t *
1061251881Spetersvn_client_diff_peg5(const apr_array_header_t *diff_options,
1062251881Speter                     const char *path,
1063251881Speter                     const svn_opt_revision_t *peg_revision,
1064251881Speter                     const svn_opt_revision_t *start_revision,
1065251881Speter                     const svn_opt_revision_t *end_revision,
1066251881Speter                     const char *relative_to_dir,
1067251881Speter                     svn_depth_t depth,
1068251881Speter                     svn_boolean_t ignore_ancestry,
1069251881Speter                     svn_boolean_t no_diff_deleted,
1070251881Speter                     svn_boolean_t show_copies_as_adds,
1071251881Speter                     svn_boolean_t ignore_content_type,
1072251881Speter                     svn_boolean_t use_git_diff_format,
1073251881Speter                     const char *header_encoding,
1074251881Speter                     apr_file_t *outfile,
1075251881Speter                     apr_file_t *errfile,
1076251881Speter                     const apr_array_header_t *changelists,
1077251881Speter                     svn_client_ctx_t *ctx,
1078251881Speter                     apr_pool_t *pool)
1079251881Speter{
1080251881Speter  svn_stream_t *outstream = svn_stream_from_aprfile2(outfile, TRUE, pool);
1081251881Speter  svn_stream_t *errstream = svn_stream_from_aprfile2(errfile, TRUE, pool);
1082251881Speter
1083251881Speter  return svn_client_diff_peg6(diff_options,
1084251881Speter                              path,
1085251881Speter                              peg_revision,
1086251881Speter                              start_revision,
1087251881Speter                              end_revision,
1088251881Speter                              relative_to_dir,
1089251881Speter                              depth,
1090251881Speter                              ignore_ancestry,
1091251881Speter                              FALSE /* no_diff_added */,
1092251881Speter                              no_diff_deleted,
1093251881Speter                              show_copies_as_adds,
1094251881Speter                              ignore_content_type,
1095251881Speter                              FALSE /* ignore_properties */,
1096251881Speter                              FALSE /* properties_only */,
1097251881Speter                              use_git_diff_format,
1098251881Speter                              header_encoding,
1099251881Speter                              outstream,
1100251881Speter                              errstream,
1101251881Speter                              changelists,
1102251881Speter                              ctx,
1103251881Speter                              pool);
1104251881Speter}
1105251881Speter
1106251881Spetersvn_error_t *
1107251881Spetersvn_client_diff_peg4(const apr_array_header_t *options,
1108251881Speter                     const char *path,
1109251881Speter                     const svn_opt_revision_t *peg_revision,
1110251881Speter                     const svn_opt_revision_t *start_revision,
1111251881Speter                     const svn_opt_revision_t *end_revision,
1112251881Speter                     const char *relative_to_dir,
1113251881Speter                     svn_depth_t depth,
1114251881Speter                     svn_boolean_t ignore_ancestry,
1115251881Speter                     svn_boolean_t no_diff_deleted,
1116251881Speter                     svn_boolean_t ignore_content_type,
1117251881Speter                     const char *header_encoding,
1118251881Speter                     apr_file_t *outfile,
1119251881Speter                     apr_file_t *errfile,
1120251881Speter                     const apr_array_header_t *changelists,
1121251881Speter                     svn_client_ctx_t *ctx,
1122251881Speter                     apr_pool_t *pool)
1123251881Speter{
1124251881Speter  return svn_client_diff_peg5(options,
1125251881Speter                              path,
1126251881Speter                              peg_revision,
1127251881Speter                              start_revision,
1128251881Speter                              end_revision,
1129251881Speter                              relative_to_dir,
1130251881Speter                              depth,
1131251881Speter                              ignore_ancestry,
1132251881Speter                              no_diff_deleted,
1133251881Speter                              FALSE,
1134251881Speter                              ignore_content_type,
1135251881Speter                              FALSE,
1136251881Speter                              header_encoding,
1137251881Speter                              outfile,
1138251881Speter                              errfile,
1139251881Speter                              changelists,
1140251881Speter                              ctx,
1141251881Speter                              pool);
1142251881Speter}
1143251881Speter
1144251881Spetersvn_error_t *
1145251881Spetersvn_client_diff_peg3(const apr_array_header_t *options,
1146251881Speter                     const char *path,
1147251881Speter                     const svn_opt_revision_t *peg_revision,
1148251881Speter                     const svn_opt_revision_t *start_revision,
1149251881Speter                     const svn_opt_revision_t *end_revision,
1150251881Speter                     svn_boolean_t recurse,
1151251881Speter                     svn_boolean_t ignore_ancestry,
1152251881Speter                     svn_boolean_t no_diff_deleted,
1153251881Speter                     svn_boolean_t ignore_content_type,
1154251881Speter                     const char *header_encoding,
1155251881Speter                     apr_file_t *outfile,
1156251881Speter                     apr_file_t *errfile,
1157251881Speter                     svn_client_ctx_t *ctx,
1158251881Speter                     apr_pool_t *pool)
1159251881Speter{
1160251881Speter  return svn_client_diff_peg4(options,
1161251881Speter                              path,
1162251881Speter                              peg_revision,
1163251881Speter                              start_revision,
1164251881Speter                              end_revision,
1165251881Speter                              NULL,
1166251881Speter                              SVN_DEPTH_INFINITY_OR_FILES(recurse),
1167251881Speter                              ignore_ancestry,
1168251881Speter                              no_diff_deleted,
1169251881Speter                              ignore_content_type,
1170251881Speter                              header_encoding,
1171251881Speter                              outfile,
1172251881Speter                              errfile,
1173251881Speter                              NULL,
1174251881Speter                              ctx,
1175251881Speter                              pool);
1176251881Speter}
1177251881Speter
1178251881Spetersvn_error_t *
1179251881Spetersvn_client_diff_peg2(const apr_array_header_t *options,
1180251881Speter                     const char *path,
1181251881Speter                     const svn_opt_revision_t *peg_revision,
1182251881Speter                     const svn_opt_revision_t *start_revision,
1183251881Speter                     const svn_opt_revision_t *end_revision,
1184251881Speter                     svn_boolean_t recurse,
1185251881Speter                     svn_boolean_t ignore_ancestry,
1186251881Speter                     svn_boolean_t no_diff_deleted,
1187251881Speter                     svn_boolean_t ignore_content_type,
1188251881Speter                     apr_file_t *outfile,
1189251881Speter                     apr_file_t *errfile,
1190251881Speter                     svn_client_ctx_t *ctx,
1191251881Speter                     apr_pool_t *pool)
1192251881Speter{
1193251881Speter  return svn_client_diff_peg3(options, path, peg_revision, start_revision,
1194251881Speter                              end_revision,
1195251881Speter                              SVN_DEPTH_INFINITY_OR_FILES(recurse),
1196251881Speter                              ignore_ancestry, no_diff_deleted,
1197251881Speter                              ignore_content_type, SVN_APR_LOCALE_CHARSET,
1198251881Speter                              outfile, errfile, ctx, pool);
1199251881Speter}
1200251881Speter
1201251881Spetersvn_error_t *
1202251881Spetersvn_client_diff_peg(const apr_array_header_t *options,
1203251881Speter                    const char *path,
1204251881Speter                    const svn_opt_revision_t *peg_revision,
1205251881Speter                    const svn_opt_revision_t *start_revision,
1206251881Speter                    const svn_opt_revision_t *end_revision,
1207251881Speter                    svn_boolean_t recurse,
1208251881Speter                    svn_boolean_t ignore_ancestry,
1209251881Speter                    svn_boolean_t no_diff_deleted,
1210251881Speter                    apr_file_t *outfile,
1211251881Speter                    apr_file_t *errfile,
1212251881Speter                    svn_client_ctx_t *ctx,
1213251881Speter                    apr_pool_t *pool)
1214251881Speter{
1215251881Speter  return svn_client_diff_peg2(options, path, peg_revision,
1216251881Speter                              start_revision, end_revision, recurse,
1217251881Speter                              ignore_ancestry, no_diff_deleted, FALSE,
1218251881Speter                              outfile, errfile, ctx, pool);
1219251881Speter}
1220251881Speter
1221251881Spetersvn_error_t *
1222251881Spetersvn_client_diff_summarize(const char *path1,
1223251881Speter                          const svn_opt_revision_t *revision1,
1224251881Speter                          const char *path2,
1225251881Speter                          const svn_opt_revision_t *revision2,
1226251881Speter                          svn_boolean_t recurse,
1227251881Speter                          svn_boolean_t ignore_ancestry,
1228251881Speter                          svn_client_diff_summarize_func_t summarize_func,
1229251881Speter                          void *summarize_baton,
1230251881Speter                          svn_client_ctx_t *ctx,
1231251881Speter                          apr_pool_t *pool)
1232251881Speter{
1233251881Speter  return svn_client_diff_summarize2(path1, revision1, path2,
1234251881Speter                                    revision2,
1235251881Speter                                    SVN_DEPTH_INFINITY_OR_FILES(recurse),
1236251881Speter                                    ignore_ancestry, NULL, summarize_func,
1237251881Speter                                    summarize_baton, ctx, pool);
1238251881Speter}
1239251881Speter
1240251881Spetersvn_error_t *
1241251881Spetersvn_client_diff_summarize_peg(const char *path,
1242251881Speter                              const svn_opt_revision_t *peg_revision,
1243251881Speter                              const svn_opt_revision_t *start_revision,
1244251881Speter                              const svn_opt_revision_t *end_revision,
1245251881Speter                              svn_boolean_t recurse,
1246251881Speter                              svn_boolean_t ignore_ancestry,
1247251881Speter                              svn_client_diff_summarize_func_t summarize_func,
1248251881Speter                              void *summarize_baton,
1249251881Speter                              svn_client_ctx_t *ctx,
1250251881Speter                              apr_pool_t *pool)
1251251881Speter{
1252251881Speter  return svn_client_diff_summarize_peg2(path, peg_revision,
1253251881Speter                                        start_revision, end_revision,
1254251881Speter                                        SVN_DEPTH_INFINITY_OR_FILES(recurse),
1255251881Speter                                        ignore_ancestry, NULL,
1256251881Speter                                        summarize_func, summarize_baton,
1257251881Speter                                        ctx, pool);
1258251881Speter}
1259251881Speter
1260251881Speter/*** From export.c ***/
1261251881Spetersvn_error_t *
1262251881Spetersvn_client_export4(svn_revnum_t *result_rev,
1263251881Speter                   const char *from_path_or_url,
1264251881Speter                   const char *to_path,
1265251881Speter                   const svn_opt_revision_t *peg_revision,
1266251881Speter                   const svn_opt_revision_t *revision,
1267251881Speter                   svn_boolean_t overwrite,
1268251881Speter                   svn_boolean_t ignore_externals,
1269251881Speter                   svn_depth_t depth,
1270251881Speter                   const char *native_eol,
1271251881Speter                   svn_client_ctx_t *ctx,
1272251881Speter                   apr_pool_t *pool)
1273251881Speter{
1274251881Speter  return svn_client_export5(result_rev, from_path_or_url, to_path,
1275251881Speter                            peg_revision, revision, overwrite, ignore_externals,
1276251881Speter                            FALSE, depth, native_eol, ctx, pool);
1277251881Speter}
1278251881Speter
1279251881Spetersvn_error_t *
1280251881Spetersvn_client_export3(svn_revnum_t *result_rev,
1281251881Speter                   const char *from_path_or_url,
1282251881Speter                   const char *to_path,
1283251881Speter                   const svn_opt_revision_t *peg_revision,
1284251881Speter                   const svn_opt_revision_t *revision,
1285251881Speter                   svn_boolean_t overwrite,
1286251881Speter                   svn_boolean_t ignore_externals,
1287251881Speter                   svn_boolean_t recurse,
1288251881Speter                   const char *native_eol,
1289251881Speter                   svn_client_ctx_t *ctx,
1290251881Speter                   apr_pool_t *pool)
1291251881Speter{
1292251881Speter  return svn_client_export4(result_rev, from_path_or_url, to_path,
1293251881Speter                            peg_revision, revision, overwrite, ignore_externals,
1294251881Speter                            SVN_DEPTH_INFINITY_OR_FILES(recurse),
1295251881Speter                            native_eol, ctx, pool);
1296251881Speter}
1297251881Speter
1298251881Spetersvn_error_t *
1299251881Spetersvn_client_export2(svn_revnum_t *result_rev,
1300251881Speter                   const char *from_path_or_url,
1301251881Speter                   const char *to_path,
1302251881Speter                   svn_opt_revision_t *revision,
1303251881Speter                   svn_boolean_t force,
1304251881Speter                   const char *native_eol,
1305251881Speter                   svn_client_ctx_t *ctx,
1306251881Speter                   apr_pool_t *pool)
1307251881Speter{
1308251881Speter  svn_opt_revision_t peg_revision;
1309251881Speter
1310251881Speter  peg_revision.kind = svn_opt_revision_unspecified;
1311251881Speter
1312251881Speter  return svn_client_export3(result_rev, from_path_or_url, to_path,
1313251881Speter                            &peg_revision, revision, force, FALSE, TRUE,
1314251881Speter                            native_eol, ctx, pool);
1315251881Speter}
1316251881Speter
1317251881Speter
1318251881Spetersvn_error_t *
1319251881Spetersvn_client_export(svn_revnum_t *result_rev,
1320251881Speter                  const char *from_path_or_url,
1321251881Speter                  const char *to_path,
1322251881Speter                  svn_opt_revision_t *revision,
1323251881Speter                  svn_boolean_t force,
1324251881Speter                  svn_client_ctx_t *ctx,
1325251881Speter                  apr_pool_t *pool)
1326251881Speter{
1327251881Speter  return svn_client_export2(result_rev, from_path_or_url, to_path, revision,
1328251881Speter                            force, NULL, ctx, pool);
1329251881Speter}
1330251881Speter
1331251881Speter/*** From list.c ***/
1332251881Speter
1333251881Speter/* Baton for use with wrap_list_func */
1334251881Speterstruct list_func_wrapper_baton {
1335251881Speter    void *list_func1_baton;
1336251881Speter    svn_client_list_func_t list_func1;
1337251881Speter};
1338251881Speter
1339251881Speter/* This implements svn_client_list_func2_t */
1340251881Speterstatic svn_error_t *
1341251881Speterlist_func_wrapper(void *baton,
1342251881Speter                  const char *path,
1343251881Speter                  const svn_dirent_t *dirent,
1344251881Speter                  const svn_lock_t *lock,
1345251881Speter                  const char *abs_path,
1346251881Speter                  const char *external_parent_url,
1347251881Speter                  const char *external_target,
1348251881Speter                  apr_pool_t *scratch_pool)
1349251881Speter{
1350251881Speter  struct list_func_wrapper_baton *lfwb = baton;
1351251881Speter
1352251881Speter  if (lfwb->list_func1)
1353251881Speter    return lfwb->list_func1(lfwb->list_func1_baton, path, dirent,
1354251881Speter                           lock, abs_path, scratch_pool);
1355251881Speter
1356251881Speter  return SVN_NO_ERROR;
1357251881Speter}
1358251881Speter
1359251881Speter/* Helper function for svn_client_list2().  It wraps old format baton
1360251881Speter   and callback function in list_func_wrapper_baton and
1361251881Speter   returns new baton and callback to use with svn_client_list3(). */
1362251881Speterstatic void
1363251881Speterwrap_list_func(svn_client_list_func2_t *list_func2,
1364251881Speter               void **list_func2_baton,
1365251881Speter               svn_client_list_func_t list_func,
1366251881Speter               void *baton,
1367251881Speter               apr_pool_t *result_pool)
1368251881Speter{
1369251881Speter  struct list_func_wrapper_baton *lfwb = apr_palloc(result_pool,
1370251881Speter                                                    sizeof(*lfwb));
1371251881Speter
1372251881Speter  /* Set the user provided old format callback in the baton. */
1373251881Speter  lfwb->list_func1_baton = baton;
1374251881Speter  lfwb->list_func1 = list_func;
1375251881Speter
1376251881Speter  *list_func2_baton = lfwb;
1377251881Speter  *list_func2 = list_func_wrapper;
1378251881Speter}
1379251881Speter
1380251881Spetersvn_error_t *
1381251881Spetersvn_client_list2(const char *path_or_url,
1382251881Speter                 const svn_opt_revision_t *peg_revision,
1383251881Speter                 const svn_opt_revision_t *revision,
1384251881Speter                 svn_depth_t depth,
1385251881Speter                 apr_uint32_t dirent_fields,
1386251881Speter                 svn_boolean_t fetch_locks,
1387251881Speter                 svn_client_list_func_t list_func,
1388251881Speter                 void *baton,
1389251881Speter                 svn_client_ctx_t *ctx,
1390251881Speter                 apr_pool_t *pool)
1391251881Speter{
1392251881Speter  svn_client_list_func2_t list_func2;
1393251881Speter  void *list_func2_baton;
1394251881Speter
1395251881Speter  wrap_list_func(&list_func2, &list_func2_baton, list_func, baton, pool);
1396251881Speter
1397251881Speter  return svn_client_list3(path_or_url, peg_revision, revision, depth,
1398251881Speter                          dirent_fields, fetch_locks,
1399251881Speter                          FALSE /* include externals */,
1400251881Speter                          list_func2, list_func2_baton, ctx, pool);
1401251881Speter}
1402251881Speter
1403251881Spetersvn_error_t *
1404251881Spetersvn_client_list(const char *path_or_url,
1405251881Speter                const svn_opt_revision_t *peg_revision,
1406251881Speter                const svn_opt_revision_t *revision,
1407251881Speter                svn_boolean_t recurse,
1408251881Speter                apr_uint32_t dirent_fields,
1409251881Speter                svn_boolean_t fetch_locks,
1410251881Speter                svn_client_list_func_t list_func,
1411251881Speter                void *baton,
1412251881Speter                svn_client_ctx_t *ctx,
1413251881Speter                apr_pool_t *pool)
1414251881Speter{
1415251881Speter  return svn_client_list2(path_or_url,
1416251881Speter                          peg_revision,
1417251881Speter                          revision,
1418251881Speter                          SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
1419251881Speter                          dirent_fields,
1420251881Speter                          fetch_locks,
1421251881Speter                          list_func,
1422251881Speter                          baton,
1423251881Speter                          ctx,
1424251881Speter                          pool);
1425251881Speter}
1426251881Speter
1427251881Speter/* Baton used by compatibility wrapper svn_client_ls3. */
1428251881Speterstruct ls_baton {
1429251881Speter  apr_hash_t *dirents;
1430251881Speter  apr_hash_t *locks;
1431251881Speter  apr_pool_t *pool;
1432251881Speter};
1433251881Speter
1434251881Speter/* This implements svn_client_list_func_t. */
1435251881Speterstatic svn_error_t *
1436251881Speterstore_dirent(void *baton, const char *path, const svn_dirent_t *dirent,
1437251881Speter             const svn_lock_t *lock, const char *abs_path, apr_pool_t *pool)
1438251881Speter{
1439251881Speter  struct ls_baton *lb = baton;
1440251881Speter
1441251881Speter  /* The dirent is allocated in a temporary pool, so duplicate it into the
1442251881Speter     correct pool.  Note, however, that the locks are stored in the correct
1443251881Speter     pool already. */
1444251881Speter  dirent = svn_dirent_dup(dirent, lb->pool);
1445251881Speter
1446251881Speter  /* An empty path means we are called for the target of the operation.
1447251881Speter     For compatibility, we only store the target if it is a file, and we
1448251881Speter     store it under the basename of the URL.  Note that this makes it
1449251881Speter     impossible to differentiate between the target being a directory with a
1450251881Speter     child with the same basename as the target and the target being a file,
1451251881Speter     but that's how it was implemented. */
1452251881Speter  if (path[0] == '\0')
1453251881Speter    {
1454251881Speter      if (dirent->kind == svn_node_file)
1455251881Speter        {
1456251881Speter          const char *base_name = svn_path_basename(abs_path, lb->pool);
1457251881Speter          svn_hash_sets(lb->dirents, base_name, dirent);
1458251881Speter          if (lock)
1459251881Speter            svn_hash_sets(lb->locks, base_name, lock);
1460251881Speter        }
1461251881Speter    }
1462251881Speter  else
1463251881Speter    {
1464251881Speter      path = apr_pstrdup(lb->pool, path);
1465251881Speter      svn_hash_sets(lb->dirents, path, dirent);
1466251881Speter      if (lock)
1467251881Speter        svn_hash_sets(lb->locks, path, lock);
1468251881Speter    }
1469251881Speter
1470251881Speter  return SVN_NO_ERROR;
1471251881Speter}
1472251881Speter
1473251881Spetersvn_error_t *
1474251881Spetersvn_client_ls3(apr_hash_t **dirents,
1475251881Speter               apr_hash_t **locks,
1476251881Speter               const char *path_or_url,
1477251881Speter               const svn_opt_revision_t *peg_revision,
1478251881Speter               const svn_opt_revision_t *revision,
1479251881Speter               svn_boolean_t recurse,
1480251881Speter               svn_client_ctx_t *ctx,
1481251881Speter               apr_pool_t *pool)
1482251881Speter{
1483251881Speter  struct ls_baton lb;
1484251881Speter
1485251881Speter  *dirents = lb.dirents = apr_hash_make(pool);
1486251881Speter  if (locks)
1487251881Speter    *locks = lb.locks = apr_hash_make(pool);
1488251881Speter  lb.pool = pool;
1489251881Speter
1490251881Speter  return svn_client_list(path_or_url, peg_revision, revision, recurse,
1491251881Speter                         SVN_DIRENT_ALL, locks != NULL,
1492251881Speter                         store_dirent, &lb, ctx, pool);
1493251881Speter}
1494251881Speter
1495251881Spetersvn_error_t *
1496251881Spetersvn_client_ls2(apr_hash_t **dirents,
1497251881Speter               const char *path_or_url,
1498251881Speter               const svn_opt_revision_t *peg_revision,
1499251881Speter               const svn_opt_revision_t *revision,
1500251881Speter               svn_boolean_t recurse,
1501251881Speter               svn_client_ctx_t *ctx,
1502251881Speter               apr_pool_t *pool)
1503251881Speter{
1504251881Speter
1505251881Speter  return svn_client_ls3(dirents, NULL, path_or_url, peg_revision,
1506251881Speter                        revision, recurse, ctx, pool);
1507251881Speter}
1508251881Speter
1509251881Speter
1510251881Spetersvn_error_t *
1511251881Spetersvn_client_ls(apr_hash_t **dirents,
1512251881Speter              const char *path_or_url,
1513251881Speter              svn_opt_revision_t *revision,
1514251881Speter              svn_boolean_t recurse,
1515251881Speter              svn_client_ctx_t *ctx,
1516251881Speter              apr_pool_t *pool)
1517251881Speter{
1518251881Speter  return svn_client_ls2(dirents, path_or_url, revision,
1519251881Speter                        revision, recurse, ctx, pool);
1520251881Speter}
1521251881Speter
1522251881Speter/*** From log.c ***/
1523299742Sdim
1524251881Spetersvn_error_t *
1525251881Spetersvn_client_log4(const apr_array_header_t *targets,
1526251881Speter                const svn_opt_revision_t *peg_revision,
1527251881Speter                const svn_opt_revision_t *start,
1528251881Speter                const svn_opt_revision_t *end,
1529251881Speter                int limit,
1530251881Speter                svn_boolean_t discover_changed_paths,
1531251881Speter                svn_boolean_t strict_node_history,
1532251881Speter                svn_boolean_t include_merged_revisions,
1533251881Speter                const apr_array_header_t *revprops,
1534251881Speter                svn_log_entry_receiver_t receiver,
1535251881Speter                void *receiver_baton,
1536251881Speter                svn_client_ctx_t *ctx,
1537251881Speter                apr_pool_t *pool)
1538251881Speter{
1539251881Speter  apr_array_header_t *revision_ranges;
1540251881Speter
1541251881Speter  revision_ranges = apr_array_make(pool, 1,
1542251881Speter                                   sizeof(svn_opt_revision_range_t *));
1543251881Speter  APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
1544251881Speter    = svn_opt__revision_range_create(start, end, pool);
1545251881Speter
1546251881Speter  return svn_client_log5(targets, peg_revision, revision_ranges, limit,
1547251881Speter                         discover_changed_paths, strict_node_history,
1548251881Speter                         include_merged_revisions, revprops, receiver,
1549251881Speter                         receiver_baton, ctx, pool);
1550251881Speter}
1551251881Speter
1552251881Speter
1553251881Spetersvn_error_t *
1554251881Spetersvn_client_log3(const apr_array_header_t *targets,
1555251881Speter                const svn_opt_revision_t *peg_revision,
1556251881Speter                const svn_opt_revision_t *start,
1557251881Speter                const svn_opt_revision_t *end,
1558251881Speter                int limit,
1559251881Speter                svn_boolean_t discover_changed_paths,
1560251881Speter                svn_boolean_t strict_node_history,
1561251881Speter                svn_log_message_receiver_t receiver,
1562251881Speter                void *receiver_baton,
1563251881Speter                svn_client_ctx_t *ctx,
1564251881Speter                apr_pool_t *pool)
1565251881Speter{
1566251881Speter  svn_log_entry_receiver_t receiver2;
1567251881Speter  void *receiver2_baton;
1568251881Speter
1569251881Speter  svn_compat_wrap_log_receiver(&receiver2, &receiver2_baton,
1570251881Speter                               receiver, receiver_baton,
1571251881Speter                               pool);
1572251881Speter
1573251881Speter  return svn_client_log4(targets, peg_revision, start, end, limit,
1574251881Speter                         discover_changed_paths, strict_node_history, FALSE,
1575251881Speter                         svn_compat_log_revprops_in(pool),
1576251881Speter                         receiver2, receiver2_baton, ctx, pool);
1577251881Speter}
1578251881Speter
1579251881Spetersvn_error_t *
1580251881Spetersvn_client_log2(const apr_array_header_t *targets,
1581251881Speter                const svn_opt_revision_t *start,
1582251881Speter                const svn_opt_revision_t *end,
1583251881Speter                int limit,
1584251881Speter                svn_boolean_t discover_changed_paths,
1585251881Speter                svn_boolean_t strict_node_history,
1586251881Speter                svn_log_message_receiver_t receiver,
1587251881Speter                void *receiver_baton,
1588251881Speter                svn_client_ctx_t *ctx,
1589251881Speter                apr_pool_t *pool)
1590251881Speter{
1591251881Speter  svn_opt_revision_t peg_revision;
1592251881Speter  peg_revision.kind = svn_opt_revision_unspecified;
1593251881Speter  return svn_client_log3(targets, &peg_revision, start, end, limit,
1594251881Speter                         discover_changed_paths, strict_node_history,
1595251881Speter                         receiver, receiver_baton, ctx, pool);
1596251881Speter}
1597251881Speter
1598251881Spetersvn_error_t *
1599251881Spetersvn_client_log(const apr_array_header_t *targets,
1600251881Speter               const svn_opt_revision_t *start,
1601251881Speter               const svn_opt_revision_t *end,
1602251881Speter               svn_boolean_t discover_changed_paths,
1603251881Speter               svn_boolean_t strict_node_history,
1604251881Speter               svn_log_message_receiver_t receiver,
1605251881Speter               void *receiver_baton,
1606251881Speter               svn_client_ctx_t *ctx,
1607251881Speter               apr_pool_t *pool)
1608251881Speter{
1609251881Speter  svn_error_t *err = SVN_NO_ERROR;
1610251881Speter
1611251881Speter  err = svn_client_log2(targets, start, end, 0, discover_changed_paths,
1612251881Speter                        strict_node_history, receiver, receiver_baton, ctx,
1613251881Speter                        pool);
1614251881Speter
1615251881Speter  /* Special case: If there have been no commits, we'll get an error
1616251881Speter   * for requesting log of a revision higher than 0.  But the
1617251881Speter   * default behavior of "svn log" is to give revisions HEAD through
1618251881Speter   * 1, on the assumption that HEAD >= 1.
1619251881Speter   *
1620251881Speter   * So if we got that error for that reason, and it looks like the
1621251881Speter   * user was just depending on the defaults (rather than explicitly
1622251881Speter   * requesting the log for revision 1), then we don't error.  Instead
1623251881Speter   * we just invoke the receiver manually on a hand-constructed log
1624251881Speter   * message for revision 0.
1625251881Speter   *
1626251881Speter   * See also http://subversion.tigris.org/issues/show_bug.cgi?id=692.
1627251881Speter   */
1628251881Speter  if (err && (err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION)
1629251881Speter      && (start->kind == svn_opt_revision_head)
1630251881Speter      && ((end->kind == svn_opt_revision_number)
1631251881Speter          && (end->value.number == 1)))
1632251881Speter    {
1633251881Speter
1634251881Speter      /* We don't need to check if HEAD is 0, because that must be the case,
1635251881Speter       * by logical deduction: The revision range specified is HEAD:1.
1636251881Speter       * HEAD cannot not exist, so the revision to which "no such revision"
1637251881Speter       * applies is 1. If revision 1 does not exist, then HEAD is 0.
1638251881Speter       * Hence, we deduce the repository is empty without needing access
1639251881Speter       * to further information. */
1640251881Speter
1641251881Speter      svn_error_clear(err);
1642251881Speter      err = SVN_NO_ERROR;
1643251881Speter
1644251881Speter      /* Log receivers are free to handle revision 0 specially... But
1645251881Speter         just in case some don't, we make up a message here. */
1646251881Speter      SVN_ERR(receiver(receiver_baton,
1647251881Speter                       NULL, 0, "", "", _("No commits in repository"),
1648251881Speter                       pool));
1649251881Speter    }
1650251881Speter
1651251881Speter  return svn_error_trace(err);
1652251881Speter}
1653251881Speter
1654251881Speter/*** From merge.c ***/
1655251881Speter
1656251881Spetersvn_error_t *
1657251881Spetersvn_client_merge4(const char *source1,
1658251881Speter                  const svn_opt_revision_t *revision1,
1659251881Speter                  const char *source2,
1660251881Speter                  const svn_opt_revision_t *revision2,
1661251881Speter                  const char *target_wcpath,
1662251881Speter                  svn_depth_t depth,
1663251881Speter                  svn_boolean_t ignore_ancestry,
1664251881Speter                  svn_boolean_t force_delete,
1665251881Speter                  svn_boolean_t record_only,
1666251881Speter                  svn_boolean_t dry_run,
1667251881Speter                  svn_boolean_t allow_mixed_rev,
1668251881Speter                  const apr_array_header_t *merge_options,
1669251881Speter                  svn_client_ctx_t *ctx,
1670251881Speter                  apr_pool_t *pool)
1671251881Speter{
1672251881Speter  SVN_ERR(svn_client_merge5(source1, revision1,
1673251881Speter                            source2, revision2,
1674251881Speter                            target_wcpath,
1675251881Speter                            depth,
1676251881Speter                            ignore_ancestry /*ignore_mergeinfo*/,
1677251881Speter                            ignore_ancestry /*diff_ignore_ancestry*/,
1678251881Speter                            force_delete, record_only,
1679251881Speter                            dry_run, allow_mixed_rev,
1680251881Speter                            merge_options, ctx, pool));
1681251881Speter  return SVN_NO_ERROR;
1682251881Speter}
1683251881Speter
1684251881Spetersvn_error_t *
1685251881Spetersvn_client_merge3(const char *source1,
1686251881Speter                  const svn_opt_revision_t *revision1,
1687251881Speter                  const char *source2,
1688251881Speter                  const svn_opt_revision_t *revision2,
1689251881Speter                  const char *target_wcpath,
1690251881Speter                  svn_depth_t depth,
1691251881Speter                  svn_boolean_t ignore_ancestry,
1692251881Speter                  svn_boolean_t force,
1693251881Speter                  svn_boolean_t record_only,
1694251881Speter                  svn_boolean_t dry_run,
1695251881Speter                  const apr_array_header_t *merge_options,
1696251881Speter                  svn_client_ctx_t *ctx,
1697251881Speter                  apr_pool_t *pool)
1698251881Speter{
1699251881Speter  return svn_client_merge4(source1, revision1, source2, revision2,
1700251881Speter                           target_wcpath, depth, ignore_ancestry, force,
1701251881Speter                           record_only, dry_run, TRUE, merge_options,
1702251881Speter                           ctx, pool);
1703251881Speter}
1704251881Speter
1705251881Spetersvn_error_t *
1706251881Spetersvn_client_merge2(const char *source1,
1707251881Speter                  const svn_opt_revision_t *revision1,
1708251881Speter                  const char *source2,
1709251881Speter                  const svn_opt_revision_t *revision2,
1710251881Speter                  const char *target_wcpath,
1711251881Speter                  svn_boolean_t recurse,
1712251881Speter                  svn_boolean_t ignore_ancestry,
1713251881Speter                  svn_boolean_t force,
1714251881Speter                  svn_boolean_t dry_run,
1715251881Speter                  const apr_array_header_t *merge_options,
1716251881Speter                  svn_client_ctx_t *ctx,
1717251881Speter                  apr_pool_t *pool)
1718251881Speter{
1719251881Speter  return svn_client_merge3(source1, revision1, source2, revision2,
1720251881Speter                           target_wcpath,
1721251881Speter                           SVN_DEPTH_INFINITY_OR_FILES(recurse),
1722251881Speter                           ignore_ancestry, force, FALSE, dry_run,
1723251881Speter                           merge_options, ctx, pool);
1724251881Speter}
1725251881Speter
1726251881Spetersvn_error_t *
1727251881Spetersvn_client_merge(const char *source1,
1728251881Speter                 const svn_opt_revision_t *revision1,
1729251881Speter                 const char *source2,
1730251881Speter                 const svn_opt_revision_t *revision2,
1731251881Speter                 const char *target_wcpath,
1732251881Speter                 svn_boolean_t recurse,
1733251881Speter                 svn_boolean_t ignore_ancestry,
1734251881Speter                 svn_boolean_t force,
1735251881Speter                 svn_boolean_t dry_run,
1736251881Speter                 svn_client_ctx_t *ctx,
1737251881Speter                 apr_pool_t *pool)
1738251881Speter{
1739251881Speter  return svn_client_merge2(source1, revision1, source2, revision2,
1740251881Speter                           target_wcpath, recurse, ignore_ancestry, force,
1741251881Speter                           dry_run, NULL, ctx, pool);
1742251881Speter}
1743251881Speter
1744251881Spetersvn_error_t *
1745251881Spetersvn_client_merge_peg4(const char *source_path_or_url,
1746251881Speter                      const apr_array_header_t *ranges_to_merge,
1747251881Speter                      const svn_opt_revision_t *source_peg_revision,
1748251881Speter                      const char *target_wcpath,
1749251881Speter                      svn_depth_t depth,
1750251881Speter                      svn_boolean_t ignore_ancestry,
1751251881Speter                      svn_boolean_t force_delete,
1752251881Speter                      svn_boolean_t record_only,
1753251881Speter                      svn_boolean_t dry_run,
1754251881Speter                      svn_boolean_t allow_mixed_rev,
1755251881Speter                      const apr_array_header_t *merge_options,
1756251881Speter                      svn_client_ctx_t *ctx,
1757251881Speter                      apr_pool_t *pool)
1758251881Speter{
1759251881Speter  SVN_ERR(svn_client_merge_peg5(source_path_or_url,
1760251881Speter                                ranges_to_merge,
1761251881Speter                                source_peg_revision,
1762251881Speter                                target_wcpath,
1763251881Speter                                depth,
1764251881Speter                                ignore_ancestry /*ignore_mergeinfo*/,
1765251881Speter                                ignore_ancestry /*diff_ignore_ancestry*/,
1766251881Speter                                force_delete, record_only,
1767251881Speter                                dry_run, allow_mixed_rev,
1768251881Speter                                merge_options, ctx, pool));
1769251881Speter  return SVN_NO_ERROR;
1770251881Speter}
1771251881Speter
1772251881Spetersvn_error_t *
1773251881Spetersvn_client_merge_peg3(const char *source,
1774251881Speter                      const apr_array_header_t *ranges_to_merge,
1775251881Speter                      const svn_opt_revision_t *peg_revision,
1776251881Speter                      const char *target_wcpath,
1777251881Speter                      svn_depth_t depth,
1778251881Speter                      svn_boolean_t ignore_ancestry,
1779251881Speter                      svn_boolean_t force,
1780251881Speter                      svn_boolean_t record_only,
1781251881Speter                      svn_boolean_t dry_run,
1782251881Speter                      const apr_array_header_t *merge_options,
1783251881Speter                      svn_client_ctx_t *ctx,
1784251881Speter                      apr_pool_t *pool)
1785251881Speter{
1786251881Speter  return svn_client_merge_peg4(source, ranges_to_merge, peg_revision,
1787251881Speter                               target_wcpath, depth, ignore_ancestry, force,
1788251881Speter                               record_only, dry_run, TRUE, merge_options,
1789251881Speter                               ctx, pool);
1790251881Speter}
1791251881Speter
1792251881Spetersvn_error_t *
1793251881Spetersvn_client_merge_peg2(const char *source,
1794251881Speter                      const svn_opt_revision_t *revision1,
1795251881Speter                      const svn_opt_revision_t *revision2,
1796251881Speter                      const svn_opt_revision_t *peg_revision,
1797251881Speter                      const char *target_wcpath,
1798251881Speter                      svn_boolean_t recurse,
1799251881Speter                      svn_boolean_t ignore_ancestry,
1800251881Speter                      svn_boolean_t force,
1801251881Speter                      svn_boolean_t dry_run,
1802251881Speter                      const apr_array_header_t *merge_options,
1803251881Speter                      svn_client_ctx_t *ctx,
1804251881Speter                      apr_pool_t *pool)
1805251881Speter{
1806251881Speter  apr_array_header_t *ranges_to_merge =
1807251881Speter    apr_array_make(pool, 1, sizeof(svn_opt_revision_range_t *));
1808251881Speter
1809251881Speter  APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *)
1810251881Speter    = svn_opt__revision_range_create(revision1, revision2, pool);
1811251881Speter  return svn_client_merge_peg3(source, ranges_to_merge,
1812251881Speter                               peg_revision,
1813251881Speter                               target_wcpath,
1814251881Speter                               SVN_DEPTH_INFINITY_OR_FILES(recurse),
1815251881Speter                               ignore_ancestry, force, FALSE, dry_run,
1816251881Speter                               merge_options, ctx, pool);
1817251881Speter}
1818251881Speter
1819251881Spetersvn_error_t *
1820251881Spetersvn_client_merge_peg(const char *source,
1821251881Speter                     const svn_opt_revision_t *revision1,
1822251881Speter                     const svn_opt_revision_t *revision2,
1823251881Speter                     const svn_opt_revision_t *peg_revision,
1824251881Speter                     const char *target_wcpath,
1825251881Speter                     svn_boolean_t recurse,
1826251881Speter                     svn_boolean_t ignore_ancestry,
1827251881Speter                     svn_boolean_t force,
1828251881Speter                     svn_boolean_t dry_run,
1829251881Speter                     svn_client_ctx_t *ctx,
1830251881Speter                     apr_pool_t *pool)
1831251881Speter{
1832251881Speter  return svn_client_merge_peg2(source, revision1, revision2, peg_revision,
1833251881Speter                               target_wcpath, recurse, ignore_ancestry, force,
1834251881Speter                               dry_run, NULL, ctx, pool);
1835251881Speter}
1836251881Speter
1837251881Speter/*** From prop_commands.c ***/
1838251881Spetersvn_error_t *
1839251881Spetersvn_client_propset3(svn_commit_info_t **commit_info_p,
1840251881Speter                    const char *propname,
1841251881Speter                    const svn_string_t *propval,
1842251881Speter                    const char *target,
1843251881Speter                    svn_depth_t depth,
1844251881Speter                    svn_boolean_t skip_checks,
1845251881Speter                    svn_revnum_t base_revision_for_url,
1846251881Speter                    const apr_array_header_t *changelists,
1847251881Speter                    const apr_hash_t *revprop_table,
1848251881Speter                    svn_client_ctx_t *ctx,
1849251881Speter                    apr_pool_t *pool)
1850251881Speter{
1851251881Speter  if (svn_path_is_url(target))
1852251881Speter    {
1853251881Speter      struct capture_baton_t cb;
1854251881Speter
1855251881Speter      cb.info = commit_info_p;
1856251881Speter      cb.pool = pool;
1857251881Speter
1858251881Speter      SVN_ERR(svn_client_propset_remote(propname, propval, target, skip_checks,
1859251881Speter                                        base_revision_for_url, revprop_table,
1860251881Speter                                        capture_commit_info, &cb, ctx, pool));
1861251881Speter    }
1862251881Speter  else
1863251881Speter    {
1864251881Speter      apr_array_header_t *targets = apr_array_make(pool, 1,
1865251881Speter                                                   sizeof(const char *));
1866251881Speter
1867251881Speter      APR_ARRAY_PUSH(targets, const char *) = target;
1868251881Speter      SVN_ERR(svn_client_propset_local(propname, propval, targets, depth,
1869251881Speter                                       skip_checks, changelists, ctx, pool));
1870251881Speter    }
1871251881Speter
1872251881Speter  return SVN_NO_ERROR;
1873251881Speter}
1874251881Speter
1875251881Spetersvn_error_t *
1876251881Spetersvn_client_propset2(const char *propname,
1877251881Speter                    const svn_string_t *propval,
1878251881Speter                    const char *target,
1879251881Speter                    svn_boolean_t recurse,
1880251881Speter                    svn_boolean_t skip_checks,
1881251881Speter                    svn_client_ctx_t *ctx,
1882251881Speter                    apr_pool_t *pool)
1883251881Speter{
1884251881Speter  return svn_client_propset3(NULL, propname, propval, target,
1885251881Speter                             SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
1886251881Speter                             skip_checks, SVN_INVALID_REVNUM,
1887251881Speter                             NULL, NULL, ctx, pool);
1888251881Speter}
1889251881Speter
1890251881Speter
1891251881Spetersvn_error_t *
1892251881Spetersvn_client_propset(const char *propname,
1893251881Speter                   const svn_string_t *propval,
1894251881Speter                   const char *target,
1895251881Speter                   svn_boolean_t recurse,
1896251881Speter                   apr_pool_t *pool)
1897251881Speter{
1898251881Speter  svn_client_ctx_t *ctx;
1899251881Speter
1900251881Speter  SVN_ERR(svn_client_create_context(&ctx, pool));
1901251881Speter
1902251881Speter  return svn_client_propset2(propname, propval, target, recurse, FALSE,
1903251881Speter                             ctx, pool);
1904251881Speter}
1905251881Speter
1906251881Spetersvn_error_t *
1907251881Spetersvn_client_revprop_set(const char *propname,
1908251881Speter                       const svn_string_t *propval,
1909251881Speter                       const char *URL,
1910251881Speter                       const svn_opt_revision_t *revision,
1911251881Speter                       svn_revnum_t *set_rev,
1912251881Speter                       svn_boolean_t force,
1913251881Speter                       svn_client_ctx_t *ctx,
1914251881Speter                       apr_pool_t *pool)
1915251881Speter{
1916251881Speter  return svn_client_revprop_set2(propname, propval, NULL, URL,
1917251881Speter                                 revision, set_rev, force, ctx, pool);
1918251881Speter
1919251881Speter}
1920251881Speter
1921251881Spetersvn_error_t *
1922251881Spetersvn_client_propget4(apr_hash_t **props,
1923251881Speter                    const char *propname,
1924251881Speter                    const char *target,
1925251881Speter                    const svn_opt_revision_t *peg_revision,
1926251881Speter                    const svn_opt_revision_t *revision,
1927251881Speter                    svn_revnum_t *actual_revnum,
1928251881Speter                    svn_depth_t depth,
1929251881Speter                    const apr_array_header_t *changelists,
1930251881Speter                    svn_client_ctx_t *ctx,
1931251881Speter                    apr_pool_t *result_pool,
1932251881Speter                    apr_pool_t *scratch_pool)
1933251881Speter{
1934251881Speter  return svn_error_trace(svn_client_propget5(props, NULL, propname, target,
1935251881Speter                                             peg_revision, revision,
1936251881Speter                                             actual_revnum, depth,
1937251881Speter                                             changelists, ctx,
1938251881Speter                                             result_pool, scratch_pool));
1939251881Speter}
1940251881Speter
1941251881Spetersvn_error_t *
1942251881Spetersvn_client_propget3(apr_hash_t **props,
1943251881Speter                    const char *propname,
1944251881Speter                    const char *path_or_url,
1945251881Speter                    const svn_opt_revision_t *peg_revision,
1946251881Speter                    const svn_opt_revision_t *revision,
1947251881Speter                    svn_revnum_t *actual_revnum,
1948251881Speter                    svn_depth_t depth,
1949251881Speter                    const apr_array_header_t *changelists,
1950251881Speter                    svn_client_ctx_t *ctx,
1951251881Speter                    apr_pool_t *pool)
1952251881Speter{
1953251881Speter  const char *target;
1954251881Speter  apr_hash_t *temp_props;
1955251881Speter  svn_error_t *err;
1956251881Speter
1957251881Speter  if (svn_path_is_url(path_or_url))
1958251881Speter    target = path_or_url;
1959251881Speter  else
1960251881Speter    SVN_ERR(svn_dirent_get_absolute(&target, path_or_url, pool));
1961251881Speter
1962251881Speter  err = svn_client_propget4(&temp_props, propname, target,
1963251881Speter                            peg_revision, revision, actual_revnum,
1964251881Speter                            depth, changelists, ctx, pool, pool);
1965251881Speter
1966251881Speter  if (err && err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE)
1967251881Speter    {
1968251881Speter      err->apr_err = SVN_ERR_ENTRY_NOT_FOUND;
1969251881Speter      return svn_error_trace(err);
1970251881Speter    }
1971251881Speter  else
1972251881Speter    SVN_ERR(err);
1973251881Speter
1974251881Speter  if (actual_revnum
1975251881Speter        && !svn_path_is_url(path_or_url)
1976251881Speter        && !SVN_IS_VALID_REVNUM(*actual_revnum))
1977251881Speter    {
1978251881Speter      /* Get the actual_revnum; added nodes have no revision yet, and old
1979251881Speter       * callers expected the mock-up revision of 0. */
1980251881Speter      svn_boolean_t added;
1981251881Speter
1982251881Speter      SVN_ERR(svn_wc__node_is_added(&added, ctx->wc_ctx, target, pool));
1983251881Speter      if (added)
1984251881Speter        *actual_revnum = 0;
1985251881Speter    }
1986251881Speter
1987251881Speter  /* We may need to fix up our hash keys for legacy callers. */
1988251881Speter  if (!svn_path_is_url(path_or_url) && strcmp(target, path_or_url) != 0)
1989251881Speter    {
1990251881Speter      apr_hash_index_t *hi;
1991251881Speter
1992251881Speter      *props = apr_hash_make(pool);
1993251881Speter      for (hi = apr_hash_first(pool, temp_props); hi;
1994251881Speter            hi = apr_hash_next(hi))
1995251881Speter        {
1996299742Sdim          const char *abspath = apr_hash_this_key(hi);
1997299742Sdim          svn_string_t *value = apr_hash_this_val(hi);
1998251881Speter          const char *relpath = svn_dirent_join(path_or_url,
1999251881Speter                                     svn_dirent_skip_ancestor(target, abspath),
2000251881Speter                                     pool);
2001251881Speter
2002251881Speter          svn_hash_sets(*props, relpath, value);
2003251881Speter        }
2004251881Speter    }
2005251881Speter  else
2006251881Speter    *props = temp_props;
2007251881Speter
2008251881Speter  return SVN_NO_ERROR;
2009251881Speter}
2010251881Speter
2011251881Spetersvn_error_t *
2012251881Spetersvn_client_propget2(apr_hash_t **props,
2013251881Speter                    const char *propname,
2014251881Speter                    const char *target,
2015251881Speter                    const svn_opt_revision_t *peg_revision,
2016251881Speter                    const svn_opt_revision_t *revision,
2017251881Speter                    svn_boolean_t recurse,
2018251881Speter                    svn_client_ctx_t *ctx,
2019251881Speter                    apr_pool_t *pool)
2020251881Speter{
2021251881Speter  return svn_client_propget3(props,
2022251881Speter                             propname,
2023251881Speter                             target,
2024251881Speter                             peg_revision,
2025251881Speter                             revision,
2026251881Speter                             NULL,
2027251881Speter                             SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
2028251881Speter                             NULL,
2029251881Speter                             ctx,
2030251881Speter                             pool);
2031251881Speter}
2032251881Speter
2033251881Spetersvn_error_t *
2034251881Spetersvn_client_propget(apr_hash_t **props,
2035251881Speter                   const char *propname,
2036251881Speter                   const char *target,
2037251881Speter                   const svn_opt_revision_t *revision,
2038251881Speter                   svn_boolean_t recurse,
2039251881Speter                   svn_client_ctx_t *ctx,
2040251881Speter                   apr_pool_t *pool)
2041251881Speter{
2042251881Speter  return svn_client_propget2(props, propname, target, revision, revision,
2043251881Speter                             recurse, ctx, pool);
2044251881Speter}
2045251881Speter
2046251881Speter
2047251881Speter/* Duplicate a HASH containing (char * -> svn_string_t *) key/value
2048251881Speter   pairs using POOL. */
2049251881Speterstatic apr_hash_t *
2050251881Speterstring_hash_dup(apr_hash_t *hash, apr_pool_t *pool)
2051251881Speter{
2052251881Speter  apr_hash_index_t *hi;
2053251881Speter  apr_hash_t *new_hash = apr_hash_make(pool);
2054251881Speter
2055251881Speter  for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
2056251881Speter    {
2057299742Sdim      const char *key = apr_pstrdup(pool, apr_hash_this_key(hi));
2058299742Sdim      apr_ssize_t klen = apr_hash_this_key_len(hi);
2059299742Sdim      svn_string_t *val = svn_string_dup(apr_hash_this_val(hi), pool);
2060251881Speter
2061251881Speter      apr_hash_set(new_hash, key, klen, val);
2062251881Speter    }
2063251881Speter  return new_hash;
2064251881Speter}
2065251881Speter
2066251881Spetersvn_client_proplist_item_t *
2067251881Spetersvn_client_proplist_item_dup(const svn_client_proplist_item_t *item,
2068251881Speter                             apr_pool_t * pool)
2069251881Speter{
2070251881Speter  svn_client_proplist_item_t *new_item = apr_pcalloc(pool, sizeof(*new_item));
2071251881Speter
2072251881Speter  if (item->node_name)
2073251881Speter    new_item->node_name = svn_stringbuf_dup(item->node_name, pool);
2074251881Speter
2075251881Speter  if (item->prop_hash)
2076251881Speter    new_item->prop_hash = string_hash_dup(item->prop_hash, pool);
2077251881Speter
2078251881Speter  return new_item;
2079251881Speter}
2080251881Speter
2081251881Speter/* Baton for use with wrap_proplist_receiver */
2082251881Speterstruct proplist_receiver_wrapper_baton {
2083251881Speter  void *baton;
2084251881Speter  svn_proplist_receiver_t receiver;
2085251881Speter};
2086251881Speter
2087251881Speter/* This implements svn_client_proplist_receiver2_t */
2088251881Speterstatic svn_error_t *
2089251881Speterproplist_wrapper_receiver(void *baton,
2090251881Speter                          const char *path,
2091251881Speter                          apr_hash_t *prop_hash,
2092251881Speter                          apr_array_header_t *inherited_props,
2093251881Speter                          apr_pool_t *pool)
2094251881Speter{
2095251881Speter  struct proplist_receiver_wrapper_baton *plrwb = baton;
2096251881Speter
2097251881Speter  if (plrwb->receiver)
2098251881Speter    return plrwb->receiver(plrwb->baton, path, prop_hash, pool);
2099251881Speter
2100251881Speter  return SVN_NO_ERROR;
2101251881Speter}
2102251881Speter
2103251881Speterstatic void
2104251881Speterwrap_proplist_receiver(svn_proplist_receiver2_t *receiver2,
2105251881Speter                       void **receiver2_baton,
2106251881Speter                       svn_proplist_receiver_t receiver,
2107251881Speter                       void *receiver_baton,
2108251881Speter                       apr_pool_t *pool)
2109251881Speter{
2110251881Speter  struct proplist_receiver_wrapper_baton *plrwb = apr_palloc(pool,
2111251881Speter                                                             sizeof(*plrwb));
2112251881Speter
2113251881Speter  /* Set the user provided old format callback in the baton. */
2114251881Speter  plrwb->baton = receiver_baton;
2115251881Speter  plrwb->receiver = receiver;
2116251881Speter
2117251881Speter  *receiver2_baton = plrwb;
2118251881Speter  *receiver2 = proplist_wrapper_receiver;
2119251881Speter}
2120251881Speter
2121251881Spetersvn_error_t *
2122251881Spetersvn_client_proplist3(const char *target,
2123251881Speter                     const svn_opt_revision_t *peg_revision,
2124251881Speter                     const svn_opt_revision_t *revision,
2125251881Speter                     svn_depth_t depth,
2126251881Speter                     const apr_array_header_t *changelists,
2127251881Speter                     svn_proplist_receiver_t receiver,
2128251881Speter                     void *receiver_baton,
2129251881Speter                     svn_client_ctx_t *ctx,
2130251881Speter                     apr_pool_t *pool)
2131251881Speter{
2132251881Speter
2133251881Speter  svn_proplist_receiver2_t receiver2;
2134251881Speter  void *receiver2_baton;
2135251881Speter
2136251881Speter  wrap_proplist_receiver(&receiver2, &receiver2_baton, receiver, receiver_baton,
2137251881Speter                         pool);
2138251881Speter
2139251881Speter  return svn_error_trace(svn_client_proplist4(target, peg_revision, revision,
2140251881Speter                                              depth, changelists, FALSE,
2141251881Speter                                              receiver2, receiver2_baton,
2142251881Speter                                              ctx, pool));
2143251881Speter}
2144251881Speter
2145251881Speter/* Receiver baton used by proplist2() */
2146251881Speterstruct proplist_receiver_baton {
2147251881Speter  apr_array_header_t *props;
2148251881Speter  apr_pool_t *pool;
2149251881Speter};
2150251881Speter
2151251881Speter/* Receiver function used by proplist2(). */
2152251881Speterstatic svn_error_t *
2153251881Speterproplist_receiver_cb(void *baton,
2154251881Speter                     const char *path,
2155251881Speter                     apr_hash_t *prop_hash,
2156251881Speter                     apr_pool_t *pool)
2157251881Speter{
2158251881Speter  struct proplist_receiver_baton *pl_baton =
2159251881Speter    (struct proplist_receiver_baton *) baton;
2160251881Speter  svn_client_proplist_item_t *tmp_item = apr_palloc(pool, sizeof(*tmp_item));
2161251881Speter  svn_client_proplist_item_t *item;
2162251881Speter
2163251881Speter  /* Because the pool passed to the receiver function is likely to be a
2164251881Speter     temporary pool of some kind, we need to make copies of *path and
2165251881Speter     *prop_hash in the pool provided by the baton. */
2166251881Speter  tmp_item->node_name = svn_stringbuf_create(path, pl_baton->pool);
2167251881Speter  tmp_item->prop_hash = prop_hash;
2168251881Speter
2169251881Speter  item = svn_client_proplist_item_dup(tmp_item, pl_baton->pool);
2170251881Speter
2171251881Speter  APR_ARRAY_PUSH(pl_baton->props, const svn_client_proplist_item_t *) = item;
2172251881Speter
2173251881Speter  return SVN_NO_ERROR;
2174251881Speter}
2175251881Speter
2176251881Spetersvn_error_t *
2177251881Spetersvn_client_proplist2(apr_array_header_t **props,
2178251881Speter                     const char *target,
2179251881Speter                     const svn_opt_revision_t *peg_revision,
2180251881Speter                     const svn_opt_revision_t *revision,
2181251881Speter                     svn_boolean_t recurse,
2182251881Speter                     svn_client_ctx_t *ctx,
2183251881Speter                     apr_pool_t *pool)
2184251881Speter{
2185251881Speter  struct proplist_receiver_baton pl_baton;
2186251881Speter
2187251881Speter  *props = apr_array_make(pool, 5, sizeof(svn_client_proplist_item_t *));
2188251881Speter  pl_baton.props = *props;
2189251881Speter  pl_baton.pool = pool;
2190251881Speter
2191251881Speter  return svn_client_proplist3(target, peg_revision, revision,
2192251881Speter                              SVN_DEPTH_INFINITY_OR_EMPTY(recurse), NULL,
2193251881Speter                              proplist_receiver_cb, &pl_baton, ctx, pool);
2194251881Speter}
2195251881Speter
2196251881Speter
2197251881Spetersvn_error_t *
2198251881Spetersvn_client_proplist(apr_array_header_t **props,
2199251881Speter                    const char *target,
2200251881Speter                    const svn_opt_revision_t *revision,
2201251881Speter                    svn_boolean_t recurse,
2202251881Speter                    svn_client_ctx_t *ctx,
2203251881Speter                    apr_pool_t *pool)
2204251881Speter{
2205251881Speter  return svn_client_proplist2(props, target, revision, revision,
2206251881Speter                              recurse, ctx, pool);
2207251881Speter}
2208251881Speter
2209251881Speter/*** From status.c ***/
2210251881Speter
2211299742Sdimsvn_error_t *
2212299742Sdimsvn_client_status5(svn_revnum_t *result_rev,
2213299742Sdim                   svn_client_ctx_t *ctx,
2214299742Sdim                   const char *path,
2215299742Sdim                   const svn_opt_revision_t *revision,
2216299742Sdim                   svn_depth_t depth,
2217299742Sdim                   svn_boolean_t get_all,
2218299742Sdim                   svn_boolean_t update,
2219299742Sdim                   svn_boolean_t no_ignore,
2220299742Sdim                   svn_boolean_t ignore_externals,
2221299742Sdim                   svn_boolean_t depth_as_sticky,
2222299742Sdim                   const apr_array_header_t *changelists,
2223299742Sdim                   svn_client_status_func_t status_func,
2224299742Sdim                   void *status_baton,
2225299742Sdim                   apr_pool_t *scratch_pool)
2226299742Sdim{
2227299742Sdim  return svn_client_status6(result_rev, ctx, path, revision, depth,
2228299742Sdim                            get_all, update, TRUE, no_ignore,
2229299742Sdim                            ignore_externals, depth_as_sticky, changelists,
2230299742Sdim                            status_func, status_baton, scratch_pool);
2231299742Sdim}
2232299742Sdim
2233251881Speterstruct status4_wrapper_baton
2234251881Speter{
2235251881Speter  svn_wc_context_t *wc_ctx;
2236251881Speter  svn_wc_status_func3_t old_func;
2237251881Speter  void *old_baton;
2238251881Speter};
2239251881Speter
2240251881Speter/* Implements svn_client_status_func_t */
2241251881Speterstatic svn_error_t *
2242251881Speterstatus4_wrapper_func(void *baton,
2243251881Speter                     const char *path,
2244251881Speter                     const svn_client_status_t *status,
2245251881Speter                     apr_pool_t *scratch_pool)
2246251881Speter{
2247251881Speter  struct status4_wrapper_baton *swb = baton;
2248251881Speter  svn_wc_status2_t *dup;
2249251881Speter  const char *local_abspath;
2250251881Speter  const svn_wc_status3_t *wc_status = status->backwards_compatibility_baton;
2251251881Speter
2252251881Speter  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
2253251881Speter  SVN_ERR(svn_wc__status2_from_3(&dup, wc_status, swb->wc_ctx,
2254251881Speter                                 local_abspath, scratch_pool,
2255251881Speter                                 scratch_pool));
2256251881Speter
2257251881Speter  return (*swb->old_func)(swb->old_baton, path, dup, scratch_pool);
2258251881Speter}
2259251881Speter
2260251881Spetersvn_error_t *
2261251881Spetersvn_client_status4(svn_revnum_t *result_rev,
2262251881Speter                   const char *path,
2263251881Speter                   const svn_opt_revision_t *revision,
2264251881Speter                   svn_wc_status_func3_t status_func,
2265251881Speter                   void *status_baton,
2266251881Speter                   svn_depth_t depth,
2267251881Speter                   svn_boolean_t get_all,
2268251881Speter                   svn_boolean_t update,
2269251881Speter                   svn_boolean_t no_ignore,
2270251881Speter                   svn_boolean_t ignore_externals,
2271251881Speter                   const apr_array_header_t *changelists,
2272251881Speter                   svn_client_ctx_t *ctx,
2273251881Speter                   apr_pool_t *pool)
2274251881Speter{
2275251881Speter  struct status4_wrapper_baton swb;
2276251881Speter
2277251881Speter  swb.wc_ctx = ctx->wc_ctx;
2278251881Speter  swb.old_func = status_func;
2279251881Speter  swb.old_baton = status_baton;
2280251881Speter
2281251881Speter  return svn_client_status5(result_rev, ctx, path, revision, depth, get_all,
2282251881Speter                            update, no_ignore, ignore_externals, TRUE,
2283251881Speter                            changelists, status4_wrapper_func, &swb, pool);
2284251881Speter}
2285251881Speter
2286251881Speterstruct status3_wrapper_baton
2287251881Speter{
2288251881Speter  svn_wc_status_func2_t old_func;
2289251881Speter  void *old_baton;
2290251881Speter};
2291251881Speter
2292251881Speterstatic svn_error_t *
2293251881Speterstatus3_wrapper_func(void *baton,
2294251881Speter                     const char *path,
2295251881Speter                     svn_wc_status2_t *status,
2296251881Speter                     apr_pool_t *pool)
2297251881Speter{
2298251881Speter  struct status3_wrapper_baton *swb = baton;
2299251881Speter
2300251881Speter  swb->old_func(swb->old_baton, path, status);
2301251881Speter  return SVN_NO_ERROR;
2302251881Speter}
2303251881Speter
2304251881Spetersvn_error_t *
2305251881Spetersvn_client_status3(svn_revnum_t *result_rev,
2306251881Speter                   const char *path,
2307251881Speter                   const svn_opt_revision_t *revision,
2308251881Speter                   svn_wc_status_func2_t status_func,
2309251881Speter                   void *status_baton,
2310251881Speter                   svn_depth_t depth,
2311251881Speter                   svn_boolean_t get_all,
2312251881Speter                   svn_boolean_t update,
2313251881Speter                   svn_boolean_t no_ignore,
2314251881Speter                   svn_boolean_t ignore_externals,
2315251881Speter                   const apr_array_header_t *changelists,
2316251881Speter                   svn_client_ctx_t *ctx,
2317251881Speter                   apr_pool_t *pool)
2318251881Speter{
2319251881Speter  struct status3_wrapper_baton swb = { 0 };
2320251881Speter  swb.old_func = status_func;
2321251881Speter  swb.old_baton = status_baton;
2322251881Speter  return svn_client_status4(result_rev, path, revision, status3_wrapper_func,
2323251881Speter                            &swb, depth, get_all, update, no_ignore,
2324251881Speter                            ignore_externals, changelists, ctx, pool);
2325251881Speter}
2326251881Speter
2327251881Spetersvn_error_t *
2328251881Spetersvn_client_status2(svn_revnum_t *result_rev,
2329251881Speter                   const char *path,
2330251881Speter                   const svn_opt_revision_t *revision,
2331251881Speter                   svn_wc_status_func2_t status_func,
2332251881Speter                   void *status_baton,
2333251881Speter                   svn_boolean_t recurse,
2334251881Speter                   svn_boolean_t get_all,
2335251881Speter                   svn_boolean_t update,
2336251881Speter                   svn_boolean_t no_ignore,
2337251881Speter                   svn_boolean_t ignore_externals,
2338251881Speter                   svn_client_ctx_t *ctx,
2339251881Speter                   apr_pool_t *pool)
2340251881Speter{
2341251881Speter  return svn_client_status3(result_rev, path, revision,
2342251881Speter                            status_func, status_baton,
2343251881Speter                            SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
2344251881Speter                            get_all, update, no_ignore, ignore_externals, NULL,
2345251881Speter                            ctx, pool);
2346251881Speter}
2347251881Speter
2348251881Speter
2349251881Speter/* Baton for old_status_func_cb; does what you think it does. */
2350251881Speterstruct old_status_func_cb_baton
2351251881Speter{
2352251881Speter  svn_wc_status_func_t original_func;
2353251881Speter  void *original_baton;
2354251881Speter};
2355251881Speter
2356251881Speter/* Help svn_client_status() accept an old-style status func and baton,
2357251881Speter   by wrapping them before passing along to svn_client_status2().
2358251881Speter
2359251881Speter   This implements the 'svn_wc_status_func2_t' function type. */
2360251881Speterstatic void old_status_func_cb(void *baton,
2361251881Speter                               const char *path,
2362251881Speter                               svn_wc_status2_t *status)
2363251881Speter{
2364251881Speter  struct old_status_func_cb_baton *b = baton;
2365251881Speter  svn_wc_status_t *stat = (svn_wc_status_t *) status;
2366251881Speter
2367251881Speter  b->original_func(b->original_baton, path, stat);
2368251881Speter}
2369251881Speter
2370251881Speter
2371251881Spetersvn_error_t *
2372251881Spetersvn_client_status(svn_revnum_t *result_rev,
2373251881Speter                  const char *path,
2374251881Speter                  svn_opt_revision_t *revision,
2375251881Speter                  svn_wc_status_func_t status_func,
2376251881Speter                  void *status_baton,
2377251881Speter                  svn_boolean_t recurse,
2378251881Speter                  svn_boolean_t get_all,
2379251881Speter                  svn_boolean_t update,
2380251881Speter                  svn_boolean_t no_ignore,
2381251881Speter                  svn_client_ctx_t *ctx,
2382251881Speter                  apr_pool_t *pool)
2383251881Speter{
2384251881Speter  struct old_status_func_cb_baton *b = apr_pcalloc(pool, sizeof(*b));
2385251881Speter  b->original_func = status_func;
2386251881Speter  b->original_baton = status_baton;
2387251881Speter
2388251881Speter  return svn_client_status2(result_rev, path, revision,
2389251881Speter                            old_status_func_cb, b,
2390251881Speter                            recurse, get_all, update, no_ignore, FALSE,
2391251881Speter                            ctx, pool);
2392251881Speter}
2393251881Speter
2394251881Speter/*** From update.c ***/
2395251881Spetersvn_error_t *
2396251881Spetersvn_client_update3(apr_array_header_t **result_revs,
2397251881Speter                   const apr_array_header_t *paths,
2398251881Speter                   const svn_opt_revision_t *revision,
2399251881Speter                   svn_depth_t depth,
2400251881Speter                   svn_boolean_t depth_is_sticky,
2401251881Speter                   svn_boolean_t ignore_externals,
2402251881Speter                   svn_boolean_t allow_unver_obstructions,
2403251881Speter                   svn_client_ctx_t *ctx,
2404251881Speter                   apr_pool_t *pool)
2405251881Speter{
2406251881Speter  return svn_client_update4(result_revs, paths, revision,
2407251881Speter                            depth, depth_is_sticky, ignore_externals,
2408251881Speter                            allow_unver_obstructions, TRUE, FALSE,
2409251881Speter                            ctx, pool);
2410251881Speter}
2411251881Speter
2412251881Spetersvn_error_t *
2413251881Spetersvn_client_update2(apr_array_header_t **result_revs,
2414251881Speter                   const apr_array_header_t *paths,
2415251881Speter                   const svn_opt_revision_t *revision,
2416251881Speter                   svn_boolean_t recurse,
2417251881Speter                   svn_boolean_t ignore_externals,
2418251881Speter                   svn_client_ctx_t *ctx,
2419251881Speter                   apr_pool_t *pool)
2420251881Speter{
2421251881Speter  return svn_client_update3(result_revs, paths, revision,
2422251881Speter                            SVN_DEPTH_INFINITY_OR_FILES(recurse), FALSE,
2423251881Speter                            ignore_externals, FALSE, ctx, pool);
2424251881Speter}
2425251881Speter
2426251881Spetersvn_error_t *
2427251881Spetersvn_client_update(svn_revnum_t *result_rev,
2428251881Speter                  const char *path,
2429251881Speter                  const svn_opt_revision_t *revision,
2430251881Speter                  svn_boolean_t recurse,
2431251881Speter                  svn_client_ctx_t *ctx,
2432251881Speter                  apr_pool_t *pool)
2433251881Speter{
2434251881Speter  apr_array_header_t *paths = apr_array_make(pool, 1, sizeof(const char *));
2435251881Speter  apr_array_header_t *result_revs;
2436251881Speter
2437251881Speter  APR_ARRAY_PUSH(paths, const char *) = path;
2438251881Speter
2439251881Speter  SVN_ERR(svn_client_update2(&result_revs, paths, revision, recurse, FALSE,
2440251881Speter                             ctx, pool));
2441251881Speter
2442251881Speter  *result_rev = APR_ARRAY_IDX(result_revs, 0, svn_revnum_t);
2443251881Speter
2444251881Speter  return SVN_NO_ERROR;
2445251881Speter}
2446251881Speter
2447251881Speter/*** From switch.c ***/
2448251881Spetersvn_error_t *
2449251881Spetersvn_client_switch2(svn_revnum_t *result_rev,
2450251881Speter                   const char *path,
2451251881Speter                   const char *switch_url,
2452251881Speter                   const svn_opt_revision_t *peg_revision,
2453251881Speter                   const svn_opt_revision_t *revision,
2454251881Speter                   svn_depth_t depth,
2455251881Speter                   svn_boolean_t depth_is_sticky,
2456251881Speter                   svn_boolean_t ignore_externals,
2457251881Speter                   svn_boolean_t allow_unver_obstructions,
2458251881Speter                   svn_client_ctx_t *ctx,
2459251881Speter                   apr_pool_t *pool)
2460251881Speter{
2461251881Speter  return svn_client_switch3(result_rev, path, switch_url, peg_revision,
2462251881Speter                            revision, depth, depth_is_sticky, ignore_externals,
2463251881Speter                            allow_unver_obstructions,
2464251881Speter                            TRUE /* ignore_ancestry */,
2465251881Speter                            ctx, pool);
2466251881Speter}
2467251881Speter
2468251881Spetersvn_error_t *
2469251881Spetersvn_client_switch(svn_revnum_t *result_rev,
2470251881Speter                  const char *path,
2471251881Speter                  const char *switch_url,
2472251881Speter                  const svn_opt_revision_t *revision,
2473251881Speter                  svn_boolean_t recurse,
2474251881Speter                  svn_client_ctx_t *ctx,
2475251881Speter                  apr_pool_t *pool)
2476251881Speter{
2477251881Speter  svn_opt_revision_t peg_revision;
2478251881Speter  peg_revision.kind = svn_opt_revision_unspecified;
2479251881Speter  return svn_client_switch2(result_rev, path, switch_url,
2480251881Speter                            &peg_revision, revision,
2481251881Speter                            SVN_DEPTH_INFINITY_OR_FILES(recurse),
2482251881Speter                            FALSE, FALSE, FALSE, ctx, pool);
2483251881Speter}
2484251881Speter
2485251881Speter/*** From cat.c ***/
2486251881Spetersvn_error_t *
2487299742Sdimsvn_client_cat2(svn_stream_t *out,
2488299742Sdim                const char *path_or_url,
2489299742Sdim                const svn_opt_revision_t *peg_revision,
2490299742Sdim                const svn_opt_revision_t *revision,
2491299742Sdim                svn_client_ctx_t *ctx,
2492299742Sdim                apr_pool_t *pool)
2493299742Sdim{
2494299742Sdim  return svn_client_cat3(NULL /* props */,
2495299742Sdim                         out, path_or_url, peg_revision, revision,
2496299742Sdim                         TRUE /* expand_keywords */,
2497299742Sdim                         ctx, pool, pool);
2498299742Sdim}
2499299742Sdim
2500299742Sdim
2501299742Sdimsvn_error_t *
2502251881Spetersvn_client_cat(svn_stream_t *out,
2503251881Speter               const char *path_or_url,
2504251881Speter               const svn_opt_revision_t *revision,
2505251881Speter               svn_client_ctx_t *ctx,
2506251881Speter               apr_pool_t *pool)
2507251881Speter{
2508251881Speter  return svn_client_cat2(out, path_or_url, revision, revision,
2509251881Speter                         ctx, pool);
2510251881Speter}
2511251881Speter
2512251881Speter/*** From checkout.c ***/
2513251881Spetersvn_error_t *
2514251881Spetersvn_client_checkout2(svn_revnum_t *result_rev,
2515251881Speter                     const char *URL,
2516251881Speter                     const char *path,
2517251881Speter                     const svn_opt_revision_t *peg_revision,
2518251881Speter                     const svn_opt_revision_t *revision,
2519251881Speter                     svn_boolean_t recurse,
2520251881Speter                     svn_boolean_t ignore_externals,
2521251881Speter                     svn_client_ctx_t *ctx,
2522251881Speter                     apr_pool_t *pool)
2523251881Speter{
2524251881Speter  return svn_error_trace(svn_client_checkout3(result_rev, URL, path,
2525251881Speter                                        peg_revision, revision,
2526251881Speter                                        SVN_DEPTH_INFINITY_OR_FILES(recurse),
2527251881Speter                                        ignore_externals, FALSE, ctx, pool));
2528251881Speter}
2529251881Speter
2530251881Spetersvn_error_t *
2531251881Spetersvn_client_checkout(svn_revnum_t *result_rev,
2532251881Speter                    const char *URL,
2533251881Speter                    const char *path,
2534251881Speter                    const svn_opt_revision_t *revision,
2535251881Speter                    svn_boolean_t recurse,
2536251881Speter                    svn_client_ctx_t *ctx,
2537251881Speter                    apr_pool_t *pool)
2538251881Speter{
2539251881Speter  svn_opt_revision_t peg_revision;
2540251881Speter
2541251881Speter  peg_revision.kind = svn_opt_revision_unspecified;
2542251881Speter
2543251881Speter  return svn_error_trace(svn_client_checkout2(result_rev, URL, path,
2544251881Speter                                              &peg_revision, revision, recurse,
2545251881Speter                                              FALSE, ctx, pool));
2546251881Speter}
2547251881Speter
2548251881Speter/*** From info.c ***/
2549251881Speter
2550299742Sdimsvn_error_t *
2551299742Sdimsvn_client_info3(const char *abspath_or_url,
2552299742Sdim                 const svn_opt_revision_t *peg_revision,
2553299742Sdim                 const svn_opt_revision_t *revision,
2554299742Sdim                 svn_depth_t depth,
2555299742Sdim                 svn_boolean_t fetch_excluded,
2556299742Sdim                 svn_boolean_t fetch_actual_only,
2557299742Sdim                 const apr_array_header_t *changelists,
2558299742Sdim                 svn_client_info_receiver2_t receiver,
2559299742Sdim                 void *receiver_baton,
2560299742Sdim                 svn_client_ctx_t *ctx,
2561299742Sdim                 apr_pool_t *pool)
2562299742Sdim{
2563299742Sdim  return svn_error_trace(
2564299742Sdim            svn_client_info4(abspath_or_url,
2565299742Sdim                             peg_revision,
2566299742Sdim                             revision,
2567299742Sdim                             depth,
2568299742Sdim                             fetch_excluded,
2569299742Sdim                             fetch_actual_only,
2570299742Sdim                             FALSE /* include_externals */,
2571299742Sdim                             changelists,
2572299742Sdim                             receiver, receiver_baton,
2573299742Sdim                             ctx, pool));
2574299742Sdim}
2575299742Sdim
2576251881Spetersvn_info_t *
2577251881Spetersvn_info_dup(const svn_info_t *info, apr_pool_t *pool)
2578251881Speter{
2579251881Speter  svn_info_t *dupinfo = apr_palloc(pool, sizeof(*dupinfo));
2580251881Speter
2581251881Speter  /* Perform a trivial copy ... */
2582251881Speter  *dupinfo = *info;
2583251881Speter
2584251881Speter  /* ...and then re-copy stuff that needs to be duped into our pool. */
2585251881Speter  if (info->URL)
2586251881Speter    dupinfo->URL = apr_pstrdup(pool, info->URL);
2587251881Speter  if (info->repos_root_URL)
2588251881Speter    dupinfo->repos_root_URL = apr_pstrdup(pool, info->repos_root_URL);
2589251881Speter  if (info->repos_UUID)
2590251881Speter    dupinfo->repos_UUID = apr_pstrdup(pool, info->repos_UUID);
2591251881Speter  if (info->last_changed_author)
2592251881Speter    dupinfo->last_changed_author = apr_pstrdup(pool,
2593251881Speter                                               info->last_changed_author);
2594251881Speter  if (info->lock)
2595251881Speter    dupinfo->lock = svn_lock_dup(info->lock, pool);
2596251881Speter  if (info->copyfrom_url)
2597251881Speter    dupinfo->copyfrom_url = apr_pstrdup(pool, info->copyfrom_url);
2598251881Speter  if (info->checksum)
2599251881Speter    dupinfo->checksum = apr_pstrdup(pool, info->checksum);
2600251881Speter  if (info->conflict_old)
2601251881Speter    dupinfo->conflict_old = apr_pstrdup(pool, info->conflict_old);
2602251881Speter  if (info->conflict_new)
2603251881Speter    dupinfo->conflict_new = apr_pstrdup(pool, info->conflict_new);
2604251881Speter  if (info->conflict_wrk)
2605251881Speter    dupinfo->conflict_wrk = apr_pstrdup(pool, info->conflict_wrk);
2606251881Speter  if (info->prejfile)
2607251881Speter    dupinfo->prejfile = apr_pstrdup(pool, info->prejfile);
2608251881Speter
2609251881Speter  return dupinfo;
2610251881Speter}
2611251881Speter
2612251881Speter/* Convert an svn_client_info2_t to an svn_info_t, doing shallow copies. */
2613251881Speterstatic svn_error_t *
2614251881Speterinfo_from_info2(svn_info_t **new_info,
2615251881Speter                svn_wc_context_t *wc_ctx,
2616251881Speter                const svn_client_info2_t *info2,
2617251881Speter                apr_pool_t *pool)
2618251881Speter{
2619251881Speter  svn_info_t *info = apr_pcalloc(pool, sizeof(*info));
2620251881Speter
2621251881Speter  info->URL                 = info2->URL;
2622251881Speter  /* Goofy backward compat handling for added nodes. */
2623251881Speter  if (SVN_IS_VALID_REVNUM(info2->rev))
2624251881Speter    info->rev               = info2->rev;
2625251881Speter  else
2626251881Speter    info->rev               = 0;
2627251881Speter
2628251881Speter  info->kind                = info2->kind;
2629251881Speter  info->repos_root_URL      = info2->repos_root_URL;
2630251881Speter  info->repos_UUID          = info2->repos_UUID;
2631251881Speter  info->last_changed_rev    = info2->last_changed_rev;
2632251881Speter  info->last_changed_date   = info2->last_changed_date;
2633251881Speter  info->last_changed_author = info2->last_changed_author;
2634251881Speter
2635251881Speter  /* Stupid old structure has a non-const LOCK member. Sigh.  */
2636251881Speter  info->lock                = (svn_lock_t *)info2->lock;
2637251881Speter
2638251881Speter  info->size64              = info2->size;
2639251881Speter  if (info2->size == SVN_INVALID_FILESIZE)
2640251881Speter    info->size               = SVN_INFO_SIZE_UNKNOWN;
2641251881Speter  else if (((svn_filesize_t)(apr_size_t)info->size64) == info->size64)
2642251881Speter    info->size               = (apr_size_t)info->size64;
2643251881Speter  else /* >= 4GB */
2644251881Speter    info->size               = SVN_INFO_SIZE_UNKNOWN;
2645251881Speter
2646251881Speter  if (info2->wc_info)
2647251881Speter    {
2648251881Speter      info->has_wc_info         = TRUE;
2649251881Speter      info->schedule            = info2->wc_info->schedule;
2650251881Speter      info->copyfrom_url        = info2->wc_info->copyfrom_url;
2651251881Speter      info->copyfrom_rev        = info2->wc_info->copyfrom_rev;
2652251881Speter      info->text_time           = info2->wc_info->recorded_time;
2653251881Speter      info->prop_time           = 0;
2654251881Speter      if (info2->wc_info->checksum
2655251881Speter            && info2->wc_info->checksum->kind == svn_checksum_md5)
2656251881Speter        info->checksum          = svn_checksum_to_cstring(
2657251881Speter                                        info2->wc_info->checksum, pool);
2658251881Speter      else
2659251881Speter        info->checksum          = NULL;
2660251881Speter      info->changelist          = info2->wc_info->changelist;
2661251881Speter      info->depth               = info2->wc_info->depth;
2662251881Speter
2663251881Speter      if (info->depth == svn_depth_unknown && info->kind == svn_node_file)
2664251881Speter        info->depth = svn_depth_infinity;
2665251881Speter
2666251881Speter      info->working_size64      = info2->wc_info->recorded_size;
2667251881Speter      if (((svn_filesize_t)(apr_size_t)info->working_size64) == info->working_size64)
2668251881Speter        info->working_size       = (apr_size_t)info->working_size64;
2669251881Speter      else /* >= 4GB */
2670251881Speter        info->working_size       = SVN_INFO_SIZE_UNKNOWN;
2671251881Speter    }
2672251881Speter  else
2673251881Speter    {
2674251881Speter      info->has_wc_info           = FALSE;
2675251881Speter      info->working_size          = SVN_INFO_SIZE_UNKNOWN;
2676251881Speter      info->working_size64        = SVN_INVALID_FILESIZE;
2677251881Speter      info->depth                 = svn_depth_unknown;
2678251881Speter    }
2679251881Speter
2680251881Speter  /* Populate conflict fields. */
2681251881Speter  if (info2->wc_info && info2->wc_info->conflicts)
2682251881Speter    {
2683251881Speter      int i;
2684251881Speter
2685251881Speter      for (i = 0; i < info2->wc_info->conflicts->nelts; i++)
2686251881Speter        {
2687251881Speter          const svn_wc_conflict_description2_t *conflict
2688251881Speter                              = APR_ARRAY_IDX(info2->wc_info->conflicts, i,
2689251881Speter                                    const svn_wc_conflict_description2_t *);
2690251881Speter
2691251881Speter          /* ### Not really sure what we should do if we get multiple
2692251881Speter             ### conflicts of the same type. */
2693251881Speter          switch (conflict->kind)
2694251881Speter            {
2695251881Speter              case svn_wc_conflict_kind_tree:
2696251881Speter                info->tree_conflict = svn_wc__cd2_to_cd(conflict, pool);
2697251881Speter                break;
2698251881Speter
2699251881Speter              case svn_wc_conflict_kind_text:
2700251881Speter                info->conflict_old = conflict->base_abspath;
2701251881Speter                info->conflict_new = conflict->my_abspath;
2702251881Speter                info->conflict_wrk = conflict->their_abspath;
2703251881Speter                break;
2704251881Speter
2705251881Speter              case svn_wc_conflict_kind_property:
2706251881Speter                info->prejfile = conflict->their_abspath;
2707251881Speter                break;
2708251881Speter            }
2709251881Speter        }
2710251881Speter    }
2711251881Speter
2712251881Speter  if (info2->wc_info && info2->wc_info->checksum)
2713251881Speter    {
2714251881Speter      const svn_checksum_t *md5_checksum;
2715251881Speter
2716251881Speter      SVN_ERR(svn_wc__node_get_md5_from_sha1(&md5_checksum,
2717251881Speter                                             wc_ctx,
2718251881Speter                                             info2->wc_info->wcroot_abspath,
2719251881Speter                                             info2->wc_info->checksum,
2720251881Speter                                             pool, pool));
2721251881Speter
2722251881Speter      info->checksum = svn_checksum_to_cstring(md5_checksum, pool);
2723251881Speter    }
2724251881Speter
2725251881Speter  *new_info = info;
2726251881Speter  return SVN_NO_ERROR;
2727251881Speter}
2728251881Speter
2729251881Speterstruct info_to_relpath_baton
2730251881Speter{
2731251881Speter  const char *anchor_abspath;
2732251881Speter  const char *anchor_relpath;
2733251881Speter  svn_info_receiver_t info_receiver;
2734251881Speter  void *info_baton;
2735251881Speter  svn_wc_context_t *wc_ctx;
2736251881Speter};
2737251881Speter
2738251881Speterstatic svn_error_t *
2739251881Speterinfo_receiver_relpath_wrapper(void *baton,
2740251881Speter                              const char *abspath_or_url,
2741251881Speter                              const svn_client_info2_t *info2,
2742251881Speter                              apr_pool_t *scratch_pool)
2743251881Speter{
2744251881Speter  struct info_to_relpath_baton *rb = baton;
2745251881Speter  const char *path = abspath_or_url;
2746251881Speter  svn_info_t *info;
2747251881Speter
2748251881Speter  if (rb->anchor_relpath &&
2749251881Speter      svn_dirent_is_ancestor(rb->anchor_abspath, abspath_or_url))
2750251881Speter    {
2751251881Speter      path = svn_dirent_join(rb->anchor_relpath,
2752251881Speter                             svn_dirent_skip_ancestor(rb->anchor_abspath,
2753251881Speter                                                      abspath_or_url),
2754251881Speter                             scratch_pool);
2755251881Speter    }
2756251881Speter
2757251881Speter  SVN_ERR(info_from_info2(&info, rb->wc_ctx, info2, scratch_pool));
2758251881Speter
2759251881Speter  SVN_ERR(rb->info_receiver(rb->info_baton,
2760251881Speter                            path,
2761251881Speter                            info,
2762251881Speter                            scratch_pool));
2763251881Speter
2764251881Speter  return SVN_NO_ERROR;
2765251881Speter}
2766251881Speter
2767251881Spetersvn_error_t *
2768251881Spetersvn_client_info2(const char *path_or_url,
2769251881Speter                 const svn_opt_revision_t *peg_revision,
2770251881Speter                 const svn_opt_revision_t *revision,
2771251881Speter                 svn_info_receiver_t receiver,
2772251881Speter                 void *receiver_baton,
2773251881Speter                 svn_depth_t depth,
2774251881Speter                 const apr_array_header_t *changelists,
2775251881Speter                 svn_client_ctx_t *ctx,
2776251881Speter                 apr_pool_t *pool)
2777251881Speter{
2778251881Speter  struct info_to_relpath_baton rb;
2779251881Speter  const char *abspath_or_url = path_or_url;
2780251881Speter
2781251881Speter  rb.anchor_relpath = NULL;
2782251881Speter  rb.info_receiver = receiver;
2783251881Speter  rb.info_baton = receiver_baton;
2784251881Speter  rb.wc_ctx = ctx->wc_ctx;
2785251881Speter
2786251881Speter  if (!svn_path_is_url(path_or_url))
2787251881Speter    {
2788251881Speter      SVN_ERR(svn_dirent_get_absolute(&abspath_or_url, path_or_url, pool));
2789251881Speter      rb.anchor_abspath = abspath_or_url;
2790251881Speter      rb.anchor_relpath = path_or_url;
2791251881Speter    }
2792251881Speter
2793251881Speter  SVN_ERR(svn_client_info3(abspath_or_url,
2794251881Speter                           peg_revision,
2795251881Speter                           revision,
2796251881Speter                           depth,
2797251881Speter                           FALSE, TRUE,
2798251881Speter                           changelists,
2799251881Speter                           info_receiver_relpath_wrapper,
2800251881Speter                           &rb,
2801251881Speter                           ctx,
2802251881Speter                           pool));
2803251881Speter
2804251881Speter  return SVN_NO_ERROR;
2805251881Speter}
2806251881Speter
2807251881Spetersvn_error_t *
2808251881Spetersvn_client_info(const char *path_or_url,
2809251881Speter                const svn_opt_revision_t *peg_revision,
2810251881Speter                const svn_opt_revision_t *revision,
2811251881Speter                svn_info_receiver_t receiver,
2812251881Speter                void *receiver_baton,
2813251881Speter                svn_boolean_t recurse,
2814251881Speter                svn_client_ctx_t *ctx,
2815251881Speter                apr_pool_t *pool)
2816251881Speter{
2817251881Speter  return svn_client_info2(path_or_url, peg_revision, revision,
2818251881Speter                          receiver, receiver_baton,
2819251881Speter                          SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
2820251881Speter                          NULL, ctx, pool);
2821251881Speter}
2822251881Speter
2823251881Speter/*** From resolved.c ***/
2824251881Spetersvn_error_t *
2825251881Spetersvn_client_resolved(const char *path,
2826251881Speter                    svn_boolean_t recursive,
2827251881Speter                    svn_client_ctx_t *ctx,
2828251881Speter                    apr_pool_t *pool)
2829251881Speter{
2830251881Speter  svn_depth_t depth = SVN_DEPTH_INFINITY_OR_EMPTY(recursive);
2831251881Speter  return svn_client_resolve(path, depth,
2832251881Speter                            svn_wc_conflict_choose_merged, ctx, pool);
2833251881Speter}
2834251881Speter/*** From revert.c ***/
2835251881Spetersvn_error_t *
2836299742Sdimsvn_client_revert2(const apr_array_header_t *paths,
2837299742Sdim                   svn_depth_t depth,
2838299742Sdim                   const apr_array_header_t *changelists,
2839299742Sdim                   svn_client_ctx_t *ctx,
2840299742Sdim                   apr_pool_t *pool)
2841299742Sdim{
2842299742Sdim  return svn_error_trace(svn_client_revert3(paths,
2843299742Sdim                                            depth,
2844299742Sdim                                            changelists,
2845299742Sdim                                            FALSE /* clear_changelists */,
2846299742Sdim                                            FALSE /* metadata_only */,
2847299742Sdim                                            ctx,
2848299742Sdim                                            pool));
2849299742Sdim}
2850299742Sdim
2851299742Sdimsvn_error_t *
2852251881Spetersvn_client_revert(const apr_array_header_t *paths,
2853251881Speter                  svn_boolean_t recursive,
2854251881Speter                  svn_client_ctx_t *ctx,
2855251881Speter                  apr_pool_t *pool)
2856251881Speter{
2857251881Speter  return svn_client_revert2(paths, SVN_DEPTH_INFINITY_OR_EMPTY(recursive),
2858251881Speter                            NULL, ctx, pool);
2859251881Speter}
2860251881Speter
2861251881Speter/*** From ra.c ***/
2862251881Spetersvn_error_t *
2863251881Spetersvn_client_open_ra_session(svn_ra_session_t **session,
2864251881Speter                           const char *url,
2865251881Speter                           svn_client_ctx_t *ctx,
2866251881Speter                           apr_pool_t *pool)
2867251881Speter{
2868251881Speter  return svn_error_trace(
2869251881Speter             svn_client_open_ra_session2(session, url,
2870251881Speter                                         NULL, ctx,
2871251881Speter                                         pool, pool));
2872251881Speter}
2873251881Speter
2874251881Spetersvn_error_t *
2875251881Spetersvn_client_uuid_from_url(const char **uuid,
2876251881Speter                         const char *url,
2877251881Speter                         svn_client_ctx_t *ctx,
2878251881Speter                         apr_pool_t *pool)
2879251881Speter{
2880251881Speter  svn_error_t *err;
2881251881Speter  apr_pool_t *subpool = svn_pool_create(pool);
2882251881Speter
2883251881Speter  err = svn_client_get_repos_root(NULL, uuid, url,
2884251881Speter                                  ctx, pool, subpool);
2885251881Speter  /* destroy the RA session */
2886251881Speter  svn_pool_destroy(subpool);
2887251881Speter
2888299742Sdim  return svn_error_trace(err);
2889251881Speter}
2890251881Speter
2891251881Spetersvn_error_t *
2892251881Spetersvn_client_uuid_from_path2(const char **uuid,
2893251881Speter                           const char *local_abspath,
2894251881Speter                           svn_client_ctx_t *ctx,
2895251881Speter                           apr_pool_t *result_pool,
2896251881Speter                           apr_pool_t *scratch_pool)
2897251881Speter{
2898251881Speter  return svn_error_trace(
2899251881Speter      svn_client_get_repos_root(NULL, uuid,
2900251881Speter                                local_abspath, ctx,
2901251881Speter                                result_pool, scratch_pool));
2902251881Speter}
2903251881Speter
2904251881Spetersvn_error_t *
2905251881Spetersvn_client_uuid_from_path(const char **uuid,
2906251881Speter                          const char *path,
2907251881Speter                          svn_wc_adm_access_t *adm_access,
2908251881Speter                          svn_client_ctx_t *ctx,
2909251881Speter                          apr_pool_t *pool)
2910251881Speter{
2911251881Speter  const char *local_abspath;
2912251881Speter
2913251881Speter  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
2914251881Speter  return svn_error_trace(
2915251881Speter    svn_client_uuid_from_path2(uuid, local_abspath, ctx, pool, pool));
2916251881Speter}
2917251881Speter
2918251881Speter/*** From url.c ***/
2919251881Spetersvn_error_t *
2920251881Spetersvn_client_root_url_from_path(const char **url,
2921251881Speter                              const char *path_or_url,
2922251881Speter                              svn_client_ctx_t *ctx,
2923251881Speter                              apr_pool_t *pool)
2924251881Speter{
2925251881Speter  apr_pool_t *subpool = svn_pool_create(pool);
2926251881Speter  svn_error_t *err;
2927251881Speter  if (!svn_path_is_url(path_or_url))
2928251881Speter    SVN_ERR(svn_dirent_get_absolute(&path_or_url, path_or_url, pool));
2929251881Speter
2930251881Speter  err = svn_client_get_repos_root(url, NULL, path_or_url,
2931251881Speter                                  ctx, pool, subpool);
2932251881Speter
2933251881Speter  /* close ra session */
2934251881Speter  svn_pool_destroy(subpool);
2935251881Speter  return svn_error_trace(err);
2936251881Speter}
2937251881Speter
2938251881Spetersvn_error_t *
2939251881Spetersvn_client_url_from_path(const char **url,
2940251881Speter                         const char *path_or_url,
2941251881Speter                         apr_pool_t *pool)
2942251881Speter{
2943251881Speter  svn_client_ctx_t *ctx;
2944251881Speter
2945251881Speter  SVN_ERR(svn_client_create_context(&ctx, pool));
2946251881Speter
2947251881Speter  return svn_client_url_from_path2(url, path_or_url, ctx, pool, pool);
2948251881Speter}
2949251881Speter
2950251881Speter/*** From mergeinfo.c ***/
2951251881Spetersvn_error_t *
2952251881Spetersvn_client_mergeinfo_log(svn_boolean_t finding_merged,
2953251881Speter                         const char *target_path_or_url,
2954251881Speter                         const svn_opt_revision_t *target_peg_revision,
2955251881Speter                         const char *source_path_or_url,
2956251881Speter                         const svn_opt_revision_t *source_peg_revision,
2957251881Speter                         svn_log_entry_receiver_t receiver,
2958251881Speter                         void *receiver_baton,
2959251881Speter                         svn_boolean_t discover_changed_paths,
2960251881Speter                         svn_depth_t depth,
2961251881Speter                         const apr_array_header_t *revprops,
2962251881Speter                         svn_client_ctx_t *ctx,
2963251881Speter                         apr_pool_t *scratch_pool)
2964251881Speter{
2965251881Speter  svn_opt_revision_t start_revision, end_revision;
2966251881Speter
2967251881Speter  start_revision.kind = svn_opt_revision_unspecified;
2968251881Speter  end_revision.kind = svn_opt_revision_unspecified;
2969251881Speter
2970251881Speter  return svn_client_mergeinfo_log2(finding_merged,
2971251881Speter                                   target_path_or_url, target_peg_revision,
2972251881Speter                                   source_path_or_url, source_peg_revision,
2973251881Speter                                   &start_revision, &end_revision,
2974251881Speter                                   receiver, receiver_baton,
2975251881Speter                                   discover_changed_paths, depth, revprops,
2976251881Speter                                   ctx, scratch_pool);
2977251881Speter}
2978251881Speter
2979251881Spetersvn_error_t *
2980251881Spetersvn_client_mergeinfo_log_merged(const char *path_or_url,
2981251881Speter                                const svn_opt_revision_t *peg_revision,
2982251881Speter                                const char *merge_source_path_or_url,
2983251881Speter                                const svn_opt_revision_t *src_peg_revision,
2984251881Speter                                svn_log_entry_receiver_t log_receiver,
2985251881Speter                                void *log_receiver_baton,
2986251881Speter                                svn_boolean_t discover_changed_paths,
2987251881Speter                                const apr_array_header_t *revprops,
2988251881Speter                                svn_client_ctx_t *ctx,
2989251881Speter                                apr_pool_t *pool)
2990251881Speter{
2991251881Speter  return svn_client_mergeinfo_log(TRUE, path_or_url, peg_revision,
2992251881Speter                                  merge_source_path_or_url,
2993251881Speter                                  src_peg_revision,
2994251881Speter                                  log_receiver, log_receiver_baton,
2995251881Speter                                  discover_changed_paths,
2996251881Speter                                  svn_depth_empty, revprops, ctx,
2997251881Speter                                  pool);
2998251881Speter}
2999251881Speter
3000251881Spetersvn_error_t *
3001251881Spetersvn_client_mergeinfo_log_eligible(const char *path_or_url,
3002251881Speter                                  const svn_opt_revision_t *peg_revision,
3003251881Speter                                  const char *merge_source_path_or_url,
3004251881Speter                                  const svn_opt_revision_t *src_peg_revision,
3005251881Speter                                  svn_log_entry_receiver_t log_receiver,
3006251881Speter                                  void *log_receiver_baton,
3007251881Speter                                  svn_boolean_t discover_changed_paths,
3008251881Speter                                  const apr_array_header_t *revprops,
3009251881Speter                                  svn_client_ctx_t *ctx,
3010251881Speter                                  apr_pool_t *pool)
3011251881Speter{
3012251881Speter  return svn_client_mergeinfo_log(FALSE, path_or_url, peg_revision,
3013251881Speter                                  merge_source_path_or_url,
3014251881Speter                                  src_peg_revision,
3015251881Speter                                  log_receiver, log_receiver_baton,
3016251881Speter                                  discover_changed_paths,
3017251881Speter                                  svn_depth_empty, revprops, ctx,
3018251881Speter                                  pool);
3019251881Speter}
3020251881Speter
3021251881Speter/*** From relocate.c ***/
3022251881Spetersvn_error_t *
3023251881Spetersvn_client_relocate(const char *path,
3024251881Speter                    const char *from_prefix,
3025251881Speter                    const char *to_prefix,
3026251881Speter                    svn_boolean_t recurse,
3027251881Speter                    svn_client_ctx_t *ctx,
3028251881Speter                    apr_pool_t *pool)
3029251881Speter{
3030251881Speter  if (! recurse)
3031251881Speter    SVN_ERR(svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
3032251881Speter                             _("Non-recursive relocation not supported")));
3033251881Speter  return svn_client_relocate2(path, from_prefix, to_prefix, TRUE, ctx, pool);
3034251881Speter}
3035251881Speter
3036251881Speter/*** From util.c ***/
3037251881Spetersvn_error_t *
3038251881Spetersvn_client_commit_item_create(const svn_client_commit_item3_t **item,
3039251881Speter                              apr_pool_t *pool)
3040251881Speter{
3041251881Speter  *item = svn_client_commit_item3_create(pool);
3042251881Speter  return SVN_NO_ERROR;
3043251881Speter}
3044251881Speter
3045251881Spetersvn_client_commit_item2_t *
3046251881Spetersvn_client_commit_item2_dup(const svn_client_commit_item2_t *item,
3047251881Speter                            apr_pool_t *pool)
3048251881Speter{
3049251881Speter  svn_client_commit_item2_t *new_item = apr_palloc(pool, sizeof(*new_item));
3050251881Speter
3051251881Speter  *new_item = *item;
3052251881Speter
3053251881Speter  if (new_item->path)
3054251881Speter    new_item->path = apr_pstrdup(pool, new_item->path);
3055251881Speter
3056251881Speter  if (new_item->url)
3057251881Speter    new_item->url = apr_pstrdup(pool, new_item->url);
3058251881Speter
3059251881Speter  if (new_item->copyfrom_url)
3060251881Speter    new_item->copyfrom_url = apr_pstrdup(pool, new_item->copyfrom_url);
3061251881Speter
3062251881Speter  if (new_item->wcprop_changes)
3063251881Speter    new_item->wcprop_changes = svn_prop_array_dup(new_item->wcprop_changes,
3064251881Speter                                                  pool);
3065251881Speter
3066251881Speter  return new_item;
3067251881Speter}
3068251881Speter
3069299742Sdimsvn_error_t *
3070299742Sdimsvn_client_cleanup(const char *path,
3071299742Sdim                   svn_client_ctx_t *ctx,
3072299742Sdim                   apr_pool_t *scratch_pool)
3073299742Sdim{
3074299742Sdim  const char *local_abspath;
3075299742Sdim
3076299742Sdim  if (svn_path_is_url(path))
3077299742Sdim    return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
3078299742Sdim                             _("'%s' is not a local path"), path);
3079299742Sdim
3080299742Sdim  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
3081299742Sdim
3082299742Sdim  return svn_error_trace(svn_client_cleanup2(local_abspath,
3083299742Sdim                                             TRUE /* break_locks */,
3084299742Sdim                                             TRUE /* fix_recorded_timestamps */,
3085299742Sdim                                             TRUE /* clear_dav_cache */,
3086299742Sdim                                             TRUE /* vacuum_pristines */,
3087299742Sdim                                             FALSE /* include_externals */,
3088299742Sdim                                             ctx, scratch_pool));
3089299742Sdim}
3090