1 | /* |
---|
2 | * relocate.c: wrapper around wc relocation functionality. |
---|
3 | * |
---|
4 | * ==================================================================== |
---|
5 | * Copyright (c) 2002-2004 CollabNet. All rights reserved. |
---|
6 | * |
---|
7 | * This software is licensed as described in the file COPYING, which |
---|
8 | * you should have received as part of this distribution. The terms |
---|
9 | * are also available at http://subversion.tigris.org/license-1.html. |
---|
10 | * If newer versions of this license are posted there, you may use a |
---|
11 | * newer version instead, at your option. |
---|
12 | * |
---|
13 | * This software consists of voluntary contributions made by many |
---|
14 | * individuals. For exact contribution history, see the revision |
---|
15 | * history and logs, available at http://subversion.tigris.org/. |
---|
16 | * ==================================================================== |
---|
17 | */ |
---|
18 | |
---|
19 | /* ==================================================================== */ |
---|
20 | |
---|
21 | |
---|
22 | |
---|
23 | /*** Includes. ***/ |
---|
24 | |
---|
25 | #include "svn_wc.h" |
---|
26 | #include "svn_client.h" |
---|
27 | #include "svn_pools.h" |
---|
28 | #include "svn_error.h" |
---|
29 | #include "svn_path.h" |
---|
30 | #include "client.h" |
---|
31 | |
---|
32 | #include "svn_private_config.h" |
---|
33 | |
---|
34 | |
---|
35 | /*** Code. ***/ |
---|
36 | |
---|
37 | /* Repository root and UUID for a repository. */ |
---|
38 | struct url_uuid_t |
---|
39 | { |
---|
40 | const char *root; |
---|
41 | const char *uuid; |
---|
42 | }; |
---|
43 | |
---|
44 | struct validator_baton_t |
---|
45 | { |
---|
46 | svn_client_ctx_t *ctx; |
---|
47 | const char *path; |
---|
48 | apr_array_header_t *url_uuids; |
---|
49 | apr_pool_t *pool; |
---|
50 | |
---|
51 | }; |
---|
52 | |
---|
53 | |
---|
54 | static svn_error_t * |
---|
55 | validator_func(void *baton, |
---|
56 | const char *uuid, |
---|
57 | const char *url, |
---|
58 | const char *root_url, |
---|
59 | apr_pool_t *pool) |
---|
60 | { |
---|
61 | struct validator_baton_t *b = baton; |
---|
62 | struct url_uuid_t *url_uuid = NULL; |
---|
63 | |
---|
64 | apr_array_header_t *uuids = b->url_uuids; |
---|
65 | int i; |
---|
66 | |
---|
67 | for (i = 0; i < uuids->nelts; ++i) |
---|
68 | { |
---|
69 | struct url_uuid_t *uu = &APR_ARRAY_IDX(uuids, i, |
---|
70 | struct url_uuid_t); |
---|
71 | if (svn_path_is_ancestor(uu->root, url)) |
---|
72 | { |
---|
73 | url_uuid = uu; |
---|
74 | break; |
---|
75 | } |
---|
76 | } |
---|
77 | |
---|
78 | /* We use an RA session in a subpool to get the UUID of the |
---|
79 | repository at the new URL so we can force the RA session to close |
---|
80 | by destroying the subpool. */ |
---|
81 | if (! url_uuid) |
---|
82 | { |
---|
83 | apr_pool_t *sesspool = svn_pool_create(pool); |
---|
84 | svn_ra_session_t *ra_session; |
---|
85 | SVN_ERR(svn_client__open_ra_session_internal(&ra_session, url, NULL, |
---|
86 | NULL, NULL, FALSE, TRUE, |
---|
87 | b->ctx, sesspool)); |
---|
88 | url_uuid = &APR_ARRAY_PUSH(uuids, struct url_uuid_t); |
---|
89 | SVN_ERR(svn_ra_get_uuid2(ra_session, &(url_uuid->uuid), pool)); |
---|
90 | SVN_ERR(svn_ra_get_repos_root2(ra_session, &(url_uuid->root), pool)); |
---|
91 | svn_pool_destroy(sesspool); |
---|
92 | } |
---|
93 | |
---|
94 | /* Make sure the url is a repository root if desired. */ |
---|
95 | if (root_url |
---|
96 | && strcmp(root_url, url_uuid->root) != 0) |
---|
97 | return svn_error_createf(SVN_ERR_CLIENT_INVALID_RELOCATION, NULL, |
---|
98 | _("'%s' is not the root of the repository"), |
---|
99 | url); |
---|
100 | |
---|
101 | /* Make sure the UUIDs match. */ |
---|
102 | if (uuid && strcmp(uuid, url_uuid->uuid) != 0) |
---|
103 | return svn_error_createf |
---|
104 | (SVN_ERR_CLIENT_INVALID_RELOCATION, NULL, |
---|
105 | _("The repository at '%s' has uuid '%s', but the WC has '%s'"), |
---|
106 | url, url_uuid->uuid, uuid); |
---|
107 | |
---|
108 | return SVN_NO_ERROR; |
---|
109 | } |
---|
110 | |
---|
111 | svn_error_t * |
---|
112 | svn_client_relocate(const char *path, |
---|
113 | const char *from, |
---|
114 | const char *to, |
---|
115 | svn_boolean_t recurse, |
---|
116 | svn_client_ctx_t *ctx, |
---|
117 | apr_pool_t *pool) |
---|
118 | { |
---|
119 | svn_wc_adm_access_t *adm_access; |
---|
120 | struct validator_baton_t vb; |
---|
121 | |
---|
122 | /* Get an access baton for PATH. */ |
---|
123 | SVN_ERR(svn_wc_adm_probe_open3(&adm_access, NULL, path, |
---|
124 | TRUE, recurse ? -1 : 0, |
---|
125 | ctx->cancel_func, ctx->cancel_baton, |
---|
126 | pool)); |
---|
127 | |
---|
128 | /* Now, populate our validator callback baton, and call the relocate code. */ |
---|
129 | vb.ctx = ctx; |
---|
130 | vb.path = path; |
---|
131 | vb.url_uuids = apr_array_make(pool, 1, sizeof(struct url_uuid_t)); |
---|
132 | vb.pool = pool; |
---|
133 | SVN_ERR(svn_wc_relocate3(path, adm_access, from, to, |
---|
134 | recurse, validator_func, &vb, pool)); |
---|
135 | |
---|
136 | /* All done. Clean up, and move on out. */ |
---|
137 | return svn_wc_adm_close2(adm_access, pool); |
---|
138 | } |
---|