68
68
* the revision if the revision is found. Set REV_IDX to the index in
69
69
* LINE_PARTS where the revision specification starts. Remove from
70
70
* LINE_PARTS the element(s) that specify the revision.
71
* Set REV_STR to the element that specifies the revision.
71
72
* PARENT_DIRECTORY_DISPLAY and LINE are given to return a nice error
137
139
line_parts[j] = line_parts[j+shift_count];
138
140
line_parts[num_line_parts-shift_count] = NULL;
142
*rev_str = apr_psprintf(pool, "-r%s", digits_ptr);
140
144
/* Found the revision, so leave the function immediately, do
141
145
* not continue looking for additional revisions. */
142
146
return SVN_NO_ERROR;
161
svn_wc_parse_externals_description3(apr_array_header_t **externals_p,
162
const char *parent_directory,
165
svn_wc__parse_externals_description(apr_array_header_t **externals_p,
166
apr_array_header_t **parser_infos_p,
167
const char *defining_directory,
163
168
const char *desc,
164
169
svn_boolean_t canonicalize_url,
165
170
apr_pool_t *pool)
168
173
apr_array_header_t *externals = NULL;
174
apr_array_header_t *parser_infos = NULL;
169
175
apr_array_header_t *lines = svn_cstring_split(desc, "\n\r", TRUE, pool);
170
const char *parent_directory_display = svn_path_is_url(parent_directory) ?
171
parent_directory : svn_dirent_local_style(parent_directory, pool);
176
const char *defining_directory_display = svn_path_is_url(defining_directory) ?
177
defining_directory : svn_dirent_local_style(defining_directory, pool);
173
179
/* If an error occurs halfway through parsing, *externals_p should stay
174
180
* untouched. So, store the list in a local var first. */
176
182
externals = apr_array_make(pool, 1, sizeof(svn_wc_external_item2_t *));
186
apr_array_make(pool, 1, sizeof(svn_wc__externals_parser_info_t *));
178
188
for (i = 0; i < lines->nelts; i++)
180
190
const char *line = APR_ARRAY_IDX(lines, i, const char *);
186
196
const char *token1;
187
197
svn_boolean_t token0_is_url;
188
198
svn_boolean_t token1_is_url;
199
svn_wc__externals_parser_info_t *info = NULL;
190
201
/* Index into line_parts where the revision specification
192
203
int rev_idx = -1;
204
const char *rev_str = NULL;
194
206
if ((! line) || (line[0] == '#'))
231
246
(SVN_ERR_CLIENT_INVALID_EXTERNALS_DESCRIPTION, NULL,
232
247
_("Error parsing %s property on '%s': '%s'"),
233
248
SVN_PROP_EXTERNALS,
234
parent_directory_display,
249
defining_directory_display,
237
252
/* To make it easy to check for the forms, find and remove -r N
240
255
set item->revision to the parsed revision. */
241
256
/* ### ugh. stupid cast. */
242
257
SVN_ERR(find_and_remove_externals_revision(&rev_idx,
243
259
(const char **)line_parts,
244
260
num_line_parts, item,
245
parent_directory_display,
261
defining_directory_display,
248
264
token0 = line_parts[0];
258
274
"cannot use two absolute URLs ('%s' and '%s') in an external; "
259
275
"one must be a path where an absolute or relative URL is "
260
276
"checked out to"),
261
SVN_PROP_EXTERNALS, parent_directory_display, token0, token1);
277
SVN_PROP_EXTERNALS, defining_directory_display, token0, token1);
263
279
if (0 == rev_idx && token1_is_url)
264
280
return svn_error_createf
266
282
_("Invalid %s property on '%s': "
267
283
"cannot use a URL '%s' as the target directory for an external "
269
SVN_PROP_EXTERNALS, parent_directory_display, token1);
285
SVN_PROP_EXTERNALS, defining_directory_display, token1);
271
287
if (1 == rev_idx && token0_is_url)
272
288
return svn_error_createf
274
290
_("Invalid %s property on '%s': "
275
291
"cannot use a URL '%s' as the target directory for an external "
277
SVN_PROP_EXTERNALS, parent_directory_display, token0);
293
SVN_PROP_EXTERNALS, defining_directory_display, token0);
279
/* The appearence of -r N or -rN forces the type of external.
295
/* The appearance of -r N or -rN forces the type of external.
280
296
If -r is at the beginning of the line or the first token is
281
297
an absolute URL or if the second token is not an absolute
282
298
URL, then the URL supports peg revisions. */
290
306
SVN_ERR(svn_opt_parse_path(&item->peg_revision, &item->url,
292
308
item->target_dir = token1;
312
info->format = svn_wc__external_description_format_2;
315
info->rev_str = apr_pstrdup(pool, rev_str);
317
if (item->peg_revision.kind != svn_opt_revision_unspecified)
318
info->peg_rev_str = strrchr(token0, '@');
296
323
item->target_dir = token0;
297
324
item->url = token1;
298
325
item->peg_revision = item->revision;
329
info->format = svn_wc__external_description_format_1;
333
info->rev_str = apr_pstrdup(pool, rev_str);
334
info->peg_rev_str = info->rev_str;
301
339
SVN_ERR(svn_opt_resolve_revisions(&item->peg_revision,
316
354
_("Invalid %s property on '%s': "
317
355
"target '%s' is an absolute path or involves '..'"),
318
356
SVN_PROP_EXTERNALS,
319
parent_directory_display,
357
defining_directory_display,
320
358
item->target_dir);
322
360
if (canonicalize_url)
335
373
APR_ARRAY_PUSH(externals, svn_wc_external_item2_t *) = item;
375
APR_ARRAY_PUSH(parser_infos, svn_wc__externals_parser_info_t *) = info;
339
379
*externals_p = externals;
381
*parser_infos_p = parser_infos;
341
383
return SVN_NO_ERROR;
387
svn_wc_parse_externals_description3(apr_array_header_t **externals_p,
388
const char *defining_directory,
390
svn_boolean_t canonicalize_url,
393
return svn_error_trace(svn_wc__parse_externals_description(externals_p,
345
402
svn_wc__externals_find_target_dups(apr_array_header_t **duplicate_targets,
346
403
apr_array_header_t *externals,
347
404
apr_pool_t *pool,
405
462
const apr_array_header_t *ext_patterns;
406
463
const char *diff3cmd;
409
465
const char *repos_root_url;
410
466
const char *repos_uuid;
467
const char *old_repos_relpath;
468
const char *new_repos_relpath;
412
470
const char *record_ancestor_abspath;
413
471
const char *recorded_repos_relpath;
431
487
const svn_checksum_t *original_checksum;
433
489
/* What we are installing now */
434
const char *new_pristine_abspath;
490
svn_wc__db_install_data_t *install_data;
435
491
svn_checksum_t *new_sha1_checksum;
436
492
svn_checksum_t *new_md5_checksum;
518
574
*file_baton = eb;
519
575
SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &eb->original_revision,
520
NULL, NULL, NULL, &eb->changed_rev,
576
&eb->old_repos_relpath, NULL, NULL,
521
578
&eb->changed_date, &eb->changed_author,
522
579
NULL, &eb->original_checksum, NULL, NULL,
523
580
&eb->had_props, NULL, NULL,
580
637
src_stream = svn_stream_empty(pool);
582
SVN_ERR(svn_wc__open_writable_base(&dest_stream, &eb->new_pristine_abspath,
583
&eb->new_md5_checksum,
584
&eb->new_sha1_checksum,
585
eb->db, eb->wri_abspath,
639
SVN_ERR(svn_wc__db_pristine_prepare_install(&dest_stream,
641
&eb->new_sha1_checksum,
642
&eb->new_md5_checksum,
643
eb->db, eb->wri_abspath,
588
646
svn_txdelta_apply(src_stream, dest_stream, NULL, eb->local_abspath, pool,
589
647
handler, handler_baton);
604
662
propchange = apr_array_push(eb->propchanges);
605
663
propchange->name = apr_pstrdup(eb->pool, name);
606
propchange->value = value ? svn_string_dup(value, eb->pool) : NULL;
664
propchange->value = svn_string_dup(value, eb->pool);
608
666
return SVN_NO_ERROR;
656
714
behavior to the pristine store. */
657
715
if (eb->new_sha1_checksum)
659
SVN_ERR(svn_wc__db_pristine_install(eb->db, eb->new_pristine_abspath,
717
SVN_ERR(svn_wc__db_pristine_install(eb->install_data,
660
718
eb->new_sha1_checksum,
661
719
eb->new_md5_checksum, pool));
663
eb->new_pristine_abspath = NULL;
721
eb->install_data = NULL;
666
724
/* Merge the changes */
768
824
svn_node_kind_t disk_kind;
769
825
svn_boolean_t install_pristine = FALSE;
770
const char *install_from = NULL;
772
827
SVN_ERR(svn_io_check_path(eb->local_abspath, &disk_kind, pool));
954
1010
investigating when we should and shouldn't update it...
955
1011
and avoid hard to debug edge cases */
957
svn_node_kind_t kind;
958
const char *old_repos_relpath;
959
svn_revnum_t changed_rev;
960
apr_time_t changed_date;
961
const char *changed_author;
962
const svn_checksum_t *checksum;
963
apr_hash_t *pristine_props;
964
const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url,
967
SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, NULL, &old_repos_relpath,
968
NULL, NULL, &changed_rev, &changed_date,
969
&changed_author, NULL, &checksum, NULL,
970
NULL, NULL, &pristine_props, NULL,
971
eb->db, eb->local_abspath,
974
if (kind != svn_node_file)
975
return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
976
_("Node '%s' is no existing file external"),
977
svn_dirent_local_style(eb->local_abspath,
980
SVN_ERR(svn_wc__db_external_add_file(
987
*eb->target_revision,
994
NULL /* clear dav props */,
995
eb->record_ancestor_abspath,
996
eb->recorded_repos_relpath,
997
eb->recorded_peg_revision,
998
eb->recorded_revision,
1000
TRUE /* keep_recorded_info */,
1001
NULL /* conflict_skel */,
1002
NULL /* work_items */,
1015
wcroot_iprops = apr_hash_make(pool);
1016
svn_hash_sets(wcroot_iprops, eb->local_abspath, eb->iprops);
1019
SVN_ERR(svn_wc__db_op_bump_revisions_post_update(eb->db,
1022
eb->new_repos_relpath,
1025
*eb->target_revision,
1027
/* exclude_relpaths */,
1029
TRUE /* empty update */,
1006
1035
return SVN_NO_ERROR;
1024
1053
const char *recorded_url,
1025
1054
const svn_opt_revision_t *recorded_peg_rev,
1026
1055
const svn_opt_revision_t *recorded_rev,
1027
svn_wc_conflict_resolver_func2_t conflict_func,
1028
void *conflict_baton,
1029
1056
svn_cancel_func_t cancel_func,
1030
1057
void *cancel_baton,
1031
1058
svn_wc_notify_func2_t notify_func,
1048
1075
eb->name = svn_dirent_basename(eb->local_abspath, NULL);
1049
1076
eb->target_revision = target_revision;
1051
eb->url = apr_pstrdup(edit_pool, url);
1052
1078
eb->repos_root_url = apr_pstrdup(edit_pool, repos_root_url);
1053
1079
eb->repos_uuid = apr_pstrdup(edit_pool, repos_uuid);
1080
eb->new_repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url, url, edit_pool);
1081
eb->old_repos_relpath = eb->new_repos_relpath;
1083
eb->original_revision = SVN_INVALID_REVNUM;
1055
1085
eb->iprops = iprops;
1075
1105
eb->recorded_revision = SVN_INVALID_REVNUM; /* Not fixed/HEAD */
1077
eb->conflict_func = conflict_func;
1078
eb->conflict_baton = conflict_baton;
1079
1107
eb->cancel_func = cancel_func;
1080
1108
eb->cancel_baton = cancel_baton;
1081
1109
eb->notify_func = notify_func;
1447
1475
SVN_ERR(svn_wc__db_base_remove(wc_ctx->db, local_abspath,
1448
FALSE /* keep_as_working */,
1449
TRUE /* queue_deletes */,
1450
FALSE /* remove_locks */,
1452
1478
NULL, NULL, scratch_pool));
1453
1479
SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath,
1454
1480
cancel_func, cancel_baton,