38
38
static svn_error_t *
39
open_admin_tmp_file (apr_file_t **fp,
39
open_admin_tmp_file(apr_file_t **fp,
43
43
svn_client__callback_baton_t *cb = callback_baton;
45
SVN_ERR (svn_wc_create_tmp_file (fp, cb->base_dir, TRUE, pool));
45
SVN_ERR(svn_wc_create_tmp_file2(fp, NULL, cb->base_dir,
46
svn_io_file_del_on_close, pool));
47
48
return SVN_NO_ERROR;
51
52
static svn_error_t *
52
open_tmp_file (apr_file_t **fp,
53
open_tmp_file(apr_file_t **fp,
56
57
svn_client__callback_baton_t *cb = callback_baton;
57
58
const char *truepath;
58
const char *ignored_filename;
61
truepath = apr_pstrdup (pool, cb->base_dir);
60
if (cb->base_dir && ! cb->read_only_wc)
61
truepath = apr_pstrdup(pool, cb->base_dir);
63
SVN_ERR (svn_io_temp_dir (&truepath, pool));
63
SVN_ERR(svn_io_temp_dir(&truepath, pool));
65
65
/* Tack on a made-up filename. */
66
truepath = svn_path_join (truepath, "tempfile", pool);
66
truepath = svn_path_join(truepath, "tempfile", pool);
68
/* Open a unique file; use APR_DELONCLOSE. */
69
SVN_ERR (svn_io_open_unique_file (fp, &ignored_filename,
70
truepath, ".tmp", TRUE, pool));
68
/* Open a unique file; use APR_DELONCLOSE. */
69
SVN_ERR(svn_io_open_unique_file2(fp, NULL, truepath, ".tmp",
70
svn_io_file_del_on_close, pool));
72
72
return SVN_NO_ERROR;
95
95
svn_client_commit_item2_t *item
96
96
= APR_ARRAY_IDX(cb->commit_items, i,
97
97
svn_client_commit_item2_t *);
98
if (! strcmp (relpath,
99
svn_path_uri_decode (item->url, pool)))
100
return svn_wc_prop_get (value, name, item->path, cb->base_access,
99
svn_path_uri_decode(item->url, pool)))
100
return svn_wc_prop_get(value, name, item->path, cb->base_access,
104
104
return SVN_NO_ERROR;
108
108
else if (cb->base_dir == NULL)
109
109
return SVN_NO_ERROR;
111
return svn_wc_prop_get (value, name,
112
svn_path_join (cb->base_dir, relpath, pool),
113
cb->base_access, pool);
111
return svn_wc_prop_get(value, name,
112
svn_path_join(cb->base_dir, relpath, pool),
113
cb->base_access, pool);
116
116
/* This implements the 'svn_ra_push_wc_prop_func_t' interface. */
117
117
static svn_error_t *
118
push_wc_prop (void *baton,
121
const svn_string_t *value,
118
push_wc_prop(void *baton,
121
const svn_string_t *value,
124
124
svn_client__callback_baton_t *cb = baton;
130
130
return svn_error_createf
131
131
(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
132
132
_("Attempt to set wc property '%s' on '%s' in a non-commit operation"),
133
name, svn_path_local_style (relpath, pool));
133
name, svn_path_local_style(relpath, pool));
135
135
for (i = 0; i < cb->commit_items->nelts; i++)
137
137
svn_client_commit_item2_t *item
138
138
= APR_ARRAY_IDX(cb->commit_items, i, svn_client_commit_item2_t *);
140
if (strcmp (relpath, svn_path_uri_decode (item->url, pool)) == 0)
140
if (strcmp(relpath, svn_path_uri_decode(item->url, pool)) == 0)
142
142
apr_pool_t *cpool = item->wcprop_changes->pool;
143
svn_prop_t *prop = apr_palloc (cpool, sizeof (*prop));
143
svn_prop_t *prop = apr_palloc(cpool, sizeof(*prop));
145
prop->name = apr_pstrdup (cpool, name);
145
prop->name = apr_pstrdup(cpool, name);
149
= svn_string_ncreate (value->data, value->len, cpool);
149
= svn_string_ncreate(value->data, value->len, cpool);
152
152
prop->value = NULL;
154
154
/* Buffer the propchange to take effect during the
155
155
post-commit process. */
156
*((svn_prop_t **) apr_array_push (item->wcprop_changes)) = prop;
156
*((svn_prop_t **) apr_array_push(item->wcprop_changes)) = prop;
157
157
return SVN_NO_ERROR;
165
165
/* This implements the 'svn_ra_set_wc_prop_func_t' interface. */
166
166
static svn_error_t *
167
set_wc_prop (void *baton,
170
const svn_string_t *value,
167
set_wc_prop(void *baton,
170
const svn_string_t *value,
173
173
svn_client__callback_baton_t *cb = baton;
174
174
svn_wc_adm_access_t *adm_access;
175
175
const svn_wc_entry_t *entry;
176
const char *full_path = svn_path_join (cb->base_dir, path, pool);
176
const char *full_path = svn_path_join(cb->base_dir, path, pool);
178
SVN_ERR (svn_wc_entry (&entry, full_path, cb->base_access, FALSE, pool));
178
SVN_ERR(svn_wc_entry(&entry, full_path, cb->base_access, FALSE, pool));
180
return svn_error_createf (SVN_ERR_UNVERSIONED_RESOURCE, NULL,
181
_("'%s' is not under version control"),
182
svn_path_local_style (full_path, pool));
180
return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
181
_("'%s' is not under version control"),
182
svn_path_local_style(full_path, pool));
184
SVN_ERR (svn_wc_adm_retrieve (&adm_access, cb->base_access,
185
(entry->kind == svn_node_dir
187
: svn_path_dirname (full_path, pool)),
184
SVN_ERR(svn_wc_adm_retrieve(&adm_access, cb->base_access,
185
(entry->kind == svn_node_dir
187
: svn_path_dirname(full_path, pool)),
190
190
/* We pass 1 for the 'force' parameter here. Since the property is
191
191
coming from the repository, we definitely want to accept it.
195
195
right, but the conflict would remind the user to make sure.
196
196
Unfortunately, we don't have a clean mechanism for doing that
197
197
here, so we just set the property and hope for the best. */
198
return svn_wc_prop_set2 (name, value, full_path, adm_access, TRUE, pool);
198
return svn_wc_prop_set2(name, value, full_path, adm_access, TRUE, pool);
212
212
/* This implements the `found_entry' prototype in
213
213
`svn_wc_entry_callbacks_t'. */
214
214
static svn_error_t *
215
invalidate_wcprop_for_entry (const char *path,
216
const svn_wc_entry_t *entry,
215
invalidate_wcprop_for_entry(const char *path,
216
const svn_wc_entry_t *entry,
220
220
struct invalidate_wcprop_walk_baton *wb = walk_baton;
221
221
svn_wc_adm_access_t *entry_access;
223
SVN_ERR (svn_wc_adm_retrieve (&entry_access, wb->base_access,
224
((entry->kind == svn_node_dir)
226
: svn_path_dirname (path, pool)),
223
SVN_ERR(svn_wc_adm_retrieve(&entry_access, wb->base_access,
224
((entry->kind == svn_node_dir)
226
: svn_path_dirname(path, pool)),
228
228
/* It doesn't matter if we pass 0 or 1 for force here, since
229
229
property deletion is always permitted. */
230
return svn_wc_prop_set2 (wb->prop_name, NULL, path, entry_access,
230
return svn_wc_prop_set2(wb->prop_name, NULL, path, entry_access,
235
235
/* This implements the `svn_ra_invalidate_wc_props_func_t' interface. */
236
236
static svn_error_t *
237
invalidate_wc_props (void *baton,
239
const char *prop_name,
237
invalidate_wc_props(void *baton,
239
const char *prop_name,
242
242
svn_client__callback_baton_t *cb = baton;
243
243
svn_wc_entry_callbacks_t walk_callbacks;
248
248
wb.prop_name = prop_name;
249
249
walk_callbacks.found_entry = invalidate_wcprop_for_entry;
251
path = svn_path_join (cb->base_dir, path, pool);
252
SVN_ERR (svn_wc_adm_probe_retrieve (&adm_access, cb->base_access, path,
254
SVN_ERR (svn_wc_walk_entries2 (path, adm_access, &walk_callbacks, &wb,
255
FALSE, cb->ctx->cancel_func,
256
cb->ctx->cancel_baton, pool));
251
path = svn_path_join(cb->base_dir, path, pool);
252
SVN_ERR(svn_wc_adm_probe_retrieve(&adm_access, cb->base_access, path,
254
SVN_ERR(svn_wc_walk_entries2(path, adm_access, &walk_callbacks, &wb,
255
FALSE, cb->ctx->cancel_func,
256
cb->ctx->cancel_baton, pool));
258
258
return SVN_NO_ERROR;
263
svn_client__open_ra_session_internal (svn_ra_session_t **ra_session,
264
const char *base_url,
265
const char *base_dir,
266
svn_wc_adm_access_t *base_access,
267
apr_array_header_t *commit_items,
268
svn_boolean_t use_admin,
269
svn_boolean_t read_only_wc,
270
svn_client_ctx_t *ctx,
263
svn_client__open_ra_session_internal(svn_ra_session_t **ra_session,
264
const char *base_url,
265
const char *base_dir,
266
svn_wc_adm_access_t *base_access,
267
apr_array_header_t *commit_items,
268
svn_boolean_t use_admin,
269
svn_boolean_t read_only_wc,
270
svn_client_ctx_t *ctx,
273
svn_ra_callbacks2_t *cbtable = apr_pcalloc (pool, sizeof(*cbtable));
274
svn_client__callback_baton_t *cb = apr_pcalloc (pool, sizeof(*cb));
273
svn_ra_callbacks2_t *cbtable = apr_pcalloc(pool, sizeof(*cbtable));
274
svn_client__callback_baton_t *cb = apr_pcalloc(pool, sizeof(*cb));
276
276
cbtable->open_tmp_file = use_admin ? open_admin_tmp_file : open_tmp_file;
277
277
cbtable->get_wc_prop = use_admin ? get_wc_prop : NULL;
285
285
cb->base_dir = base_dir;
286
286
cb->base_access = base_access;
287
cb->read_only_wc = read_only_wc;
288
289
cb->commit_items = commit_items;
291
SVN_ERR (svn_ra_open2 (ra_session, base_url, cbtable, cb,
292
SVN_ERR(svn_ra_open2(ra_session, base_url, cbtable, cb,
294
295
return SVN_NO_ERROR;
298
svn_client_open_ra_session (svn_ra_session_t **session,
300
svn_client_ctx_t *ctx,
299
svn_client_open_ra_session(svn_ra_session_t **session,
301
svn_client_ctx_t *ctx,
303
return svn_client__open_ra_session_internal (session, url, NULL, NULL, NULL,
304
FALSE, TRUE, ctx, pool);
304
return svn_client__open_ra_session_internal(session, url, NULL, NULL, NULL,
305
FALSE, TRUE, ctx, pool);
309
svn_client_uuid_from_url (const char **uuid,
311
svn_client_ctx_t *ctx,
310
svn_client_uuid_from_url(const char **uuid,
312
svn_client_ctx_t *ctx,
314
315
svn_ra_session_t *ra_session;
315
apr_pool_t *subpool = svn_pool_create (pool);
316
apr_pool_t *subpool = svn_pool_create(pool);
317
318
/* use subpool to create a temporary RA session */
318
SVN_ERR (svn_client__open_ra_session_internal (&ra_session, url,
319
NULL, /* no base dir */
320
NULL, NULL, FALSE, TRUE,
319
SVN_ERR(svn_client__open_ra_session_internal(&ra_session, url,
320
NULL, /* no base dir */
321
NULL, NULL, FALSE, TRUE,
323
SVN_ERR (svn_ra_get_uuid (ra_session, uuid, subpool));
324
SVN_ERR(svn_ra_get_uuid(ra_session, uuid, subpool));
325
326
/* Copy the uuid in to the passed-in pool. */
326
*uuid = apr_pstrdup (pool, *uuid);
327
*uuid = apr_pstrdup(pool, *uuid);
328
329
/* destroy the RA session */
329
svn_pool_destroy (subpool);
330
svn_pool_destroy(subpool);
331
332
return SVN_NO_ERROR;
336
svn_client_uuid_from_path (const char **uuid,
338
svn_wc_adm_access_t *adm_access,
339
svn_client_ctx_t *ctx,
337
svn_client_uuid_from_path(const char **uuid,
339
svn_wc_adm_access_t *adm_access,
340
svn_client_ctx_t *ctx,
342
343
const svn_wc_entry_t *entry;
344
SVN_ERR (svn_wc_entry (&entry, path, adm_access,
345
TRUE, /* show deleted */ pool));
345
SVN_ERR(svn_wc_entry(&entry, path, adm_access,
346
TRUE, /* show deleted */ pool));
348
return svn_error_createf (SVN_ERR_ENTRY_NOT_FOUND, NULL,
349
_("Can't find entry for '%s'"),
350
svn_path_local_style (path, pool));
349
return svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL,
350
_("Can't find entry for '%s'"),
351
svn_path_local_style(path, pool));
366
367
http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=101831
367
368
Message-ID: <877jgjtkus.fsf@debian2.lan> */
368
369
svn_boolean_t is_root;
369
SVN_ERR (svn_wc_is_wc_root (&is_root, path, adm_access, pool));
370
SVN_ERR(svn_wc_is_wc_root(&is_root, path, adm_access, pool));
371
return svn_error_createf (SVN_ERR_ENTRY_MISSING_URL, NULL,
372
_("'%s' has no URL"),
373
svn_path_local_style (path, pool));
372
return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
373
_("'%s' has no URL"),
374
svn_path_local_style(path, pool));
375
return svn_client_uuid_from_path (uuid, svn_path_dirname (path, pool),
376
adm_access, ctx, pool);
376
return svn_client_uuid_from_path(uuid, svn_path_dirname(path, pool),
377
adm_access, ctx, pool);
379
380
return SVN_NO_ERROR;
384
svn_client__prev_log_path (const char **prev_path_p,
386
svn_revnum_t *copyfrom_rev_p,
387
apr_hash_t *changed_paths,
389
svn_node_kind_t kind,
390
svn_revnum_t revision,
385
svn_client__prev_log_path(const char **prev_path_p,
387
svn_revnum_t *copyfrom_rev_p,
388
apr_hash_t *changed_paths,
390
svn_node_kind_t kind,
391
svn_revnum_t revision,
393
394
svn_log_changed_path_t *change;
394
395
const char *prev_path = NULL;
444
445
apr_array_header_t *paths;
446
447
/* Build a sorted list of the changed paths. */
447
paths = svn_sort__hash (changed_paths,
448
svn_sort_compare_items_as_paths, pool);
448
paths = svn_sort__hash(changed_paths,
449
svn_sort_compare_items_as_paths, pool);
450
451
/* Now, walk the list of paths backwards, looking a parent of
451
452
our path that has copyfrom information. */
452
453
for (i = paths->nelts; i > 0; i--)
454
svn_sort__item_t item = APR_ARRAY_IDX (paths,
455
i - 1, svn_sort__item_t);
455
svn_sort__item_t item = APR_ARRAY_IDX(paths,
456
i - 1, svn_sort__item_t);
456
457
const char *ch_path = item.key;
457
int len = strlen (ch_path);
458
int len = strlen(ch_path);
459
460
/* See if our path is the child of this change path. If
460
461
not, keep looking. */
461
if (! ((strncmp (ch_path, path, len) == 0) && (path[len] == '/')))
462
if (! ((strncmp(ch_path, path, len) == 0) && (path[len] == '/')))
464
465
/* Okay, our path *is* a child of this change path. If
467
468
path, to the change's copyfrom path. Otherwise, this
468
469
change isn't really interesting to us, and our search
470
change = apr_hash_get (changed_paths, ch_path, len);
471
change = apr_hash_get(changed_paths, ch_path, len);
471
472
if (change->copyfrom_path)
474
475
*action_p = change->action;
475
476
if (copyfrom_rev_p)
476
477
*copyfrom_rev_p = change->copyfrom_rev;
477
prev_path = svn_path_join (change->copyfrom_path,
478
path + len + 1, pool);
478
prev_path = svn_path_join(change->copyfrom_path,
479
path + len + 1, pool);
489
490
if (kind == svn_node_dir)
490
prev_path = apr_pstrdup (pool, path);
491
prev_path = apr_pstrdup(pool, path);
492
return svn_error_createf (SVN_ERR_CLIENT_UNRELATED_RESOURCES, NULL,
493
_("Missing changed-path information for "
494
"'%s' in revision %ld"),
495
svn_path_local_style (path, pool), revision);
493
return svn_error_createf(SVN_ERR_CLIENT_UNRELATED_RESOURCES, NULL,
494
_("Missing changed-path information for "
495
"'%s' in revision %ld"),
496
svn_path_local_style(path, pool), revision);
498
499
*prev_path_p = prev_path;
530
531
(defined above) and attempts to "fill in" all three paths in the
531
532
baton over the course of many iterations. */
532
533
static svn_error_t *
533
log_receiver (void *baton,
534
apr_hash_t *changed_paths,
535
svn_revnum_t revision,
534
log_receiver(void *baton,
535
apr_hash_t *changed_paths,
536
svn_revnum_t revision,
541
542
struct log_receiver_baton *lrb = baton;
542
543
const char *current_path = lrb->last_path;
561
562
/* Determine the paths for any of the revisions for which we haven't
562
563
gotten paths already. */
563
564
if ((! *lrb->start_path_p) && (revision <= lrb->start_revision))
564
*lrb->start_path_p = apr_pstrdup (lrb->pool, current_path);
565
*lrb->start_path_p = apr_pstrdup(lrb->pool, current_path);
565
566
if ((! *lrb->end_path_p) && (revision <= lrb->end_revision))
566
*lrb->end_path_p = apr_pstrdup (lrb->pool, current_path);
567
*lrb->end_path_p = apr_pstrdup(lrb->pool, current_path);
567
568
if ((! lrb->peg_path) && (revision <= lrb->peg_revision))
568
lrb->peg_path = apr_pstrdup (lrb->pool, current_path);
569
lrb->peg_path = apr_pstrdup(lrb->pool, current_path);
570
571
/* Figure out at which repository path our object of interest lived
571
572
in the previous revision. */
572
SVN_ERR (svn_client__prev_log_path (&prev_path, NULL, NULL, changed_paths,
573
current_path, lrb->kind,
573
SVN_ERR(svn_client__prev_log_path(&prev_path, NULL, NULL, changed_paths,
574
current_path, lrb->kind,
576
577
/* Squirrel away our "next place to look" path (suffer the strcmp
577
578
hit to save on allocations). */
579
580
lrb->last_path = NULL;
580
else if (strcmp (prev_path, current_path) != 0)
581
lrb->last_path = apr_pstrdup (lrb->pool, prev_path);
581
else if (strcmp(prev_path, current_path) != 0)
582
lrb->last_path = apr_pstrdup(lrb->pool, prev_path);
583
584
return SVN_NO_ERROR;
592
593
### This is needed for 1.0.x servers, which don't have the get_locations
593
594
RA layer function. */
594
595
static svn_error_t *
595
slow_locations (const char **start_path, const char** end_path,
596
const char *abs_path, svn_revnum_t peg_revnum,
597
svn_revnum_t start_revnum, svn_revnum_t end_revnum,
598
const char *orig_path,
599
svn_ra_session_t *ra_session,
600
svn_client_ctx_t *ctx,
596
slow_locations(const char **start_path, const char** end_path,
597
const char *abs_path, svn_revnum_t peg_revnum,
598
svn_revnum_t start_revnum, svn_revnum_t end_revnum,
599
const char *orig_path,
600
svn_ra_session_t *ra_session,
601
svn_client_ctx_t *ctx,
603
604
struct log_receiver_baton lrb = { 0 };
604
605
apr_array_header_t *targets;
606
607
svn_boolean_t pegrev_is_youngest = FALSE;
608
609
/* Sanity check: verify that the peg-object exists in repos. */
609
SVN_ERR (svn_ra_check_path (ra_session, "", peg_revnum, &(lrb.kind), pool));
610
SVN_ERR(svn_ra_check_path(ra_session, "", peg_revnum, &(lrb.kind), pool));
610
611
if (lrb.kind == svn_node_none)
611
612
return svn_error_createf
612
613
(SVN_ERR_FS_NOT_FOUND, NULL,
632
633
oldest = (end_revnum < oldest) ? end_revnum : oldest;
634
635
/* Build a one-item TARGETS array, as input to ra->get_log() */
635
targets = apr_array_make (pool, 1, sizeof (const char *));
636
APR_ARRAY_PUSH (targets, const char *) = "";
636
targets = apr_array_make(pool, 1, sizeof(const char *));
637
APR_ARRAY_PUSH(targets, const char *) = "";
638
639
/* Let the RA layer drive our log information handler, which will do
639
640
the work of finding the actual locations for our resource.
640
641
Notice that we always run on the youngest rev of the 3 inputs. */
641
SVN_ERR (svn_ra_get_log (ra_session, targets, youngest, oldest, 0,
642
TRUE, FALSE, log_receiver, &lrb, pool));
642
SVN_ERR(svn_ra_get_log(ra_session, targets, youngest, oldest, 0,
643
TRUE, FALSE, log_receiver, &lrb, pool));
644
645
/* If the received log information did not cover any of the
645
646
requested revisions, use the last known path. (This normally
679
svn_client__repos_locations (const char **start_url,
680
svn_opt_revision_t **start_revision,
681
const char **end_url,
682
svn_opt_revision_t **end_revision,
684
const svn_opt_revision_t *revision,
685
const svn_opt_revision_t *start,
686
const svn_opt_revision_t *end,
687
svn_client_ctx_t *ctx,
680
svn_client__repos_locations(const char **start_url,
681
svn_opt_revision_t **start_revision,
682
const char **end_url,
683
svn_opt_revision_t **end_revision,
684
svn_ra_session_t *ra_session,
686
const svn_opt_revision_t *revision,
687
const svn_opt_revision_t *start,
688
const svn_opt_revision_t *end,
689
svn_client_ctx_t *ctx,
690
692
const char *repos_url;
704
705
set it to the same thing as START.) */
705
706
if (revision->kind == svn_opt_revision_unspecified
706
707
|| start->kind == svn_opt_revision_unspecified)
707
return svn_error_create (SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);
708
return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);
709
710
/* Check to see if this is schedule add with history working copy
710
711
path. If it is, then we need to use the URL and peg revision of
711
712
the copyfrom information. */
712
if (! svn_path_is_url (path))
713
if (! svn_path_is_url(path))
714
715
svn_wc_adm_access_t *adm_access;
715
716
const svn_wc_entry_t *entry;
716
SVN_ERR (svn_wc_adm_probe_open3 (&adm_access, NULL, path,
717
FALSE, 0, ctx->cancel_func,
718
ctx->cancel_baton, pool));
719
SVN_ERR (svn_wc_entry (&entry, path, adm_access, FALSE, pool));
720
SVN_ERR (svn_wc_adm_close (adm_access));
717
SVN_ERR(svn_wc_adm_probe_open3(&adm_access, NULL, path,
718
FALSE, 0, ctx->cancel_func,
719
ctx->cancel_baton, pool));
720
SVN_ERR(svn_wc_entry(&entry, path, adm_access, FALSE, pool));
721
SVN_ERR(svn_wc_adm_close(adm_access));
721
722
if (entry->copyfrom_url && revision->kind == svn_opt_revision_working)
723
724
url = entry->copyfrom_url;
724
725
peg_revnum = entry->copyfrom_rev;
726
if (!entry->url || strcmp(entry->url, entry->copyfrom_url) != 0)
728
/* We can't use the caller provided RA session in this case */
726
732
else if (entry->url)
743
749
WORKING revisions, we should already have the correct URL:s, so we
744
750
don't need to do anything more here in that case. */
746
/* Open a RA session to this URL. */
747
SVN_ERR (svn_client__open_ra_session_internal (&ra_session, url, NULL,
752
/* Open a RA session to this URL if we don't have one already. */
754
SVN_ERR(svn_client__open_ra_session_internal(&ra_session, url, NULL,
748
755
NULL, NULL, FALSE, TRUE,
751
758
/* Resolve the opt_revision_ts. */
752
759
if (peg_revnum == SVN_INVALID_REVNUM)
753
SVN_ERR (svn_client__get_revision_number (&peg_revnum,
754
ra_session, revision, path,
760
SVN_ERR(svn_client__get_revision_number(&peg_revnum,
761
ra_session, revision, path,
757
SVN_ERR (svn_client__get_revision_number (&start_revnum,
758
ra_session, start, path, pool));
764
SVN_ERR(svn_client__get_revision_number(&start_revnum,
765
ra_session, start, path, pool));
759
766
if (end->kind == svn_opt_revision_unspecified)
760
767
end_revnum = start_revnum;
762
SVN_ERR (svn_client__get_revision_number (&end_revnum,
763
ra_session, end, path, pool));
769
SVN_ERR(svn_client__get_revision_number(&end_revnum,
770
ra_session, end, path, pool));
765
772
/* Set the output revision variables. */
766
*start_revision = apr_pcalloc (pool, sizeof (**start_revision));
773
*start_revision = apr_pcalloc(pool, sizeof(**start_revision));
767
774
(*start_revision)->kind = svn_opt_revision_number;
768
775
(*start_revision)->value.number = start_revnum;
769
776
if (end->kind != svn_opt_revision_unspecified)
771
*end_revision = apr_pcalloc (pool, sizeof (**end_revision));
778
*end_revision = apr_pcalloc(pool, sizeof(**end_revision));
772
779
(*end_revision)->kind = svn_opt_revision_number;
773
780
(*end_revision)->value.number = end_revnum;
779
786
*start_url = url;
780
787
if (end->kind != svn_opt_revision_unspecified)
782
svn_pool_destroy (subpool);
789
svn_pool_destroy(subpool);
783
790
return SVN_NO_ERROR;
786
SVN_ERR (svn_ra_get_repos_root (ra_session, &repos_url, subpool));
793
SVN_ERR(svn_ra_get_repos_root(ra_session, &repos_url, subpool));
788
revs = apr_array_make (subpool, 2, sizeof (svn_revnum_t));
789
APR_ARRAY_PUSH (revs, svn_revnum_t) = start_revnum;
795
revs = apr_array_make(subpool, 2, sizeof(svn_revnum_t));
796
APR_ARRAY_PUSH(revs, svn_revnum_t) = start_revnum;
790
797
if (end_revnum != start_revnum)
791
APR_ARRAY_PUSH (revs, svn_revnum_t) = end_revnum;
798
APR_ARRAY_PUSH(revs, svn_revnum_t) = end_revnum;
793
if (! (err = svn_ra_get_locations (ra_session, &rev_locs, "", peg_revnum,
800
if (! (err = svn_ra_get_locations(ra_session, &rev_locs, "", peg_revnum,
796
start_path = apr_hash_get (rev_locs, &start_revnum,
797
sizeof (svn_revnum_t));
798
end_path = apr_hash_get (rev_locs, &end_revnum, sizeof (svn_revnum_t));
803
start_path = apr_hash_get(rev_locs, &start_revnum,
804
sizeof(svn_revnum_t));
805
end_path = apr_hash_get(rev_locs, &end_revnum, sizeof(svn_revnum_t));
800
807
else if (err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
802
svn_error_clear (err);
809
svn_error_clear(err);
803
810
/* Do it the slow way for 1.0.x servers. */
804
SVN_ERR (slow_locations (&start_path, &end_path,
805
svn_path_uri_decode (url + strlen (repos_url),
807
peg_revnum, start_revnum, end_revnum,
808
path, ra_session, ctx, subpool));
811
SVN_ERR(slow_locations(&start_path, &end_path,
812
svn_path_uri_decode(url + strlen(repos_url),
814
peg_revnum, start_revnum, end_revnum,
815
path, ra_session, ctx, subpool));
832
839
end_path = end_path + 1;
834
841
/* Set our return variables */
835
*start_url = svn_path_join (repos_url, svn_path_uri_encode (start_path,
842
*start_url = svn_path_join(repos_url, svn_path_uri_encode(start_path,
837
844
if (end->kind != svn_opt_revision_unspecified)
838
*end_url = svn_path_join (repos_url, svn_path_uri_encode (end_path,
845
*end_url = svn_path_join(repos_url, svn_path_uri_encode(end_path,
841
svn_pool_destroy (subpool);
848
svn_pool_destroy(subpool);
842
849
return SVN_NO_ERROR;
848
svn_client__ra_session_from_path (svn_ra_session_t **ra_session_p,
851
const char *path_or_url,
852
const svn_opt_revision_t *peg_revision_p,
853
const svn_opt_revision_t *revision,
854
svn_client_ctx_t *ctx,
855
svn_client__ra_session_from_path(svn_ra_session_t **ra_session_p,
858
const char *path_or_url,
859
const svn_opt_revision_t *peg_revision_p,
860
const svn_opt_revision_t *revision,
861
svn_client_ctx_t *ctx,
857
864
svn_ra_session_t *ra_session;
858
865
const char *initial_url, *url;
863
870
svn_revnum_t rev;
864
871
const char *ignored_url;
866
SVN_ERR (svn_client_url_from_path (&initial_url, path_or_url, pool));
873
SVN_ERR(svn_client_url_from_path(&initial_url, path_or_url, pool));
867
874
if (! initial_url)
868
return svn_error_createf (SVN_ERR_ENTRY_MISSING_URL, NULL,
869
_("'%s' has no URL"), path_or_url);
875
return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
876
_("'%s' has no URL"), path_or_url);
871
878
/* If a peg revision was specified, but a desired revision was not,
872
879
assume it is the same as the peg revision. */
904
911
peg_revision = *peg_revision_p;
914
SVN_ERR(svn_client__open_ra_session_internal(&ra_session, initial_url,
916
FALSE, FALSE, ctx, pool));
907
918
dead_end_rev.kind = svn_opt_revision_unspecified;
909
920
/* Run the history function to get the object's (possibly
910
921
different) url in REVISION. */
911
SVN_ERR (svn_client__repos_locations (&url, &new_rev,
912
&ignored_url, &ignored_rev,
913
path_or_url, &peg_revision,
915
&start_rev, &dead_end_rev,
922
SVN_ERR(svn_client__repos_locations(&url, &new_rev,
923
&ignored_url, &ignored_rev,
925
path_or_url, &peg_revision,
927
&start_rev, &dead_end_rev,
917
929
good_rev = new_rev;
919
SVN_ERR (svn_client__open_ra_session_internal (&ra_session, url,
921
FALSE, FALSE, ctx, pool));
931
/* Make the session point to the real URL. */
932
SVN_ERR(svn_ra_reparent(ra_session, url, pool));
923
934
/* Resolve good_rev into a real revnum. */
924
SVN_ERR (svn_client__get_revision_number (&rev, ra_session,
925
good_rev, url, pool));
926
if (! SVN_IS_VALID_REVNUM (rev))
927
SVN_ERR (svn_ra_get_latest_revnum (ra_session, &rev, pool));
935
SVN_ERR(svn_client__get_revision_number(&rev, ra_session,
936
good_rev, url, pool));
937
if (! SVN_IS_VALID_REVNUM(rev))
938
SVN_ERR(svn_ra_get_latest_revnum(ra_session, &rev, pool));
929
940
*ra_session_p = ra_session;