1193323Sed/*
2193323Sed * deprecated.c:  holding file for all deprecated APIs.
3193323Sed *                "we can't lose 'em, but we can shun 'em!"
4193323Sed *
5193323Sed * ====================================================================
6193323Sed *    Licensed to the Apache Software Foundation (ASF) under one
7193323Sed *    or more contributor license agreements.  See the NOTICE file
8193323Sed *    distributed with this work for additional information
9193323Sed *    regarding copyright ownership.  The ASF licenses this file
10193323Sed *    to you under the Apache License, Version 2.0 (the
11193323Sed *    "License"); you may not use this file except in compliance
12193323Sed *    with the License.  You may obtain a copy of the License at
13193323Sed *
14193323Sed *      http://www.apache.org/licenses/LICENSE-2.0
15193323Sed *
16198090Srdivacky *    Unless required by applicable law or agreed to in writing,
17193323Sed *    software distributed under the License is distributed on an
18193323Sed *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19193323Sed *    KIND, either express or implied.  See the License for the
20193323Sed *    specific language governing permissions and limitations
21193323Sed *    under the License.
22193323Sed * ====================================================================
23193323Sed */
24193323Sed
25193323Sed/* ==================================================================== */
26193323Sed
27193323Sed
28193323Sed
29193323Sed/*** Includes. ***/
30193323Sed
31193323Sed/* We define this here to remove any further warnings about the usage of
32193323Sed   deprecated functions in this file. */
33198396Srdivacky#define SVN_DEPRECATED
34193323Sed
35193323Sed#include <string.h>
36198090Srdivacky#include "svn_client.h"
37195098Sed#include "svn_path.h"
38193323Sed#include "svn_compat.h"
39193323Sed#include "svn_hash.h"
40195098Sed#include "svn_props.h"
41193323Sed#include "svn_utf.h"
42193323Sed#include "svn_string.h"
43193323Sed#include "svn_pools.h"
44193323Sed
45193323Sed#include "client.h"
46193323Sed#include "mergeinfo.h"
47193323Sed
48193323Sed#include "private/svn_opt_private.h"
49193323Sed#include "private/svn_wc_private.h"
50193323Sed#include "svn_private_config.h"
51193323Sed
52198090Srdivacky
53193323Sed
54193323Sed
55193323Sed/*** Code. ***/
56193323Sed
57198090Srdivacky
58198090Srdivacky/* Baton for capture_commit_info() */
59198090Srdivackystruct capture_baton_t {
60193323Sed  svn_commit_info_t **info;
61193323Sed  apr_pool_t *pool;
62193323Sed};
63193323Sed
64193323Sed
65193323Sed/* Callback which implements svn_commit_callback2_t for use with some
66193323Sed   backward compat functions. */
67193323Sedstatic svn_error_t *
68193323Sedcapture_commit_info(const svn_commit_info_t *commit_info,
69193323Sed                    void *baton,
70193323Sed                    apr_pool_t *pool)
71193323Sed{
72193323Sed  struct capture_baton_t *cb = baton;
73193323Sed
74193323Sed  *(cb->info) = svn_commit_info_dup(commit_info, cb->pool);
75193323Sed
76193323Sed  return SVN_NO_ERROR;
77193323Sed}
78193323Sed
79193323Sed
80193323Sed/*** From add.c ***/
81193323Sedsvn_error_t *
82198090Srdivackysvn_client_add4(const char *path,
83193323Sed                svn_depth_t depth,
84193323Sed                svn_boolean_t force,
85193323Sed                svn_boolean_t no_ignore,
86193323Sed                svn_boolean_t add_parents,
87193323Sed                svn_client_ctx_t *ctx,
88193323Sed                apr_pool_t *pool)
89193323Sed{
90193323Sed  return svn_client_add5(path, depth, force, no_ignore, FALSE, add_parents,
91193323Sed                         ctx, pool);
92193323Sed}
93193323Sed
94198090Srdivackysvn_error_t *
95193323Sedsvn_client_add3(const char *path,
96193323Sed                svn_boolean_t recursive,
97193323Sed                svn_boolean_t force,
98193323Sed                svn_boolean_t no_ignore,
99193323Sed                svn_client_ctx_t *ctx,
100193323Sed                apr_pool_t *pool)
101193323Sed{
102193323Sed  return svn_client_add4(path, SVN_DEPTH_INFINITY_OR_EMPTY(recursive),
103193323Sed                         force, no_ignore, FALSE, ctx,
104193323Sed                         pool);
105193323Sed}
106193323Sed
107193323Sedsvn_error_t *
108193323Sedsvn_client_add2(const char *path,
109193323Sed                svn_boolean_t recursive,
110193323Sed                svn_boolean_t force,
111193323Sed                svn_client_ctx_t *ctx,
112193323Sed                apr_pool_t *pool)
113193323Sed{
114193323Sed  return svn_client_add3(path, recursive, force, FALSE, ctx, pool);
115193323Sed}
116193323Sed
117193323Sedsvn_error_t *
118193323Sedsvn_client_add(const char *path,
119193323Sed               svn_boolean_t recursive,
120193323Sed               svn_client_ctx_t *ctx,
121193323Sed               apr_pool_t *pool)
122193323Sed{
123193323Sed  return svn_client_add3(path, recursive, FALSE, FALSE, ctx, pool);
124193323Sed}
125193323Sed
126193323Sedsvn_error_t *
127193323Sedsvn_client_mkdir3(svn_commit_info_t **commit_info_p,
128193323Sed                  const apr_array_header_t *paths,
129193323Sed                  svn_boolean_t make_parents,
130193323Sed                  const apr_hash_t *revprop_table,
131193323Sed                  svn_client_ctx_t *ctx,
132193323Sed                  apr_pool_t *pool)
133193323Sed{
134193323Sed  struct capture_baton_t cb;
135193323Sed
136193323Sed  cb.info = commit_info_p;
137193323Sed  cb.pool = pool;
138193323Sed
139193323Sed  return svn_client_mkdir4(paths, make_parents, revprop_table,
140193323Sed                           capture_commit_info, &cb, ctx, pool);
141193323Sed}
142193323Sed
143193323Sedsvn_error_t *
144193323Sedsvn_client_mkdir2(svn_commit_info_t **commit_info_p,
145193323Sed                  const apr_array_header_t *paths,
146193323Sed                  svn_client_ctx_t *ctx,
147193323Sed                  apr_pool_t *pool)
148193323Sed{
149193323Sed  return svn_client_mkdir3(commit_info_p, paths, FALSE, NULL, ctx, pool);
150193323Sed}
151193323Sed
152193323Sed
153193323Sedsvn_error_t *
154193323Sedsvn_client_mkdir(svn_client_commit_info_t **commit_info_p,
155193323Sed                 const apr_array_header_t *paths,
156193323Sed                 svn_client_ctx_t *ctx,
157193323Sed                 apr_pool_t *pool)
158193323Sed{
159193323Sed  svn_commit_info_t *commit_info = NULL;
160193323Sed  svn_error_t *err;
161193323Sed
162193574Sed  err = svn_client_mkdir2(&commit_info, paths, ctx, pool);
163193323Sed  /* These structs have the same layout for the common fields. */
164193323Sed  *commit_info_p = (svn_client_commit_info_t *) commit_info;
165193323Sed  return svn_error_trace(err);
166193323Sed}
167193323Sed
168193323Sed/*** From blame.c ***/
169193323Sed
170193323Sedstruct blame_receiver_wrapper_baton2 {
171193323Sed  void *baton;
172193323Sed  svn_client_blame_receiver2_t receiver;
173193323Sed};
174193574Sed
175193323Sedstatic svn_error_t *
176193323Sedblame_wrapper_receiver2(void *baton,
177193323Sed   svn_revnum_t start_revnum,
178193323Sed   svn_revnum_t end_revnum,
179193323Sed   apr_int64_t line_no,
180193323Sed   svn_revnum_t revision,
181193323Sed   apr_hash_t *rev_props,
182193323Sed   svn_revnum_t merged_revision,
183193323Sed   apr_hash_t *merged_rev_props,
184193323Sed   const char *merged_path,
185193323Sed   const char *line,
186193323Sed   svn_boolean_t local_change,
187193323Sed   apr_pool_t *pool)
188193323Sed{
189193323Sed  struct blame_receiver_wrapper_baton2 *brwb = baton;
190193323Sed  const char *author = NULL;
191193323Sed  const char *date = NULL;
192193323Sed  const char *merged_author = NULL;
193193323Sed  const char *merged_date = NULL;
194193323Sed
195193323Sed  if (rev_props != NULL)
196193323Sed    {
197193323Sed      author = svn_prop_get_value(rev_props, SVN_PROP_REVISION_AUTHOR);
198193323Sed      date = svn_prop_get_value(rev_props, SVN_PROP_REVISION_DATE);
199193323Sed    }
200193323Sed  if (merged_rev_props != NULL)
201193323Sed    {
202193323Sed      merged_author = svn_prop_get_value(merged_rev_props,
203193323Sed                                         SVN_PROP_REVISION_AUTHOR);
204193323Sed      merged_date = svn_prop_get_value(merged_rev_props,
205193323Sed                                       SVN_PROP_REVISION_DATE);
206193323Sed    }
207193323Sed
208193323Sed  if (brwb->receiver)
209193323Sed    return brwb->receiver(brwb->baton, line_no, revision, author, date,
210193323Sed                          merged_revision, merged_author, merged_date,
211193323Sed                          merged_path, line, pool);
212193323Sed
213193323Sed  return SVN_NO_ERROR;
214193323Sed}
215193323Sed
216193323Sedsvn_error_t *
217193323Sedsvn_client_blame4(const char *target,
218193323Sed                  const svn_opt_revision_t *peg_revision,
219193323Sed                  const svn_opt_revision_t *start,
220193323Sed                  const svn_opt_revision_t *end,
221193323Sed                  const svn_diff_file_options_t *diff_options,
222193323Sed                  svn_boolean_t ignore_mime_type,
223193323Sed                  svn_boolean_t include_merged_revisions,
224193323Sed                  svn_client_blame_receiver2_t receiver,
225193323Sed                  void *receiver_baton,
226193323Sed                  svn_client_ctx_t *ctx,
227193323Sed                  apr_pool_t *pool)
228193323Sed{
229193323Sed  struct blame_receiver_wrapper_baton2 baton;
230193323Sed
231193323Sed  baton.receiver = receiver;
232193323Sed  baton.baton = receiver_baton;
233193323Sed
234193323Sed  return svn_client_blame5(target, peg_revision, start, end, diff_options,
235193323Sed                           ignore_mime_type, include_merged_revisions,
236193323Sed                           blame_wrapper_receiver2, &baton, ctx, pool);
237193323Sed}
238193323Sed
239193323Sed
240193323Sed/* Baton for use with wrap_blame_receiver */
241193323Sedstruct blame_receiver_wrapper_baton {
242193323Sed  void *baton;
243193323Sed  svn_client_blame_receiver_t receiver;
244193323Sed};
245193323Sed
246193323Sed/* This implements svn_client_blame_receiver2_t */
247193323Sedstatic svn_error_t *
248193323Sedblame_wrapper_receiver(void *baton,
249198090Srdivacky                       apr_int64_t line_no,
250193323Sed                       svn_revnum_t revision,
251193323Sed                       const char *author,
252193323Sed                       const char *date,
253193323Sed                       svn_revnum_t merged_revision,
254193323Sed                       const char *merged_author,
255193323Sed                       const char *merged_date,
256193323Sed                       const char *merged_path,
257193323Sed                       const char *line,
258193323Sed                       apr_pool_t *pool)
259193323Sed{
260193323Sed  struct blame_receiver_wrapper_baton *brwb = baton;
261193323Sed
262193323Sed  if (brwb->receiver)
263193323Sed    return brwb->receiver(brwb->baton,
264193323Sed                          line_no, revision, author, date, line, pool);
265193323Sed
266193323Sed  return SVN_NO_ERROR;
267193323Sed}
268193323Sed
269193323Sedstatic void
270193323Sedwrap_blame_receiver(svn_client_blame_receiver2_t *receiver2,
271193323Sed                    void **receiver2_baton,
272193323Sed                    svn_client_blame_receiver_t receiver,
273193323Sed                    void *receiver_baton,
274193323Sed                    apr_pool_t *pool)
275193323Sed{
276193323Sed  struct blame_receiver_wrapper_baton *brwb = apr_palloc(pool, sizeof(*brwb));
277193323Sed
278193323Sed  /* Set the user provided old format callback in the baton. */
279193323Sed  brwb->baton = receiver_baton;
280193323Sed  brwb->receiver = receiver;
281193323Sed
282193323Sed  *receiver2_baton = brwb;
283193323Sed  *receiver2 = blame_wrapper_receiver;
284193323Sed}
285193323Sed
286193323Sedsvn_error_t *
287193323Sedsvn_client_blame3(const char *target,
288193323Sed                  const svn_opt_revision_t *peg_revision,
289193323Sed                  const svn_opt_revision_t *start,
290193323Sed                  const svn_opt_revision_t *end,
291193323Sed                  const svn_diff_file_options_t *diff_options,
292193323Sed                  svn_boolean_t ignore_mime_type,
293193323Sed                  svn_client_blame_receiver_t receiver,
294193323Sed                  void *receiver_baton,
295193323Sed                  svn_client_ctx_t *ctx,
296193323Sed                  apr_pool_t *pool)
297193323Sed{
298193323Sed  svn_client_blame_receiver2_t receiver2;
299193323Sed  void *receiver2_baton;
300193323Sed
301193323Sed  wrap_blame_receiver(&receiver2, &receiver2_baton, receiver, receiver_baton,
302193323Sed                      pool);
303193323Sed
304193323Sed  return svn_client_blame4(target, peg_revision, start, end, diff_options,
305193323Sed                           ignore_mime_type, FALSE, receiver2, receiver2_baton,
306193323Sed                           ctx, pool);
307193323Sed}
308193323Sed
309193323Sed/* svn_client_blame3 guarantees 'no EOL chars' as part of the receiver
310193323Sed   LINE argument.  Older versions depend on the fact that if a CR is
311193323Sed   required, that CR is already part of the LINE data.
312193323Sed
313193323Sed   Because of this difference, we need to trap old receivers and append
314193323Sed   a CR to LINE before passing it on to the actual receiver on platforms
315193323Sed   which want CRLF line termination.
316193323Sed
317193323Sed*/
318193323Sed
319193323Sedstruct wrapped_receiver_baton_s
320193323Sed{
321193323Sed  svn_client_blame_receiver_t orig_receiver;
322193323Sed  void *orig_baton;
323193323Sed};
324193323Sed
325193323Sedstatic svn_error_t *
326193323Sedwrapped_receiver(void *baton,
327193323Sed                 apr_int64_t line_no,
328193323Sed                 svn_revnum_t revision,
329193323Sed                 const char *author,
330193323Sed                 const char *date,
331193323Sed                 const char *line,
332193323Sed                 apr_pool_t *pool)
333193323Sed{
334193323Sed  struct wrapped_receiver_baton_s *b = baton;
335193323Sed  svn_stringbuf_t *expanded_line = svn_stringbuf_create(line, pool);
336193323Sed
337193323Sed  svn_stringbuf_appendbyte(expanded_line, '\r');
338193323Sed
339193323Sed  return b->orig_receiver(b->orig_baton, line_no, revision, author,
340193323Sed                          date, expanded_line->data, pool);
341193323Sed}
342193323Sed
343193323Sedstatic void
344193323Sedwrap_pre_blame3_receiver(svn_client_blame_receiver_t *receiver,
345193323Sed                         void **receiver_baton,
346193323Sed                         apr_pool_t *pool)
347193323Sed{
348193323Sed  if (sizeof(APR_EOL_STR) == 3)
349193323Sed    {
350193323Sed      struct wrapped_receiver_baton_s *b = apr_palloc(pool,sizeof(*b));
351193323Sed
352193323Sed      b->orig_receiver = *receiver;
353193323Sed      b->orig_baton = *receiver_baton;
354193323Sed
355193323Sed      *receiver_baton = b;
356193323Sed      *receiver = wrapped_receiver;
357193323Sed    }
358193323Sed}
359193323Sed
360193323Sedsvn_error_t *
361193323Sedsvn_client_blame2(const char *target,
362193323Sed                  const svn_opt_revision_t *peg_revision,
363193323Sed                  const svn_opt_revision_t *start,
364193323Sed                  const svn_opt_revision_t *end,
365193323Sed                  svn_client_blame_receiver_t receiver,
366193323Sed                  void *receiver_baton,
367195098Sed                  svn_client_ctx_t *ctx,
368195098Sed                  apr_pool_t *pool)
369198090Srdivacky{
370193323Sed  wrap_pre_blame3_receiver(&receiver, &receiver_baton, pool);
371193323Sed  return svn_client_blame3(target, peg_revision, start, end,
372193323Sed                           svn_diff_file_options_create(pool), FALSE,
373193323Sed                           receiver, receiver_baton, ctx, pool);
374193323Sed}
375193323Sedsvn_error_t *
376193323Sedsvn_client_blame(const char *target,
377193323Sed                 const svn_opt_revision_t *start,
378193323Sed                 const svn_opt_revision_t *end,
379193323Sed                 svn_client_blame_receiver_t receiver,
380193323Sed                 void *receiver_baton,
381193323Sed                 svn_client_ctx_t *ctx,
382193323Sed                 apr_pool_t *pool)
383193323Sed{
384193323Sed  wrap_pre_blame3_receiver(&receiver, &receiver_baton, pool);
385193323Sed  return svn_client_blame2(target, end, start, end,
386193323Sed                           receiver, receiver_baton, ctx, pool);
387195098Sed}
388193323Sed
389193323Sed/*** From cmdline.c ***/
390193323Sedsvn_error_t *
391193323Sedsvn_client_args_to_target_array(apr_array_header_t **targets_p,
392193323Sed                                apr_getopt_t *os,
393193323Sed                                const apr_array_header_t *known_targets,
394193323Sed                                svn_client_ctx_t *ctx,
395193323Sed                                apr_pool_t *pool)
396193323Sed{
397193323Sed  return svn_client_args_to_target_array2(targets_p, os, known_targets, ctx,
398193323Sed                                          FALSE, pool);
399193323Sed}
400193323Sed
401193323Sed/*** From commit.c ***/
402193323Sedsvn_error_t *
403193323Sedsvn_client_import4(const char *path,
404193323Sed                   const char *url,
405193323Sed                   svn_depth_t depth,
406193323Sed                   svn_boolean_t no_ignore,
407193323Sed                   svn_boolean_t ignore_unknown_node_types,
408193323Sed                   const apr_hash_t *revprop_table,
409193323Sed                   svn_commit_callback2_t commit_callback,
410193323Sed                   void *commit_baton,
411193323Sed                   svn_client_ctx_t *ctx,
412193323Sed                   apr_pool_t *pool)
413195098Sed{
414193323Sed  return svn_error_trace(svn_client_import5(path, url, depth, no_ignore,
415193323Sed                                            FALSE, ignore_unknown_node_types,
416193323Sed                                            revprop_table,
417193323Sed                                            NULL, NULL,
418193323Sed                                            commit_callback, commit_baton,
419193323Sed                                            ctx, pool));
420193323Sed}
421193323Sed
422193323Sed
423193323Sedsvn_error_t *
424195098Sedsvn_client_import3(svn_commit_info_t **commit_info_p,
425193323Sed                   const char *path,
426193323Sed                   const char *url,
427193323Sed                   svn_depth_t depth,
428193323Sed                   svn_boolean_t no_ignore,
429193323Sed                   svn_boolean_t ignore_unknown_node_types,
430193323Sed                   const apr_hash_t *revprop_table,
431193323Sed                   svn_client_ctx_t *ctx,
432193323Sed                   apr_pool_t *pool)
433193323Sed{
434193323Sed  struct capture_baton_t cb;
435193323Sed
436193323Sed  cb.info = commit_info_p;
437193323Sed  cb.pool = pool;
438193323Sed
439193323Sed  return svn_client_import4(path, url, depth, no_ignore,
440193323Sed                            ignore_unknown_node_types, revprop_table,
441193323Sed                            capture_commit_info, &cb, ctx, pool);
442193323Sed}
443193323Sed
444193323Sedsvn_error_t *
445193323Sedsvn_client_import2(svn_commit_info_t **commit_info_p,
446193323Sed                   const char *path,
447193323Sed                   const char *url,
448193323Sed                   svn_boolean_t nonrecursive,
449193323Sed                   svn_boolean_t no_ignore,
450193323Sed                   svn_client_ctx_t *ctx,
451193323Sed                   apr_pool_t *pool)
452193323Sed{
453193323Sed  return svn_client_import3(commit_info_p,
454193323Sed                            path, url,
455193323Sed                            SVN_DEPTH_INFINITY_OR_FILES(! nonrecursive),
456193323Sed                            no_ignore, FALSE, NULL, ctx, pool);
457193323Sed}
458198090Srdivacky
459193323Sedsvn_error_t *
460193323Sedsvn_client_import(svn_client_commit_info_t **commit_info_p,
461193323Sed                  const char *path,
462193323Sed                  const char *url,
463198892Srdivacky                  svn_boolean_t nonrecursive,
464198892Srdivacky                  svn_client_ctx_t *ctx,
465198892Srdivacky                  apr_pool_t *pool)
466198892Srdivacky{
467198892Srdivacky  svn_commit_info_t *commit_info = NULL;
468193323Sed  svn_error_t *err;
469193323Sed
470193323Sed  err = svn_client_import2(&commit_info,
471193323Sed                           path, url, nonrecursive,
472193323Sed                           FALSE, ctx, pool);
473193323Sed  /* These structs have the same layout for the common fields. */
474193323Sed  *commit_info_p = (svn_client_commit_info_t *) commit_info;
475193323Sed  return svn_error_trace(err);
476193323Sed}
477193323Sed
478193323Sed
479193323Sed/* Wrapper notify_func2 function and baton for downgrading
480193323Sed   svn_wc_notify_commit_copied and svn_wc_notify_commit_copied_replaced
481193323Sed   to svn_wc_notify_commit_added and svn_wc_notify_commit_replaced,
482193323Sed   respectively. */
483193323Sedstruct downgrade_commit_copied_notify_baton
484193323Sed{
485198090Srdivacky  svn_wc_notify_func2_t orig_notify_func2;
486193323Sed  void *orig_notify_baton2;
487193323Sed};
488193323Sed
489198090Srdivackystatic void
490193323Seddowngrade_commit_copied_notify_func(void *baton,
491193323Sed                                    const svn_wc_notify_t *notify,
492193323Sed                                    apr_pool_t *pool)
493193323Sed{
494193323Sed  struct downgrade_commit_copied_notify_baton *b = baton;
495193323Sed
496198090Srdivacky  if (notify->action == svn_wc_notify_commit_copied)
497193323Sed    {
498193323Sed      svn_wc_notify_t *my_notify = svn_wc_dup_notify(notify, pool);
499193323Sed      my_notify->action = svn_wc_notify_commit_added;
500193323Sed      notify = my_notify;
501193323Sed    }
502193323Sed  else if (notify->action == svn_wc_notify_commit_copied_replaced)
503193323Sed    {
504193323Sed      svn_wc_notify_t *my_notify = svn_wc_dup_notify(notify, pool);
505193323Sed      my_notify->action = svn_wc_notify_commit_replaced;
506193323Sed      notify = my_notify;
507193323Sed    }
508193323Sed
509193323Sed  /* Call the wrapped notification system (if any) with MY_NOTIFY,
510193323Sed     which is either the original NOTIFY object, or a tweaked deep
511193323Sed     copy thereof. */
512193323Sed  if (b->orig_notify_func2)
513193323Sed    b->orig_notify_func2(b->orig_notify_baton2, notify, pool);
514193323Sed}
515193323Sed
516193323Sedsvn_error_t *
517193323Sedsvn_client_commit5(const apr_array_header_t *targets,
518193323Sed                   svn_depth_t depth,
519193323Sed                   svn_boolean_t keep_locks,
520193323Sed                   svn_boolean_t keep_changelists,
521193323Sed                   svn_boolean_t commit_as_operations,
522193323Sed                   const apr_array_header_t *changelists,
523193323Sed                   const apr_hash_t *revprop_table,
524193323Sed                   svn_commit_callback2_t commit_callback,
525193323Sed                   void *commit_baton,
526193323Sed                   svn_client_ctx_t *ctx,
527193323Sed                   apr_pool_t *pool)
528193323Sed{
529193323Sed  return svn_client_commit6(targets, depth, keep_locks, keep_changelists,
530193323Sed                            commit_as_operations,
531193323Sed                            FALSE,  /* include_file_externals */
532193323Sed                            FALSE, /* include_dir_externals */
533193323Sed                            changelists, revprop_table, commit_callback,
534193323Sed                            commit_baton, ctx, pool);
535193323Sed}
536193323Sed
537193323Sedsvn_error_t *
538193323Sedsvn_client_commit4(svn_commit_info_t **commit_info_p,
539193323Sed                   const apr_array_header_t *targets,
540193323Sed                   svn_depth_t depth,
541193323Sed                   svn_boolean_t keep_locks,
542193323Sed                   svn_boolean_t keep_changelists,
543193323Sed                   const apr_array_header_t *changelists,
544193323Sed                   const apr_hash_t *revprop_table,
545193323Sed                   svn_client_ctx_t *ctx,
546193323Sed                   apr_pool_t *pool)
547193323Sed{
548193323Sed  struct capture_baton_t cb;
549193323Sed  struct downgrade_commit_copied_notify_baton notify_baton;
550193323Sed  svn_error_t *err;
551193323Sed
552193323Sed  notify_baton.orig_notify_func2 = ctx->notify_func2;
553193323Sed  notify_baton.orig_notify_baton2 = ctx->notify_baton2;
554193323Sed
555193323Sed  *commit_info_p = NULL;
556193323Sed  cb.info = commit_info_p;
557193323Sed  cb.pool = pool;
558193323Sed
559193323Sed  /* Swap out the notification system (if any) with a thin filtering
560193323Sed     wrapper. */
561193323Sed  if (ctx->notify_func2)
562193323Sed    {
563193323Sed      ctx->notify_func2 = downgrade_commit_copied_notify_func;
564193323Sed      ctx->notify_baton2 = &notify_baton;
565193323Sed    }
566193323Sed
567193323Sed  err = svn_client_commit5(targets, depth, keep_locks, keep_changelists, FALSE,
568193323Sed                           changelists, revprop_table,
569193323Sed                           capture_commit_info, &cb, ctx, pool);
570193323Sed
571193323Sed  /* Ensure that the original notification system is in place. */
572193323Sed  ctx->notify_func2 = notify_baton.orig_notify_func2;
573193323Sed  ctx->notify_baton2 = notify_baton.orig_notify_baton2;
574193323Sed
575193323Sed  SVN_ERR(err);
576193323Sed
577193323Sed  if (! *commit_info_p)
578193323Sed    *commit_info_p = svn_create_commit_info(pool);
579193323Sed
580193323Sed  return SVN_NO_ERROR;
581193323Sed}
582193323Sed
583193323Sedsvn_error_t *
584193323Sedsvn_client_commit3(svn_commit_info_t **commit_info_p,
585193323Sed                   const apr_array_header_t *targets,
586193323Sed                   svn_boolean_t recurse,
587193323Sed                   svn_boolean_t keep_locks,
588193323Sed                   svn_client_ctx_t *ctx,
589193323Sed                   apr_pool_t *pool)
590193323Sed{
591193323Sed  svn_depth_t depth = SVN_DEPTH_INFINITY_OR_EMPTY(recurse);
592193323Sed
593193323Sed  return svn_client_commit4(commit_info_p, targets, depth, keep_locks,
594193323Sed                            FALSE, NULL, NULL, ctx, pool);
595193323Sed}
596193323Sed
597193323Sedsvn_error_t *
598193323Sedsvn_client_commit2(svn_client_commit_info_t **commit_info_p,
599193323Sed                   const apr_array_header_t *targets,
600193323Sed                   svn_boolean_t recurse,
601193323Sed                   svn_boolean_t keep_locks,
602193323Sed                   svn_client_ctx_t *ctx,
603193323Sed                   apr_pool_t *pool)
604193323Sed{
605193323Sed  svn_commit_info_t *commit_info = NULL;
606193323Sed  svn_error_t *err;
607193323Sed
608193323Sed  err = svn_client_commit3(&commit_info, targets, recurse, keep_locks,
609193323Sed                           ctx, pool);
610193323Sed  /* These structs have the same layout for the common fields. */
611193323Sed  *commit_info_p = (svn_client_commit_info_t *) commit_info;
612193323Sed  return svn_error_trace(err);
613193323Sed}
614193323Sed
615193323Sedsvn_error_t *
616193323Sedsvn_client_commit(svn_client_commit_info_t **commit_info_p,
617193323Sed                  const apr_array_header_t *targets,
618193323Sed                  svn_boolean_t nonrecursive,
619193323Sed                  svn_client_ctx_t *ctx,
620198090Srdivacky                  apr_pool_t *pool)
621193323Sed{
622193323Sed  return svn_client_commit2(commit_info_p, targets,
623193323Sed                            ! nonrecursive,
624193323Sed                            TRUE,
625193323Sed                            ctx, pool);
626193323Sed}
627193323Sed
628193323Sed/*** From copy.c ***/
629193323Sedsvn_error_t *
630193323Sedsvn_client_copy5(svn_commit_info_t **commit_info_p,
631193323Sed                 const apr_array_header_t *sources,
632195098Sed                 const char *dst_path,
633195098Sed                 svn_boolean_t copy_as_child,
634195098Sed                 svn_boolean_t make_parents,
635195098Sed                 svn_boolean_t ignore_externals,
636195098Sed                 const apr_hash_t *revprop_table,
637193323Sed                 svn_client_ctx_t *ctx,
638195098Sed                 apr_pool_t *pool)
639193323Sed{
640198090Srdivacky  struct capture_baton_t cb;
641193323Sed
642193323Sed  cb.info = commit_info_p;
643193323Sed  cb.pool = pool;
644198090Srdivacky
645198090Srdivacky  return svn_client_copy6(sources, dst_path, copy_as_child, make_parents,
646193323Sed                          ignore_externals, revprop_table,
647193323Sed                          capture_commit_info, &cb, ctx, pool);
648193323Sed}
649193323Sed
650193323Sedsvn_error_t *
651193323Sedsvn_client_copy4(svn_commit_info_t **commit_info_p,
652193323Sed                 const apr_array_header_t *sources,
653193323Sed                 const char *dst_path,
654193323Sed                 svn_boolean_t copy_as_child,
655193323Sed                 svn_boolean_t make_parents,
656193323Sed                 const apr_hash_t *revprop_table,
657193323Sed                 svn_client_ctx_t *ctx,
658193323Sed                 apr_pool_t *pool)
659193323Sed{
660193323Sed  return svn_client_copy5(commit_info_p, sources, dst_path, copy_as_child,
661198090Srdivacky                          make_parents, FALSE, revprop_table, ctx, pool);
662198090Srdivacky}
663193323Sed
664193323Sedsvn_error_t *
665193323Sedsvn_client_copy3(svn_commit_info_t **commit_info_p,
666193323Sed                 const char *src_path,
667193323Sed                 const svn_opt_revision_t *src_revision,
668193323Sed                 const char *dst_path,
669193323Sed                 svn_client_ctx_t *ctx,
670193323Sed                 apr_pool_t *pool)
671193323Sed{
672193323Sed  apr_array_header_t *sources = apr_array_make(pool, 1,
673193323Sed                                  sizeof(const svn_client_copy_source_t *));
674193323Sed  svn_client_copy_source_t copy_source;
675193323Sed
676193323Sed  copy_source.path = src_path;
677193323Sed  copy_source.revision = src_revision;
678193323Sed  copy_source.peg_revision = src_revision;
679193323Sed
680193323Sed  APR_ARRAY_PUSH(sources, const svn_client_copy_source_t *) = &copy_source;
681193323Sed
682193323Sed  return svn_client_copy4(commit_info_p, sources, dst_path, FALSE, FALSE,
683193323Sed                          NULL, ctx, pool);
684193323Sed}
685193323Sed
686193323Sedsvn_error_t *
687193323Sedsvn_client_copy2(svn_commit_info_t **commit_info_p,
688193323Sed                 const char *src_path,
689193323Sed                 const svn_opt_revision_t *src_revision,
690193323Sed                 const char *dst_path,
691193323Sed                 svn_client_ctx_t *ctx,
692193323Sed                 apr_pool_t *pool)
693193323Sed{
694193323Sed  svn_error_t *err;
695193323Sed
696193323Sed  err = svn_client_copy3(commit_info_p, src_path, src_revision,
697193323Sed                         dst_path, ctx, pool);
698193323Sed
699193323Sed  /* If the target exists, try to copy the source as a child of the target.
700193323Sed     This will obviously fail if target is not a directory, but that's exactly
701193323Sed     what we want. */
702193323Sed  if (err && (err->apr_err == SVN_ERR_ENTRY_EXISTS
703193323Sed              || err->apr_err == SVN_ERR_FS_ALREADY_EXISTS))
704193323Sed    {
705193323Sed      const char *src_basename = svn_path_basename(src_path, pool);
706193323Sed
707193323Sed      svn_error_clear(err);
708193323Sed
709193323Sed      return svn_client_copy3(commit_info_p, src_path, src_revision,
710193323Sed                              svn_path_join(dst_path, src_basename, pool),
711193323Sed                              ctx, pool);
712193323Sed    }
713193323Sed
714193323Sed  return svn_error_trace(err);
715193323Sed}
716193323Sed
717193323Sedsvn_error_t *
718193323Sedsvn_client_copy(svn_client_commit_info_t **commit_info_p,
719193323Sed                const char *src_path,
720193323Sed                const svn_opt_revision_t *src_revision,
721193323Sed                const char *dst_path,
722193323Sed                svn_client_ctx_t *ctx,
723193323Sed                apr_pool_t *pool)
724193323Sed{
725193323Sed  svn_commit_info_t *commit_info = NULL;
726193323Sed  svn_error_t *err;
727193323Sed
728193323Sed  err = svn_client_copy2(&commit_info, src_path, src_revision, dst_path,
729193323Sed                         ctx, pool);
730193323Sed  /* These structs have the same layout for the common fields. */
731193323Sed  *commit_info_p = (svn_client_commit_info_t *) commit_info;
732193323Sed  return svn_error_trace(err);
733193323Sed}
734193323Sed
735193323Sedsvn_error_t *
736193323Sedsvn_client_move6(const apr_array_header_t *src_paths,
737193323Sed                 const char *dst_path,
738193323Sed                 svn_boolean_t move_as_child,
739193323Sed                 svn_boolean_t make_parents,
740193323Sed                 const apr_hash_t *revprop_table,
741193323Sed                 svn_commit_callback2_t commit_callback,
742193323Sed                 void *commit_baton,
743193323Sed                 svn_client_ctx_t *ctx,
744193323Sed                 apr_pool_t *pool)
745193323Sed{
746193323Sed  return svn_error_trace(svn_client_move7(src_paths, dst_path,
747193323Sed                                          move_as_child, make_parents,
748193323Sed                                          TRUE /* allow_mixed_revisions */,
749193323Sed                                          FALSE /* metadata_only */,
750193323Sed                                          revprop_table,
751193323Sed                                          commit_callback, commit_baton,
752193323Sed                                          ctx, pool));
753193323Sed}
754193323Sed
755193323Sedsvn_error_t *
756198090Srdivackysvn_client_move5(svn_commit_info_t **commit_info_p,
757193323Sed                 const apr_array_header_t *src_paths,
758193323Sed                 const char *dst_path,
759193323Sed                 svn_boolean_t force,
760193323Sed                 svn_boolean_t move_as_child,
761193323Sed                 svn_boolean_t make_parents,
762193323Sed                 const apr_hash_t *revprop_table,
763193323Sed                 svn_client_ctx_t *ctx,
764193323Sed                 apr_pool_t *pool)
765193323Sed{
766193323Sed  struct capture_baton_t cb;
767193323Sed
768193323Sed  cb.info = commit_info_p;
769193323Sed  cb.pool = pool;
770193323Sed
771193323Sed  return svn_client_move6(src_paths, dst_path, move_as_child,
772193323Sed                          make_parents, revprop_table,
773193323Sed                          capture_commit_info, &cb, ctx, pool);
774198090Srdivacky}
775193323Sed
776193323Sedsvn_error_t *
777193323Sedsvn_client_move4(svn_commit_info_t **commit_info_p,
778193323Sed                 const char *src_path,
779193323Sed                 const char *dst_path,
780193323Sed                 svn_boolean_t force,
781193323Sed                 svn_client_ctx_t *ctx,
782193323Sed                 apr_pool_t *pool)
783193323Sed{
784193323Sed  apr_array_header_t *src_paths =
785198090Srdivacky    apr_array_make(pool, 1, sizeof(const char *));
786193323Sed  APR_ARRAY_PUSH(src_paths, const char *) = src_path;
787193323Sed
788198090Srdivacky
789193323Sed  return svn_client_move5(commit_info_p, src_paths, dst_path, force, FALSE,
790198090Srdivacky                          FALSE, NULL, ctx, pool);
791198090Srdivacky}
792193323Sed
793193323Sedsvn_error_t *
794193323Sedsvn_client_move3(svn_commit_info_t **commit_info_p,
795193323Sed                 const char *src_path,
796193323Sed                 const char *dst_path,
797193323Sed                 svn_boolean_t force,
798193323Sed                 svn_client_ctx_t *ctx,
799193323Sed                 apr_pool_t *pool)
800193323Sed{
801193323Sed  svn_error_t *err;
802193323Sed
803193323Sed  err = svn_client_move4(commit_info_p, src_path, dst_path, force, ctx, pool);
804193323Sed
805193323Sed  /* If the target exists, try to move the source as a child of the target.
806193323Sed     This will obviously fail if target is not a directory, but that's exactly
807193323Sed     what we want. */
808193323Sed  if (err && (err->apr_err == SVN_ERR_ENTRY_EXISTS
809198090Srdivacky              || err->apr_err == SVN_ERR_FS_ALREADY_EXISTS))
810193323Sed    {
811193323Sed      const char *src_basename = svn_path_basename(src_path, pool);
812193323Sed
813193323Sed      svn_error_clear(err);
814193323Sed
815193323Sed      return svn_client_move4(commit_info_p, src_path,
816193323Sed                              svn_path_join(dst_path, src_basename, pool),
817193323Sed                              force, ctx, pool);
818193323Sed    }
819193323Sed
820193323Sed  return svn_error_trace(err);
821193323Sed}
822193323Sed
823193323Sedsvn_error_t *
824193323Sedsvn_client_move2(svn_client_commit_info_t **commit_info_p,
825193323Sed                 const char *src_path,
826193323Sed                 const char *dst_path,
827193323Sed                 svn_boolean_t force,
828193323Sed                 svn_client_ctx_t *ctx,
829193323Sed                 apr_pool_t *pool)
830193323Sed{
831193323Sed  svn_commit_info_t *commit_info = NULL;
832193323Sed  svn_error_t *err;
833193323Sed
834193323Sed  err = svn_client_move3(&commit_info, src_path, dst_path, force, ctx, pool);
835193323Sed  /* These structs have the same layout for the common fields. */
836193323Sed  *commit_info_p = (svn_client_commit_info_t *) commit_info;
837193323Sed  return svn_error_trace(err);
838193323Sed}
839193323Sed
840193323Sed
841198090Srdivackysvn_error_t *
842198090Srdivackysvn_client_move(svn_client_commit_info_t **commit_info_p,
843198090Srdivacky                const char *src_path,
844198090Srdivacky                const svn_opt_revision_t *src_revision,
845198090Srdivacky                const char *dst_path,
846198090Srdivacky                svn_boolean_t force,
847198090Srdivacky                svn_client_ctx_t *ctx,
848198090Srdivacky                apr_pool_t *pool)
849198090Srdivacky{
850198090Srdivacky  /* It doesn't make sense to specify revisions in a move. */
851198090Srdivacky
852198090Srdivacky  /* ### todo: this check could fail wrongly.  For example,
853198090Srdivacky     someone could pass in an svn_opt_revision_number that just
854193323Sed     happens to be the HEAD.  It's fair enough to punt then, IMHO,
855193323Sed     and just demand that the user not specify a revision at all;
856193323Sed     beats mucking up this function with RA calls and such. */
857193323Sed  if (src_revision->kind != svn_opt_revision_unspecified
858193323Sed      && src_revision->kind != svn_opt_revision_head)
859193323Sed    {
860193323Sed      return svn_error_create
861193323Sed        (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
862193323Sed         _("Cannot specify revisions (except HEAD) with move operations"));
863198090Srdivacky    }
864198090Srdivacky
865193323Sed  return svn_client_move2(commit_info_p, src_path, dst_path, force, ctx, pool);
866193323Sed}
867193323Sed
868193323Sed/*** From delete.c ***/
869193323Sedsvn_error_t *
870198090Srdivackysvn_client_delete3(svn_commit_info_t **commit_info_p,
871198090Srdivacky                   const apr_array_header_t *paths,
872193323Sed                   svn_boolean_t force,
873193323Sed                   svn_boolean_t keep_local,
874193323Sed                   const apr_hash_t *revprop_table,
875193323Sed                   svn_client_ctx_t *ctx,
876193323Sed                   apr_pool_t *pool)
877193323Sed{
878198090Srdivacky  struct capture_baton_t cb;
879198090Srdivacky
880193323Sed  cb.info = commit_info_p;
881193323Sed  cb.pool = pool;
882198090Srdivacky
883193323Sed  return svn_client_delete4(paths, force, keep_local, revprop_table,
884193323Sed                            capture_commit_info, &cb, ctx, pool);
885198090Srdivacky}
886193323Sed
887193323Sedsvn_error_t *
888193323Sedsvn_client_delete2(svn_commit_info_t **commit_info_p,
889193323Sed                   const apr_array_header_t *paths,
890193323Sed                   svn_boolean_t force,
891193323Sed                   svn_client_ctx_t *ctx,
892193323Sed                   apr_pool_t *pool)
893193323Sed{
894193323Sed  return svn_client_delete3(commit_info_p, paths, force, FALSE, NULL,
895193323Sed                            ctx, pool);
896193323Sed}
897193323Sed
898193323Sedsvn_error_t *
899193323Sedsvn_client_delete(svn_client_commit_info_t **commit_info_p,
900193323Sed                  const apr_array_header_t *paths,
901193323Sed                  svn_boolean_t force,
902193323Sed                  svn_client_ctx_t *ctx,
903193323Sed                  apr_pool_t *pool)
904193323Sed{
905193323Sed  svn_commit_info_t *commit_info = NULL;
906193323Sed  svn_error_t *err = NULL;
907193323Sed
908193323Sed  err = svn_client_delete2(&commit_info, paths, force, ctx, pool);
909193323Sed  /* These structs have the same layout for the common fields. */
910193323Sed  *commit_info_p = (svn_client_commit_info_t *) commit_info;
911193323Sed  return svn_error_trace(err);
912193323Sed}
913193323Sed
914193323Sed/*** From diff.c ***/
915193323Sed
916193323Sedsvn_error_t *
917193323Sedsvn_client_diff5(const apr_array_header_t *diff_options,
918193323Sed                 const char *path1,
919193323Sed                 const svn_opt_revision_t *revision1,
920198090Srdivacky                 const char *path2,
921198090Srdivacky                 const svn_opt_revision_t *revision2,
922193323Sed                 const char *relative_to_dir,
923193323Sed                 svn_depth_t depth,
924198090Srdivacky                 svn_boolean_t ignore_ancestry,
925193323Sed                 svn_boolean_t no_diff_deleted,
926193323Sed                 svn_boolean_t show_copies_as_adds,
927198090Srdivacky                 svn_boolean_t ignore_content_type,
928193323Sed                 svn_boolean_t use_git_diff_format,
929193323Sed                 const char *header_encoding,
930193323Sed                 apr_file_t *outfile,
931193323Sed                 apr_file_t *errfile,
932193323Sed                 const apr_array_header_t *changelists,
933193323Sed                 svn_client_ctx_t *ctx,
934193323Sed                 apr_pool_t *pool)
935193323Sed{
936193323Sed  svn_stream_t *outstream = svn_stream_from_aprfile2(outfile, TRUE, pool);
937193323Sed  svn_stream_t *errstream = svn_stream_from_aprfile2(errfile, TRUE, pool);
938193323Sed
939193323Sed  return svn_client_diff6(diff_options, path1, revision1, path2,
940193323Sed                          revision2, relative_to_dir, depth,
941193323Sed                          ignore_ancestry, FALSE /* no_diff_added */,
942193323Sed                          no_diff_deleted, show_copies_as_adds,
943193323Sed                          ignore_content_type, FALSE /* ignore_properties */,
944193323Sed                          FALSE /* properties_only */, use_git_diff_format,
945193323Sed                          header_encoding,
946193323Sed                          outstream, errstream, changelists, ctx, pool);
947193323Sed}
948193323Sed
949193323Sedsvn_error_t *
950193323Sedsvn_client_diff4(const apr_array_header_t *options,
951193323Sed                 const char *path1,
952193323Sed                 const svn_opt_revision_t *revision1,
953193323Sed                 const char *path2,
954193323Sed                 const svn_opt_revision_t *revision2,
955193323Sed                 const char *relative_to_dir,
956193323Sed                 svn_depth_t depth,
957193323Sed                 svn_boolean_t ignore_ancestry,
958193323Sed                 svn_boolean_t no_diff_deleted,
959193323Sed                 svn_boolean_t ignore_content_type,
960198090Srdivacky                 const char *header_encoding,
961198090Srdivacky                 apr_file_t *outfile,
962193323Sed                 apr_file_t *errfile,
963193323Sed                 const apr_array_header_t *changelists,
964193323Sed                 svn_client_ctx_t *ctx,
965193323Sed                 apr_pool_t *pool)
966193323Sed{
967193323Sed  return svn_client_diff5(options, path1, revision1, path2,
968193323Sed                          revision2, relative_to_dir, depth,
969193323Sed                          ignore_ancestry, no_diff_deleted, FALSE,
970198090Srdivacky                          ignore_content_type, FALSE, header_encoding,
971195098Sed                          outfile, errfile, changelists, ctx, pool);
972195098Sed}
973195098Sed
974195098Sedsvn_error_t *
975198090Srdivackysvn_client_diff3(const apr_array_header_t *options,
976193323Sed                 const char *path1,
977198090Srdivacky                 const svn_opt_revision_t *revision1,
978198090Srdivacky                 const char *path2,
979193323Sed                 const svn_opt_revision_t *revision2,
980193323Sed                 svn_boolean_t recurse,
981193323Sed                 svn_boolean_t ignore_ancestry,
982193323Sed                 svn_boolean_t no_diff_deleted,
983193323Sed                 svn_boolean_t ignore_content_type,
984193323Sed                 const char *header_encoding,
985193323Sed                 apr_file_t *outfile,
986193323Sed                 apr_file_t *errfile,
987193323Sed                 svn_client_ctx_t *ctx,
988193323Sed                 apr_pool_t *pool)
989195098Sed{
990193323Sed  return svn_client_diff4(options, path1, revision1, path2,
991193323Sed                          revision2, NULL,
992193323Sed                          SVN_DEPTH_INFINITY_OR_FILES(recurse),
993193323Sed                          ignore_ancestry, no_diff_deleted,
994193323Sed                          ignore_content_type, header_encoding,
995193323Sed                          outfile, errfile, NULL, ctx, pool);
996193323Sed}
997193323Sed
998193323Sedsvn_error_t *
999195098Sedsvn_client_diff2(const apr_array_header_t *options,
1000193323Sed                 const char *path1,
1001193323Sed                 const svn_opt_revision_t *revision1,
1002193323Sed                 const char *path2,
1003193323Sed                 const svn_opt_revision_t *revision2,
1004195098Sed                 svn_boolean_t recurse,
1005193323Sed                 svn_boolean_t ignore_ancestry,
1006193323Sed                 svn_boolean_t no_diff_deleted,
1007193323Sed                 svn_boolean_t ignore_content_type,
1008193323Sed                 apr_file_t *outfile,
1009193323Sed                 apr_file_t *errfile,
1010198090Srdivacky                 svn_client_ctx_t *ctx,
1011193323Sed                 apr_pool_t *pool)
1012193323Sed{
1013193323Sed  return svn_client_diff3(options, path1, revision1, path2, revision2,
1014193323Sed                          recurse, ignore_ancestry, no_diff_deleted,
1015193323Sed                          ignore_content_type, SVN_APR_LOCALE_CHARSET,
1016193323Sed                          outfile, errfile, ctx, pool);
1017193323Sed}
1018193323Sed
1019193323Sedsvn_error_t *
1020193323Sedsvn_client_diff(const apr_array_header_t *options,
1021193323Sed                const char *path1,
1022193323Sed                const svn_opt_revision_t *revision1,
1023193323Sed                const char *path2,
1024193323Sed                const svn_opt_revision_t *revision2,
1025198090Srdivacky                svn_boolean_t recurse,
1026195098Sed                svn_boolean_t ignore_ancestry,
1027195098Sed                svn_boolean_t no_diff_deleted,
1028195098Sed                apr_file_t *outfile,
1029193323Sed                apr_file_t *errfile,
1030193323Sed                svn_client_ctx_t *ctx,
1031193323Sed                apr_pool_t *pool)
1032193323Sed{
1033195098Sed  return svn_client_diff2(options, path1, revision1, path2, revision2,
1034193323Sed                          recurse, ignore_ancestry, no_diff_deleted, FALSE,
1035193323Sed                          outfile, errfile, ctx, pool);
1036193323Sed}
1037193323Sed
1038195098Sedsvn_error_t *
1039193323Sedsvn_client_diff_peg5(const apr_array_header_t *diff_options,
1040193323Sed                     const char *path,
1041193323Sed                     const svn_opt_revision_t *peg_revision,
1042193323Sed                     const svn_opt_revision_t *start_revision,
1043193323Sed                     const svn_opt_revision_t *end_revision,
1044198090Srdivacky                     const char *relative_to_dir,
1045193323Sed                     svn_depth_t depth,
1046198090Srdivacky                     svn_boolean_t ignore_ancestry,
1047195098Sed                     svn_boolean_t no_diff_deleted,
1048195098Sed                     svn_boolean_t show_copies_as_adds,
1049195098Sed                     svn_boolean_t ignore_content_type,
1050193323Sed                     svn_boolean_t use_git_diff_format,
1051193323Sed                     const char *header_encoding,
1052193323Sed                     apr_file_t *outfile,
1053193323Sed                     apr_file_t *errfile,
1054193323Sed                     const apr_array_header_t *changelists,
1055193323Sed                     svn_client_ctx_t *ctx,
1056193323Sed                     apr_pool_t *pool)
1057193323Sed{
1058195098Sed  svn_stream_t *outstream = svn_stream_from_aprfile2(outfile, TRUE, pool);
1059193323Sed  svn_stream_t *errstream = svn_stream_from_aprfile2(errfile, TRUE, pool);
1060193323Sed
1061193323Sed  return svn_client_diff_peg6(diff_options,
1062193323Sed                              path,
1063195098Sed                              peg_revision,
1064193323Sed                              start_revision,
1065193323Sed                              end_revision,
1066193323Sed                              relative_to_dir,
1067193323Sed                              depth,
1068193323Sed                              ignore_ancestry,
1069193323Sed                              FALSE /* no_diff_added */,
1070198090Srdivacky                              no_diff_deleted,
1071193323Sed                              show_copies_as_adds,
1072195098Sed                              ignore_content_type,
1073195098Sed                              FALSE /* ignore_properties */,
1074195098Sed                              FALSE /* properties_only */,
1075195098Sed                              use_git_diff_format,
1076193323Sed                              header_encoding,
1077193323Sed                              outstream,
1078193323Sed                              errstream,
1079193323Sed                              changelists,
1080193323Sed                              ctx,
1081193323Sed                              pool);
1082193323Sed}
1083193323Sed
1084195098Sedsvn_error_t *
1085193323Sedsvn_client_diff_peg4(const apr_array_header_t *options,
1086193323Sed                     const char *path,
1087193323Sed                     const svn_opt_revision_t *peg_revision,
1088193323Sed                     const svn_opt_revision_t *start_revision,
1089195098Sed                     const svn_opt_revision_t *end_revision,
1090193323Sed                     const char *relative_to_dir,
1091193323Sed                     svn_depth_t depth,
1092193323Sed                     svn_boolean_t ignore_ancestry,
1093193323Sed                     svn_boolean_t no_diff_deleted,
1094193323Sed                     svn_boolean_t ignore_content_type,
1095193323Sed                     const char *header_encoding,
1096193323Sed                     apr_file_t *outfile,
1097193323Sed                     apr_file_t *errfile,
1098193323Sed                     const apr_array_header_t *changelists,
1099193323Sed                     svn_client_ctx_t *ctx,
1100193323Sed                     apr_pool_t *pool)
1101193323Sed{
1102193323Sed  return svn_client_diff_peg5(options,
1103193323Sed                              path,
1104193323Sed                              peg_revision,
1105193323Sed                              start_revision,
1106193323Sed                              end_revision,
1107193323Sed                              relative_to_dir,
1108193323Sed                              depth,
1109198090Srdivacky                              ignore_ancestry,
1110198090Srdivacky                              no_diff_deleted,
1111198090Srdivacky                              FALSE,
1112198090Srdivacky                              ignore_content_type,
1113193323Sed                              FALSE,
1114193323Sed                              header_encoding,
1115198090Srdivacky                              outfile,
1116193323Sed                              errfile,
1117193323Sed                              changelists,
1118193323Sed                              ctx,
1119193323Sed                              pool);
1120193323Sed}
1121193323Sed
1122193323Sedsvn_error_t *
1123193323Sedsvn_client_diff_peg3(const apr_array_header_t *options,
1124198090Srdivacky                     const char *path,
1125193323Sed                     const svn_opt_revision_t *peg_revision,
1126193323Sed                     const svn_opt_revision_t *start_revision,
1127193323Sed                     const svn_opt_revision_t *end_revision,
1128195098Sed                     svn_boolean_t recurse,
1129193323Sed                     svn_boolean_t ignore_ancestry,
1130193323Sed                     svn_boolean_t no_diff_deleted,
1131193323Sed                     svn_boolean_t ignore_content_type,
1132193323Sed                     const char *header_encoding,
1133198090Srdivacky                     apr_file_t *outfile,
1134195098Sed                     apr_file_t *errfile,
1135195098Sed                     svn_client_ctx_t *ctx,
1136195098Sed                     apr_pool_t *pool)
1137195098Sed{
1138193323Sed  return svn_client_diff_peg4(options,
1139193323Sed                              path,
1140195098Sed                              peg_revision,
1141193323Sed                              start_revision,
1142193323Sed                              end_revision,
1143193323Sed                              NULL,
1144193323Sed                              SVN_DEPTH_INFINITY_OR_FILES(recurse),
1145193323Sed                              ignore_ancestry,
1146193323Sed                              no_diff_deleted,
1147193323Sed                              ignore_content_type,
1148193323Sed                              header_encoding,
1149193323Sed                              outfile,
1150193323Sed                              errfile,
1151193323Sed                              NULL,
1152193323Sed                              ctx,
1153193323Sed                              pool);
1154193323Sed}
1155193323Sed
1156193323Sedsvn_error_t *
1157193323Sedsvn_client_diff_peg2(const apr_array_header_t *options,
1158193323Sed                     const char *path,
1159193323Sed                     const svn_opt_revision_t *peg_revision,
1160193323Sed                     const svn_opt_revision_t *start_revision,
1161193323Sed                     const svn_opt_revision_t *end_revision,
1162193323Sed                     svn_boolean_t recurse,
1163193323Sed                     svn_boolean_t ignore_ancestry,
1164193323Sed                     svn_boolean_t no_diff_deleted,
1165193323Sed                     svn_boolean_t ignore_content_type,
1166193323Sed                     apr_file_t *outfile,
1167193323Sed                     apr_file_t *errfile,
1168193323Sed                     svn_client_ctx_t *ctx,
1169193323Sed                     apr_pool_t *pool)
1170193323Sed{
1171193323Sed  return svn_client_diff_peg3(options, path, peg_revision, start_revision,
1172198090Srdivacky                              end_revision,
1173193323Sed                              SVN_DEPTH_INFINITY_OR_FILES(recurse),
1174193323Sed                              ignore_ancestry, no_diff_deleted,
1175198090Srdivacky                              ignore_content_type, SVN_APR_LOCALE_CHARSET,
1176193323Sed                              outfile, errfile, ctx, pool);
1177193323Sed}
1178193323Sed
1179193323Sedsvn_error_t *
1180193323Sedsvn_client_diff_peg(const apr_array_header_t *options,
1181193323Sed                    const char *path,
1182198090Srdivacky                    const svn_opt_revision_t *peg_revision,
1183193323Sed                    const svn_opt_revision_t *start_revision,
1184198090Srdivacky                    const svn_opt_revision_t *end_revision,
1185193323Sed                    svn_boolean_t recurse,
1186193323Sed                    svn_boolean_t ignore_ancestry,
1187193323Sed                    svn_boolean_t no_diff_deleted,
1188193323Sed                    apr_file_t *outfile,
1189193323Sed                    apr_file_t *errfile,
1190193323Sed                    svn_client_ctx_t *ctx,
1191193323Sed                    apr_pool_t *pool)
1192198090Srdivacky{
1193193323Sed  return svn_client_diff_peg2(options, path, peg_revision,
1194193323Sed                              start_revision, end_revision, recurse,
1195193323Sed                              ignore_ancestry, no_diff_deleted, FALSE,
1196193323Sed                              outfile, errfile, ctx, pool);
1197193323Sed}
1198193323Sed
1199198090Srdivackysvn_error_t *
1200193323Sedsvn_client_diff_summarize(const char *path1,
1201193323Sed                          const svn_opt_revision_t *revision1,
1202193323Sed                          const char *path2,
1203198090Srdivacky                          const svn_opt_revision_t *revision2,
1204193323Sed                          svn_boolean_t recurse,
1205193323Sed                          svn_boolean_t ignore_ancestry,
1206193323Sed                          svn_client_diff_summarize_func_t summarize_func,
1207193323Sed                          void *summarize_baton,
1208193323Sed                          svn_client_ctx_t *ctx,
1209193323Sed                          apr_pool_t *pool)
1210193323Sed{
1211193323Sed  return svn_client_diff_summarize2(path1, revision1, path2,
1212193323Sed                                    revision2,
1213193323Sed                                    SVN_DEPTH_INFINITY_OR_FILES(recurse),
1214193323Sed                                    ignore_ancestry, NULL, summarize_func,
1215193323Sed                                    summarize_baton, ctx, pool);
1216193323Sed}
1217193323Sed
1218193323Sedsvn_error_t *
1219193323Sedsvn_client_diff_summarize_peg(const char *path,
1220193323Sed                              const svn_opt_revision_t *peg_revision,
1221193323Sed                              const svn_opt_revision_t *start_revision,
1222193323Sed                              const svn_opt_revision_t *end_revision,
1223193323Sed                              svn_boolean_t recurse,
1224193323Sed                              svn_boolean_t ignore_ancestry,
1225193323Sed                              svn_client_diff_summarize_func_t summarize_func,
1226198090Srdivacky                              void *summarize_baton,
1227193323Sed                              svn_client_ctx_t *ctx,
1228193323Sed                              apr_pool_t *pool)
1229193323Sed{
1230193323Sed  return svn_client_diff_summarize_peg2(path, peg_revision,
1231193323Sed                                        start_revision, end_revision,
1232193323Sed                                        SVN_DEPTH_INFINITY_OR_FILES(recurse),
1233193323Sed                                        ignore_ancestry, NULL,
1234198090Srdivacky                                        summarize_func, summarize_baton,
1235193323Sed                                        ctx, pool);
1236193323Sed}
1237193323Sed
1238193323Sed/*** From export.c ***/
1239193323Sedsvn_error_t *
1240193323Sedsvn_client_export4(svn_revnum_t *result_rev,
1241193323Sed                   const char *from_path_or_url,
1242193323Sed                   const char *to_path,
1243193323Sed                   const svn_opt_revision_t *peg_revision,
1244198090Srdivacky                   const svn_opt_revision_t *revision,
1245193323Sed                   svn_boolean_t overwrite,
1246193323Sed                   svn_boolean_t ignore_externals,
1247193323Sed                   svn_depth_t depth,
1248198090Srdivacky                   const char *native_eol,
1249193323Sed                   svn_client_ctx_t *ctx,
1250193323Sed                   apr_pool_t *pool)
1251193323Sed{
1252193323Sed  return svn_client_export5(result_rev, from_path_or_url, to_path,
1253193323Sed                            peg_revision, revision, overwrite, ignore_externals,
1254198090Srdivacky                            FALSE, depth, native_eol, ctx, pool);
1255193323Sed}
1256193323Sed
1257193323Sedsvn_error_t *
1258193323Sedsvn_client_export3(svn_revnum_t *result_rev,
1259193323Sed                   const char *from_path_or_url,
1260193323Sed                   const char *to_path,
1261193323Sed                   const svn_opt_revision_t *peg_revision,
1262198090Srdivacky                   const svn_opt_revision_t *revision,
1263193323Sed                   svn_boolean_t overwrite,
1264193323Sed                   svn_boolean_t ignore_externals,
1265193323Sed                   svn_boolean_t recurse,
1266193323Sed                   const char *native_eol,
1267193323Sed                   svn_client_ctx_t *ctx,
1268193323Sed                   apr_pool_t *pool)
1269193323Sed{
1270193323Sed  return svn_client_export4(result_rev, from_path_or_url, to_path,
1271193323Sed                            peg_revision, revision, overwrite, ignore_externals,
1272193323Sed                            SVN_DEPTH_INFINITY_OR_FILES(recurse),
1273199481Srdivacky                            native_eol, ctx, pool);
1274199481Srdivacky}
1275193323Sed
1276193323Sedsvn_error_t *
1277193323Sedsvn_client_export2(svn_revnum_t *result_rev,
1278193323Sed                   const char *from_path_or_url,
1279193323Sed                   const char *to_path,
1280193323Sed                   svn_opt_revision_t *revision,
1281193323Sed                   svn_boolean_t force,
1282193323Sed                   const char *native_eol,
1283193323Sed                   svn_client_ctx_t *ctx,
1284193323Sed                   apr_pool_t *pool)
1285198090Srdivacky{
1286193323Sed  svn_opt_revision_t peg_revision;
1287193323Sed
1288193323Sed  peg_revision.kind = svn_opt_revision_unspecified;
1289193323Sed
1290193323Sed  return svn_client_export3(result_rev, from_path_or_url, to_path,
1291193323Sed                            &peg_revision, revision, force, FALSE, TRUE,
1292193323Sed                            native_eol, ctx, pool);
1293193323Sed}
1294193323Sed
1295193323Sed
1296193323Sedsvn_error_t *
1297193323Sedsvn_client_export(svn_revnum_t *result_rev,
1298193323Sed                  const char *from_path_or_url,
1299193323Sed                  const char *to_path,
1300193323Sed                  svn_opt_revision_t *revision,
1301198090Srdivacky                  svn_boolean_t force,
1302193323Sed                  svn_client_ctx_t *ctx,
1303193323Sed                  apr_pool_t *pool)
1304193323Sed{
1305193323Sed  return svn_client_export2(result_rev, from_path_or_url, to_path, revision,
1306193323Sed                            force, NULL, ctx, pool);
1307193323Sed}
1308193323Sed
1309193323Sed/*** From list.c ***/
1310193323Sed
1311193323Sed/* Baton for use with wrap_list_func */
1312193323Sedstruct list_func_wrapper_baton {
1313193323Sed    void *list_func1_baton;
1314193323Sed    svn_client_list_func_t list_func1;
1315193323Sed};
1316193323Sed
1317193323Sed/* This implements svn_client_list_func2_t */
1318193323Sedstatic svn_error_t *
1319193323Sedlist_func_wrapper(void *baton,
1320193323Sed                  const char *path,
1321193323Sed                  const svn_dirent_t *dirent,
1322193323Sed                  const svn_lock_t *lock,
1323193323Sed                  const char *abs_path,
1324193323Sed                  const char *external_parent_url,
1325193323Sed                  const char *external_target,
1326198892Srdivacky                  apr_pool_t *scratch_pool)
1327198892Srdivacky{
1328198892Srdivacky  struct list_func_wrapper_baton *lfwb = baton;
1329198892Srdivacky
1330198892Srdivacky  if (lfwb->list_func1)
1331198892Srdivacky    return lfwb->list_func1(lfwb->list_func1_baton, path, dirent,
1332198892Srdivacky                           lock, abs_path, scratch_pool);
1333198892Srdivacky
1334198892Srdivacky  return SVN_NO_ERROR;
1335198892Srdivacky}
1336198892Srdivacky
1337198892Srdivacky/* Helper function for svn_client_list2().  It wraps old format baton
1338198892Srdivacky   and callback function in list_func_wrapper_baton and
1339198892Srdivacky   returns new baton and callback to use with svn_client_list3(). */
1340198892Srdivackystatic void
1341198892Srdivackywrap_list_func(svn_client_list_func2_t *list_func2,
1342198892Srdivacky               void **list_func2_baton,
1343193323Sed               svn_client_list_func_t list_func,
1344193323Sed               void *baton,
1345193323Sed               apr_pool_t *result_pool)
1346193323Sed{
1347193323Sed  struct list_func_wrapper_baton *lfwb = apr_palloc(result_pool,
1348193323Sed                                                    sizeof(*lfwb));
1349193323Sed
1350193323Sed  /* Set the user provided old format callback in the baton. */
1351193323Sed  lfwb->list_func1_baton = baton;
1352193323Sed  lfwb->list_func1 = list_func;
1353193323Sed
1354193323Sed  *list_func2_baton = lfwb;
1355193323Sed  *list_func2 = list_func_wrapper;
1356193323Sed}
1357193323Sed
1358193323Sedsvn_error_t *
1359193323Sedsvn_client_list2(const char *path_or_url,
1360193323Sed                 const svn_opt_revision_t *peg_revision,
1361193323Sed                 const svn_opt_revision_t *revision,
1362193323Sed                 svn_depth_t depth,
1363193323Sed                 apr_uint32_t dirent_fields,
1364193323Sed                 svn_boolean_t fetch_locks,
1365198090Srdivacky                 svn_client_list_func_t list_func,
1366193323Sed                 void *baton,
1367193323Sed                 svn_client_ctx_t *ctx,
1368193323Sed                 apr_pool_t *pool)
1369193323Sed{
1370193323Sed  svn_client_list_func2_t list_func2;
1371193323Sed  void *list_func2_baton;
1372193323Sed
1373193323Sed  wrap_list_func(&list_func2, &list_func2_baton, list_func, baton, pool);
1374193323Sed
1375198090Srdivacky  return svn_client_list3(path_or_url, peg_revision, revision, depth,
1376193323Sed                          dirent_fields, fetch_locks,
1377198090Srdivacky                          FALSE /* include externals */,
1378198090Srdivacky                          list_func2, list_func2_baton, ctx, pool);
1379193323Sed}
1380193323Sed
1381193323Sedsvn_error_t *
1382199481Srdivackysvn_client_list(const char *path_or_url,
1383193323Sed                const svn_opt_revision_t *peg_revision,
1384193323Sed                const svn_opt_revision_t *revision,
1385193323Sed                svn_boolean_t recurse,
1386193323Sed                apr_uint32_t dirent_fields,
1387193323Sed                svn_boolean_t fetch_locks,
1388198090Srdivacky                svn_client_list_func_t list_func,
1389193323Sed                void *baton,
1390193323Sed                svn_client_ctx_t *ctx,
1391198090Srdivacky                apr_pool_t *pool)
1392198090Srdivacky{
1393193323Sed  return svn_client_list2(path_or_url,
1394193323Sed                          peg_revision,
1395193323Sed                          revision,
1396193323Sed                          SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
1397193323Sed                          dirent_fields,
1398199481Srdivacky                          fetch_locks,
1399193323Sed                          list_func,
1400193323Sed                          baton,
1401193323Sed                          ctx,
1402198090Srdivacky                          pool);
1403193323Sed}
1404193323Sed
1405193323Sed/* Baton used by compatibility wrapper svn_client_ls3. */
1406193323Sedstruct ls_baton {
1407193323Sed  apr_hash_t *dirents;
1408193323Sed  apr_hash_t *locks;
1409193323Sed  apr_pool_t *pool;
1410193323Sed};
1411193323Sed
1412193323Sed/* This implements svn_client_list_func_t. */
1413193323Sedstatic svn_error_t *
1414193323Sedstore_dirent(void *baton, const char *path, const svn_dirent_t *dirent,
1415193323Sed             const svn_lock_t *lock, const char *abs_path, apr_pool_t *pool)
1416193323Sed{
1417193323Sed  struct ls_baton *lb = baton;
1418193323Sed
1419193323Sed  /* The dirent is allocated in a temporary pool, so duplicate it into the
1420193323Sed     correct pool.  Note, however, that the locks are stored in the correct
1421193323Sed     pool already. */
1422193323Sed  dirent = svn_dirent_dup(dirent, lb->pool);
1423193323Sed
1424193323Sed  /* An empty path means we are called for the target of the operation.
1425193323Sed     For compatibility, we only store the target if it is a file, and we
1426193323Sed     store it under the basename of the URL.  Note that this makes it
1427193323Sed     impossible to differentiate between the target being a directory with a
1428193323Sed     child with the same basename as the target and the target being a file,
1429193323Sed     but that's how it was implemented. */
1430193323Sed  if (path[0] == '\0')
1431193323Sed    {
1432198090Srdivacky      if (dirent->kind == svn_node_file)
1433193323Sed        {
1434193323Sed          const char *base_name = svn_path_basename(abs_path, lb->pool);
1435193323Sed          svn_hash_sets(lb->dirents, base_name, dirent);
1436193323Sed          if (lock)
1437193323Sed            svn_hash_sets(lb->locks, base_name, lock);
1438193323Sed        }
1439193323Sed    }
1440193323Sed  else
1441193323Sed    {
1442193323Sed      path = apr_pstrdup(lb->pool, path);
1443193323Sed      svn_hash_sets(lb->dirents, path, dirent);
1444193323Sed      if (lock)
1445193323Sed        svn_hash_sets(lb->locks, path, lock);
1446193323Sed    }
1447193323Sed
1448193323Sed  return SVN_NO_ERROR;
1449193323Sed}
1450193323Sed
1451193323Sedsvn_error_t *
1452193323Sedsvn_client_ls3(apr_hash_t **dirents,
1453193323Sed               apr_hash_t **locks,
1454193323Sed               const char *path_or_url,
1455193323Sed               const svn_opt_revision_t *peg_revision,
1456193323Sed               const svn_opt_revision_t *revision,
1457193323Sed               svn_boolean_t recurse,
1458193323Sed               svn_client_ctx_t *ctx,
1459193323Sed               apr_pool_t *pool)
1460193323Sed{
1461193323Sed  struct ls_baton lb;
1462193323Sed
1463193323Sed  *dirents = lb.dirents = apr_hash_make(pool);
1464193323Sed  if (locks)
1465193323Sed    *locks = lb.locks = apr_hash_make(pool);
1466193323Sed  lb.pool = pool;
1467193323Sed
1468193323Sed  return svn_client_list(path_or_url, peg_revision, revision, recurse,
1469193323Sed                         SVN_DIRENT_ALL, locks != NULL,
1470193323Sed                         store_dirent, &lb, ctx, pool);
1471193323Sed}
1472193323Sed
1473193323Sedsvn_error_t *
1474193323Sedsvn_client_ls2(apr_hash_t **dirents,
1475193323Sed               const char *path_or_url,
1476193323Sed               const svn_opt_revision_t *peg_revision,
1477193323Sed               const svn_opt_revision_t *revision,
1478193323Sed               svn_boolean_t recurse,
1479193323Sed               svn_client_ctx_t *ctx,
1480193323Sed               apr_pool_t *pool)
1481193323Sed{
1482193323Sed
1483193323Sed  return svn_client_ls3(dirents, NULL, path_or_url, peg_revision,
1484193323Sed                        revision, recurse, ctx, pool);
1485193323Sed}
1486193323Sed
1487193323Sed
1488193323Sedsvn_error_t *
1489193323Sedsvn_client_ls(apr_hash_t **dirents,
1490193323Sed              const char *path_or_url,
1491193323Sed              svn_opt_revision_t *revision,
1492193323Sed              svn_boolean_t recurse,
1493193323Sed              svn_client_ctx_t *ctx,
1494193323Sed              apr_pool_t *pool)
1495193323Sed{
1496193323Sed  return svn_client_ls2(dirents, path_or_url, revision,
1497193323Sed                        revision, recurse, ctx, pool);
1498193323Sed}
1499193323Sed
1500193323Sed/*** From log.c ***/
1501193323Sedsvn_error_t *
1502193323Sedsvn_client_log4(const apr_array_header_t *targets,
1503193323Sed                const svn_opt_revision_t *peg_revision,
1504193323Sed                const svn_opt_revision_t *start,
1505193323Sed                const svn_opt_revision_t *end,
1506193323Sed                int limit,
1507198090Srdivacky                svn_boolean_t discover_changed_paths,
1508198090Srdivacky                svn_boolean_t strict_node_history,
1509198090Srdivacky                svn_boolean_t include_merged_revisions,
1510198090Srdivacky                const apr_array_header_t *revprops,
1511193323Sed                svn_log_entry_receiver_t receiver,
1512193323Sed                void *receiver_baton,
1513193323Sed                svn_client_ctx_t *ctx,
1514193323Sed                apr_pool_t *pool)
1515193323Sed{
1516193323Sed  apr_array_header_t *revision_ranges;
1517193323Sed
1518193323Sed  revision_ranges = apr_array_make(pool, 1,
1519193323Sed                                   sizeof(svn_opt_revision_range_t *));
1520193323Sed  APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
1521193323Sed    = svn_opt__revision_range_create(start, end, pool);
1522193323Sed
1523193323Sed  return svn_client_log5(targets, peg_revision, revision_ranges, limit,
1524193323Sed                         discover_changed_paths, strict_node_history,
1525193323Sed                         include_merged_revisions, revprops, receiver,
1526193323Sed                         receiver_baton, ctx, pool);
1527193323Sed}
1528193323Sed
1529193323Sed
1530193323Sedsvn_error_t *
1531193323Sedsvn_client_log3(const apr_array_header_t *targets,
1532193323Sed                const svn_opt_revision_t *peg_revision,
1533193323Sed                const svn_opt_revision_t *start,
1534193323Sed                const svn_opt_revision_t *end,
1535193323Sed                int limit,
1536193323Sed                svn_boolean_t discover_changed_paths,
1537193323Sed                svn_boolean_t strict_node_history,
1538193323Sed                svn_log_message_receiver_t receiver,
1539193323Sed                void *receiver_baton,
1540193323Sed                svn_client_ctx_t *ctx,
1541193323Sed                apr_pool_t *pool)
1542193323Sed{
1543193323Sed  svn_log_entry_receiver_t receiver2;
1544193323Sed  void *receiver2_baton;
1545193323Sed
1546193323Sed  svn_compat_wrap_log_receiver(&receiver2, &receiver2_baton,
1547193323Sed                               receiver, receiver_baton,
1548193323Sed                               pool);
1549193323Sed
1550193323Sed  return svn_client_log4(targets, peg_revision, start, end, limit,
1551193323Sed                         discover_changed_paths, strict_node_history, FALSE,
1552193323Sed                         svn_compat_log_revprops_in(pool),
1553193323Sed                         receiver2, receiver2_baton, ctx, pool);
1554193323Sed}
1555193323Sed
1556193323Sedsvn_error_t *
1557193323Sedsvn_client_log2(const apr_array_header_t *targets,
1558193323Sed                const svn_opt_revision_t *start,
1559193323Sed                const svn_opt_revision_t *end,
1560193323Sed                int limit,
1561193323Sed                svn_boolean_t discover_changed_paths,
1562193323Sed                svn_boolean_t strict_node_history,
1563193323Sed                svn_log_message_receiver_t receiver,
1564193323Sed                void *receiver_baton,
1565193323Sed                svn_client_ctx_t *ctx,
1566193323Sed                apr_pool_t *pool)
1567193323Sed{
1568193323Sed  svn_opt_revision_t peg_revision;
1569193323Sed  peg_revision.kind = svn_opt_revision_unspecified;
1570193323Sed  return svn_client_log3(targets, &peg_revision, start, end, limit,
1571193323Sed                         discover_changed_paths, strict_node_history,
1572193323Sed                         receiver, receiver_baton, ctx, pool);
1573193323Sed}
1574193323Sed
1575193323Sedsvn_error_t *
1576193323Sedsvn_client_log(const apr_array_header_t *targets,
1577193323Sed               const svn_opt_revision_t *start,
1578193323Sed               const svn_opt_revision_t *end,
1579193323Sed               svn_boolean_t discover_changed_paths,
1580193323Sed               svn_boolean_t strict_node_history,
1581193323Sed               svn_log_message_receiver_t receiver,
1582193323Sed               void *receiver_baton,
1583193323Sed               svn_client_ctx_t *ctx,
1584193323Sed               apr_pool_t *pool)
1585193323Sed{
1586193323Sed  svn_error_t *err = SVN_NO_ERROR;
1587193323Sed
1588193323Sed  err = svn_client_log2(targets, start, end, 0, discover_changed_paths,
1589193323Sed                        strict_node_history, receiver, receiver_baton, ctx,
1590193323Sed                        pool);
1591193323Sed
1592193323Sed  /* Special case: If there have been no commits, we'll get an error
1593193323Sed   * for requesting log of a revision higher than 0.  But the
1594193323Sed   * default behavior of "svn log" is to give revisions HEAD through
1595193323Sed   * 1, on the assumption that HEAD >= 1.
1596193323Sed   *
1597193323Sed   * So if we got that error for that reason, and it looks like the
1598193323Sed   * user was just depending on the defaults (rather than explicitly
1599193323Sed   * requesting the log for revision 1), then we don't error.  Instead
1600193323Sed   * we just invoke the receiver manually on a hand-constructed log
1601193323Sed   * message for revision 0.
1602193323Sed   *
1603193323Sed   * See also http://subversion.tigris.org/issues/show_bug.cgi?id=692.
1604193323Sed   */
1605193323Sed  if (err && (err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION)
1606193323Sed      && (start->kind == svn_opt_revision_head)
1607193323Sed      && ((end->kind == svn_opt_revision_number)
1608193323Sed          && (end->value.number == 1)))
1609193323Sed    {
1610193323Sed
1611193323Sed      /* We don't need to check if HEAD is 0, because that must be the case,
1612193323Sed       * by logical deduction: The revision range specified is HEAD:1.
1613193323Sed       * HEAD cannot not exist, so the revision to which "no such revision"
1614193323Sed       * applies is 1. If revision 1 does not exist, then HEAD is 0.
1615193323Sed       * Hence, we deduce the repository is empty without needing access
1616193323Sed       * to further information. */
1617193323Sed
1618193323Sed      svn_error_clear(err);
1619193323Sed      err = SVN_NO_ERROR;
1620193323Sed
1621193323Sed      /* Log receivers are free to handle revision 0 specially... But
1622193323Sed         just in case some don't, we make up a message here. */
1623193323Sed      SVN_ERR(receiver(receiver_baton,
1624193323Sed                       NULL, 0, "", "", _("No commits in repository"),
1625193323Sed                       pool));
1626193323Sed    }
1627193323Sed
1628193323Sed  return svn_error_trace(err);
1629193323Sed}
1630193323Sed
1631193323Sed/*** From merge.c ***/
1632193323Sed
1633193323Sedsvn_error_t *
1634193323Sedsvn_client_merge4(const char *source1,
1635193323Sed                  const svn_opt_revision_t *revision1,
1636193323Sed                  const char *source2,
1637193323Sed                  const svn_opt_revision_t *revision2,
1638193323Sed                  const char *target_wcpath,
1639193323Sed                  svn_depth_t depth,
1640193323Sed                  svn_boolean_t ignore_ancestry,
1641193323Sed                  svn_boolean_t force_delete,
1642193323Sed                  svn_boolean_t record_only,
1643193323Sed                  svn_boolean_t dry_run,
1644193323Sed                  svn_boolean_t allow_mixed_rev,
1645193323Sed                  const apr_array_header_t *merge_options,
1646193323Sed                  svn_client_ctx_t *ctx,
1647193323Sed                  apr_pool_t *pool)
1648193323Sed{
1649193323Sed  SVN_ERR(svn_client_merge5(source1, revision1,
1650193323Sed                            source2, revision2,
1651193323Sed                            target_wcpath,
1652193323Sed                            depth,
1653193323Sed                            ignore_ancestry /*ignore_mergeinfo*/,
1654193323Sed                            ignore_ancestry /*diff_ignore_ancestry*/,
1655193323Sed                            force_delete, record_only,
1656193323Sed                            dry_run, allow_mixed_rev,
1657193323Sed                            merge_options, ctx, pool));
1658193323Sed  return SVN_NO_ERROR;
1659193323Sed}
1660193323Sed
1661193323Sedsvn_error_t *
1662193323Sedsvn_client_merge3(const char *source1,
1663193323Sed                  const svn_opt_revision_t *revision1,
1664193323Sed                  const char *source2,
1665193323Sed                  const svn_opt_revision_t *revision2,
1666193323Sed                  const char *target_wcpath,
1667193323Sed                  svn_depth_t depth,
1668193323Sed                  svn_boolean_t ignore_ancestry,
1669193323Sed                  svn_boolean_t force,
1670193323Sed                  svn_boolean_t record_only,
1671193323Sed                  svn_boolean_t dry_run,
1672193323Sed                  const apr_array_header_t *merge_options,
1673193323Sed                  svn_client_ctx_t *ctx,
1674193323Sed                  apr_pool_t *pool)
1675193323Sed{
1676193323Sed  return svn_client_merge4(source1, revision1, source2, revision2,
1677193323Sed                           target_wcpath, depth, ignore_ancestry, force,
1678193323Sed                           record_only, dry_run, TRUE, merge_options,
1679193323Sed                           ctx, pool);
1680193323Sed}
1681193323Sed
1682193323Sedsvn_error_t *
1683193323Sedsvn_client_merge2(const char *source1,
1684193323Sed                  const svn_opt_revision_t *revision1,
1685193323Sed                  const char *source2,
1686193323Sed                  const svn_opt_revision_t *revision2,
1687193323Sed                  const char *target_wcpath,
1688193323Sed                  svn_boolean_t recurse,
1689193323Sed                  svn_boolean_t ignore_ancestry,
1690193323Sed                  svn_boolean_t force,
1691193323Sed                  svn_boolean_t dry_run,
1692193323Sed                  const apr_array_header_t *merge_options,
1693193323Sed                  svn_client_ctx_t *ctx,
1694193323Sed                  apr_pool_t *pool)
1695193323Sed{
1696193323Sed  return svn_client_merge3(source1, revision1, source2, revision2,
1697193323Sed                           target_wcpath,
1698193323Sed                           SVN_DEPTH_INFINITY_OR_FILES(recurse),
1699193323Sed                           ignore_ancestry, force, FALSE, dry_run,
1700193323Sed                           merge_options, ctx, pool);
1701193323Sed}
1702193323Sed
1703193323Sedsvn_error_t *
1704193323Sedsvn_client_merge(const char *source1,
1705193323Sed                 const svn_opt_revision_t *revision1,
1706193323Sed                 const char *source2,
1707193323Sed                 const svn_opt_revision_t *revision2,
1708193323Sed                 const char *target_wcpath,
1709193323Sed                 svn_boolean_t recurse,
1710193323Sed                 svn_boolean_t ignore_ancestry,
1711193323Sed                 svn_boolean_t force,
1712193323Sed                 svn_boolean_t dry_run,
1713193323Sed                 svn_client_ctx_t *ctx,
1714193323Sed                 apr_pool_t *pool)
1715193323Sed{
1716193323Sed  return svn_client_merge2(source1, revision1, source2, revision2,
1717193323Sed                           target_wcpath, recurse, ignore_ancestry, force,
1718193323Sed                           dry_run, NULL, ctx, pool);
1719193323Sed}
1720193323Sed
1721193323Sedsvn_error_t *
1722193323Sedsvn_client_merge_peg4(const char *source_path_or_url,
1723193323Sed                      const apr_array_header_t *ranges_to_merge,
1724193323Sed                      const svn_opt_revision_t *source_peg_revision,
1725193323Sed                      const char *target_wcpath,
1726193323Sed                      svn_depth_t depth,
1727193323Sed                      svn_boolean_t ignore_ancestry,
1728193323Sed                      svn_boolean_t force_delete,
1729193323Sed                      svn_boolean_t record_only,
1730193323Sed                      svn_boolean_t dry_run,
1731193323Sed                      svn_boolean_t allow_mixed_rev,
1732193323Sed                      const apr_array_header_t *merge_options,
1733193323Sed                      svn_client_ctx_t *ctx,
1734193323Sed                      apr_pool_t *pool)
1735193323Sed{
1736193323Sed  SVN_ERR(svn_client_merge_peg5(source_path_or_url,
1737193323Sed                                ranges_to_merge,
1738198090Srdivacky                                source_peg_revision,
1739193323Sed                                target_wcpath,
1740193323Sed                                depth,
1741193323Sed                                ignore_ancestry /*ignore_mergeinfo*/,
1742193323Sed                                ignore_ancestry /*diff_ignore_ancestry*/,
1743193323Sed                                force_delete, record_only,
1744193323Sed                                dry_run, allow_mixed_rev,
1745193323Sed                                merge_options, ctx, pool));
1746193323Sed  return SVN_NO_ERROR;
1747193323Sed}
1748193323Sed
1749193323Sedsvn_error_t *
1750193323Sedsvn_client_merge_peg3(const char *source,
1751193323Sed                      const apr_array_header_t *ranges_to_merge,
1752193323Sed                      const svn_opt_revision_t *peg_revision,
1753193323Sed                      const char *target_wcpath,
1754193323Sed                      svn_depth_t depth,
1755193323Sed                      svn_boolean_t ignore_ancestry,
1756193323Sed                      svn_boolean_t force,
1757193323Sed                      svn_boolean_t record_only,
1758193323Sed                      svn_boolean_t dry_run,
1759193323Sed                      const apr_array_header_t *merge_options,
1760193323Sed                      svn_client_ctx_t *ctx,
1761193323Sed                      apr_pool_t *pool)
1762193323Sed{
1763193323Sed  return svn_client_merge_peg4(source, ranges_to_merge, peg_revision,
1764193323Sed                               target_wcpath, depth, ignore_ancestry, force,
1765193323Sed                               record_only, dry_run, TRUE, merge_options,
1766193323Sed                               ctx, pool);
1767193323Sed}
1768193323Sed
1769193323Sedsvn_error_t *
1770193323Sedsvn_client_merge_peg2(const char *source,
1771193323Sed                      const svn_opt_revision_t *revision1,
1772193323Sed                      const svn_opt_revision_t *revision2,
1773193323Sed                      const svn_opt_revision_t *peg_revision,
1774193323Sed                      const char *target_wcpath,
1775193323Sed                      svn_boolean_t recurse,
1776193323Sed                      svn_boolean_t ignore_ancestry,
1777193323Sed                      svn_boolean_t force,
1778193323Sed                      svn_boolean_t dry_run,
1779193323Sed                      const apr_array_header_t *merge_options,
1780193323Sed                      svn_client_ctx_t *ctx,
1781193323Sed                      apr_pool_t *pool)
1782193323Sed{
1783198090Srdivacky  apr_array_header_t *ranges_to_merge =
1784193323Sed    apr_array_make(pool, 1, sizeof(svn_opt_revision_range_t *));
1785193323Sed
1786193323Sed  APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *)
1787193323Sed    = svn_opt__revision_range_create(revision1, revision2, pool);
1788193323Sed  return svn_client_merge_peg3(source, ranges_to_merge,
1789193323Sed                               peg_revision,
1790198090Srdivacky                               target_wcpath,
1791193323Sed                               SVN_DEPTH_INFINITY_OR_FILES(recurse),
1792193323Sed                               ignore_ancestry, force, FALSE, dry_run,
1793193323Sed                               merge_options, ctx, pool);
1794193323Sed}
1795193323Sed
1796193323Sedsvn_error_t *
1797193323Sedsvn_client_merge_peg(const char *source,
1798193323Sed                     const svn_opt_revision_t *revision1,
1799193323Sed                     const svn_opt_revision_t *revision2,
1800193323Sed                     const svn_opt_revision_t *peg_revision,
1801193323Sed                     const char *target_wcpath,
1802193323Sed                     svn_boolean_t recurse,
1803193323Sed                     svn_boolean_t ignore_ancestry,
1804198090Srdivacky                     svn_boolean_t force,
1805193323Sed                     svn_boolean_t dry_run,
1806193323Sed                     svn_client_ctx_t *ctx,
1807193323Sed                     apr_pool_t *pool)
1808193323Sed{
1809193323Sed  return svn_client_merge_peg2(source, revision1, revision2, peg_revision,
1810193323Sed                               target_wcpath, recurse, ignore_ancestry, force,
1811193323Sed                               dry_run, NULL, ctx, pool);
1812193323Sed}
1813193323Sed
1814193323Sed/*** From prop_commands.c ***/
1815193323Sedsvn_error_t *
1816193323Sedsvn_client_propset3(svn_commit_info_t **commit_info_p,
1817193323Sed                    const char *propname,
1818193323Sed                    const svn_string_t *propval,
1819193323Sed                    const char *target,
1820193323Sed                    svn_depth_t depth,
1821193323Sed                    svn_boolean_t skip_checks,
1822193323Sed                    svn_revnum_t base_revision_for_url,
1823193323Sed                    const apr_array_header_t *changelists,
1824193323Sed                    const apr_hash_t *revprop_table,
1825193323Sed                    svn_client_ctx_t *ctx,
1826193323Sed                    apr_pool_t *pool)
1827193323Sed{
1828193323Sed  if (svn_path_is_url(target))
1829193323Sed    {
1830193323Sed      struct capture_baton_t cb;
1831193323Sed
1832193323Sed      cb.info = commit_info_p;
1833193323Sed      cb.pool = pool;
1834193323Sed
1835193323Sed      SVN_ERR(svn_client_propset_remote(propname, propval, target, skip_checks,
1836193323Sed                                        base_revision_for_url, revprop_table,
1837193323Sed                                        capture_commit_info, &cb, ctx, pool));
1838193323Sed    }
1839193323Sed  else
1840193323Sed    {
1841193323Sed      apr_array_header_t *targets = apr_array_make(pool, 1,
1842193323Sed                                                   sizeof(const char *));
1843193323Sed
1844193323Sed      APR_ARRAY_PUSH(targets, const char *) = target;
1845198090Srdivacky      SVN_ERR(svn_client_propset_local(propname, propval, targets, depth,
1846193323Sed                                       skip_checks, changelists, ctx, pool));
1847193323Sed    }
1848193323Sed
1849193323Sed  return SVN_NO_ERROR;
1850193323Sed}
1851193323Sed
1852193323Sedsvn_error_t *
1853193323Sedsvn_client_propset2(const char *propname,
1854193323Sed                    const svn_string_t *propval,
1855193323Sed                    const char *target,
1856193323Sed                    svn_boolean_t recurse,
1857198090Srdivacky                    svn_boolean_t skip_checks,
1858193323Sed                    svn_client_ctx_t *ctx,
1859193323Sed                    apr_pool_t *pool)
1860193323Sed{
1861193323Sed  return svn_client_propset3(NULL, propname, propval, target,
1862193323Sed                             SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
1863193323Sed                             skip_checks, SVN_INVALID_REVNUM,
1864193323Sed                             NULL, NULL, ctx, pool);
1865193323Sed}
1866193323Sed
1867193323Sed
1868193323Sedsvn_error_t *
1869193323Sedsvn_client_propset(const char *propname,
1870198090Srdivacky                   const svn_string_t *propval,
1871193323Sed                   const char *target,
1872193323Sed                   svn_boolean_t recurse,
1873193323Sed                   apr_pool_t *pool)
1874193323Sed{
1875193323Sed  svn_client_ctx_t *ctx;
1876193323Sed
1877193323Sed  SVN_ERR(svn_client_create_context(&ctx, pool));
1878193323Sed
1879193323Sed  return svn_client_propset2(propname, propval, target, recurse, FALSE,
1880193323Sed                             ctx, pool);
1881193323Sed}
1882193323Sed
1883193323Sedsvn_error_t *
1884193323Sedsvn_client_revprop_set(const char *propname,
1885193323Sed                       const svn_string_t *propval,
1886193323Sed                       const char *URL,
1887193323Sed                       const svn_opt_revision_t *revision,
1888193323Sed                       svn_revnum_t *set_rev,
1889193323Sed                       svn_boolean_t force,
1890193323Sed                       svn_client_ctx_t *ctx,
1891193323Sed                       apr_pool_t *pool)
1892193323Sed{
1893193323Sed  return svn_client_revprop_set2(propname, propval, NULL, URL,
1894193323Sed                                 revision, set_rev, force, ctx, pool);
1895193323Sed
1896193323Sed}
1897193323Sed
1898193323Sedsvn_error_t *
1899193323Sedsvn_client_propget4(apr_hash_t **props,
1900193323Sed                    const char *propname,
1901193323Sed                    const char *target,
1902193323Sed                    const svn_opt_revision_t *peg_revision,
1903193323Sed                    const svn_opt_revision_t *revision,
1904193323Sed                    svn_revnum_t *actual_revnum,
1905193323Sed                    svn_depth_t depth,
1906193323Sed                    const apr_array_header_t *changelists,
1907193323Sed                    svn_client_ctx_t *ctx,
1908193323Sed                    apr_pool_t *result_pool,
1909193323Sed                    apr_pool_t *scratch_pool)
1910193323Sed{
1911193323Sed  return svn_error_trace(svn_client_propget5(props, NULL, propname, target,
1912193323Sed                                             peg_revision, revision,
1913193323Sed                                             actual_revnum, depth,
1914193323Sed                                             changelists, ctx,
1915193323Sed                                             result_pool, scratch_pool));
1916193323Sed}
1917193323Sed
1918193323Sedsvn_error_t *
1919193323Sedsvn_client_propget3(apr_hash_t **props,
1920193323Sed                    const char *propname,
1921193323Sed                    const char *path_or_url,
1922193323Sed                    const svn_opt_revision_t *peg_revision,
1923193323Sed                    const svn_opt_revision_t *revision,
1924193323Sed                    svn_revnum_t *actual_revnum,
1925193323Sed                    svn_depth_t depth,
1926193323Sed                    const apr_array_header_t *changelists,
1927193323Sed                    svn_client_ctx_t *ctx,
1928193323Sed                    apr_pool_t *pool)
1929193323Sed{
1930193323Sed  const char *target;
1931193323Sed  apr_hash_t *temp_props;
1932193323Sed  svn_error_t *err;
1933193323Sed
1934193323Sed  if (svn_path_is_url(path_or_url))
1935193323Sed    target = path_or_url;
1936193323Sed  else
1937193323Sed    SVN_ERR(svn_dirent_get_absolute(&target, path_or_url, pool));
1938193323Sed
1939193323Sed  err = svn_client_propget4(&temp_props, propname, target,
1940193323Sed                            peg_revision, revision, actual_revnum,
1941193323Sed                            depth, changelists, ctx, pool, pool);
1942193323Sed
1943193323Sed  if (err && err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE)
1944193323Sed    {
1945193323Sed      err->apr_err = SVN_ERR_ENTRY_NOT_FOUND;
1946193323Sed      return svn_error_trace(err);
1947193323Sed    }
1948193323Sed  else
1949193323Sed    SVN_ERR(err);
1950193323Sed
1951193323Sed  if (actual_revnum
1952193323Sed        && !svn_path_is_url(path_or_url)
1953193323Sed        && !SVN_IS_VALID_REVNUM(*actual_revnum))
1954193323Sed    {
1955193323Sed      /* Get the actual_revnum; added nodes have no revision yet, and old
1956193323Sed       * callers expected the mock-up revision of 0. */
1957193323Sed      svn_boolean_t added;
1958193323Sed
1959193323Sed      SVN_ERR(svn_wc__node_is_added(&added, ctx->wc_ctx, target, pool));
1960193323Sed      if (added)
1961193323Sed        *actual_revnum = 0;
1962193323Sed    }
1963193323Sed
1964193323Sed  /* We may need to fix up our hash keys for legacy callers. */
1965193323Sed  if (!svn_path_is_url(path_or_url) && strcmp(target, path_or_url) != 0)
1966193323Sed    {
1967193323Sed      apr_hash_index_t *hi;
1968193323Sed
1969193323Sed      *props = apr_hash_make(pool);
1970193323Sed      for (hi = apr_hash_first(pool, temp_props); hi;
1971193323Sed            hi = apr_hash_next(hi))
1972193323Sed        {
1973193323Sed          const char *abspath = svn__apr_hash_index_key(hi);
1974193323Sed          svn_string_t *value = svn__apr_hash_index_val(hi);
1975193323Sed          const char *relpath = svn_dirent_join(path_or_url,
1976198090Srdivacky                                     svn_dirent_skip_ancestor(target, abspath),
1977198090Srdivacky                                     pool);
1978193323Sed
1979193323Sed          svn_hash_sets(*props, relpath, value);
1980193323Sed        }
1981193323Sed    }
1982193323Sed  else
1983193323Sed    *props = temp_props;
1984193323Sed
1985193323Sed  return SVN_NO_ERROR;
1986193323Sed}
1987193323Sed
1988193323Sedsvn_error_t *
1989198090Srdivackysvn_client_propget2(apr_hash_t **props,
1990193323Sed                    const char *propname,
1991193323Sed                    const char *target,
1992193323Sed                    const svn_opt_revision_t *peg_revision,
1993193323Sed                    const svn_opt_revision_t *revision,
1994193323Sed                    svn_boolean_t recurse,
1995193323Sed                    svn_client_ctx_t *ctx,
1996193323Sed                    apr_pool_t *pool)
1997193323Sed{
1998193323Sed  return svn_client_propget3(props,
1999193323Sed                             propname,
2000193323Sed                             target,
2001193323Sed                             peg_revision,
2002193323Sed                             revision,
2003193323Sed                             NULL,
2004193323Sed                             SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
2005193323Sed                             NULL,
2006193323Sed                             ctx,
2007193323Sed                             pool);
2008193323Sed}
2009193323Sed
2010193323Sedsvn_error_t *
2011193323Sedsvn_client_propget(apr_hash_t **props,
2012193323Sed                   const char *propname,
2013193323Sed                   const char *target,
2014193323Sed                   const svn_opt_revision_t *revision,
2015193323Sed                   svn_boolean_t recurse,
2016193323Sed                   svn_client_ctx_t *ctx,
2017193323Sed                   apr_pool_t *pool)
2018193323Sed{
2019193323Sed  return svn_client_propget2(props, propname, target, revision, revision,
2020193323Sed                             recurse, ctx, pool);
2021193323Sed}
2022193323Sed
2023193323Sed
2024193323Sed/* Duplicate a HASH containing (char * -> svn_string_t *) key/value
2025193323Sed   pairs using POOL. */
2026193323Sedstatic apr_hash_t *
2027193323Sedstring_hash_dup(apr_hash_t *hash, apr_pool_t *pool)
2028193323Sed{
2029193323Sed  apr_hash_index_t *hi;
2030193323Sed  apr_hash_t *new_hash = apr_hash_make(pool);
2031193323Sed
2032193323Sed  for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
2033193323Sed    {
2034193323Sed      const char *key = apr_pstrdup(pool, svn__apr_hash_index_key(hi));
2035193323Sed      apr_ssize_t klen = svn__apr_hash_index_klen(hi);
2036193323Sed      svn_string_t *val = svn_string_dup(svn__apr_hash_index_val(hi), pool);
2037193323Sed
2038193323Sed      apr_hash_set(new_hash, key, klen, val);
2039193323Sed    }
2040193323Sed  return new_hash;
2041193323Sed}
2042193323Sed
2043193323Sedsvn_client_proplist_item_t *
2044193323Sedsvn_client_proplist_item_dup(const svn_client_proplist_item_t *item,
2045193323Sed                             apr_pool_t * pool)
2046193323Sed{
2047193323Sed  svn_client_proplist_item_t *new_item = apr_pcalloc(pool, sizeof(*new_item));
2048193323Sed
2049193323Sed  if (item->node_name)
2050193323Sed    new_item->node_name = svn_stringbuf_dup(item->node_name, pool);
2051193323Sed
2052193323Sed  if (item->prop_hash)
2053193323Sed    new_item->prop_hash = string_hash_dup(item->prop_hash, pool);
2054193323Sed
2055193323Sed  return new_item;
2056193323Sed}
2057193323Sed
2058193323Sed/* Baton for use with wrap_proplist_receiver */
2059193323Sedstruct proplist_receiver_wrapper_baton {
2060193323Sed  void *baton;
2061193323Sed  svn_proplist_receiver_t receiver;
2062193323Sed};
2063193323Sed
2064193323Sed/* This implements svn_client_proplist_receiver2_t */
2065193323Sedstatic svn_error_t *
2066193323Sedproplist_wrapper_receiver(void *baton,
2067193323Sed                          const char *path,
2068193323Sed                          apr_hash_t *prop_hash,
2069193323Sed                          apr_array_header_t *inherited_props,
2070193323Sed                          apr_pool_t *pool)
2071193323Sed{
2072193323Sed  struct proplist_receiver_wrapper_baton *plrwb = baton;
2073193323Sed
2074193323Sed  if (plrwb->receiver)
2075193323Sed    return plrwb->receiver(plrwb->baton, path, prop_hash, pool);
2076193323Sed
2077193323Sed  return SVN_NO_ERROR;
2078193323Sed}
2079193323Sed
2080193323Sedstatic void
2081193323Sedwrap_proplist_receiver(svn_proplist_receiver2_t *receiver2,
2082193323Sed                       void **receiver2_baton,
2083193323Sed                       svn_proplist_receiver_t receiver,
2084193323Sed                       void *receiver_baton,
2085193323Sed                       apr_pool_t *pool)
2086193323Sed{
2087193323Sed  struct proplist_receiver_wrapper_baton *plrwb = apr_palloc(pool,
2088193323Sed                                                             sizeof(*plrwb));
2089193323Sed
2090193323Sed  /* Set the user provided old format callback in the baton. */
2091193323Sed  plrwb->baton = receiver_baton;
2092193323Sed  plrwb->receiver = receiver;
2093193323Sed
2094193323Sed  *receiver2_baton = plrwb;
2095193323Sed  *receiver2 = proplist_wrapper_receiver;
2096193323Sed}
2097193323Sed
2098193323Sedsvn_error_t *
2099193323Sedsvn_client_proplist3(const char *target,
2100193323Sed                     const svn_opt_revision_t *peg_revision,
2101193323Sed                     const svn_opt_revision_t *revision,
2102193323Sed                     svn_depth_t depth,
2103193323Sed                     const apr_array_header_t *changelists,
2104193323Sed                     svn_proplist_receiver_t receiver,
2105193323Sed                     void *receiver_baton,
2106193323Sed                     svn_client_ctx_t *ctx,
2107193323Sed                     apr_pool_t *pool)
2108193323Sed{
2109193323Sed
2110193323Sed  svn_proplist_receiver2_t receiver2;
2111193323Sed  void *receiver2_baton;
2112193323Sed
2113193323Sed  wrap_proplist_receiver(&receiver2, &receiver2_baton, receiver, receiver_baton,
2114193323Sed                         pool);
2115193323Sed
2116193323Sed  return svn_error_trace(svn_client_proplist4(target, peg_revision, revision,
2117193323Sed                                              depth, changelists, FALSE,
2118193323Sed                                              receiver2, receiver2_baton,
2119193323Sed                                              ctx, pool));
2120193323Sed}
2121193323Sed
2122193323Sed/* Receiver baton used by proplist2() */
2123193323Sedstruct proplist_receiver_baton {
2124193323Sed  apr_array_header_t *props;
2125193323Sed  apr_pool_t *pool;
2126193323Sed};
2127193323Sed
2128193323Sed/* Receiver function used by proplist2(). */
2129193323Sedstatic svn_error_t *
2130193323Sedproplist_receiver_cb(void *baton,
2131193323Sed                     const char *path,
2132193323Sed                     apr_hash_t *prop_hash,
2133193323Sed                     apr_pool_t *pool)
2134193323Sed{
2135193323Sed  struct proplist_receiver_baton *pl_baton =
2136193323Sed    (struct proplist_receiver_baton *) baton;
2137193323Sed  svn_client_proplist_item_t *tmp_item = apr_palloc(pool, sizeof(*tmp_item));
2138193323Sed  svn_client_proplist_item_t *item;
2139193323Sed
2140193323Sed  /* Because the pool passed to the receiver function is likely to be a
2141193323Sed     temporary pool of some kind, we need to make copies of *path and
2142193323Sed     *prop_hash in the pool provided by the baton. */
2143193323Sed  tmp_item->node_name = svn_stringbuf_create(path, pl_baton->pool);
2144193323Sed  tmp_item->prop_hash = prop_hash;
2145193323Sed
2146193323Sed  item = svn_client_proplist_item_dup(tmp_item, pl_baton->pool);
2147193323Sed
2148193323Sed  APR_ARRAY_PUSH(pl_baton->props, const svn_client_proplist_item_t *) = item;
2149193323Sed
2150193323Sed  return SVN_NO_ERROR;
2151193323Sed}
2152193323Sed
2153193323Sedsvn_error_t *
2154193323Sedsvn_client_proplist2(apr_array_header_t **props,
2155193323Sed                     const char *target,
2156193323Sed                     const svn_opt_revision_t *peg_revision,
2157193323Sed                     const svn_opt_revision_t *revision,
2158193323Sed                     svn_boolean_t recurse,
2159193323Sed                     svn_client_ctx_t *ctx,
2160193323Sed                     apr_pool_t *pool)
2161193323Sed{
2162193323Sed  struct proplist_receiver_baton pl_baton;
2163193323Sed
2164193323Sed  *props = apr_array_make(pool, 5, sizeof(svn_client_proplist_item_t *));
2165193323Sed  pl_baton.props = *props;
2166193323Sed  pl_baton.pool = pool;
2167193323Sed
2168193323Sed  return svn_client_proplist3(target, peg_revision, revision,
2169193323Sed                              SVN_DEPTH_INFINITY_OR_EMPTY(recurse), NULL,
2170193323Sed                              proplist_receiver_cb, &pl_baton, ctx, pool);
2171193323Sed}
2172193323Sed
2173193323Sed
2174193323Sedsvn_error_t *
2175193323Sedsvn_client_proplist(apr_array_header_t **props,
2176193323Sed                    const char *target,
2177193323Sed                    const svn_opt_revision_t *revision,
2178193323Sed                    svn_boolean_t recurse,
2179193323Sed                    svn_client_ctx_t *ctx,
2180193323Sed                    apr_pool_t *pool)
2181193323Sed{
2182193323Sed  return svn_client_proplist2(props, target, revision, revision,
2183193323Sed                              recurse, ctx, pool);
2184193323Sed}
2185193323Sed
2186193323Sed/*** From status.c ***/
2187193323Sed
2188193323Sedstruct status4_wrapper_baton
2189193323Sed{
2190193323Sed  svn_wc_context_t *wc_ctx;
2191193323Sed  svn_wc_status_func3_t old_func;
2192193323Sed  void *old_baton;
2193193323Sed};
2194193323Sed
2195193323Sed/* Implements svn_client_status_func_t */
2196193323Sedstatic svn_error_t *
2197193323Sedstatus4_wrapper_func(void *baton,
2198193323Sed                     const char *path,
2199193323Sed                     const svn_client_status_t *status,
2200193323Sed                     apr_pool_t *scratch_pool)
2201193323Sed{
2202193323Sed  struct status4_wrapper_baton *swb = baton;
2203193323Sed  svn_wc_status2_t *dup;
2204193323Sed  const char *local_abspath;
2205193323Sed  const svn_wc_status3_t *wc_status = status->backwards_compatibility_baton;
2206193323Sed
2207193323Sed  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
2208198090Srdivacky  SVN_ERR(svn_wc__status2_from_3(&dup, wc_status, swb->wc_ctx,
2209198090Srdivacky                                 local_abspath, scratch_pool,
2210198090Srdivacky                                 scratch_pool));
2211198090Srdivacky
2212193323Sed  return (*swb->old_func)(swb->old_baton, path, dup, scratch_pool);
2213198090Srdivacky}
2214198090Srdivacky
2215198090Srdivackysvn_error_t *
2216198090Srdivackysvn_client_status4(svn_revnum_t *result_rev,
2217198090Srdivacky                   const char *path,
2218198090Srdivacky                   const svn_opt_revision_t *revision,
2219198090Srdivacky                   svn_wc_status_func3_t status_func,
2220198090Srdivacky                   void *status_baton,
2221198090Srdivacky                   svn_depth_t depth,
2222193323Sed                   svn_boolean_t get_all,
2223193323Sed                   svn_boolean_t update,
2224193323Sed                   svn_boolean_t no_ignore,
2225193323Sed                   svn_boolean_t ignore_externals,
2226193323Sed                   const apr_array_header_t *changelists,
2227193323Sed                   svn_client_ctx_t *ctx,
2228193323Sed                   apr_pool_t *pool)
2229193323Sed{
2230193323Sed  struct status4_wrapper_baton swb;
2231193323Sed
2232193323Sed  swb.wc_ctx = ctx->wc_ctx;
2233193323Sed  swb.old_func = status_func;
2234193323Sed  swb.old_baton = status_baton;
2235193323Sed
2236193323Sed  return svn_client_status5(result_rev, ctx, path, revision, depth, get_all,
2237198090Srdivacky                            update, no_ignore, ignore_externals, TRUE,
2238193323Sed                            changelists, status4_wrapper_func, &swb, pool);
2239193323Sed}
2240193323Sed
2241193323Sedstruct status3_wrapper_baton
2242193323Sed{
2243193323Sed  svn_wc_status_func2_t old_func;
2244193323Sed  void *old_baton;
2245193323Sed};
2246193323Sed
2247193323Sedstatic svn_error_t *
2248198090Srdivackystatus3_wrapper_func(void *baton,
2249193323Sed                     const char *path,
2250193323Sed                     svn_wc_status2_t *status,
2251193323Sed                     apr_pool_t *pool)
2252193323Sed{
2253193323Sed  struct status3_wrapper_baton *swb = baton;
2254193323Sed
2255193323Sed  swb->old_func(swb->old_baton, path, status);
2256193323Sed  return SVN_NO_ERROR;
2257193323Sed}
2258193323Sed
2259193323Sedsvn_error_t *
2260193323Sedsvn_client_status3(svn_revnum_t *result_rev,
2261193323Sed                   const char *path,
2262193323Sed                   const svn_opt_revision_t *revision,
2263193323Sed                   svn_wc_status_func2_t status_func,
2264193323Sed                   void *status_baton,
2265198090Srdivacky                   svn_depth_t depth,
2266193323Sed                   svn_boolean_t get_all,
2267193323Sed                   svn_boolean_t update,
2268193323Sed                   svn_boolean_t no_ignore,
2269193323Sed                   svn_boolean_t ignore_externals,
2270193323Sed                   const apr_array_header_t *changelists,
2271193323Sed                   svn_client_ctx_t *ctx,
2272193323Sed                   apr_pool_t *pool)
2273193323Sed{
2274193323Sed  struct status3_wrapper_baton swb = { 0 };
2275193323Sed  swb.old_func = status_func;
2276193323Sed  swb.old_baton = status_baton;
2277193323Sed  return svn_client_status4(result_rev, path, revision, status3_wrapper_func,
2278193323Sed                            &swb, depth, get_all, update, no_ignore,
2279193323Sed                            ignore_externals, changelists, ctx, pool);
2280193323Sed}
2281193323Sed
2282193323Sedsvn_error_t *
2283198090Srdivackysvn_client_status2(svn_revnum_t *result_rev,
2284193323Sed                   const char *path,
2285193323Sed                   const svn_opt_revision_t *revision,
2286193323Sed                   svn_wc_status_func2_t status_func,
2287193323Sed                   void *status_baton,
2288193323Sed                   svn_boolean_t recurse,
2289193323Sed                   svn_boolean_t get_all,
2290193323Sed                   svn_boolean_t update,
2291193323Sed                   svn_boolean_t no_ignore,
2292193323Sed                   svn_boolean_t ignore_externals,
2293193323Sed                   svn_client_ctx_t *ctx,
2294193323Sed                   apr_pool_t *pool)
2295193323Sed{
2296193323Sed  return svn_client_status3(result_rev, path, revision,
2297193323Sed                            status_func, status_baton,
2298193323Sed                            SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse),
2299193323Sed                            get_all, update, no_ignore, ignore_externals, NULL,
2300193323Sed                            ctx, pool);
2301193323Sed}
2302193323Sed
2303193323Sed
2304193323Sed/* Baton for old_status_func_cb; does what you think it does. */
2305193323Sedstruct old_status_func_cb_baton
2306193323Sed{
2307193323Sed  svn_wc_status_func_t original_func;
2308193323Sed  void *original_baton;
2309193323Sed};
2310193323Sed
2311193323Sed/* Help svn_client_status() accept an old-style status func and baton,
2312193323Sed   by wrapping them before passing along to svn_client_status2().
2313193323Sed
2314193323Sed   This implements the 'svn_wc_status_func2_t' function type. */
2315193323Sedstatic void old_status_func_cb(void *baton,
2316193323Sed                               const char *path,
2317193323Sed                               svn_wc_status2_t *status)
2318193323Sed{
2319193323Sed  struct old_status_func_cb_baton *b = baton;
2320193323Sed  svn_wc_status_t *stat = (svn_wc_status_t *) status;
2321193323Sed
2322193323Sed  b->original_func(b->original_baton, path, stat);
2323193323Sed}
2324193323Sed
2325193323Sed
2326193323Sedsvn_error_t *
2327193323Sedsvn_client_status(svn_revnum_t *result_rev,
2328193323Sed                  const char *path,
2329193323Sed                  svn_opt_revision_t *revision,
2330193323Sed                  svn_wc_status_func_t status_func,
2331193323Sed                  void *status_baton,
2332193323Sed                  svn_boolean_t recurse,
2333193323Sed                  svn_boolean_t get_all,
2334193323Sed                  svn_boolean_t update,
2335193323Sed                  svn_boolean_t no_ignore,
2336193323Sed                  svn_client_ctx_t *ctx,
2337193323Sed                  apr_pool_t *pool)
2338193323Sed{
2339193323Sed  struct old_status_func_cb_baton *b = apr_pcalloc(pool, sizeof(*b));
2340193323Sed  b->original_func = status_func;
2341198090Srdivacky  b->original_baton = status_baton;
2342193323Sed
2343193323Sed  return svn_client_status2(result_rev, path, revision,
2344193323Sed                            old_status_func_cb, b,
2345193323Sed                            recurse, get_all, update, no_ignore, FALSE,
2346193323Sed                            ctx, pool);
2347193323Sed}
2348193323Sed
2349193323Sed/*** From update.c ***/
2350193323Sedsvn_error_t *
2351193323Sedsvn_client_update3(apr_array_header_t **result_revs,
2352193323Sed                   const apr_array_header_t *paths,
2353193323Sed                   const svn_opt_revision_t *revision,
2354193323Sed                   svn_depth_t depth,
2355193323Sed                   svn_boolean_t depth_is_sticky,
2356193323Sed                   svn_boolean_t ignore_externals,
2357193323Sed                   svn_boolean_t allow_unver_obstructions,
2358193323Sed                   svn_client_ctx_t *ctx,
2359193323Sed                   apr_pool_t *pool)
2360193323Sed{
2361193323Sed  return svn_client_update4(result_revs, paths, revision,
2362193323Sed                            depth, depth_is_sticky, ignore_externals,
2363193323Sed                            allow_unver_obstructions, TRUE, FALSE,
2364193323Sed                            ctx, pool);
2365193323Sed}
2366193323Sed
2367193323Sedsvn_error_t *
2368193323Sedsvn_client_update2(apr_array_header_t **result_revs,
2369193323Sed                   const apr_array_header_t *paths,
2370193323Sed                   const svn_opt_revision_t *revision,
2371193323Sed                   svn_boolean_t recurse,
2372193323Sed                   svn_boolean_t ignore_externals,
2373193323Sed                   svn_client_ctx_t *ctx,
2374193323Sed                   apr_pool_t *pool)
2375198090Srdivacky{
2376193323Sed  return svn_client_update3(result_revs, paths, revision,
2377193323Sed                            SVN_DEPTH_INFINITY_OR_FILES(recurse), FALSE,
2378193323Sed                            ignore_externals, FALSE, ctx, pool);
2379193323Sed}
2380193323Sed
2381193323Sedsvn_error_t *
2382193323Sedsvn_client_update(svn_revnum_t *result_rev,
2383193323Sed                  const char *path,
2384193323Sed                  const svn_opt_revision_t *revision,
2385193323Sed                  svn_boolean_t recurse,
2386193323Sed                  svn_client_ctx_t *ctx,
2387193323Sed                  apr_pool_t *pool)
2388193323Sed{
2389193323Sed  apr_array_header_t *paths = apr_array_make(pool, 1, sizeof(const char *));
2390193323Sed  apr_array_header_t *result_revs;
2391193323Sed
2392193323Sed  APR_ARRAY_PUSH(paths, const char *) = path;
2393193323Sed
2394193323Sed  SVN_ERR(svn_client_update2(&result_revs, paths, revision, recurse, FALSE,
2395193323Sed                             ctx, pool));
2396193323Sed
2397193323Sed  *result_rev = APR_ARRAY_IDX(result_revs, 0, svn_revnum_t);
2398193323Sed
2399193323Sed  return SVN_NO_ERROR;
2400193323Sed}
2401193323Sed
2402193323Sed/*** From switch.c ***/
2403193323Sedsvn_error_t *
2404193323Sedsvn_client_switch2(svn_revnum_t *result_rev,
2405193323Sed                   const char *path,
2406193323Sed                   const char *switch_url,
2407193323Sed                   const svn_opt_revision_t *peg_revision,
2408193323Sed                   const svn_opt_revision_t *revision,
2409193323Sed                   svn_depth_t depth,
2410193323Sed                   svn_boolean_t depth_is_sticky,
2411193323Sed                   svn_boolean_t ignore_externals,
2412193323Sed                   svn_boolean_t allow_unver_obstructions,
2413193323Sed                   svn_client_ctx_t *ctx,
2414193323Sed                   apr_pool_t *pool)
2415193323Sed{
2416193323Sed  return svn_client_switch3(result_rev, path, switch_url, peg_revision,
2417193323Sed                            revision, depth, depth_is_sticky, ignore_externals,
2418193323Sed                            allow_unver_obstructions,
2419193323Sed                            TRUE /* ignore_ancestry */,
2420193323Sed                            ctx, pool);
2421193323Sed}
2422193323Sed
2423193323Sedsvn_error_t *
2424193323Sedsvn_client_switch(svn_revnum_t *result_rev,
2425193323Sed                  const char *path,
2426193323Sed                  const char *switch_url,
2427193323Sed                  const svn_opt_revision_t *revision,
2428193323Sed                  svn_boolean_t recurse,
2429193323Sed                  svn_client_ctx_t *ctx,
2430193323Sed                  apr_pool_t *pool)
2431193323Sed{
2432193323Sed  svn_opt_revision_t peg_revision;
2433193323Sed  peg_revision.kind = svn_opt_revision_unspecified;
2434193323Sed  return svn_client_switch2(result_rev, path, switch_url,
2435193323Sed                            &peg_revision, revision,
2436193323Sed                            SVN_DEPTH_INFINITY_OR_FILES(recurse),
2437193323Sed                            FALSE, FALSE, FALSE, ctx, pool);
2438193323Sed}
2439193323Sed
2440193323Sed/*** From cat.c ***/
2441193323Sedsvn_error_t *
2442193323Sedsvn_client_cat(svn_stream_t *out,
2443193323Sed               const char *path_or_url,
2444193323Sed               const svn_opt_revision_t *revision,
2445193323Sed               svn_client_ctx_t *ctx,
2446193323Sed               apr_pool_t *pool)
2447193323Sed{
2448193323Sed  return svn_client_cat2(out, path_or_url, revision, revision,
2449193323Sed                         ctx, pool);
2450193323Sed}
2451193323Sed
2452193323Sed/*** From checkout.c ***/
2453193323Sedsvn_error_t *
2454193323Sedsvn_client_checkout2(svn_revnum_t *result_rev,
2455193323Sed                     const char *URL,
2456193323Sed                     const char *path,
2457193323Sed                     const svn_opt_revision_t *peg_revision,
2458193323Sed                     const svn_opt_revision_t *revision,
2459193323Sed                     svn_boolean_t recurse,
2460193323Sed                     svn_boolean_t ignore_externals,
2461193323Sed                     svn_client_ctx_t *ctx,
2462193323Sed                     apr_pool_t *pool)
2463193323Sed{
2464193323Sed  return svn_error_trace(svn_client_checkout3(result_rev, URL, path,
2465193323Sed                                        peg_revision, revision,
2466193323Sed                                        SVN_DEPTH_INFINITY_OR_FILES(recurse),
2467193323Sed                                        ignore_externals, FALSE, ctx, pool));
2468193323Sed}
2469193323Sed
2470193323Sedsvn_error_t *
2471193323Sedsvn_client_checkout(svn_revnum_t *result_rev,
2472193323Sed                    const char *URL,
2473193323Sed                    const char *path,
2474193323Sed                    const svn_opt_revision_t *revision,
2475193323Sed                    svn_boolean_t recurse,
2476193323Sed                    svn_client_ctx_t *ctx,
2477193323Sed                    apr_pool_t *pool)
2478193323Sed{
2479193323Sed  svn_opt_revision_t peg_revision;
2480193323Sed
2481193323Sed  peg_revision.kind = svn_opt_revision_unspecified;
2482193323Sed
2483193323Sed  return svn_error_trace(svn_client_checkout2(result_rev, URL, path,
2484193323Sed                                              &peg_revision, revision, recurse,
2485193323Sed                                              FALSE, ctx, pool));
2486193323Sed}
2487193323Sed
2488193323Sed/*** From info.c ***/
2489193323Sed
2490193323Sedsvn_info_t *
2491193323Sedsvn_info_dup(const svn_info_t *info, apr_pool_t *pool)
2492193323Sed{
2493193323Sed  svn_info_t *dupinfo = apr_palloc(pool, sizeof(*dupinfo));
2494193323Sed
2495193323Sed  /* Perform a trivial copy ... */
2496198090Srdivacky  *dupinfo = *info;
2497193323Sed
2498193323Sed  /* ...and then re-copy stuff that needs to be duped into our pool. */
2499193323Sed  if (info->URL)
2500193323Sed    dupinfo->URL = apr_pstrdup(pool, info->URL);
2501193323Sed  if (info->repos_root_URL)
2502193323Sed    dupinfo->repos_root_URL = apr_pstrdup(pool, info->repos_root_URL);
2503193323Sed  if (info->repos_UUID)
2504193323Sed    dupinfo->repos_UUID = apr_pstrdup(pool, info->repos_UUID);
2505193323Sed  if (info->last_changed_author)
2506193323Sed    dupinfo->last_changed_author = apr_pstrdup(pool,
2507193323Sed                                               info->last_changed_author);
2508193323Sed  if (info->lock)
2509193323Sed    dupinfo->lock = svn_lock_dup(info->lock, pool);
2510193323Sed  if (info->copyfrom_url)
2511193323Sed    dupinfo->copyfrom_url = apr_pstrdup(pool, info->copyfrom_url);
2512193323Sed  if (info->checksum)
2513193323Sed    dupinfo->checksum = apr_pstrdup(pool, info->checksum);
2514193323Sed  if (info->conflict_old)
2515193323Sed    dupinfo->conflict_old = apr_pstrdup(pool, info->conflict_old);
2516193323Sed  if (info->conflict_new)
2517193323Sed    dupinfo->conflict_new = apr_pstrdup(pool, info->conflict_new);
2518193323Sed  if (info->conflict_wrk)
2519193323Sed    dupinfo->conflict_wrk = apr_pstrdup(pool, info->conflict_wrk);
2520193323Sed  if (info->prejfile)
2521193323Sed    dupinfo->prejfile = apr_pstrdup(pool, info->prejfile);
2522193323Sed
2523193323Sed  return dupinfo;
2524193323Sed}
2525193323Sed
2526193323Sed/* Convert an svn_client_info2_t to an svn_info_t, doing shallow copies. */
2527193323Sedstatic svn_error_t *
2528193323Sedinfo_from_info2(svn_info_t **new_info,
2529193323Sed                svn_wc_context_t *wc_ctx,
2530193323Sed                const svn_client_info2_t *info2,
2531198090Srdivacky                apr_pool_t *pool)
2532193323Sed{
2533193323Sed  svn_info_t *info = apr_pcalloc(pool, sizeof(*info));
2534193323Sed
2535193323Sed  info->URL                 = info2->URL;
2536193323Sed  /* Goofy backward compat handling for added nodes. */
2537193323Sed  if (SVN_IS_VALID_REVNUM(info2->rev))
2538193323Sed    info->rev               = info2->rev;
2539193323Sed  else
2540193323Sed    info->rev               = 0;
2541193323Sed
2542193323Sed  info->kind                = info2->kind;
2543193323Sed  info->repos_root_URL      = info2->repos_root_URL;
2544193323Sed  info->repos_UUID          = info2->repos_UUID;
2545193323Sed  info->last_changed_rev    = info2->last_changed_rev;
2546193323Sed  info->last_changed_date   = info2->last_changed_date;
2547193323Sed  info->last_changed_author = info2->last_changed_author;
2548193323Sed
2549193323Sed  /* Stupid old structure has a non-const LOCK member. Sigh.  */
2550193323Sed  info->lock                = (svn_lock_t *)info2->lock;
2551193323Sed
2552193323Sed  info->size64              = info2->size;
2553193323Sed  if (info2->size == SVN_INVALID_FILESIZE)
2554193323Sed    info->size               = SVN_INFO_SIZE_UNKNOWN;
2555193323Sed  else if (((svn_filesize_t)(apr_size_t)info->size64) == info->size64)
2556193323Sed    info->size               = (apr_size_t)info->size64;
2557193323Sed  else /* >= 4GB */
2558193323Sed    info->size               = SVN_INFO_SIZE_UNKNOWN;
2559193323Sed
2560193323Sed  if (info2->wc_info)
2561193323Sed    {
2562193323Sed      info->has_wc_info         = TRUE;
2563193323Sed      info->schedule            = info2->wc_info->schedule;
2564193323Sed      info->copyfrom_url        = info2->wc_info->copyfrom_url;
2565193323Sed      info->copyfrom_rev        = info2->wc_info->copyfrom_rev;
2566193323Sed      info->text_time           = info2->wc_info->recorded_time;
2567193323Sed      info->prop_time           = 0;
2568193323Sed      if (info2->wc_info->checksum
2569193323Sed            && info2->wc_info->checksum->kind == svn_checksum_md5)
2570193323Sed        info->checksum          = svn_checksum_to_cstring(
2571193323Sed                                        info2->wc_info->checksum, pool);
2572193323Sed      else
2573193323Sed        info->checksum          = NULL;
2574193323Sed      info->changelist          = info2->wc_info->changelist;
2575193323Sed      info->depth               = info2->wc_info->depth;
2576193323Sed
2577193323Sed      if (info->depth == svn_depth_unknown && info->kind == svn_node_file)
2578193323Sed        info->depth = svn_depth_infinity;
2579193323Sed
2580193323Sed      info->working_size64      = info2->wc_info->recorded_size;
2581193323Sed      if (((svn_filesize_t)(apr_size_t)info->working_size64) == info->working_size64)
2582193323Sed        info->working_size       = (apr_size_t)info->working_size64;
2583193323Sed      else /* >= 4GB */
2584193323Sed        info->working_size       = SVN_INFO_SIZE_UNKNOWN;
2585193323Sed    }
2586193323Sed  else
2587193323Sed    {
2588193323Sed      info->has_wc_info           = FALSE;
2589193323Sed      info->working_size          = SVN_INFO_SIZE_UNKNOWN;
2590193323Sed      info->working_size64        = SVN_INVALID_FILESIZE;
2591193323Sed      info->depth                 = svn_depth_unknown;
2592193323Sed    }
2593193323Sed
2594193323Sed  /* Populate conflict fields. */
2595193323Sed  if (info2->wc_info && info2->wc_info->conflicts)
2596193323Sed    {
2597193323Sed      int i;
2598193323Sed
2599193323Sed      for (i = 0; i < info2->wc_info->conflicts->nelts; i++)
2600193323Sed        {
2601193323Sed          const svn_wc_conflict_description2_t *conflict
2602193323Sed                              = APR_ARRAY_IDX(info2->wc_info->conflicts, i,
2603193323Sed                                    const svn_wc_conflict_description2_t *);
2604193323Sed
2605193323Sed          /* ### Not really sure what we should do if we get multiple
2606193323Sed             ### conflicts of the same type. */
2607193323Sed          switch (conflict->kind)
2608193323Sed            {
2609193323Sed              case svn_wc_conflict_kind_tree:
2610193323Sed                info->tree_conflict = svn_wc__cd2_to_cd(conflict, pool);
2611193323Sed                break;
2612193323Sed
2613193323Sed              case svn_wc_conflict_kind_text:
2614193323Sed                info->conflict_old = conflict->base_abspath;
2615193323Sed                info->conflict_new = conflict->my_abspath;
2616193323Sed                info->conflict_wrk = conflict->their_abspath;
2617193323Sed                break;
2618193323Sed
2619193323Sed              case svn_wc_conflict_kind_property:
2620193323Sed                info->prejfile = conflict->their_abspath;
2621193323Sed                break;
2622193323Sed            }
2623193323Sed        }
2624193323Sed    }
2625193323Sed
2626193323Sed  if (info2->wc_info && info2->wc_info->checksum)
2627193323Sed    {
2628193323Sed      const svn_checksum_t *md5_checksum;
2629193323Sed
2630193323Sed      SVN_ERR(svn_wc__node_get_md5_from_sha1(&md5_checksum,
2631193323Sed                                             wc_ctx,
2632193323Sed                                             info2->wc_info->wcroot_abspath,
2633198090Srdivacky                                             info2->wc_info->checksum,
2634193323Sed                                             pool, pool));
2635193323Sed
2636193323Sed      info->checksum = svn_checksum_to_cstring(md5_checksum, pool);
2637193323Sed    }
2638193323Sed
2639193323Sed  *new_info = info;
2640193323Sed  return SVN_NO_ERROR;
2641193323Sed}
2642193323Sed
2643193323Sedstruct info_to_relpath_baton
2644193323Sed{
2645193323Sed  const char *anchor_abspath;
2646193323Sed  const char *anchor_relpath;
2647193323Sed  svn_info_receiver_t info_receiver;
2648193323Sed  void *info_baton;
2649193323Sed  svn_wc_context_t *wc_ctx;
2650198090Srdivacky};
2651193323Sed
2652193323Sedstatic svn_error_t *
2653193323Sedinfo_receiver_relpath_wrapper(void *baton,
2654193323Sed                              const char *abspath_or_url,
2655193323Sed                              const svn_client_info2_t *info2,
2656193323Sed                              apr_pool_t *scratch_pool)
2657193323Sed{
2658193323Sed  struct info_to_relpath_baton *rb = baton;
2659198090Srdivacky  const char *path = abspath_or_url;
2660193323Sed  svn_info_t *info;
2661193323Sed
2662193323Sed  if (rb->anchor_relpath &&
2663193323Sed      svn_dirent_is_ancestor(rb->anchor_abspath, abspath_or_url))
2664193323Sed    {
2665193323Sed      path = svn_dirent_join(rb->anchor_relpath,
2666193323Sed                             svn_dirent_skip_ancestor(rb->anchor_abspath,
2667193323Sed                                                      abspath_or_url),
2668193323Sed                             scratch_pool);
2669193323Sed    }
2670193323Sed
2671193323Sed  SVN_ERR(info_from_info2(&info, rb->wc_ctx, info2, scratch_pool));
2672193323Sed
2673193323Sed  SVN_ERR(rb->info_receiver(rb->info_baton,
2674193323Sed                            path,
2675193323Sed                            info,
2676193323Sed                            scratch_pool));
2677193323Sed
2678193323Sed  return SVN_NO_ERROR;
2679193323Sed}
2680193323Sed
2681193323Sedsvn_error_t *
2682193323Sedsvn_client_info2(const char *path_or_url,
2683193323Sed                 const svn_opt_revision_t *peg_revision,
2684193323Sed                 const svn_opt_revision_t *revision,
2685193323Sed                 svn_info_receiver_t receiver,
2686193323Sed                 void *receiver_baton,
2687193323Sed                 svn_depth_t depth,
2688193323Sed                 const apr_array_header_t *changelists,
2689193323Sed                 svn_client_ctx_t *ctx,
2690193323Sed                 apr_pool_t *pool)
2691193323Sed{
2692193323Sed  struct info_to_relpath_baton rb;
2693193323Sed  const char *abspath_or_url = path_or_url;
2694193323Sed
2695193323Sed  rb.anchor_relpath = NULL;
2696193323Sed  rb.info_receiver = receiver;
2697198090Srdivacky  rb.info_baton = receiver_baton;
2698198090Srdivacky  rb.wc_ctx = ctx->wc_ctx;
2699193323Sed
2700193323Sed  if (!svn_path_is_url(path_or_url))
2701198090Srdivacky    {
2702193323Sed      SVN_ERR(svn_dirent_get_absolute(&abspath_or_url, path_or_url, pool));
2703198090Srdivacky      rb.anchor_abspath = abspath_or_url;
2704198090Srdivacky      rb.anchor_relpath = path_or_url;
2705198090Srdivacky    }
2706198090Srdivacky
2707198090Srdivacky  SVN_ERR(svn_client_info3(abspath_or_url,
2708193323Sed                           peg_revision,
2709193323Sed                           revision,
2710193323Sed                           depth,
2711193323Sed                           FALSE, TRUE,
2712193323Sed                           changelists,
2713193323Sed                           info_receiver_relpath_wrapper,
2714193323Sed                           &rb,
2715193323Sed                           ctx,
2716193323Sed                           pool));
2717193323Sed
2718193323Sed  return SVN_NO_ERROR;
2719193323Sed}
2720193323Sed
2721193323Sedsvn_error_t *
2722193323Sedsvn_client_info(const char *path_or_url,
2723193323Sed                const svn_opt_revision_t *peg_revision,
2724193323Sed                const svn_opt_revision_t *revision,
2725193323Sed                svn_info_receiver_t receiver,
2726193323Sed                void *receiver_baton,
2727193323Sed                svn_boolean_t recurse,
2728193323Sed                svn_client_ctx_t *ctx,
2729193323Sed                apr_pool_t *pool)
2730193323Sed{
2731193323Sed  return svn_client_info2(path_or_url, peg_revision, revision,
2732193323Sed                          receiver, receiver_baton,
2733193323Sed                          SVN_DEPTH_INFINITY_OR_EMPTY(recurse),
2734193323Sed                          NULL, ctx, pool);
2735193323Sed}
2736193323Sed
2737193323Sed/*** From resolved.c ***/
2738193323Sedsvn_error_t *
2739193323Sedsvn_client_resolved(const char *path,
2740193323Sed                    svn_boolean_t recursive,
2741193323Sed                    svn_client_ctx_t *ctx,
2742193323Sed                    apr_pool_t *pool)
2743193323Sed{
2744193323Sed  svn_depth_t depth = SVN_DEPTH_INFINITY_OR_EMPTY(recursive);
2745193323Sed  return svn_client_resolve(path, depth,
2746193323Sed                            svn_wc_conflict_choose_merged, ctx, pool);
2747193323Sed}
2748193323Sed/*** From revert.c ***/
2749193323Sedsvn_error_t *
2750193323Sedsvn_client_revert(const apr_array_header_t *paths,
2751193323Sed                  svn_boolean_t recursive,
2752193323Sed                  svn_client_ctx_t *ctx,
2753193323Sed                  apr_pool_t *pool)
2754193323Sed{
2755193323Sed  return svn_client_revert2(paths, SVN_DEPTH_INFINITY_OR_EMPTY(recursive),
2756193323Sed                            NULL, ctx, pool);
2757193323Sed}
2758193323Sed
2759193323Sed/*** From ra.c ***/
2760193323Sedsvn_error_t *
2761193323Sedsvn_client_open_ra_session(svn_ra_session_t **session,
2762193323Sed                           const char *url,
2763193323Sed                           svn_client_ctx_t *ctx,
2764193323Sed                           apr_pool_t *pool)
2765193323Sed{
2766193323Sed  return svn_error_trace(
2767193323Sed             svn_client_open_ra_session2(session, url,
2768193323Sed                                         NULL, ctx,
2769193323Sed                                         pool, pool));
2770193323Sed}
2771193323Sed
2772193323Sedsvn_error_t *
2773193323Sedsvn_client_uuid_from_url(const char **uuid,
2774193323Sed                         const char *url,
2775193323Sed                         svn_client_ctx_t *ctx,
2776193323Sed                         apr_pool_t *pool)
2777193323Sed{
2778193323Sed  svn_error_t *err;
2779193323Sed  apr_pool_t *subpool = svn_pool_create(pool);
2780193323Sed
2781193323Sed  err = svn_client_get_repos_root(NULL, uuid, url,
2782193323Sed                                  ctx, pool, subpool);
2783193323Sed  /* destroy the RA session */
2784193323Sed  svn_pool_destroy(subpool);
2785193323Sed
2786193323Sed  return svn_error_trace(err);;
2787193323Sed}
2788193323Sed
2789193323Sedsvn_error_t *
2790193323Sedsvn_client_uuid_from_path2(const char **uuid,
2791193323Sed                           const char *local_abspath,
2792193323Sed                           svn_client_ctx_t *ctx,
2793193323Sed                           apr_pool_t *result_pool,
2794193323Sed                           apr_pool_t *scratch_pool)
2795193323Sed{
2796193323Sed  return svn_error_trace(
2797193323Sed      svn_client_get_repos_root(NULL, uuid,
2798193323Sed                                local_abspath, ctx,
2799193323Sed                                result_pool, scratch_pool));
2800193323Sed}
2801193323Sed
2802193323Sedsvn_error_t *
2803193323Sedsvn_client_uuid_from_path(const char **uuid,
2804193323Sed                          const char *path,
2805193323Sed                          svn_wc_adm_access_t *adm_access,
2806193323Sed                          svn_client_ctx_t *ctx,
2807193323Sed                          apr_pool_t *pool)
2808193323Sed{
2809193323Sed  const char *local_abspath;
2810193323Sed
2811193323Sed  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
2812193323Sed  return svn_error_trace(
2813193323Sed    svn_client_uuid_from_path2(uuid, local_abspath, ctx, pool, pool));
2814193323Sed}
2815193323Sed
2816193323Sed/*** From url.c ***/
2817193323Sedsvn_error_t *
2818193323Sedsvn_client_root_url_from_path(const char **url,
2819193323Sed                              const char *path_or_url,
2820193323Sed                              svn_client_ctx_t *ctx,
2821193323Sed                              apr_pool_t *pool)
2822193323Sed{
2823193323Sed  apr_pool_t *subpool = svn_pool_create(pool);
2824193323Sed  svn_error_t *err;
2825193323Sed  if (!svn_path_is_url(path_or_url))
2826193323Sed    SVN_ERR(svn_dirent_get_absolute(&path_or_url, path_or_url, pool));
2827193323Sed
2828193323Sed  err = svn_client_get_repos_root(url, NULL, path_or_url,
2829193323Sed                                  ctx, pool, subpool);
2830193323Sed
2831193323Sed  /* close ra session */
2832193323Sed  svn_pool_destroy(subpool);
2833193323Sed  return svn_error_trace(err);
2834193323Sed}
2835193323Sed
2836193323Sedsvn_error_t *
2837193323Sedsvn_client_url_from_path(const char **url,
2838193323Sed                         const char *path_or_url,
2839193323Sed                         apr_pool_t *pool)
2840193323Sed{
2841193323Sed  svn_client_ctx_t *ctx;
2842193323Sed
2843193323Sed  SVN_ERR(svn_client_create_context(&ctx, pool));
2844193323Sed
2845193323Sed  return svn_client_url_from_path2(url, path_or_url, ctx, pool, pool);
2846193323Sed}
2847193323Sed
2848193323Sed/*** From mergeinfo.c ***/
2849193574Sedsvn_error_t *
2850193574Sedsvn_client_mergeinfo_log(svn_boolean_t finding_merged,
2851193574Sed                         const char *target_path_or_url,
2852193574Sed                         const svn_opt_revision_t *target_peg_revision,
2853193574Sed                         const char *source_path_or_url,
2854193323Sed                         const svn_opt_revision_t *source_peg_revision,
2855193323Sed                         svn_log_entry_receiver_t receiver,
2856193323Sed                         void *receiver_baton,
2857193323Sed                         svn_boolean_t discover_changed_paths,
2858193323Sed                         svn_depth_t depth,
2859193574Sed                         const apr_array_header_t *revprops,
2860193574Sed                         svn_client_ctx_t *ctx,
2861193574Sed                         apr_pool_t *scratch_pool)
2862193323Sed{
2863193323Sed  svn_opt_revision_t start_revision, end_revision;
2864193323Sed
2865193323Sed  start_revision.kind = svn_opt_revision_unspecified;
2866193323Sed  end_revision.kind = svn_opt_revision_unspecified;
2867193323Sed
2868193323Sed  return svn_client_mergeinfo_log2(finding_merged,
2869193323Sed                                   target_path_or_url, target_peg_revision,
2870193323Sed                                   source_path_or_url, source_peg_revision,
2871193323Sed                                   &start_revision, &end_revision,
2872193323Sed                                   receiver, receiver_baton,
2873193323Sed                                   discover_changed_paths, depth, revprops,
2874193323Sed                                   ctx, scratch_pool);
2875193323Sed}
2876193323Sed
2877193323Sedsvn_error_t *
2878193323Sedsvn_client_mergeinfo_log_merged(const char *path_or_url,
2879193323Sed                                const svn_opt_revision_t *peg_revision,
2880193323Sed                                const char *merge_source_path_or_url,
2881193323Sed                                const svn_opt_revision_t *src_peg_revision,
2882193323Sed                                svn_log_entry_receiver_t log_receiver,
2883193323Sed                                void *log_receiver_baton,
2884193323Sed                                svn_boolean_t discover_changed_paths,
2885193323Sed                                const apr_array_header_t *revprops,
2886193323Sed                                svn_client_ctx_t *ctx,
2887193323Sed                                apr_pool_t *pool)
2888193323Sed{
2889193323Sed  return svn_client_mergeinfo_log(TRUE, path_or_url, peg_revision,
2890193323Sed                                  merge_source_path_or_url,
2891193323Sed                                  src_peg_revision,
2892193323Sed                                  log_receiver, log_receiver_baton,
2893193323Sed                                  discover_changed_paths,
2894193323Sed                                  svn_depth_empty, revprops, ctx,
2895193323Sed                                  pool);
2896193323Sed}
2897193323Sed
2898193323Sedsvn_error_t *
2899193323Sedsvn_client_mergeinfo_log_eligible(const char *path_or_url,
2900193323Sed                                  const svn_opt_revision_t *peg_revision,
2901193323Sed                                  const char *merge_source_path_or_url,
2902193323Sed                                  const svn_opt_revision_t *src_peg_revision,
2903193323Sed                                  svn_log_entry_receiver_t log_receiver,
2904193323Sed                                  void *log_receiver_baton,
2905193323Sed                                  svn_boolean_t discover_changed_paths,
2906193323Sed                                  const apr_array_header_t *revprops,
2907198090Srdivacky                                  svn_client_ctx_t *ctx,
2908193323Sed                                  apr_pool_t *pool)
2909193323Sed{
2910193323Sed  return svn_client_mergeinfo_log(FALSE, path_or_url, peg_revision,
2911193323Sed                                  merge_source_path_or_url,
2912193323Sed                                  src_peg_revision,
2913193323Sed                                  log_receiver, log_receiver_baton,
2914193323Sed                                  discover_changed_paths,
2915193323Sed                                  svn_depth_empty, revprops, ctx,
2916193323Sed                                  pool);
2917193323Sed}
2918193323Sed
2919193323Sed/*** From relocate.c ***/
2920193323Sedsvn_error_t *
2921193323Sedsvn_client_relocate(const char *path,
2922193323Sed                    const char *from_prefix,
2923193323Sed                    const char *to_prefix,
2924193323Sed                    svn_boolean_t recurse,
2925193323Sed                    svn_client_ctx_t *ctx,
2926193323Sed                    apr_pool_t *pool)
2927193323Sed{
2928193323Sed  if (! recurse)
2929193323Sed    SVN_ERR(svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
2930193323Sed                             _("Non-recursive relocation not supported")));
2931193323Sed  return svn_client_relocate2(path, from_prefix, to_prefix, TRUE, ctx, pool);
2932193323Sed}
2933193323Sed
2934193323Sed/*** From util.c ***/
2935193323Sedsvn_error_t *
2936193323Sedsvn_client_commit_item_create(const svn_client_commit_item3_t **item,
2937193323Sed                              apr_pool_t *pool)
2938193323Sed{
2939193323Sed  *item = svn_client_commit_item3_create(pool);
2940193323Sed  return SVN_NO_ERROR;
2941193323Sed}
2942193323Sed
2943193323Sedsvn_client_commit_item2_t *
2944193323Sedsvn_client_commit_item2_dup(const svn_client_commit_item2_t *item,
2945193323Sed                            apr_pool_t *pool)
2946193323Sed{
2947193323Sed  svn_client_commit_item2_t *new_item = apr_palloc(pool, sizeof(*new_item));
2948193323Sed
2949193323Sed  *new_item = *item;
2950198090Srdivacky
2951193323Sed  if (new_item->path)
2952193323Sed    new_item->path = apr_pstrdup(pool, new_item->path);
2953193323Sed
2954193323Sed  if (new_item->url)
2955193323Sed    new_item->url = apr_pstrdup(pool, new_item->url);
2956193323Sed
2957193323Sed  if (new_item->copyfrom_url)
2958193323Sed    new_item->copyfrom_url = apr_pstrdup(pool, new_item->copyfrom_url);
2959193323Sed
2960193323Sed  if (new_item->wcprop_changes)
2961193323Sed    new_item->wcprop_changes = svn_prop_array_dup(new_item->wcprop_changes,
2962193323Sed                                                  pool);
2963193323Sed
2964193323Sed  return new_item;
2965193323Sed}
2966193323Sed
2967193323Sed