diff options
Diffstat (limited to 'subversion/include/private/svn_diff_tree.h')
-rw-r--r-- | subversion/include/private/svn_diff_tree.h | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/subversion/include/private/svn_diff_tree.h b/subversion/include/private/svn_diff_tree.h new file mode 100644 index 0000000..8cd4c0e --- /dev/null +++ b/subversion/include/private/svn_diff_tree.h @@ -0,0 +1,357 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + * + * @file svn_diff_tree.h + * @brief Generic diff handler. Replacing the old svn_wc_diff_callbacks4_t + * infrastructure + */ + +#ifndef SVN_DIFF_TREE_H +#define SVN_DIFF_TREE_H + +#include "svn_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * About the diff tree processor. + * + * Subversion uses two kinds of editors to describe changes. One to + * describe changes on how to *exactly* transform one tree to another tree, + * as efficiently as possible and one to describe the difference between trees + * in order to review the changes, or to allow applying them on a third tree + * which is similar to those other trees. + * + * The first case was originally handled by svn_delta_editor_t and might be + * replaced by svn_editor_t in a future version. This diff processor handles + * the other case and as such forms the layer below our diff and merge + * handling. + * + * The major difference between this and the other editors is that this diff + * always provides access to the full text and/or properties in the left and + * right tree when applicable to allow processor implementers to decide how + * to interpret changes. + * + * Originally this diff processor was not formalized explicitly, but + * informally handled by the working copy diff callbacks. These callbacks just + * provided the information to drive a unified diff and a textual merge. To go + * one step further and allow full tree conflict detection we needed a better + * defined diff handling. Instead of adding yet a few more functions and + * arguments to the already overloaded diff callbacks the api was completely + * redesigned with a few points in mind. + * + * * It must be able to drive the old callbacks interface without users + * noticing the difference (100% compatible). + * (Implemented as svn_wc__wrap_diff_callbacks()) + * + * * It should provide the information that was missing in the old interface, + * but required to close existing issues. + * + * E.g. - properties and children on deleted directories. + * - revision numbers and copyfrom information on directories. + * + * To cleanup the implementation and make it easier on diff processors to + * handle the results I also added the following constraints. + * + * * Diffs should be fully reversable: anything that is deleted should be + * available, just like something that is added. + * (Proven via svn_diff__tree_processor_reverse_create) + * ### Still in doubt if *_deleted() needs a copy_to argument, for the + * ### 99% -> 100%. + * + * * Diff processors should have an easy way to communicate that they are + * not interrested in certain expensive to obtain results. + * + * * Directories should have clear open and close events to allow adding them + * before their children, but still allowing property changes to have + * defined behavior. + * + * * Files and directories should be handled as similar as possible as in + * many cases they are just nodes in a tree. + * + * * It should be easy to create diff wrappers to apply certain transforms. + * + * During the creation an additional requirement of knowing about 'some + * absent' nodes was added, to allow the merge to work on just this processor + * api. + * + * The api describes a clean open-close walk through a tree, depending on the + * driver multiple siblings can be described at the same time, but when a + * directory is closed all descendants are done. + * + * Note that it is possible for nodes to be described as a delete followed by + * an add at the same place within one parent. (Iff the diff is reversed you + * can see an add followed by a delete!) + * + * The directory batons live between the open and close events of a directory + * and are thereby guaranteed to outlive the batons of their descendants. + */ + +/* Describes the source of a merge */ +typedef struct svn_diff_source_t +{ + /* Always available */ + svn_revnum_t revision; + + /* Depending on the driver available for copyfrom */ + const char *repos_relpath; +} svn_diff_source_t; + +/** + * A callback vtable invoked by our diff-editors, as they receive diffs + * from the server. 'svn diff' and 'svn merge' implement their own versions + * of this vtable. + * + * All callbacks receive the processor and at least a parent baton. Forwarding + * the processor allows future extensions to call into the old functions without + * revving the entire API. + * + * Users must call svn_diff__tree_processor_create() to allow adding new + * callbacks later. (E.g. when we decide how to add move support) These + * extensions can then just call into other callbacks. + * + * @since New in 1.8. + */ +typedef struct svn_diff_tree_processor_t +{ + /** The value passed to svn_diff__tree_processor_create() as BATON. + */ + void *baton; /* To avoid an additional in some places */ + + /* Called before a directories children are processed. + * + * Set *SKIP_CHILDREN to TRUE, to skip calling callbacks for all + * children. + * + * Set *SKIP to TRUE to skip calling the added, deleted, changed + * or closed callback for this node only. + */ + svn_error_t * + (*dir_opened)(void **new_dir_baton, + svn_boolean_t *skip, + svn_boolean_t *skip_children, + const char *relpath, + const svn_diff_source_t *left_source, + const svn_diff_source_t *right_source, + const svn_diff_source_t *copyfrom_source, + void *parent_dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + /* Called after a directory and all its children are added + */ + svn_error_t * + (*dir_added)(const char *relpath, + const svn_diff_source_t *copyfrom_source, + const svn_diff_source_t *right_source, + /*const*/ apr_hash_t *copyfrom_props, + /*const*/ apr_hash_t *right_props, + void *dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called after all children of this node are reported as deleted. + * + * The default implementation calls dir_closed(). + */ + svn_error_t * + (*dir_deleted)(const char *relpath, + const svn_diff_source_t *left_source, + /*const*/ apr_hash_t *left_props, + void *dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called instead of dir_closed() if the properties on the directory + * were modified. + * + * The default implementation calls dir_closed(). + */ + svn_error_t * + (*dir_changed)(const char *relpath, + const svn_diff_source_t *left_source, + const svn_diff_source_t *right_source, + /*const*/ apr_hash_t *left_props, + /*const*/ apr_hash_t *right_props, + const apr_array_header_t *prop_changes, + void *dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called when a directory is closed without applying changes to + * the directory itself. + * + * When dir_changed or dir_deleted are handled by the default implementation + * they call dir_closed() + */ + svn_error_t * + (*dir_closed)(const char *relpath, + const svn_diff_source_t *left_source, + const svn_diff_source_t *right_source, + void *dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called before file_added(), file_deleted(), file_changed() and + file_closed() + */ + svn_error_t * + (*file_opened)(void **new_file_baton, + svn_boolean_t *skip, + const char *relpath, + const svn_diff_source_t *left_source, + const svn_diff_source_t *right_source, + const svn_diff_source_t *copyfrom_source, + void *dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + /* Called after file_opened() for newly added and copied files */ + svn_error_t * + (*file_added)(const char *relpath, + const svn_diff_source_t *copyfrom_source, + const svn_diff_source_t *right_source, + const char *copyfrom_file, + const char *right_file, + /*const*/ apr_hash_t *copyfrom_props, + /*const*/ apr_hash_t *right_props, + void *file_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called after file_opened() for deleted or moved away files */ + svn_error_t * + (*file_deleted)(const char *relpath, + const svn_diff_source_t *left_source, + const char *left_file, + /*const*/ apr_hash_t *left_props, + void *file_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called after file_opened() for changed files */ + svn_error_t * + (*file_changed)(const char *relpath, + const svn_diff_source_t *left_source, + const svn_diff_source_t *right_source, + const char *left_file, + const char *right_file, + /*const*/ apr_hash_t *left_props, + /*const*/ apr_hash_t *right_props, + svn_boolean_t file_modified, + const apr_array_header_t *prop_changes, + void *file_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called after file_opened() for unmodified files */ + svn_error_t * + (*file_closed)(const char *relpath, + const svn_diff_source_t *left_source, + const svn_diff_source_t *right_source, + void *file_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called when encountering a marker for an absent file or directory */ + svn_error_t * + (*node_absent)(const char *relpath, + void *dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); +} svn_diff_tree_processor_t; + +/** + * Create a new svn_diff_tree_processor_t instance with all functions + * set to a callback doing nothing but copying the parent baton to + * the new baton. + * + * @since New in 1.8. + */ +svn_diff_tree_processor_t * +svn_diff__tree_processor_create(void *baton, + apr_pool_t *result_pool); + +/** + * Create a new svn_diff_tree_processor_t instance with all functions setup + * to call into another svn_diff_tree_processor_t processor, but with all + * adds and deletes inverted. + * + * @since New in 1.8. + */ /* Used by libsvn clients repository diff */ +const svn_diff_tree_processor_t * +svn_diff__tree_processor_reverse_create(const svn_diff_tree_processor_t * processor, + const char *prefix_relpath, + apr_pool_t *result_pool); + +/** + * Create a new svn_diff_tree_processor_t instance with all functions setup + * to call into processor for all paths equal to and below prefix_relpath. + * + * @since New in 1.8. + */ /* Used by libsvn clients repository diff */ +const svn_diff_tree_processor_t * +svn_diff__tree_processor_filter_create(const svn_diff_tree_processor_t *processor, + const char *prefix_relpath, + apr_pool_t *result_pool); + +/** + * Create a new svn_diff_tree_processor_t instace with all function setup + * to call into processor with all adds with copyfrom information transformed + * to simple node changes. + * + * @since New in 1.8. + */ /* Used by libsvn_wc diff editor */ +const svn_diff_tree_processor_t * +svn_diff__tree_processor_copy_as_changed_create( + const svn_diff_tree_processor_t *processor, + apr_pool_t *result_pool); + + +/** + * Create a new svn_diff_tree_processor_t instance with all functions setup + * to first call into processor1 and then processor2. + * + * This function is mostly a debug and migration helper. + * + * @since New in 1.8. + */ /* Used by libsvn clients repository diff */ +const svn_diff_tree_processor_t * +svn_diff__tree_processor_tee_create(const svn_diff_tree_processor_t *processor1, + const svn_diff_tree_processor_t *processor2, + apr_pool_t *result_pool); + + +svn_diff_source_t * +svn_diff__source_create(svn_revnum_t revision, + apr_pool_t *result_pool); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_DIFF_TREE_H */ + |