1251881Speter/** 2251881Speter * @copyright 3251881Speter * ==================================================================== 4251881Speter * Licensed to the Apache Software Foundation (ASF) under one 5251881Speter * or more contributor license agreements. See the NOTICE file 6251881Speter * distributed with this work for additional information 7251881Speter * regarding copyright ownership. The ASF licenses this file 8251881Speter * to you under the Apache License, Version 2.0 (the 9251881Speter * "License"); you may not use this file except in compliance 10251881Speter * with the License. You may obtain a copy of the License at 11251881Speter * 12251881Speter * http://www.apache.org/licenses/LICENSE-2.0 13251881Speter * 14251881Speter * Unless required by applicable law or agreed to in writing, 15251881Speter * software distributed under the License is distributed on an 16251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17251881Speter * KIND, either express or implied. See the License for the 18251881Speter * specific language governing permissions and limitations 19251881Speter * under the License. 20251881Speter * ==================================================================== 21251881Speter * @endcopyright 22251881Speter * 23251881Speter * @file svn_wc.h 24251881Speter * @brief Generic diff handler. Replacing the old svn_wc_diff_callbacks4_t 25251881Speter * infrastructure 26251881Speter */ 27251881Speter 28251881Speter#ifndef SVN_DIFF_PROCESSOR_H 29251881Speter#define SVN_DIFF_PROCESSOR_H 30251881Speter 31251881Speter#include "svn_types.h" 32251881Speter 33251881Speter#ifdef __cplusplus 34251881Speterextern "C" { 35251881Speter#endif /* __cplusplus */ 36251881Speter 37251881Speter/* 38251881Speter * About the diff tree processor. 39251881Speter * 40251881Speter * Subversion uses two kinds of editors to describe changes. One to 41251881Speter * describe changes on how to *exactly* transform one tree to another tree, 42251881Speter * as efficiently as possible and one to describe the difference between trees 43251881Speter * in order to review the changes, or to allow applying them on a third tree 44251881Speter * which is similar to those other trees. 45251881Speter * 46251881Speter * The first case was originally handled by svn_delta_editor_t and might be 47251881Speter * replaced by svn_editor_t in a future version. This diff processor handles 48251881Speter * the other case and as such forms the layer below our diff and merge 49251881Speter * handling. 50251881Speter * 51251881Speter * The major difference between this and the other editors is that this diff 52251881Speter * always provides access to the full text and/or properties in the left and 53251881Speter * right tree when applicable to allow processor implementers to decide how 54251881Speter * to interpret changes. 55251881Speter * 56251881Speter * Originally this diff processor was not formalized explicitly, but 57251881Speter * informally handled by the working copy diff callbacks. These callbacks just 58251881Speter * provided the information to drive a unified diff and a textual merge. To go 59251881Speter * one step further and allow full tree conflict detection we needed a better 60251881Speter * defined diff handling. Instead of adding yet a few more functions and 61251881Speter * arguments to the already overloaded diff callbacks the api was completely 62251881Speter * redesigned with a few points in mind. 63251881Speter * 64251881Speter * * It must be able to drive the old callbacks interface without users 65251881Speter * noticing the difference (100% compatible). 66251881Speter * (Implemented as svn_wc__wrap_diff_callbacks()) 67251881Speter * 68251881Speter * * It should provide the information that was missing in the old interface, 69251881Speter * but required to close existing issues. 70251881Speter * 71251881Speter * E.g. - properties and children on deleted directories. 72251881Speter * - revision numbers and copyfrom information on directories. 73251881Speter * 74251881Speter * To cleanup the implementation and make it easier on diff processors to 75251881Speter * handle the results I also added the following constraints. 76251881Speter * 77251881Speter * * Diffs should be fully reversable: anything that is deleted should be 78251881Speter * available, just like something that is added. 79251881Speter * (Proven via svn_diff__tree_processor_reverse_create) 80251881Speter * ### Still in doubt if *_deleted() needs a copy_to argument, for the 81251881Speter * ### 99% -> 100%. 82251881Speter * 83251881Speter * * Diff processors should have an easy way to communicate that they are 84251881Speter * not interrested in certain expensive to obtain results. 85251881Speter * 86251881Speter * * Directories should have clear open and close events to allow adding them 87251881Speter * before their children, but still allowing property changes to have 88251881Speter * defined behavior. 89251881Speter * 90251881Speter * * Files and directories should be handled as similar as possible as in 91251881Speter * many cases they are just nodes in a tree. 92251881Speter * 93251881Speter * * It should be easy to create diff wrappers to apply certain transforms. 94251881Speter * 95251881Speter * During the creation an additional requirement of knowing about 'some 96251881Speter * absent' nodes was added, to allow the merge to work on just this processor 97251881Speter * api. 98251881Speter * 99251881Speter * The api describes a clean open-close walk through a tree, depending on the 100251881Speter * driver multiple siblings can be described at the same time, but when a 101251881Speter * directory is closed all descendants are done. 102251881Speter * 103251881Speter * Note that it is possible for nodes to be described as a delete followed by 104251881Speter * an add at the same place within one parent. (Iff the diff is reversed you 105251881Speter * can see an add followed by a delete!) 106251881Speter * 107251881Speter * The directory batons live between the open and close events of a directory 108251881Speter * and are thereby guaranteed to outlive the batons of their descendants. 109251881Speter */ 110251881Speter 111251881Speter/* Describes the source of a merge */ 112251881Spetertypedef struct svn_diff_source_t 113251881Speter{ 114251881Speter /* Always available */ 115251881Speter svn_revnum_t revision; 116251881Speter 117251881Speter /* Depending on the driver available for copyfrom */ 118251881Speter const char *repos_relpath; 119251881Speter} svn_diff_source_t; 120251881Speter 121251881Speter/** 122251881Speter * A callback vtable invoked by our diff-editors, as they receive diffs 123251881Speter * from the server. 'svn diff' and 'svn merge' implement their own versions 124251881Speter * of this vtable. 125251881Speter * 126251881Speter * All callbacks receive the processor and at least a parent baton. Forwarding 127251881Speter * the processor allows future extensions to call into the old functions without 128251881Speter * revving the entire API. 129251881Speter * 130251881Speter * Users must call svn_diff__tree_processor_create() to allow adding new 131251881Speter * callbacks later. (E.g. when we decide how to add move support) These 132251881Speter * extensions can then just call into other callbacks. 133251881Speter * 134251881Speter * @since New in 1.8. 135251881Speter */ 136251881Spetertypedef struct svn_diff_tree_processor_t 137251881Speter{ 138251881Speter /** The value passed to svn_diff__tree_processor_create() as BATON. 139251881Speter */ 140251881Speter void *baton; /* To avoid an additional in some places */ 141251881Speter 142251881Speter /* Called before a directories children are processed. 143251881Speter * 144251881Speter * Set *SKIP_CHILDREN to TRUE, to skip calling callbacks for all 145251881Speter * children. 146251881Speter * 147251881Speter * Set *SKIP to TRUE to skip calling the added, deleted, changed 148251881Speter * or closed callback for this node only. 149251881Speter */ 150251881Speter svn_error_t * 151251881Speter (*dir_opened)(void **new_dir_baton, 152251881Speter svn_boolean_t *skip, 153251881Speter svn_boolean_t *skip_children, 154251881Speter const char *relpath, 155251881Speter const svn_diff_source_t *left_source, 156251881Speter const svn_diff_source_t *right_source, 157251881Speter const svn_diff_source_t *copyfrom_source, 158251881Speter void *parent_dir_baton, 159251881Speter const struct svn_diff_tree_processor_t *processor, 160251881Speter apr_pool_t *result_pool, 161251881Speter apr_pool_t *scratch_pool); 162251881Speter 163251881Speter /* Called after a directory and all its children are added 164251881Speter */ 165251881Speter svn_error_t * 166251881Speter (*dir_added)(const char *relpath, 167251881Speter const svn_diff_source_t *copyfrom_source, 168251881Speter const svn_diff_source_t *right_source, 169251881Speter /*const*/ apr_hash_t *copyfrom_props, 170251881Speter /*const*/ apr_hash_t *right_props, 171251881Speter void *dir_baton, 172251881Speter const struct svn_diff_tree_processor_t *processor, 173251881Speter apr_pool_t *scratch_pool); 174251881Speter 175251881Speter /* Called after all children of this node are reported as deleted. 176251881Speter * 177251881Speter * The default implementation calls dir_closed(). 178251881Speter */ 179251881Speter svn_error_t * 180251881Speter (*dir_deleted)(const char *relpath, 181251881Speter const svn_diff_source_t *left_source, 182251881Speter /*const*/ apr_hash_t *left_props, 183251881Speter void *dir_baton, 184251881Speter const struct svn_diff_tree_processor_t *processor, 185251881Speter apr_pool_t *scratch_pool); 186251881Speter 187251881Speter /* Called instead of dir_closed() if the properties on the directory 188251881Speter * were modified. 189251881Speter * 190251881Speter * The default implementation calls dir_closed(). 191251881Speter */ 192251881Speter svn_error_t * 193251881Speter (*dir_changed)(const char *relpath, 194251881Speter const svn_diff_source_t *left_source, 195251881Speter const svn_diff_source_t *right_source, 196251881Speter /*const*/ apr_hash_t *left_props, 197251881Speter /*const*/ apr_hash_t *right_props, 198251881Speter const apr_array_header_t *prop_changes, 199251881Speter void *dir_baton, 200251881Speter const struct svn_diff_tree_processor_t *processor, 201251881Speter apr_pool_t *scratch_pool); 202251881Speter 203251881Speter /* Called when a directory is closed without applying changes to 204251881Speter * the directory itself. 205251881Speter * 206251881Speter * When dir_changed or dir_deleted are handled by the default implementation 207251881Speter * they call dir_closed() 208251881Speter */ 209251881Speter svn_error_t * 210251881Speter (*dir_closed)(const char *relpath, 211251881Speter const svn_diff_source_t *left_source, 212251881Speter const svn_diff_source_t *right_source, 213251881Speter void *dir_baton, 214251881Speter const struct svn_diff_tree_processor_t *processor, 215251881Speter apr_pool_t *scratch_pool); 216251881Speter 217251881Speter /* Called before file_added(), file_deleted(), file_changed() and 218251881Speter file_closed() 219251881Speter */ 220251881Speter svn_error_t * 221251881Speter (*file_opened)(void **new_file_baton, 222251881Speter svn_boolean_t *skip, 223251881Speter const char *relpath, 224251881Speter const svn_diff_source_t *left_source, 225251881Speter const svn_diff_source_t *right_source, 226251881Speter const svn_diff_source_t *copyfrom_source, 227251881Speter void *dir_baton, 228251881Speter const struct svn_diff_tree_processor_t *processor, 229251881Speter apr_pool_t *result_pool, 230251881Speter apr_pool_t *scratch_pool); 231251881Speter 232251881Speter /* Called after file_opened() for newly added and copied files */ 233251881Speter svn_error_t * 234251881Speter (*file_added)(const char *relpath, 235251881Speter const svn_diff_source_t *copyfrom_source, 236251881Speter const svn_diff_source_t *right_source, 237251881Speter const char *copyfrom_file, 238251881Speter const char *right_file, 239251881Speter /*const*/ apr_hash_t *copyfrom_props, 240251881Speter /*const*/ apr_hash_t *right_props, 241251881Speter void *file_baton, 242251881Speter const struct svn_diff_tree_processor_t *processor, 243251881Speter apr_pool_t *scratch_pool); 244251881Speter 245251881Speter /* Called after file_opened() for deleted or moved away files */ 246251881Speter svn_error_t * 247251881Speter (*file_deleted)(const char *relpath, 248251881Speter const svn_diff_source_t *left_source, 249251881Speter const char *left_file, 250251881Speter /*const*/ apr_hash_t *left_props, 251251881Speter void *file_baton, 252251881Speter const struct svn_diff_tree_processor_t *processor, 253251881Speter apr_pool_t *scratch_pool); 254251881Speter 255251881Speter /* Called after file_opened() for changed files */ 256251881Speter svn_error_t * 257251881Speter (*file_changed)(const char *relpath, 258251881Speter const svn_diff_source_t *left_source, 259251881Speter const svn_diff_source_t *right_source, 260251881Speter const char *left_file, 261251881Speter const char *right_file, 262251881Speter /*const*/ apr_hash_t *left_props, 263251881Speter /*const*/ apr_hash_t *right_props, 264251881Speter svn_boolean_t file_modified, 265251881Speter const apr_array_header_t *prop_changes, 266251881Speter void *file_baton, 267251881Speter const struct svn_diff_tree_processor_t *processor, 268251881Speter apr_pool_t *scratch_pool); 269251881Speter 270251881Speter /* Called after file_opened() for unmodified files */ 271251881Speter svn_error_t * 272251881Speter (*file_closed)(const char *relpath, 273251881Speter const svn_diff_source_t *left_source, 274251881Speter const svn_diff_source_t *right_source, 275251881Speter void *file_baton, 276251881Speter const struct svn_diff_tree_processor_t *processor, 277251881Speter apr_pool_t *scratch_pool); 278251881Speter 279251881Speter /* Called when encountering a marker for an absent file or directory */ 280251881Speter svn_error_t * 281251881Speter (*node_absent)(const char *relpath, 282251881Speter void *dir_baton, 283251881Speter const struct svn_diff_tree_processor_t *processor, 284251881Speter apr_pool_t *scratch_pool); 285251881Speter} svn_diff_tree_processor_t; 286251881Speter 287251881Speter/** 288251881Speter * Create a new svn_diff_tree_processor_t instance with all functions 289251881Speter * set to a callback doing nothing but copying the parent baton to 290251881Speter * the new baton. 291251881Speter * 292251881Speter * @since New in 1.8. 293251881Speter */ 294251881Spetersvn_diff_tree_processor_t * 295251881Spetersvn_diff__tree_processor_create(void *baton, 296251881Speter apr_pool_t *result_pool); 297251881Speter 298251881Speter/** 299251881Speter * Create a new svn_diff_tree_processor_t instance with all functions setup 300251881Speter * to call into another svn_diff_tree_processor_t processor, but with all 301251881Speter * adds and deletes inverted. 302251881Speter * 303251881Speter * @since New in 1.8. 304251881Speter */ /* Used by libsvn clients repository diff */ 305251881Speterconst svn_diff_tree_processor_t * 306251881Spetersvn_diff__tree_processor_reverse_create(const svn_diff_tree_processor_t * processor, 307251881Speter const char *prefix_relpath, 308251881Speter apr_pool_t *result_pool); 309251881Speter 310251881Speter/** 311251881Speter * Create a new svn_diff_tree_processor_t instance with all functions setup 312251881Speter * to call into processor for all paths equal to and below prefix_relpath. 313251881Speter * 314251881Speter * @since New in 1.8. 315251881Speter */ /* Used by libsvn clients repository diff */ 316251881Speterconst svn_diff_tree_processor_t * 317251881Spetersvn_diff__tree_processor_filter_create(const svn_diff_tree_processor_t *processor, 318251881Speter const char *prefix_relpath, 319251881Speter apr_pool_t *result_pool); 320251881Speter 321251881Speter/** 322251881Speter * Create a new svn_diff_tree_processor_t instace with all function setup 323251881Speter * to call into processor with all adds with copyfrom information transformed 324251881Speter * to simple node changes. 325251881Speter * 326251881Speter * @since New in 1.8. 327251881Speter */ /* Used by libsvn_wc diff editor */ 328251881Speterconst svn_diff_tree_processor_t * 329251881Spetersvn_diff__tree_processor_copy_as_changed_create( 330251881Speter const svn_diff_tree_processor_t *processor, 331251881Speter apr_pool_t *result_pool); 332251881Speter 333251881Speter 334251881Speter/** 335251881Speter * Create a new svn_diff_tree_processor_t instance with all functions setup 336251881Speter * to first call into processor1 and then processor2. 337251881Speter * 338251881Speter * This function is mostly a debug and migration helper. 339251881Speter * 340251881Speter * @since New in 1.8. 341251881Speter */ /* Used by libsvn clients repository diff */ 342251881Speterconst svn_diff_tree_processor_t * 343251881Spetersvn_diff__tree_processor_tee_create(const svn_diff_tree_processor_t *processor1, 344251881Speter const svn_diff_tree_processor_t *processor2, 345251881Speter apr_pool_t *result_pool); 346251881Speter 347251881Speter 348251881Spetersvn_diff_source_t * 349251881Spetersvn_diff__source_create(svn_revnum_t revision, 350251881Speter apr_pool_t *result_pool); 351251881Speter 352251881Speter#ifdef __cplusplus 353251881Speter} 354251881Speter#endif /* __cplusplus */ 355251881Speter 356251881Speter#endif /* SVN_DIFF_PROCESSOR_H */ 357251881Speter 358