Issue #4828: remind user they can use '-v' to show experimental options.
[svn/apache.git] / subversion / svnrdump / dump_editor.c
blobef52b41b43dc3f0f0648a0af8acf585cfad87f22
1 /*
2 * dump_editor.c: The svn_delta_editor_t editor used by svnrdump to
3 * dump revisions.
5 * ====================================================================
6 * Licensed to the Apache Software Foundation (ASF) under one
7 * or more contributor license agreements. See the NOTICE file
8 * distributed with this work for additional information
9 * regarding copyright ownership. The ASF licenses this file
10 * to you under the Apache License, Version 2.0 (the
11 * "License"); you may not use this file except in compliance
12 * with the License. You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing,
17 * software distributed under the License is distributed on an
18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19 * KIND, either express or implied. See the License for the
20 * specific language governing permissions and limitations
21 * under the License.
22 * ====================================================================
25 #include "svn_types.h"
26 #include "svn_props.h"
27 #include "svn_ra.h"
28 #include "svn_io.h"
29 #include "svn_delta.h"
31 #include "private/svn_repos_private.h"
32 #include "private/svn_editor.h"
34 #include "svnrdump.h"
35 #include <assert.h>
38 /* The baton used by the dump editor. */
39 struct dump_edit_baton {
40 /* A backdoor ra session to fetch additional information during the edit. */
41 svn_ra_session_t *ra_session;
43 /* The revision we're currently dumping. */
44 svn_revnum_t current_revision;
47 static svn_error_t *
48 fetch_base_func(const char **filename,
49 void *baton,
50 const char *path,
51 svn_revnum_t base_revision,
52 apr_pool_t *result_pool,
53 apr_pool_t *scratch_pool)
55 struct dump_edit_baton *eb = baton;
56 svn_stream_t *fstream;
57 svn_error_t *err;
59 if (path[0] == '/')
60 path += 1;
62 if (! SVN_IS_VALID_REVNUM(base_revision))
63 base_revision = eb->current_revision - 1;
65 SVN_ERR(svn_stream_open_unique(&fstream, filename, NULL,
66 svn_io_file_del_on_pool_cleanup,
67 result_pool, scratch_pool));
69 err = svn_ra_get_file(eb->ra_session, path, base_revision,
70 fstream, NULL, NULL, scratch_pool);
71 if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
73 svn_error_clear(err);
74 SVN_ERR(svn_stream_close(fstream));
76 *filename = NULL;
77 return SVN_NO_ERROR;
79 else if (err)
80 return svn_error_trace(err);
82 SVN_ERR(svn_stream_close(fstream));
84 return SVN_NO_ERROR;
87 static svn_error_t *
88 fetch_props_func(apr_hash_t **props,
89 void *baton,
90 const char *path,
91 svn_revnum_t base_revision,
92 apr_pool_t *result_pool,
93 apr_pool_t *scratch_pool)
95 struct dump_edit_baton *eb = baton;
96 svn_node_kind_t node_kind;
98 if (path[0] == '/')
99 path += 1;
101 if (! SVN_IS_VALID_REVNUM(base_revision))
102 base_revision = eb->current_revision - 1;
104 SVN_ERR(svn_ra_check_path(eb->ra_session, path, base_revision, &node_kind,
105 scratch_pool));
107 if (node_kind == svn_node_file)
109 SVN_ERR(svn_ra_get_file(eb->ra_session, path, base_revision,
110 NULL, NULL, props, result_pool));
112 else if (node_kind == svn_node_dir)
114 apr_array_header_t *tmp_props;
116 SVN_ERR(svn_ra_get_dir2(eb->ra_session, NULL, NULL, props, path,
117 base_revision, 0 /* Dirent fields */,
118 result_pool));
119 tmp_props = svn_prop_hash_to_array(*props, result_pool);
120 SVN_ERR(svn_categorize_props(tmp_props, NULL, NULL, &tmp_props,
121 result_pool));
122 *props = svn_prop_array_to_hash(tmp_props, result_pool);
124 else
126 *props = apr_hash_make(result_pool);
129 return SVN_NO_ERROR;
132 static svn_error_t *
133 fetch_kind_func(svn_node_kind_t *kind,
134 void *baton,
135 const char *path,
136 svn_revnum_t base_revision,
137 apr_pool_t *scratch_pool)
139 struct dump_edit_baton *eb = baton;
141 if (path[0] == '/')
142 path += 1;
144 if (! SVN_IS_VALID_REVNUM(base_revision))
145 base_revision = eb->current_revision - 1;
147 SVN_ERR(svn_ra_check_path(eb->ra_session, path, base_revision, kind,
148 scratch_pool));
150 return SVN_NO_ERROR;
153 svn_error_t *
154 svn_rdump__get_dump_editor(const svn_delta_editor_t **editor,
155 void **edit_baton,
156 svn_revnum_t revision,
157 svn_stream_t *stream,
158 svn_ra_session_t *ra_session,
159 const char *update_anchor_relpath,
160 svn_cancel_func_t cancel_func,
161 void *cancel_baton,
162 apr_pool_t *pool)
164 struct dump_edit_baton *eb;
165 svn_delta_shim_callbacks_t *shim_callbacks =
166 svn_delta_shim_callbacks_default(pool);
168 eb = apr_pcalloc(pool, sizeof(struct dump_edit_baton));
169 eb->ra_session = ra_session;
170 eb->current_revision = revision;
172 SVN_ERR(svn_repos__get_dump_editor(editor, edit_baton,
173 stream, update_anchor_relpath, pool));
175 /* Wrap this editor in a cancellation editor. */
176 SVN_ERR(svn_delta_get_cancellation_editor(cancel_func, cancel_baton,
177 *editor, *edit_baton,
178 editor, edit_baton,
179 pool));
181 shim_callbacks->fetch_base_func = fetch_base_func;
182 shim_callbacks->fetch_props_func = fetch_props_func;
183 shim_callbacks->fetch_kind_func = fetch_kind_func;
184 shim_callbacks->fetch_baton = eb;
186 SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
187 NULL, NULL, shim_callbacks, pool, pool));
189 return SVN_NO_ERROR;