summaryrefslogtreecommitdiff
path: root/subversion/include/private/svn_diff_tree.h
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/include/private/svn_diff_tree.h')
-rw-r--r--subversion/include/private/svn_diff_tree.h357
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 */
+