2 * repos_diff_summarize.c -- The diff summarize editor for summarizing
3 * the differences of two repository versions
5 * ====================================================================
6 * Copyright (c) 2005-2006 CollabNet. All rights reserved.
8 * This software is licensed as described in the file COPYING, which
9 * you should have received as part of this distribution. The terms
10 * are also available at http://subversion.tigris.org/license-1.html.
11 * If newer versions of this license are posted there, you may use a
12 * newer version instead, at your option.
14 * This software consists of voluntary contributions made by many
15 * individuals. For exact contribution history, see the revision
16 * history and logs, available at http://subversion.tigris.org/.
17 * ====================================================================
21 #include "svn_props.h"
22 #include "svn_pools.h"
27 /* Overall crawler editor baton. */
29 /* The target of the diff, relative to the root of the edit */
32 /* The summarize callback passed down from the API */
33 svn_client_diff_summarize_func_t summarize_func
;
35 /* The summarize callback baton */
36 void *summarize_func_baton
;
38 /* An RA session used to check the kind of deleted paths */
39 svn_ra_session_t
*ra_session
;
41 /* The start revision for the comparison */
42 svn_revnum_t revision
;
48 /* The overall crawler editor baton */
49 struct edit_baton
*edit_baton
;
51 /* The summarize filled by the editor calls, NULL if this item hasn't
52 been modified (yet) */
53 svn_client_diff_summarize_t
*summarize
;
55 /* The path of the file or directory within the repository */
58 /* The kind of this item */
59 svn_node_kind_t node_kind
;
61 /* The file/directory pool */
62 apr_pool_t
*item_pool
;
66 /* Create an item baton, with the fields initialized to EDIT_BATON, PATH,
67 * NODE_KIND and POOL, respectively. Allocate the returned structure in POOL.
69 static struct item_baton
*
70 create_item_baton(struct edit_baton
*edit_baton
,
72 svn_node_kind_t node_kind
,
75 struct item_baton
*b
= apr_pcalloc(pool
, sizeof(*b
));
77 b
->edit_baton
= edit_baton
;
78 /* Issue #2765: b->path is supposed to be relative to the target.
79 If the target is a file, just use an empty path. This way the
80 receiver can just concatenate this path to the original path
81 without doing any extra checks. */
82 if (node_kind
== svn_node_file
&& strcmp(path
, edit_baton
->target
) == 0)
85 b
->path
= apr_pstrdup(pool
, path
);
86 b
->node_kind
= node_kind
;
92 /* Make sure that this item baton contains a summarize struct.
93 * If it doesn't before this call, allocate a new struct in the item's pool,
94 * initializing the diff kind to normal.
95 * All other fields are also initialized from IB to to NULL/invalid values. */
97 ensure_summarize(struct item_baton
*ib
)
99 svn_client_diff_summarize_t
*sum
;
103 sum
= apr_pcalloc(ib
->item_pool
, sizeof(*sum
));
105 sum
->node_kind
= ib
->node_kind
;
106 sum
->summarize_kind
= svn_client_diff_summarize_kind_normal
;
107 sum
->path
= ib
->path
;
113 /* An editor function. The root of the comparison hierarchy */
115 open_root(void *edit_baton
,
116 svn_revnum_t base_revision
,
120 struct item_baton
*ib
= create_item_baton(edit_baton
, "",
127 /* An editor function. */
129 delete_entry(const char *path
,
130 svn_revnum_t base_revision
,
134 struct item_baton
*ib
= parent_baton
;
135 struct edit_baton
*eb
= ib
->edit_baton
;
136 svn_client_diff_summarize_t
*sum
;
137 svn_node_kind_t kind
;
139 /* We need to know if this is a directory or a file */
140 SVN_ERR(svn_ra_check_path(eb
->ra_session
,
146 sum
= apr_pcalloc(pool
, sizeof(*sum
));
147 sum
->summarize_kind
= svn_client_diff_summarize_kind_deleted
;
149 sum
->node_kind
= kind
;
151 SVN_ERR(eb
->summarize_func(sum
, eb
->summarize_func_baton
, pool
));
156 /* An editor function. */
158 add_directory(const char *path
,
160 const char *copyfrom_path
,
161 svn_revnum_t copyfrom_rev
,
165 struct item_baton
*pb
= parent_baton
;
166 struct item_baton
*cb
;
168 cb
= create_item_baton(pb
->edit_baton
, path
, svn_node_dir
, pool
);
169 ensure_summarize(cb
);
170 cb
->summarize
->summarize_kind
= svn_client_diff_summarize_kind_added
;
176 /* An editor function. */
178 open_directory(const char *path
,
180 svn_revnum_t base_revision
,
184 struct item_baton
*pb
= parent_baton
;
185 struct item_baton
*cb
;
187 cb
= create_item_baton(pb
->edit_baton
, path
, svn_node_dir
, pool
);
194 /* An editor function. */
196 close_directory(void *dir_baton
,
199 struct item_baton
*ib
= dir_baton
;
200 struct edit_baton
*eb
= ib
->edit_baton
;
203 SVN_ERR(eb
->summarize_func(ib
->summarize
, eb
->summarize_func_baton
,
210 /* An editor function. */
212 add_file(const char *path
,
214 const char *copyfrom_path
,
215 svn_revnum_t copyfrom_rev
,
219 struct item_baton
*pb
= parent_baton
;
220 struct item_baton
*cb
;
222 cb
= create_item_baton(pb
->edit_baton
, path
, svn_node_file
, pool
);
223 ensure_summarize(cb
);
224 cb
->summarize
->summarize_kind
= svn_client_diff_summarize_kind_added
;
230 /* An editor function. */
232 open_file(const char *path
,
234 svn_revnum_t base_revision
,
238 struct item_baton
*pb
= parent_baton
;
239 struct item_baton
*cb
;
241 cb
= create_item_baton(pb
->edit_baton
, path
, svn_node_file
, pool
);
247 /* An editor function. */
249 apply_textdelta(void *file_baton
,
250 const char *base_checksum
,
252 svn_txdelta_window_handler_t
*handler
,
253 void **handler_baton
)
255 struct item_baton
*ib
= file_baton
;
257 ensure_summarize(ib
);
258 if (ib
->summarize
->summarize_kind
== svn_client_diff_summarize_kind_normal
)
259 ib
->summarize
->summarize_kind
= svn_client_diff_summarize_kind_modified
;
261 *handler
= svn_delta_noop_window_handler
;
262 *handler_baton
= NULL
;
268 /* An editor function. */
270 close_file(void *file_baton
,
271 const char *text_checksum
,
274 struct item_baton
*fb
= file_baton
;
275 struct edit_baton
*eb
= fb
->edit_baton
;
278 SVN_ERR(eb
->summarize_func(fb
->summarize
, eb
->summarize_func_baton
,
285 /* An editor function, implementing both change_file_prop and
286 * change_dir_prop. */
288 change_prop(void *entry_baton
,
290 const svn_string_t
*value
,
293 struct item_baton
*ib
= entry_baton
;
295 if (svn_property_kind(NULL
, name
) == svn_prop_regular_kind
)
297 ensure_summarize(ib
);
298 ib
->summarize
->prop_changed
= TRUE
;
304 /* Create a repository diff summarize editor and baton. */
306 svn_client__get_diff_summarize_editor(const char *target
,
307 svn_client_diff_summarize_func_t
310 svn_ra_session_t
*ra_session
,
311 svn_revnum_t revision
,
312 svn_cancel_func_t cancel_func
,
314 const svn_delta_editor_t
**editor
,
318 svn_delta_editor_t
*tree_editor
= svn_delta_default_editor(pool
);
319 struct edit_baton
*eb
= apr_palloc(pool
, sizeof(*eb
));
322 eb
->summarize_func
= summarize_func
;
323 eb
->summarize_func_baton
= item_baton
;
324 eb
->ra_session
= ra_session
;
325 eb
->revision
= revision
;
327 tree_editor
->open_root
= open_root
;
328 tree_editor
->delete_entry
= delete_entry
;
329 tree_editor
->add_directory
= add_directory
;
330 tree_editor
->open_directory
= open_directory
;
331 tree_editor
->change_dir_prop
= change_prop
;
332 tree_editor
->close_directory
= close_directory
;
334 tree_editor
->add_file
= add_file
;
335 tree_editor
->open_file
= open_file
;
336 tree_editor
->apply_textdelta
= apply_textdelta
;
337 tree_editor
->change_file_prop
= change_prop
;
338 tree_editor
->close_file
= close_file
;
340 SVN_ERR(svn_delta_get_cancellation_editor
341 (cancel_func
, cancel_baton
, tree_editor
, eb
, editor
, edit_baton
,