3
* ====================================================================
4
* Licensed to the Apache Software Foundation (ASF) under one
5
* or more contributor license agreements. See the NOTICE file
6
* distributed with this work for additional information
7
* regarding copyright ownership. The ASF licenses this file
8
* to you under the Apache License, Version 2.0 (the
9
* "License"); you may not use this file except in compliance
10
* with the License. You may obtain a copy of the License at
12
* http://www.apache.org/licenses/LICENSE-2.0
14
* Unless required by applicable law or agreed to in writing,
15
* software distributed under the License is distributed on an
16
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17
* KIND, either express or implied. See the License for the
18
* specific language governing permissions and limitations
20
* ====================================================================
24
* @brief Generic diff handler. Replacing the old svn_wc_diff_callbacks4_t
28
#ifndef SVN_DIFF_PROCESSOR_H
29
#define SVN_DIFF_PROCESSOR_H
31
#include "svn_types.h"
35
#endif /* __cplusplus */
38
* About the diff tree processor.
40
* Subversion uses two kinds of editors to describe changes. One to
41
* describe changes on how to *exactly* transform one tree to another tree,
42
* as efficiently as possible and one to describe the difference between trees
43
* in order to review the changes, or to allow applying them on a third tree
44
* which is similar to those other trees.
46
* The first case was originally handled by svn_delta_editor_t and might be
47
* replaced by svn_editor_t in a future version. This diff processor handles
48
* the other case and as such forms the layer below our diff and merge
51
* The major difference between this and the other editors is that this diff
52
* always provides access to the full text and/or properties in the left and
53
* right tree when applicable to allow processor implementers to decide how
54
* to interpret changes.
56
* Originally this diff processor was not formalized explicitly, but
57
* informally handled by the working copy diff callbacks. These callbacks just
58
* provided the information to drive a unified diff and a textual merge. To go
59
* one step further and allow full tree conflict detection we needed a better
60
* defined diff handling. Instead of adding yet a few more functions and
61
* arguments to the already overloaded diff callbacks the api was completely
62
* redesigned with a few points in mind.
64
* * It must be able to drive the old callbacks interface without users
65
* noticing the difference (100% compatible).
66
* (Implemented as svn_wc__wrap_diff_callbacks())
68
* * It should provide the information that was missing in the old interface,
69
* but required to close existing issues.
71
* E.g. - properties and children on deleted directories.
72
* - revision numbers and copyfrom information on directories.
74
* To cleanup the implementation and make it easier on diff processors to
75
* handle the results I also added the following constraints.
77
* * Diffs should be fully reversable: anything that is deleted should be
78
* available, just like something that is added.
79
* (Proven via svn_diff__tree_processor_reverse_create)
80
* ### Still in doubt if *_deleted() needs a copy_to argument, for the
83
* * Diff processors should have an easy way to communicate that they are
84
* not interrested in certain expensive to obtain results.
86
* * Directories should have clear open and close events to allow adding them
87
* before their children, but still allowing property changes to have
90
* * Files and directories should be handled as similar as possible as in
91
* many cases they are just nodes in a tree.
93
* * It should be easy to create diff wrappers to apply certain transforms.
95
* During the creation an additional requirement of knowing about 'some
96
* absent' nodes was added, to allow the merge to work on just this processor
99
* The api describes a clean open-close walk through a tree, depending on the
100
* driver multiple siblings can be described at the same time, but when a
101
* directory is closed all descendants are done.
103
* Note that it is possible for nodes to be described as a delete followed by
104
* an add at the same place within one parent. (Iff the diff is reversed you
105
* can see an add followed by a delete!)
107
* The directory batons live between the open and close events of a directory
108
* and are thereby guaranteed to outlive the batons of their descendants.
111
/* Describes the source of a merge */
112
typedef struct svn_diff_source_t
114
/* Always available */
115
svn_revnum_t revision;
117
/* Depending on the driver available for copyfrom */
118
const char *repos_relpath;
122
* A callback vtable invoked by our diff-editors, as they receive diffs
123
* from the server. 'svn diff' and 'svn merge' implement their own versions
126
* All callbacks receive the processor and at least a parent baton. Forwarding
127
* the processor allows future extensions to call into the old functions without
128
* revving the entire API.
130
* Users must call svn_diff__tree_processor_create() to allow adding new
131
* callbacks later. (E.g. when we decide how to add move support) These
132
* extensions can then just call into other callbacks.
136
typedef struct svn_diff_tree_processor_t
138
/** The value passed to svn_diff__tree_processor_create() as BATON.
140
void *baton; /* To avoid an additional in some places */
142
/* Called before a directories children are processed.
144
* Set *SKIP_CHILDREN to TRUE, to skip calling callbacks for all
147
* Set *SKIP to TRUE to skip calling the added, deleted, changed
148
* or closed callback for this node only.
151
(*dir_opened)(void **new_dir_baton,
153
svn_boolean_t *skip_children,
155
const svn_diff_source_t *left_source,
156
const svn_diff_source_t *right_source,
157
const svn_diff_source_t *copyfrom_source,
158
void *parent_dir_baton,
159
const struct svn_diff_tree_processor_t *processor,
160
apr_pool_t *result_pool,
161
apr_pool_t *scratch_pool);
163
/* Called after a directory and all its children are added
166
(*dir_added)(const char *relpath,
167
const svn_diff_source_t *copyfrom_source,
168
const svn_diff_source_t *right_source,
169
/*const*/ apr_hash_t *copyfrom_props,
170
/*const*/ apr_hash_t *right_props,
172
const struct svn_diff_tree_processor_t *processor,
173
apr_pool_t *scratch_pool);
175
/* Called after all children of this node are reported as deleted.
177
* The default implementation calls dir_closed().
180
(*dir_deleted)(const char *relpath,
181
const svn_diff_source_t *left_source,
182
/*const*/ apr_hash_t *left_props,
184
const struct svn_diff_tree_processor_t *processor,
185
apr_pool_t *scratch_pool);
187
/* Called instead of dir_closed() if the properties on the directory
190
* The default implementation calls dir_closed().
193
(*dir_changed)(const char *relpath,
194
const svn_diff_source_t *left_source,
195
const svn_diff_source_t *right_source,
196
/*const*/ apr_hash_t *left_props,
197
/*const*/ apr_hash_t *right_props,
198
const apr_array_header_t *prop_changes,
200
const struct svn_diff_tree_processor_t *processor,
201
apr_pool_t *scratch_pool);
203
/* Called when a directory is closed without applying changes to
204
* the directory itself.
206
* When dir_changed or dir_deleted are handled by the default implementation
207
* they call dir_closed()
210
(*dir_closed)(const char *relpath,
211
const svn_diff_source_t *left_source,
212
const svn_diff_source_t *right_source,
214
const struct svn_diff_tree_processor_t *processor,
215
apr_pool_t *scratch_pool);
217
/* Called before file_added(), file_deleted(), file_changed() and
221
(*file_opened)(void **new_file_baton,
224
const svn_diff_source_t *left_source,
225
const svn_diff_source_t *right_source,
226
const svn_diff_source_t *copyfrom_source,
228
const struct svn_diff_tree_processor_t *processor,
229
apr_pool_t *result_pool,
230
apr_pool_t *scratch_pool);
232
/* Called after file_opened() for newly added and copied files */
234
(*file_added)(const char *relpath,
235
const svn_diff_source_t *copyfrom_source,
236
const svn_diff_source_t *right_source,
237
const char *copyfrom_file,
238
const char *right_file,
239
/*const*/ apr_hash_t *copyfrom_props,
240
/*const*/ apr_hash_t *right_props,
242
const struct svn_diff_tree_processor_t *processor,
243
apr_pool_t *scratch_pool);
245
/* Called after file_opened() for deleted or moved away files */
247
(*file_deleted)(const char *relpath,
248
const svn_diff_source_t *left_source,
249
const char *left_file,
250
/*const*/ apr_hash_t *left_props,
252
const struct svn_diff_tree_processor_t *processor,
253
apr_pool_t *scratch_pool);
255
/* Called after file_opened() for changed files */
257
(*file_changed)(const char *relpath,
258
const svn_diff_source_t *left_source,
259
const svn_diff_source_t *right_source,
260
const char *left_file,
261
const char *right_file,
262
/*const*/ apr_hash_t *left_props,
263
/*const*/ apr_hash_t *right_props,
264
svn_boolean_t file_modified,
265
const apr_array_header_t *prop_changes,
267
const struct svn_diff_tree_processor_t *processor,
268
apr_pool_t *scratch_pool);
270
/* Called after file_opened() for unmodified files */
272
(*file_closed)(const char *relpath,
273
const svn_diff_source_t *left_source,
274
const svn_diff_source_t *right_source,
276
const struct svn_diff_tree_processor_t *processor,
277
apr_pool_t *scratch_pool);
279
/* Called when encountering a marker for an absent file or directory */
281
(*node_absent)(const char *relpath,
283
const struct svn_diff_tree_processor_t *processor,
284
apr_pool_t *scratch_pool);
285
} svn_diff_tree_processor_t;
288
* Create a new svn_diff_tree_processor_t instance with all functions
289
* set to a callback doing nothing but copying the parent baton to
294
svn_diff_tree_processor_t *
295
svn_diff__tree_processor_create(void *baton,
296
apr_pool_t *result_pool);
299
* Create a new svn_diff_tree_processor_t instance with all functions setup
300
* to call into another svn_diff_tree_processor_t processor, but with all
301
* adds and deletes inverted.
304
*/ /* Used by libsvn clients repository diff */
305
const svn_diff_tree_processor_t *
306
svn_diff__tree_processor_reverse_create(const svn_diff_tree_processor_t * processor,
307
const char *prefix_relpath,
308
apr_pool_t *result_pool);
311
* Create a new svn_diff_tree_processor_t instance with all functions setup
312
* to call into processor for all paths equal to and below prefix_relpath.
315
*/ /* Used by libsvn clients repository diff */
316
const svn_diff_tree_processor_t *
317
svn_diff__tree_processor_filter_create(const svn_diff_tree_processor_t *processor,
318
const char *prefix_relpath,
319
apr_pool_t *result_pool);
322
* Create a new svn_diff_tree_processor_t instace with all function setup
323
* to call into processor with all adds with copyfrom information transformed
324
* to simple node changes.
327
*/ /* Used by libsvn_wc diff editor */
328
const svn_diff_tree_processor_t *
329
svn_diff__tree_processor_copy_as_changed_create(
330
const svn_diff_tree_processor_t *processor,
331
apr_pool_t *result_pool);
335
* Create a new svn_diff_tree_processor_t instance with all functions setup
336
* to first call into processor1 and then processor2.
338
* This function is mostly a debug and migration helper.
341
*/ /* Used by libsvn clients repository diff */
342
const svn_diff_tree_processor_t *
343
svn_diff__tree_processor_tee_create(const svn_diff_tree_processor_t *processor1,
344
const svn_diff_tree_processor_t *processor2,
345
apr_pool_t *result_pool);
349
svn_diff__source_create(svn_revnum_t revision,
350
apr_pool_t *result_pool);
354
#endif /* __cplusplus */
356
#endif /* SVN_DIFF_PROCESSOR_H */