42
43
#include "svn_private_config.h"
45
svn_client__pathrev_t *
46
svn_client__pathrev_create(const char *repos_root_url,
47
const char *repos_uuid,
50
apr_pool_t *result_pool)
52
svn_client__pathrev_t *loc = apr_palloc(result_pool, sizeof(*loc));
54
SVN_ERR_ASSERT_NO_RETURN(svn_path_is_url(repos_root_url));
55
SVN_ERR_ASSERT_NO_RETURN(svn_path_is_url(url));
57
loc->repos_root_url = apr_pstrdup(result_pool, repos_root_url);
58
loc->repos_uuid = apr_pstrdup(result_pool, repos_uuid);
60
loc->url = apr_pstrdup(result_pool, url);
64
svn_client__pathrev_t *
65
svn_client__pathrev_create_with_relpath(const char *repos_root_url,
66
const char *repos_uuid,
69
apr_pool_t *result_pool)
71
SVN_ERR_ASSERT_NO_RETURN(svn_relpath_is_canonical(relpath));
73
return svn_client__pathrev_create(
74
repos_root_url, repos_uuid, rev,
75
svn_path_url_add_component2(repos_root_url, relpath, result_pool),
80
svn_client__pathrev_create_with_session(svn_client__pathrev_t **pathrev_p,
81
svn_ra_session_t *ra_session,
84
apr_pool_t *result_pool)
86
svn_client__pathrev_t *pathrev = apr_palloc(result_pool, sizeof(*pathrev));
88
SVN_ERR_ASSERT(svn_path_is_url(url));
90
SVN_ERR(svn_ra_get_repos_root2(ra_session, &pathrev->repos_root_url,
92
SVN_ERR(svn_ra_get_uuid2(ra_session, &pathrev->repos_uuid, result_pool));
94
pathrev->url = apr_pstrdup(result_pool, url);
99
svn_client__pathrev_t *
100
svn_client__pathrev_dup(const svn_client__pathrev_t *pathrev,
101
apr_pool_t *result_pool)
103
return svn_client__pathrev_create(
104
pathrev->repos_root_url, pathrev->repos_uuid,
105
pathrev->rev, pathrev->url, result_pool);
108
svn_client__pathrev_t *
109
svn_client__pathrev_join_relpath(const svn_client__pathrev_t *pathrev,
111
apr_pool_t *result_pool)
113
return svn_client__pathrev_create(
114
pathrev->repos_root_url, pathrev->repos_uuid, pathrev->rev,
115
svn_path_url_add_component2(pathrev->url, relpath, result_pool),
120
svn_client__pathrev_relpath(const svn_client__pathrev_t *pathrev,
121
apr_pool_t *result_pool)
123
return svn_uri_skip_ancestor(pathrev->repos_root_url, pathrev->url,
128
svn_client__pathrev_fspath(const svn_client__pathrev_t *pathrev,
129
apr_pool_t *result_pool)
131
return svn_fspath__canonicalize(svn_uri_skip_ancestor(
132
pathrev->repos_root_url, pathrev->url,
44
138
svn_client_commit_item3_t *
45
139
svn_client_commit_item3_create(apr_pool_t *pool)
79
svn_client__path_relative_to_root(const char **rel_path,
80
svn_wc_context_t *wc_ctx,
81
const char *abspath_or_url,
82
const char *repos_root,
83
svn_boolean_t include_leading_slash,
84
svn_ra_session_t *ra_session,
85
apr_pool_t *result_pool,
86
apr_pool_t *scratch_pool)
88
const char *repos_relpath;
90
/* If we have a WC path... */
91
if (! svn_path_is_url(abspath_or_url))
93
/* ...fetch its entry, and attempt to get both its full URL and
94
repository root URL. If we can't get REPOS_ROOT from the WC
95
entry, we'll get it from the RA layer.*/
97
SVN_ERR(svn_wc__node_get_repos_relpath(&repos_relpath,
103
SVN_ERR_ASSERT(repos_relpath != NULL);
105
/* Merge handling passes a root that is not the repos root */
106
else if (repos_root != NULL)
108
if (!svn_uri__is_ancestor(repos_root, abspath_or_url))
109
return svn_error_createf(SVN_ERR_CLIENT_UNRELATED_RESOURCES, NULL,
110
_("URL '%s' is not a child of repository "
112
abspath_or_url, repos_root);
114
repos_relpath = svn_uri_skip_ancestor(repos_root, abspath_or_url,
173
svn_client__wc_node_get_base(svn_client__pathrev_t **base_p,
174
const char *wc_abspath,
175
svn_wc_context_t *wc_ctx,
176
apr_pool_t *result_pool,
177
apr_pool_t *scratch_pool)
181
*base_p = apr_palloc(result_pool, sizeof(**base_p));
183
SVN_ERR(svn_wc__node_get_base(NULL,
186
&(*base_p)->repos_root_url,
187
&(*base_p)->repos_uuid,
190
TRUE /* ignore_enoent */,
191
TRUE /* show_hidden */,
192
result_pool, scratch_pool));
193
if ((*base_p)->repos_root_url && relpath)
195
(*base_p)->url = svn_path_url_add_component2(
196
(*base_p)->repos_root_url, relpath, result_pool);
206
svn_client__wc_node_get_origin(svn_client__pathrev_t **origin_p,
207
const char *wc_abspath,
208
svn_client_ctx_t *ctx,
209
apr_pool_t *result_pool,
210
apr_pool_t *scratch_pool)
214
*origin_p = apr_palloc(result_pool, sizeof(**origin_p));
216
SVN_ERR(svn_wc__node_get_origin(NULL /* is_copy */,
219
&(*origin_p)->repos_root_url,
220
&(*origin_p)->repos_uuid,
221
NULL, ctx->wc_ctx, wc_abspath,
222
FALSE /* scan_deleted */,
223
result_pool, scratch_pool));
224
if ((*origin_p)->repos_root_url && relpath)
226
(*origin_p)->url = svn_path_url_add_component2(
227
(*origin_p)->repos_root_url, relpath, result_pool);
237
svn_client_get_repos_root(const char **repos_root,
238
const char **repos_uuid,
239
const char *abspath_or_url,
240
svn_client_ctx_t *ctx,
241
apr_pool_t *result_pool,
242
apr_pool_t *scratch_pool)
244
svn_ra_session_t *ra_session;
246
/* If PATH_OR_URL is a local path we can fetch the repos root locally. */
247
if (!svn_path_is_url(abspath_or_url))
119
249
svn_error_t *err;
121
SVN_ERR_ASSERT(ra_session != NULL);
123
/* Ask the RA layer to create a relative path for us */
124
err = svn_ra_get_path_relative_to_root(ra_session, &repos_relpath,
125
abspath_or_url, scratch_pool);
250
err = svn_wc__node_get_repos_info(NULL, NULL, repos_root, repos_uuid,
251
ctx->wc_ctx, abspath_or_url,
252
result_pool, scratch_pool);
129
if (err->apr_err == SVN_ERR_RA_ILLEGAL_URL)
130
return svn_error_createf(SVN_ERR_CLIENT_UNRELATED_RESOURCES, err,
131
_("URL '%s' is not inside repository"),
256
if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND
257
&& err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
258
return svn_error_trace(err);
134
return svn_error_trace(err);
260
svn_error_clear(err);
138
if (include_leading_slash)
139
*rel_path = apr_pstrcat(result_pool, "/", repos_relpath, NULL);
141
*rel_path = repos_relpath;
147
svn_client__get_repos_root(const char **repos_root,
148
const char *abspath_or_url,
149
svn_client_ctx_t *ctx,
150
apr_pool_t *result_pool,
151
apr_pool_t *scratch_pool)
153
svn_ra_session_t *ra_session;
155
/* If PATH_OR_URL is a local path we can fetch the repos root locally. */
156
if (!svn_path_is_url(abspath_or_url))
158
SVN_ERR(svn_wc__node_get_repos_info(repos_root, NULL,
159
ctx->wc_ctx, abspath_or_url,
160
result_pool, scratch_pool));
162
266
return SVN_NO_ERROR;
165
269
/* If PATH_OR_URL was a URL, we use the RA layer to look it up. */
166
SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL,
168
NULL, NULL, FALSE, TRUE,
270
SVN_ERR(svn_client_open_ra_session2(&ra_session, abspath_or_url, NULL,
271
ctx, scratch_pool, scratch_pool));
171
SVN_ERR(svn_ra_get_repos_root2(ra_session, repos_root, result_pool));
274
SVN_ERR(svn_ra_get_repos_root2(ra_session, repos_root, result_pool));
276
SVN_ERR(svn_ra_get_uuid2(ra_session, repos_uuid, result_pool));
173
278
return SVN_NO_ERROR;
178
svn_client__default_walker_error_handler(const char *path,
183
return svn_error_trace(err);
187
281
const svn_opt_revision_t *
188
282
svn_cl__rev_default_to_head_or_base(const svn_opt_revision_t *revision,
189
283
const char *path_or_url)
239
333
return SVN_NO_ERROR;
336
struct shim_callbacks_baton
338
svn_wc_context_t *wc_ctx;
339
apr_hash_t *relpath_map;
343
fetch_props_func(apr_hash_t **props,
346
svn_revnum_t base_revision,
347
apr_pool_t *result_pool,
348
apr_pool_t *scratch_pool)
350
struct shim_callbacks_baton *scb = baton;
351
const char *local_abspath;
353
local_abspath = svn_hash_gets(scb->relpath_map, path);
356
*props = apr_hash_make(result_pool);
360
/* Reads the pristine properties of WORKING, not those of BASE */
361
SVN_ERR(svn_wc_get_pristine_props(props, scb->wc_ctx, local_abspath,
362
result_pool, scratch_pool));
365
*props = apr_hash_make(result_pool);
371
fetch_kind_func(svn_node_kind_t *kind,
374
svn_revnum_t base_revision,
375
apr_pool_t *scratch_pool)
377
struct shim_callbacks_baton *scb = baton;
378
const char *local_abspath;
380
local_abspath = svn_hash_gets(scb->relpath_map, path);
383
*kind = svn_node_unknown;
386
/* Reads the WORKING kind. Not the BASE kind */
387
SVN_ERR(svn_wc_read_kind2(kind, scb->wc_ctx, local_abspath,
388
TRUE, FALSE, scratch_pool));
394
fetch_base_func(const char **filename,
397
svn_revnum_t base_revision,
398
apr_pool_t *result_pool,
399
apr_pool_t *scratch_pool)
401
struct shim_callbacks_baton *scb = baton;
402
const char *local_abspath;
403
svn_stream_t *pristine_stream;
404
svn_stream_t *temp_stream;
407
local_abspath = svn_hash_gets(scb->relpath_map, path);
414
/* Reads the pristine of WORKING, not of BASE */
415
err = svn_wc_get_pristine_contents2(&pristine_stream, scb->wc_ctx,
416
local_abspath, scratch_pool,
418
if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
420
svn_error_clear(err);
425
return svn_error_trace(err);
427
SVN_ERR(svn_stream_open_unique(&temp_stream, filename, NULL,
428
svn_io_file_del_on_pool_cleanup,
429
result_pool, scratch_pool));
430
SVN_ERR(svn_stream_copy3(pristine_stream, temp_stream, NULL, NULL,
436
svn_delta_shim_callbacks_t *
437
svn_client__get_shim_callbacks(svn_wc_context_t *wc_ctx,
438
apr_hash_t *relpath_map,
439
apr_pool_t *result_pool)
441
svn_delta_shim_callbacks_t *callbacks =
442
svn_delta_shim_callbacks_default(result_pool);
443
struct shim_callbacks_baton *scb = apr_pcalloc(result_pool, sizeof(*scb));
445
scb->wc_ctx = wc_ctx;
447
scb->relpath_map = relpath_map;
449
scb->relpath_map = apr_hash_make(result_pool);
451
callbacks->fetch_props_func = fetch_props_func;
452
callbacks->fetch_kind_func = fetch_kind_func;
453
callbacks->fetch_base_func = fetch_base_func;
454
callbacks->fetch_baton = scb;