2 * repos_diff_summarize.c -- The diff callbacks for summarizing
3 * the differences of two repository versions
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
22 * ====================================================================
26 #include "svn_dirent_uri.h"
29 #include "svn_props.h"
30 #include "svn_pools.h"
32 #include "private/svn_wc_private.h"
37 /* Diff callbacks baton. */
38 struct summarize_baton_t {
39 apr_pool_t *baton_pool; /* For allocating skip_path */
41 /* The target path of the diff, relative to the anchor; "" if target == anchor. */
42 const char *skip_relpath;
44 /* The summarize callback passed down from the API */
45 svn_client_diff_summarize_func_t summarize_func;
47 /* The summarize callback baton */
48 void *summarize_func_baton;
51 /* Call B->summarize_func with B->summarize_func_baton, passing it a
52 * summary object composed from PATH (but made to be relative to the target
53 * of the diff), SUMMARIZE_KIND, PROP_CHANGED (or FALSE if the action is an
54 * add or delete) and NODE_KIND. */
56 send_summary(struct summarize_baton_t *b,
58 svn_client_diff_summarize_kind_t summarize_kind,
59 svn_boolean_t prop_changed,
60 svn_node_kind_t node_kind,
61 apr_pool_t *scratch_pool)
63 svn_client_diff_summarize_t *sum = apr_pcalloc(scratch_pool, sizeof(*sum));
65 SVN_ERR_ASSERT(summarize_kind != svn_client_diff_summarize_kind_normal
68 /* PATH is relative to the anchor of the diff, but SUM->path needs to be
69 relative to the target of the diff. */
70 sum->path = svn_relpath_skip_ancestor(b->skip_relpath, path);
71 sum->summarize_kind = summarize_kind;
72 if (summarize_kind == svn_client_diff_summarize_kind_modified
73 || summarize_kind == svn_client_diff_summarize_kind_normal)
74 sum->prop_changed = prop_changed;
75 sum->node_kind = node_kind;
77 SVN_ERR(b->summarize_func(sum, b->summarize_func_baton, scratch_pool));
81 /* Are there any changes to relevant (normal) props in PROPS? */
83 props_changed_hash(apr_hash_t *props,
84 apr_pool_t *scratch_pool)
91 for (hi = apr_hash_first(scratch_pool, props); hi; hi = apr_hash_next(hi))
93 const char *name = apr_hash_this_key(hi);
95 if (svn_property_kind2(name) == svn_prop_regular_kind)
104 /* Are there any changes to relevant (normal) props in PROPCHANGES? */
106 props_changed(const apr_array_header_t *propchanges,
107 apr_pool_t *scratch_pool)
109 apr_array_header_t *props;
111 svn_error_clear(svn_categorize_props(propchanges, NULL, NULL, &props,
113 return (props->nelts != 0);
116 /* svn_diff_tree_processor_t callback */
118 diff_dir_opened(void **new_dir_baton,
120 svn_boolean_t *skip_children,
122 const svn_diff_source_t *left_source,
123 const svn_diff_source_t *right_source,
124 const svn_diff_source_t *copyfrom_source,
125 void *parent_dir_baton,
126 const struct svn_diff_tree_processor_t *processor,
127 apr_pool_t *result_pool,
128 apr_pool_t *scratch_pool)
130 /* struct summarize_baton_t *b = processor->baton; */
132 /* ### Send here instead of from dir_added() ? */
135 SVN_ERR(send_summary(b, relpath, svn_client_diff_summarize_kind_added,
136 FALSE, svn_node_dir, scratch_pool));
142 /* svn_diff_tree_processor_t callback */
144 diff_dir_changed(const char *relpath,
145 const svn_diff_source_t *left_source,
146 const svn_diff_source_t *right_source,
147 /*const*/ apr_hash_t *left_props,
148 /*const*/ apr_hash_t *right_props,
149 const apr_array_header_t *prop_changes,
151 const struct svn_diff_tree_processor_t *processor,
152 apr_pool_t *scratch_pool)
154 struct summarize_baton_t *b = processor->baton;
156 SVN_ERR(send_summary(b, relpath, svn_client_diff_summarize_kind_normal,
157 TRUE, svn_node_dir, scratch_pool));
162 /* svn_diff_tree_processor_t callback */
164 diff_dir_added(const char *relpath,
165 const svn_diff_source_t *copyfrom_source,
166 const svn_diff_source_t *right_source,
167 /*const*/ apr_hash_t *copyfrom_props,
168 /*const*/ apr_hash_t *right_props,
170 const struct svn_diff_tree_processor_t *processor,
171 apr_pool_t *scratch_pool)
173 struct summarize_baton_t *b = processor->baton;
175 /* ### Send from dir_opened without prop info? */
176 SVN_ERR(send_summary(b, relpath, svn_client_diff_summarize_kind_added,
177 props_changed_hash(right_props, scratch_pool),
178 svn_node_dir, scratch_pool));
183 /* svn_diff_tree_processor_t callback */
185 diff_dir_deleted(const char *relpath,
186 const svn_diff_source_t *left_source,
187 /*const*/ apr_hash_t *left_props,
189 const struct svn_diff_tree_processor_t *processor,
190 apr_pool_t *scratch_pool)
192 struct summarize_baton_t *b = processor->baton;
194 SVN_ERR(send_summary(b, relpath, svn_client_diff_summarize_kind_deleted,
195 FALSE, svn_node_dir, scratch_pool));
200 /* svn_diff_tree_processor_t callback */
202 diff_file_added(const char *relpath,
203 const svn_diff_source_t *copyfrom_source,
204 const svn_diff_source_t *right_source,
205 const char *copyfrom_file,
206 const char *right_file,
207 /*const*/ apr_hash_t *copyfrom_props,
208 /*const*/ apr_hash_t *right_props,
210 const struct svn_diff_tree_processor_t *processor,
211 apr_pool_t *scratch_pool)
213 struct summarize_baton_t *b = processor->baton;
215 SVN_ERR(send_summary(b, relpath, svn_client_diff_summarize_kind_added,
216 props_changed_hash(right_props, scratch_pool),
217 svn_node_file, scratch_pool));
222 /* svn_diff_tree_processor_t callback */
224 diff_file_changed(const char *relpath,
225 const svn_diff_source_t *left_source,
226 const svn_diff_source_t *right_source,
227 const char *left_file,
228 const char *right_file,
229 /*const*/ apr_hash_t *left_props,
230 /*const*/ apr_hash_t *right_props,
231 svn_boolean_t file_modified,
232 const apr_array_header_t *prop_changes,
234 const struct svn_diff_tree_processor_t *processor,
235 apr_pool_t *scratch_pool)
237 struct summarize_baton_t *b = processor->baton;
239 SVN_ERR(send_summary(b, relpath,
240 file_modified ? svn_client_diff_summarize_kind_modified
241 : svn_client_diff_summarize_kind_normal,
242 props_changed(prop_changes, scratch_pool),
243 svn_node_file, scratch_pool));
248 /* svn_diff_tree_processor_t callback */
250 diff_file_deleted(const char *relpath,
251 const svn_diff_source_t *left_source,
252 const char *left_file,
253 /*const*/ apr_hash_t *left_props,
255 const struct svn_diff_tree_processor_t *processor,
256 apr_pool_t *scratch_pool)
258 struct summarize_baton_t *b = processor->baton;
260 SVN_ERR(send_summary(b, relpath, svn_client_diff_summarize_kind_deleted,
261 FALSE, svn_node_file, scratch_pool));
267 svn_client__get_diff_summarize_callbacks(
268 const svn_diff_tree_processor_t **diff_processor,
269 const char ***p_root_relpath,
270 svn_client_diff_summarize_func_t summarize_func,
271 void *summarize_baton,
272 const char *original_target,
273 apr_pool_t *result_pool,
274 apr_pool_t *scratch_pool)
276 svn_diff_tree_processor_t *dp;
277 struct summarize_baton_t *b = apr_pcalloc(result_pool, sizeof(*b));
279 b->baton_pool = result_pool;
280 b->summarize_func = summarize_func;
281 b->summarize_func_baton = summarize_baton;
283 dp = svn_diff__tree_processor_create(b, result_pool);
285 /*dp->file_opened = diff_file_opened;*/
286 dp->file_added = diff_file_added;
287 dp->file_deleted = diff_file_deleted;
288 dp->file_changed = diff_file_changed;
290 dp->dir_opened = diff_dir_opened;
291 dp->dir_changed = diff_dir_changed;
292 dp->dir_deleted = diff_dir_deleted;
293 dp->dir_added = diff_dir_added;
295 *diff_processor = dp;
296 *p_root_relpath = &b->skip_relpath;
301 svn_client_diff_summarize_t *
302 svn_client_diff_summarize_dup(const svn_client_diff_summarize_t *diff,
305 svn_client_diff_summarize_t *dup_diff = apr_palloc(pool, sizeof(*dup_diff));
310 dup_diff->path = apr_pstrdup(pool, diff->path);