1251881Speter/* 2299742Sdim * diff_local.c -- A simple diff walker which compares local files against 3299742Sdim * their pristine versions. 4251881Speter * 5251881Speter * ==================================================================== 6251881Speter * Licensed to the Apache Software Foundation (ASF) under one 7251881Speter * or more contributor license agreements. See the NOTICE file 8251881Speter * distributed with this work for additional information 9251881Speter * regarding copyright ownership. The ASF licenses this file 10251881Speter * to you under the Apache License, Version 2.0 (the 11251881Speter * "License"); you may not use this file except in compliance 12251881Speter * with the License. You may obtain a copy of the License at 13251881Speter * 14251881Speter * http://www.apache.org/licenses/LICENSE-2.0 15251881Speter * 16251881Speter * Unless required by applicable law or agreed to in writing, 17251881Speter * software distributed under the License is distributed on an 18251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19251881Speter * KIND, either express or implied. See the License for the 20251881Speter * specific language governing permissions and limitations 21251881Speter * under the License. 22251881Speter * ==================================================================== 23251881Speter * 24251881Speter * This is the simple working copy diff algorithm which is used when you 25251881Speter * just use 'svn diff PATH'. It shows what is modified in your working copy 26251881Speter * since a node was checked out or copied but doesn't show most kinds of 27251881Speter * restructuring operations. 28251881Speter * 29251881Speter * You can look at this as another form of the status walker. 30251881Speter */ 31251881Speter 32251881Speter#include <apr_hash.h> 33251881Speter 34251881Speter#include "svn_error.h" 35251881Speter#include "svn_pools.h" 36251881Speter#include "svn_dirent_uri.h" 37251881Speter#include "svn_path.h" 38251881Speter#include "svn_hash.h" 39251881Speter 40251881Speter#include "private/svn_wc_private.h" 41251881Speter#include "private/svn_diff_tree.h" 42251881Speter 43251881Speter#include "wc.h" 44299742Sdim#include "wc_db.h" 45251881Speter#include "props.h" 46251881Speter#include "diff.h" 47251881Speter 48251881Speter#include "svn_private_config.h" 49251881Speter 50251881Speter/*-------------------------------------------------------------------------*/ 51251881Speter 52251881Speter/* Baton containing the state of a directory 53251881Speter reported open via a diff processor */ 54251881Speterstruct node_state_t 55251881Speter{ 56251881Speter struct node_state_t *parent; 57251881Speter 58251881Speter apr_pool_t *pool; 59251881Speter 60251881Speter const char *local_abspath; 61251881Speter const char *relpath; 62251881Speter void *baton; 63251881Speter 64251881Speter svn_diff_source_t *left_src; 65251881Speter svn_diff_source_t *right_src; 66251881Speter svn_diff_source_t *copy_src; 67251881Speter 68251881Speter svn_boolean_t skip; 69251881Speter svn_boolean_t skip_children; 70251881Speter 71251881Speter apr_hash_t *left_props; 72251881Speter apr_hash_t *right_props; 73251881Speter const apr_array_header_t *propchanges; 74251881Speter}; 75251881Speter 76251881Speter/* The diff baton */ 77251881Speterstruct diff_baton 78251881Speter{ 79251881Speter /* A wc db. */ 80251881Speter svn_wc__db_t *db; 81251881Speter 82251881Speter /* Report editor paths relative from this directory */ 83251881Speter const char *anchor_abspath; 84251881Speter 85251881Speter struct node_state_t *cur; 86251881Speter 87251881Speter const svn_diff_tree_processor_t *processor; 88251881Speter 89251881Speter /* Should this diff ignore node ancestry? */ 90251881Speter svn_boolean_t ignore_ancestry; 91251881Speter 92251881Speter /* Cancel function/baton */ 93251881Speter svn_cancel_func_t cancel_func; 94251881Speter void *cancel_baton; 95251881Speter 96251881Speter apr_pool_t *pool; 97251881Speter}; 98251881Speter 99251881Speter/* Recursively opens directories on the stack in EB, until LOCAL_ABSPATH 100251881Speter is reached. If RECURSIVE_SKIP is TRUE, don't open LOCAL_ABSPATH itself, 101251881Speter but create it marked with skip+skip_children. 102251881Speter */ 103251881Speterstatic svn_error_t * 104251881Speterensure_state(struct diff_baton *eb, 105251881Speter const char *local_abspath, 106251881Speter svn_boolean_t recursive_skip, 107251881Speter apr_pool_t *scratch_pool) 108251881Speter{ 109251881Speter struct node_state_t *ns; 110251881Speter apr_pool_t *ns_pool; 111251881Speter if (!eb->cur) 112251881Speter { 113262253Speter const char *relpath; 114262253Speter 115262253Speter relpath = svn_dirent_skip_ancestor(eb->anchor_abspath, local_abspath); 116262253Speter if (! relpath) 117251881Speter return SVN_NO_ERROR; 118251881Speter 119299742Sdim /* Don't recurse on the anchor, as that might loop infinitely because 120262253Speter svn_dirent_dirname("/",...) -> "/" 121262253Speter svn_dirent_dirname("C:/",...) -> "C:/" (Windows) */ 122262253Speter if (*relpath) 123262253Speter SVN_ERR(ensure_state(eb, 124299742Sdim svn_dirent_dirname(local_abspath, scratch_pool), 125262253Speter FALSE, 126262253Speter scratch_pool)); 127251881Speter } 128251881Speter else if (svn_dirent_is_child(eb->cur->local_abspath, local_abspath, NULL)) 129299742Sdim SVN_ERR(ensure_state(eb, svn_dirent_dirname(local_abspath, scratch_pool), 130251881Speter FALSE, 131251881Speter scratch_pool)); 132251881Speter else 133251881Speter return SVN_NO_ERROR; 134251881Speter 135251881Speter if (eb->cur && eb->cur->skip_children) 136251881Speter return SVN_NO_ERROR; 137251881Speter 138251881Speter ns_pool = svn_pool_create(eb->cur ? eb->cur->pool : eb->pool); 139251881Speter ns = apr_pcalloc(ns_pool, sizeof(*ns)); 140251881Speter 141251881Speter ns->pool = ns_pool; 142251881Speter ns->local_abspath = apr_pstrdup(ns_pool, local_abspath); 143251881Speter ns->relpath = svn_dirent_skip_ancestor(eb->anchor_abspath, ns->local_abspath); 144251881Speter ns->parent = eb->cur; 145251881Speter eb->cur = ns; 146251881Speter 147251881Speter if (recursive_skip) 148251881Speter { 149251881Speter ns->skip = TRUE; 150251881Speter ns->skip_children = TRUE; 151251881Speter return SVN_NO_ERROR; 152251881Speter } 153251881Speter 154251881Speter { 155251881Speter svn_revnum_t revision; 156251881Speter svn_error_t *err; 157251881Speter 158251881Speter err = svn_wc__db_base_get_info(NULL, NULL, &revision, NULL, NULL, NULL, 159251881Speter NULL, NULL, NULL, NULL, NULL, NULL, NULL, 160251881Speter NULL, NULL, NULL, 161251881Speter eb->db, local_abspath, 162251881Speter scratch_pool, scratch_pool); 163251881Speter 164251881Speter if (err) 165251881Speter { 166251881Speter if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND) 167251881Speter return svn_error_trace(err); 168251881Speter svn_error_clear(err); 169251881Speter 170251881Speter revision = 0; /* Use original revision? */ 171251881Speter } 172251881Speter ns->left_src = svn_diff__source_create(revision, ns->pool); 173251881Speter ns->right_src = svn_diff__source_create(SVN_INVALID_REVNUM, ns->pool); 174251881Speter 175251881Speter SVN_ERR(eb->processor->dir_opened(&ns->baton, &ns->skip, 176251881Speter &ns->skip_children, 177251881Speter ns->relpath, 178251881Speter ns->left_src, 179251881Speter ns->right_src, 180251881Speter NULL /* copyfrom_source */, 181251881Speter ns->parent ? ns->parent->baton : NULL, 182251881Speter eb->processor, 183251881Speter ns->pool, scratch_pool)); 184251881Speter } 185251881Speter 186251881Speter return SVN_NO_ERROR; 187251881Speter} 188251881Speter 189251881Speter/* Implements svn_wc_status_func3_t */ 190251881Speterstatic svn_error_t * 191251881Speterdiff_status_callback(void *baton, 192251881Speter const char *local_abspath, 193251881Speter const svn_wc_status3_t *status, 194251881Speter apr_pool_t *scratch_pool) 195251881Speter{ 196251881Speter struct diff_baton *eb = baton; 197251881Speter svn_wc__db_t *db = eb->db; 198251881Speter 199262253Speter if (! status->versioned) 200262253Speter return SVN_NO_ERROR; /* unversioned (includes dir externals) */ 201262253Speter 202262253Speter if (status->node_status == svn_wc_status_conflicted 203262253Speter && status->text_status == svn_wc_status_none 204262253Speter && status->prop_status == svn_wc_status_none) 205251881Speter { 206262253Speter /* Node is an actual only node describing a tree conflict */ 207262253Speter return SVN_NO_ERROR; 208251881Speter } 209251881Speter 210251881Speter /* Not text/prop modified, not copied. Easy out */ 211251881Speter if (status->node_status == svn_wc_status_normal && !status->copied) 212251881Speter return SVN_NO_ERROR; 213251881Speter 214251881Speter /* Mark all directories where we are no longer inside as closed */ 215251881Speter while (eb->cur 216251881Speter && !svn_dirent_is_ancestor(eb->cur->local_abspath, local_abspath)) 217251881Speter { 218251881Speter struct node_state_t *ns = eb->cur; 219251881Speter 220251881Speter if (!ns->skip) 221251881Speter { 222251881Speter if (ns->propchanges) 223251881Speter SVN_ERR(eb->processor->dir_changed(ns->relpath, 224251881Speter ns->left_src, 225251881Speter ns->right_src, 226251881Speter ns->left_props, 227251881Speter ns->right_props, 228251881Speter ns->propchanges, 229251881Speter ns->baton, 230251881Speter eb->processor, 231251881Speter ns->pool)); 232251881Speter else 233251881Speter SVN_ERR(eb->processor->dir_closed(ns->relpath, 234251881Speter ns->left_src, 235251881Speter ns->right_src, 236251881Speter ns->baton, 237251881Speter eb->processor, 238251881Speter ns->pool)); 239251881Speter } 240251881Speter eb->cur = ns->parent; 241251881Speter svn_pool_clear(ns->pool); 242251881Speter } 243251881Speter SVN_ERR(ensure_state(eb, svn_dirent_dirname(local_abspath, scratch_pool), 244251881Speter FALSE, scratch_pool)); 245251881Speter 246251881Speter if (eb->cur && eb->cur->skip_children) 247251881Speter return SVN_NO_ERROR; 248251881Speter 249251881Speter /* This code does about the same thing as the inner body of 250251881Speter walk_local_nodes_diff() in diff_editor.c, except that 251251881Speter it is already filtered by the status walker, doesn't have to 252251881Speter account for remote changes (and many tiny other details) */ 253251881Speter 254251881Speter { 255251881Speter svn_boolean_t repos_only; 256251881Speter svn_boolean_t local_only; 257251881Speter svn_wc__db_status_t db_status; 258251881Speter svn_boolean_t have_base; 259251881Speter svn_node_kind_t base_kind; 260251881Speter svn_node_kind_t db_kind = status->kind; 261251881Speter svn_depth_t depth_below_here = svn_depth_unknown; 262251881Speter 263251881Speter const char *child_abspath = local_abspath; 264251881Speter const char *child_relpath = svn_dirent_skip_ancestor(eb->anchor_abspath, 265251881Speter local_abspath); 266251881Speter 267251881Speter 268251881Speter repos_only = FALSE; 269251881Speter local_only = FALSE; 270251881Speter 271251881Speter /* ### optimize away this call using status info. Should 272251881Speter be possible in almost every case (except conflict, missing, obst.)*/ 273251881Speter SVN_ERR(svn_wc__db_read_info(&db_status, NULL, NULL, NULL, NULL, NULL, 274251881Speter NULL, NULL, NULL, NULL, NULL, NULL, NULL, 275251881Speter NULL, NULL, NULL, NULL, NULL, NULL, NULL, 276251881Speter NULL, NULL, NULL, NULL, 277251881Speter &have_base, NULL, NULL, 278251881Speter eb->db, local_abspath, 279251881Speter scratch_pool, scratch_pool)); 280251881Speter if (!have_base) 281251881Speter { 282251881Speter local_only = TRUE; /* Only report additions */ 283251881Speter } 284251881Speter else if (db_status == svn_wc__db_status_normal) 285251881Speter { 286251881Speter /* Simple diff */ 287251881Speter base_kind = db_kind; 288251881Speter } 289251881Speter else if (db_status == svn_wc__db_status_deleted) 290251881Speter { 291251881Speter svn_wc__db_status_t base_status; 292251881Speter repos_only = TRUE; 293251881Speter SVN_ERR(svn_wc__db_base_get_info(&base_status, &base_kind, NULL, 294251881Speter NULL, NULL, NULL, NULL, NULL, 295251881Speter NULL, NULL, NULL, NULL, NULL, 296251881Speter NULL, NULL, NULL, 297251881Speter eb->db, local_abspath, 298251881Speter scratch_pool, scratch_pool)); 299251881Speter 300251881Speter if (base_status != svn_wc__db_status_normal) 301251881Speter return SVN_NO_ERROR; 302251881Speter } 303251881Speter else 304251881Speter { 305251881Speter /* working status is either added or deleted */ 306251881Speter svn_wc__db_status_t base_status; 307251881Speter 308251881Speter SVN_ERR(svn_wc__db_base_get_info(&base_status, &base_kind, NULL, 309251881Speter NULL, NULL, NULL, NULL, NULL, 310251881Speter NULL, NULL, NULL, NULL, NULL, 311251881Speter NULL, NULL, NULL, 312251881Speter eb->db, local_abspath, 313251881Speter scratch_pool, scratch_pool)); 314251881Speter 315251881Speter if (base_status != svn_wc__db_status_normal) 316251881Speter local_only = TRUE; 317251881Speter else if (base_kind != db_kind || !eb->ignore_ancestry) 318251881Speter { 319251881Speter repos_only = TRUE; 320251881Speter local_only = TRUE; 321251881Speter } 322251881Speter } 323251881Speter 324251881Speter if (repos_only) 325251881Speter { 326251881Speter /* Report repository form deleted */ 327251881Speter if (base_kind == svn_node_file) 328251881Speter SVN_ERR(svn_wc__diff_base_only_file(db, child_abspath, 329251881Speter child_relpath, 330251881Speter SVN_INVALID_REVNUM, 331251881Speter eb->processor, 332251881Speter eb->cur ? eb->cur->baton : NULL, 333251881Speter scratch_pool)); 334251881Speter else if (base_kind == svn_node_dir) 335251881Speter SVN_ERR(svn_wc__diff_base_only_dir(db, child_abspath, 336251881Speter child_relpath, 337251881Speter SVN_INVALID_REVNUM, 338251881Speter depth_below_here, 339251881Speter eb->processor, 340251881Speter eb->cur ? eb->cur->baton : NULL, 341251881Speter eb->cancel_func, 342251881Speter eb->cancel_baton, 343251881Speter scratch_pool)); 344251881Speter } 345251881Speter else if (!local_only) 346251881Speter { 347251881Speter /* Diff base against actual */ 348251881Speter if (db_kind == svn_node_file) 349251881Speter { 350251881Speter SVN_ERR(svn_wc__diff_base_working_diff(db, child_abspath, 351251881Speter child_relpath, 352251881Speter SVN_INVALID_REVNUM, 353251881Speter eb->processor, 354251881Speter eb->cur 355251881Speter ? eb->cur->baton 356251881Speter : NULL, 357251881Speter FALSE, 358251881Speter eb->cancel_func, 359251881Speter eb->cancel_baton, 360251881Speter scratch_pool)); 361251881Speter } 362251881Speter else if (db_kind == svn_node_dir) 363251881Speter { 364251881Speter SVN_ERR(ensure_state(eb, local_abspath, FALSE, scratch_pool)); 365251881Speter 366251881Speter if (status->prop_status != svn_wc_status_none 367251881Speter && status->prop_status != svn_wc_status_normal) 368251881Speter { 369251881Speter apr_array_header_t *propchanges; 370251881Speter SVN_ERR(svn_wc__db_base_get_props(&eb->cur->left_props, 371251881Speter eb->db, local_abspath, 372251881Speter eb->cur->pool, 373251881Speter scratch_pool)); 374251881Speter SVN_ERR(svn_wc__db_read_props(&eb->cur->right_props, 375251881Speter eb->db, local_abspath, 376251881Speter eb->cur->pool, 377251881Speter scratch_pool)); 378251881Speter 379251881Speter SVN_ERR(svn_prop_diffs(&propchanges, 380251881Speter eb->cur->right_props, 381251881Speter eb->cur->left_props, 382251881Speter eb->cur->pool)); 383251881Speter 384251881Speter eb->cur->propchanges = propchanges; 385251881Speter } 386251881Speter } 387251881Speter } 388251881Speter 389262253Speter if (local_only && (db_status != svn_wc__db_status_deleted)) 390251881Speter { 391251881Speter if (db_kind == svn_node_file) 392251881Speter SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath, 393251881Speter child_relpath, 394251881Speter eb->processor, 395251881Speter eb->cur ? eb->cur->baton : NULL, 396251881Speter FALSE, 397251881Speter eb->cancel_func, 398251881Speter eb->cancel_baton, 399251881Speter scratch_pool)); 400251881Speter else if (db_kind == svn_node_dir) 401251881Speter SVN_ERR(svn_wc__diff_local_only_dir(db, child_abspath, 402251881Speter child_relpath, depth_below_here, 403251881Speter eb->processor, 404251881Speter eb->cur ? eb->cur->baton : NULL, 405251881Speter FALSE, 406251881Speter eb->cancel_func, 407251881Speter eb->cancel_baton, 408251881Speter scratch_pool)); 409251881Speter } 410251881Speter 411251881Speter if (db_kind == svn_node_dir && (local_only || repos_only)) 412251881Speter SVN_ERR(ensure_state(eb, local_abspath, TRUE /* skip */, scratch_pool)); 413251881Speter } 414251881Speter 415251881Speter return SVN_NO_ERROR; 416251881Speter} 417251881Speter 418251881Speter 419251881Speter/* Public Interface */ 420251881Spetersvn_error_t * 421299742Sdimsvn_wc__diff7(const char **root_relpath, 422299742Sdim svn_boolean_t *root_is_dir, 423299742Sdim svn_wc_context_t *wc_ctx, 424299742Sdim const char *local_abspath, 425299742Sdim svn_depth_t depth, 426299742Sdim svn_boolean_t ignore_ancestry, 427299742Sdim const apr_array_header_t *changelist_filter, 428299742Sdim const svn_diff_tree_processor_t *diff_processor, 429299742Sdim svn_cancel_func_t cancel_func, 430299742Sdim void *cancel_baton, 431299742Sdim apr_pool_t *result_pool, 432299742Sdim apr_pool_t *scratch_pool) 433251881Speter{ 434251881Speter struct diff_baton eb = { 0 }; 435251881Speter svn_node_kind_t kind; 436251881Speter svn_boolean_t get_all; 437251881Speter 438251881Speter SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath)); 439251881Speter SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath, 440251881Speter FALSE /* allow_missing */, 441251881Speter TRUE /* show_deleted */, 442251881Speter FALSE /* show_hidden */, 443251881Speter scratch_pool)); 444251881Speter 445299742Sdim eb.anchor_abspath = local_abspath; 446251881Speter 447299742Sdim if (root_relpath) 448299742Sdim { 449299742Sdim svn_boolean_t is_wcroot; 450251881Speter 451299742Sdim SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, 452299742Sdim wc_ctx->db, local_abspath, scratch_pool)); 453251881Speter 454299742Sdim if (!is_wcroot) 455299742Sdim eb.anchor_abspath = svn_dirent_dirname(local_abspath, scratch_pool); 456299742Sdim } 457299742Sdim else if (kind != svn_node_dir) 458299742Sdim eb.anchor_abspath = svn_dirent_dirname(local_abspath, scratch_pool); 459251881Speter 460299742Sdim if (root_relpath) 461299742Sdim *root_relpath = apr_pstrdup(result_pool, 462299742Sdim svn_dirent_skip_ancestor(eb.anchor_abspath, 463299742Sdim local_abspath)); 464299742Sdim if (root_is_dir) 465299742Sdim *root_is_dir = (kind == svn_node_dir); 466251881Speter 467289166Speter /* Apply changelist filtering to the output */ 468289166Speter if (changelist_filter && changelist_filter->nelts) 469289166Speter { 470289166Speter apr_hash_t *changelist_hash; 471289166Speter 472289166Speter SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelist_filter, 473299742Sdim result_pool)); 474299742Sdim diff_processor = svn_wc__changelist_filter_tree_processor_create( 475299742Sdim diff_processor, wc_ctx, local_abspath, 476299742Sdim changelist_hash, result_pool); 477289166Speter } 478289166Speter 479251881Speter eb.db = wc_ctx->db; 480299742Sdim eb.processor = diff_processor; 481251881Speter eb.ignore_ancestry = ignore_ancestry; 482251881Speter eb.pool = scratch_pool; 483251881Speter 484299742Sdim if (ignore_ancestry) 485251881Speter get_all = TRUE; /* We need unmodified descendants of copies */ 486251881Speter else 487251881Speter get_all = FALSE; 488251881Speter 489251881Speter /* Walk status handles files and directories */ 490251881Speter SVN_ERR(svn_wc__internal_walk_status(wc_ctx->db, local_abspath, depth, 491251881Speter get_all, 492251881Speter TRUE /* no_ignore */, 493251881Speter FALSE /* ignore_text_mods */, 494251881Speter NULL /* ignore_patterns */, 495251881Speter diff_status_callback, &eb, 496251881Speter cancel_func, cancel_baton, 497251881Speter scratch_pool)); 498251881Speter 499251881Speter /* Close the remaining open directories */ 500251881Speter while (eb.cur) 501251881Speter { 502251881Speter struct node_state_t *ns = eb.cur; 503251881Speter 504251881Speter if (!ns->skip) 505251881Speter { 506251881Speter if (ns->propchanges) 507299742Sdim SVN_ERR(diff_processor->dir_changed(ns->relpath, 508299742Sdim ns->left_src, 509299742Sdim ns->right_src, 510299742Sdim ns->left_props, 511299742Sdim ns->right_props, 512299742Sdim ns->propchanges, 513299742Sdim ns->baton, 514299742Sdim diff_processor, 515299742Sdim ns->pool)); 516251881Speter else 517299742Sdim SVN_ERR(diff_processor->dir_closed(ns->relpath, 518299742Sdim ns->left_src, 519299742Sdim ns->right_src, 520299742Sdim ns->baton, 521299742Sdim diff_processor, 522299742Sdim ns->pool)); 523251881Speter } 524251881Speter eb.cur = ns->parent; 525251881Speter svn_pool_clear(ns->pool); 526251881Speter } 527251881Speter 528251881Speter return SVN_NO_ERROR; 529251881Speter} 530299742Sdim 531299742Sdimsvn_error_t * 532299742Sdimsvn_wc_diff6(svn_wc_context_t *wc_ctx, 533299742Sdim const char *local_abspath, 534299742Sdim const svn_wc_diff_callbacks4_t *callbacks, 535299742Sdim void *callback_baton, 536299742Sdim svn_depth_t depth, 537299742Sdim svn_boolean_t ignore_ancestry, 538299742Sdim svn_boolean_t show_copies_as_adds, 539299742Sdim svn_boolean_t use_git_diff_format, 540299742Sdim const apr_array_header_t *changelist_filter, 541299742Sdim svn_cancel_func_t cancel_func, 542299742Sdim void *cancel_baton, 543299742Sdim apr_pool_t *scratch_pool) 544299742Sdim{ 545299742Sdim const svn_diff_tree_processor_t *processor; 546299742Sdim 547299742Sdim SVN_ERR(svn_wc__wrap_diff_callbacks(&processor, 548299742Sdim callbacks, callback_baton, TRUE, 549299742Sdim scratch_pool, scratch_pool)); 550299742Sdim 551299742Sdim if (use_git_diff_format) 552299742Sdim show_copies_as_adds = TRUE; 553299742Sdim if (show_copies_as_adds) 554299742Sdim ignore_ancestry = FALSE; 555299742Sdim 556299742Sdim if (! show_copies_as_adds && !use_git_diff_format) 557299742Sdim processor = svn_diff__tree_processor_copy_as_changed_create(processor, 558299742Sdim scratch_pool); 559299742Sdim 560299742Sdim return svn_error_trace(svn_wc__diff7(NULL, NULL, 561299742Sdim wc_ctx, local_abspath, 562299742Sdim depth, 563299742Sdim ignore_ancestry, 564299742Sdim changelist_filter, 565299742Sdim processor, 566299742Sdim cancel_func, cancel_baton, 567299742Sdim scratch_pool, scratch_pool)); 568299742Sdim} 569299742Sdim 570