1251881Speter/* 2251881Speter * notify.c: feedback handlers for cmdline client. 3251881Speter * 4251881Speter * ==================================================================== 5251881Speter * Licensed to the Apache Software Foundation (ASF) under one 6251881Speter * or more contributor license agreements. See the NOTICE file 7251881Speter * distributed with this work for additional information 8251881Speter * regarding copyright ownership. The ASF licenses this file 9251881Speter * to you under the Apache License, Version 2.0 (the 10251881Speter * "License"); you may not use this file except in compliance 11251881Speter * with the License. You may obtain a copy of the License at 12251881Speter * 13251881Speter * http://www.apache.org/licenses/LICENSE-2.0 14251881Speter * 15251881Speter * Unless required by applicable law or agreed to in writing, 16251881Speter * software distributed under the License is distributed on an 17251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18251881Speter * KIND, either express or implied. See the License for the 19251881Speter * specific language governing permissions and limitations 20251881Speter * under the License. 21251881Speter * ==================================================================== 22251881Speter */ 23251881Speter 24251881Speter/* ==================================================================== */ 25251881Speter 26251881Speter 27251881Speter 28251881Speter/*** Includes. ***/ 29251881Speter 30251881Speter#define APR_WANT_STDIO 31251881Speter#define APR_WANT_STRFUNC 32251881Speter#include <apr_want.h> 33251881Speter 34251881Speter#include "svn_cmdline.h" 35251881Speter#include "svn_pools.h" 36251881Speter#include "svn_dirent_uri.h" 37251881Speter#include "svn_path.h" 38251881Speter#include "svn_sorts.h" 39251881Speter#include "svn_hash.h" 40251881Speter#include "cl.h" 41251881Speter#include "private/svn_subr_private.h" 42251881Speter#include "private/svn_dep_compat.h" 43251881Speter 44251881Speter#include "svn_private_config.h" 45251881Speter 46251881Speter 47251881Speter/* Baton for notify and friends. */ 48251881Speterstruct notify_baton 49251881Speter{ 50251881Speter svn_boolean_t received_some_change; 51251881Speter svn_boolean_t is_checkout; 52251881Speter svn_boolean_t is_export; 53251881Speter svn_boolean_t is_wc_to_repos_copy; 54251881Speter svn_boolean_t sent_first_txdelta; 55299742Sdim int in_external; 56251881Speter svn_boolean_t had_print_error; /* Used to not keep printing error messages 57251881Speter when we've already had one print error. */ 58251881Speter 59251881Speter svn_cl__conflict_stats_t *conflict_stats; 60251881Speter 61251881Speter /* The cwd, for use in decomposing absolute paths. */ 62251881Speter const char *path_prefix; 63251881Speter}; 64251881Speter 65251881Speter/* Conflict stats for operations such as update and merge. */ 66251881Speterstruct svn_cl__conflict_stats_t 67251881Speter{ 68251881Speter apr_pool_t *stats_pool; 69251881Speter apr_hash_t *text_conflicts, *prop_conflicts, *tree_conflicts; 70251881Speter int text_conflicts_resolved, prop_conflicts_resolved, tree_conflicts_resolved; 71251881Speter int skipped_paths; 72251881Speter}; 73251881Speter 74251881Spetersvn_cl__conflict_stats_t * 75251881Spetersvn_cl__conflict_stats_create(apr_pool_t *pool) 76251881Speter{ 77251881Speter svn_cl__conflict_stats_t *conflict_stats 78251881Speter = apr_palloc(pool, sizeof(*conflict_stats)); 79251881Speter 80251881Speter conflict_stats->stats_pool = pool; 81251881Speter conflict_stats->text_conflicts = apr_hash_make(pool); 82251881Speter conflict_stats->prop_conflicts = apr_hash_make(pool); 83251881Speter conflict_stats->tree_conflicts = apr_hash_make(pool); 84251881Speter conflict_stats->text_conflicts_resolved = 0; 85251881Speter conflict_stats->prop_conflicts_resolved = 0; 86251881Speter conflict_stats->tree_conflicts_resolved = 0; 87251881Speter conflict_stats->skipped_paths = 0; 88251881Speter return conflict_stats; 89251881Speter} 90251881Speter 91251881Speter/* Add the PATH (as a key, with a meaningless value) into the HASH in NB. */ 92251881Speterstatic void 93251881Speterstore_path(struct notify_baton *nb, apr_hash_t *hash, const char *path) 94251881Speter{ 95251881Speter svn_hash_sets(hash, apr_pstrdup(nb->conflict_stats->stats_pool, path), ""); 96251881Speter} 97251881Speter 98251881Spetervoid 99251881Spetersvn_cl__conflict_stats_resolved(svn_cl__conflict_stats_t *conflict_stats, 100251881Speter const char *path_local, 101251881Speter svn_wc_conflict_kind_t conflict_kind) 102251881Speter{ 103251881Speter switch (conflict_kind) 104251881Speter { 105251881Speter case svn_wc_conflict_kind_text: 106251881Speter if (svn_hash_gets(conflict_stats->text_conflicts, path_local)) 107251881Speter { 108251881Speter svn_hash_sets(conflict_stats->text_conflicts, path_local, NULL); 109251881Speter conflict_stats->text_conflicts_resolved++; 110251881Speter } 111251881Speter break; 112251881Speter case svn_wc_conflict_kind_property: 113251881Speter if (svn_hash_gets(conflict_stats->prop_conflicts, path_local)) 114251881Speter { 115251881Speter svn_hash_sets(conflict_stats->prop_conflicts, path_local, NULL); 116251881Speter conflict_stats->prop_conflicts_resolved++; 117251881Speter } 118251881Speter break; 119251881Speter case svn_wc_conflict_kind_tree: 120251881Speter if (svn_hash_gets(conflict_stats->tree_conflicts, path_local)) 121251881Speter { 122251881Speter svn_hash_sets(conflict_stats->tree_conflicts, path_local, NULL); 123251881Speter conflict_stats->tree_conflicts_resolved++; 124251881Speter } 125251881Speter break; 126251881Speter } 127251881Speter} 128251881Speter 129251881Speterstatic const char * 130251881Speterremaining_str(apr_pool_t *pool, int n_remaining) 131251881Speter{ 132299742Sdim return apr_psprintf(pool, Q_("%d remaining", 133251881Speter "%d remaining", 134251881Speter n_remaining), 135251881Speter n_remaining); 136251881Speter} 137251881Speter 138251881Speterstatic const char * 139251881Speterresolved_str(apr_pool_t *pool, int n_resolved) 140251881Speter{ 141251881Speter return apr_psprintf(pool, Q_("and %d already resolved", 142251881Speter "and %d already resolved", 143251881Speter n_resolved), 144251881Speter n_resolved); 145251881Speter} 146251881Speter 147251881Spetersvn_error_t * 148299742Sdimsvn_cl__print_conflict_stats(svn_cl__conflict_stats_t *conflict_stats, 149299742Sdim apr_pool_t *scratch_pool) 150251881Speter{ 151299742Sdim int n_text = apr_hash_count(conflict_stats->text_conflicts); 152299742Sdim int n_prop = apr_hash_count(conflict_stats->prop_conflicts); 153299742Sdim int n_tree = apr_hash_count(conflict_stats->tree_conflicts); 154299742Sdim int n_text_r = conflict_stats->text_conflicts_resolved; 155299742Sdim int n_prop_r = conflict_stats->prop_conflicts_resolved; 156299742Sdim int n_tree_r = conflict_stats->tree_conflicts_resolved; 157251881Speter 158251881Speter if (n_text > 0 || n_text_r > 0 159251881Speter || n_prop > 0 || n_prop_r > 0 160251881Speter || n_tree > 0 || n_tree_r > 0 161299742Sdim || conflict_stats->skipped_paths > 0) 162251881Speter SVN_ERR(svn_cmdline_printf(scratch_pool, 163251881Speter _("Summary of conflicts:\n"))); 164251881Speter 165251881Speter if (n_text_r == 0 && n_prop_r == 0 && n_tree_r == 0) 166251881Speter { 167251881Speter if (n_text > 0) 168251881Speter SVN_ERR(svn_cmdline_printf(scratch_pool, 169251881Speter _(" Text conflicts: %d\n"), 170251881Speter n_text)); 171251881Speter if (n_prop > 0) 172251881Speter SVN_ERR(svn_cmdline_printf(scratch_pool, 173251881Speter _(" Property conflicts: %d\n"), 174251881Speter n_prop)); 175251881Speter if (n_tree > 0) 176251881Speter SVN_ERR(svn_cmdline_printf(scratch_pool, 177251881Speter _(" Tree conflicts: %d\n"), 178251881Speter n_tree)); 179251881Speter } 180251881Speter else 181251881Speter { 182251881Speter if (n_text > 0 || n_text_r > 0) 183251881Speter SVN_ERR(svn_cmdline_printf(scratch_pool, 184251881Speter _(" Text conflicts: %s (%s)\n"), 185251881Speter remaining_str(scratch_pool, n_text), 186251881Speter resolved_str(scratch_pool, n_text_r))); 187251881Speter if (n_prop > 0 || n_prop_r > 0) 188251881Speter SVN_ERR(svn_cmdline_printf(scratch_pool, 189251881Speter _(" Property conflicts: %s (%s)\n"), 190251881Speter remaining_str(scratch_pool, n_prop), 191251881Speter resolved_str(scratch_pool, n_prop_r))); 192251881Speter if (n_tree > 0 || n_tree_r > 0) 193251881Speter SVN_ERR(svn_cmdline_printf(scratch_pool, 194251881Speter _(" Tree conflicts: %s (%s)\n"), 195251881Speter remaining_str(scratch_pool, n_tree), 196251881Speter resolved_str(scratch_pool, n_tree_r))); 197251881Speter } 198299742Sdim if (conflict_stats->skipped_paths > 0) 199251881Speter SVN_ERR(svn_cmdline_printf(scratch_pool, 200251881Speter _(" Skipped paths: %d\n"), 201299742Sdim conflict_stats->skipped_paths)); 202251881Speter 203251881Speter return SVN_NO_ERROR; 204251881Speter} 205251881Speter 206299742Sdimsvn_error_t * 207299742Sdimsvn_cl__notifier_print_conflict_stats(void *baton, apr_pool_t *scratch_pool) 208251881Speter{ 209251881Speter struct notify_baton *nb = baton; 210299742Sdim 211299742Sdim SVN_ERR(svn_cl__print_conflict_stats(nb->conflict_stats, scratch_pool)); 212299742Sdim return SVN_NO_ERROR; 213299742Sdim} 214299742Sdim 215299742Sdim/* The body for notify() function with standard error handling semantic. 216299742Sdim * Handling of errors implemented at caller side. */ 217299742Sdimstatic svn_error_t * 218299742Sdimnotify_body(struct notify_baton *nb, 219299742Sdim const svn_wc_notify_t *n, 220299742Sdim apr_pool_t *pool) 221299742Sdim{ 222251881Speter char statchar_buf[5] = " "; 223251881Speter const char *path_local; 224251881Speter 225251881Speter if (n->url) 226251881Speter path_local = n->url; 227251881Speter else 228251881Speter { 229299742Sdim /* Skip the path prefix in N, if supplied, or else the path prefix 230299742Sdim in NB (which was set to the current working directory). */ 231251881Speter if (n->path_prefix) 232251881Speter path_local = svn_cl__local_style_skip_ancestor(n->path_prefix, n->path, 233251881Speter pool); 234299742Sdim else 235251881Speter path_local = svn_cl__local_style_skip_ancestor(nb->path_prefix, n->path, 236251881Speter pool); 237251881Speter } 238251881Speter 239251881Speter switch (n->action) 240251881Speter { 241251881Speter case svn_wc_notify_skip: 242251881Speter nb->conflict_stats->skipped_paths++; 243251881Speter if (n->content_state == svn_wc_notify_state_missing) 244251881Speter { 245299742Sdim SVN_ERR(svn_cmdline_printf(pool, 246299742Sdim _("Skipped missing target: '%s'\n"), 247299742Sdim path_local)); 248251881Speter } 249251881Speter else if (n->content_state == svn_wc_notify_state_source_missing) 250251881Speter { 251299742Sdim SVN_ERR(svn_cmdline_printf( 252299742Sdim pool, 253299742Sdim _("Skipped target: '%s' -- copy-source is missing\n"), 254299742Sdim path_local)); 255251881Speter } 256251881Speter else 257251881Speter { 258299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("Skipped '%s'\n"), path_local)); 259251881Speter } 260251881Speter break; 261251881Speter case svn_wc_notify_update_skip_obstruction: 262251881Speter nb->conflict_stats->skipped_paths++; 263299742Sdim SVN_ERR(svn_cmdline_printf( 264299742Sdim pool, 265299742Sdim _("Skipped '%s' -- An obstructing working copy was found\n"), 266299742Sdim path_local)); 267251881Speter break; 268251881Speter case svn_wc_notify_update_skip_working_only: 269251881Speter nb->conflict_stats->skipped_paths++; 270299742Sdim SVN_ERR(svn_cmdline_printf( 271299742Sdim pool, _("Skipped '%s' -- Has no versioned parent\n"), 272299742Sdim path_local)); 273251881Speter break; 274251881Speter case svn_wc_notify_update_skip_access_denied: 275251881Speter nb->conflict_stats->skipped_paths++; 276299742Sdim SVN_ERR(svn_cmdline_printf( 277299742Sdim pool, _("Skipped '%s' -- Access denied\n"), 278299742Sdim path_local)); 279251881Speter break; 280251881Speter case svn_wc_notify_skip_conflicted: 281251881Speter nb->conflict_stats->skipped_paths++; 282299742Sdim SVN_ERR(svn_cmdline_printf( 283299742Sdim pool, _("Skipped '%s' -- Node remains in conflict\n"), 284299742Sdim path_local)); 285251881Speter break; 286251881Speter case svn_wc_notify_update_delete: 287251881Speter case svn_wc_notify_exclude: 288251881Speter nb->received_some_change = TRUE; 289299742Sdim SVN_ERR(svn_cmdline_printf(pool, "D %s\n", path_local)); 290251881Speter break; 291251881Speter case svn_wc_notify_update_broken_lock: 292299742Sdim SVN_ERR(svn_cmdline_printf(pool, "B %s\n", path_local)); 293251881Speter break; 294251881Speter 295251881Speter case svn_wc_notify_update_external_removed: 296251881Speter nb->received_some_change = TRUE; 297251881Speter if (n->err && n->err->message) 298251881Speter { 299299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("Removed external '%s': %s\n"), 300299742Sdim path_local, n->err->message)); 301251881Speter } 302251881Speter else 303251881Speter { 304299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("Removed external '%s'\n"), 305299742Sdim path_local)); 306251881Speter } 307251881Speter break; 308251881Speter 309251881Speter case svn_wc_notify_left_local_modifications: 310299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("Left local modifications as '%s'\n"), 311299742Sdim path_local)); 312251881Speter break; 313251881Speter 314251881Speter case svn_wc_notify_update_replace: 315251881Speter nb->received_some_change = TRUE; 316299742Sdim SVN_ERR(svn_cmdline_printf(pool, "R %s\n", path_local)); 317251881Speter break; 318251881Speter 319251881Speter case svn_wc_notify_update_add: 320251881Speter nb->received_some_change = TRUE; 321251881Speter if (n->content_state == svn_wc_notify_state_conflicted) 322251881Speter { 323251881Speter store_path(nb, nb->conflict_stats->text_conflicts, path_local); 324299742Sdim SVN_ERR(svn_cmdline_printf(pool, "C %s\n", path_local)); 325251881Speter } 326251881Speter else 327251881Speter { 328299742Sdim SVN_ERR(svn_cmdline_printf(pool, "A %s\n", path_local)); 329251881Speter } 330251881Speter break; 331251881Speter 332251881Speter case svn_wc_notify_exists: 333251881Speter nb->received_some_change = TRUE; 334251881Speter if (n->content_state == svn_wc_notify_state_conflicted) 335251881Speter { 336251881Speter store_path(nb, nb->conflict_stats->text_conflicts, path_local); 337251881Speter statchar_buf[0] = 'C'; 338251881Speter } 339251881Speter else 340251881Speter statchar_buf[0] = 'E'; 341251881Speter 342251881Speter if (n->prop_state == svn_wc_notify_state_conflicted) 343251881Speter { 344251881Speter store_path(nb, nb->conflict_stats->prop_conflicts, path_local); 345251881Speter statchar_buf[1] = 'C'; 346251881Speter } 347251881Speter else if (n->prop_state == svn_wc_notify_state_merged) 348251881Speter statchar_buf[1] = 'G'; 349251881Speter 350299742Sdim SVN_ERR(svn_cmdline_printf(pool, "%s %s\n", statchar_buf, path_local)); 351251881Speter break; 352251881Speter 353251881Speter case svn_wc_notify_restore: 354299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("Restored '%s'\n"), 355299742Sdim path_local)); 356251881Speter break; 357251881Speter 358251881Speter case svn_wc_notify_revert: 359299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("Reverted '%s'\n"), 360299742Sdim path_local)); 361251881Speter break; 362251881Speter 363251881Speter case svn_wc_notify_failed_revert: 364299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("Failed to revert '%s' -- " 365299742Sdim "try updating instead.\n"), 366299742Sdim path_local)); 367251881Speter break; 368251881Speter 369251881Speter case svn_wc_notify_resolved: 370299742Sdim SVN_ERR(svn_cmdline_printf(pool, 371299742Sdim _("Resolved conflicted state of '%s'\n"), 372299742Sdim path_local)); 373251881Speter break; 374251881Speter 375251881Speter case svn_wc_notify_add: 376251881Speter /* We *should* only get the MIME_TYPE if PATH is a file. If we 377251881Speter do get it, and the mime-type is not textual, note that this 378251881Speter is a binary addition. */ 379251881Speter if (n->mime_type && (svn_mime_type_is_binary(n->mime_type))) 380251881Speter { 381299742Sdim SVN_ERR(svn_cmdline_printf(pool, "A (bin) %s\n", 382299742Sdim path_local)); 383251881Speter } 384251881Speter else 385251881Speter { 386299742Sdim SVN_ERR(svn_cmdline_printf(pool, "A %s\n", 387299742Sdim path_local)); 388251881Speter } 389251881Speter break; 390251881Speter 391251881Speter case svn_wc_notify_delete: 392251881Speter nb->received_some_change = TRUE; 393299742Sdim SVN_ERR(svn_cmdline_printf(pool, "D %s\n", 394299742Sdim path_local)); 395251881Speter break; 396251881Speter 397251881Speter case svn_wc_notify_patch: 398251881Speter { 399251881Speter nb->received_some_change = TRUE; 400251881Speter if (n->content_state == svn_wc_notify_state_conflicted) 401251881Speter { 402251881Speter store_path(nb, nb->conflict_stats->text_conflicts, path_local); 403251881Speter statchar_buf[0] = 'C'; 404251881Speter } 405251881Speter else if (n->kind == svn_node_file) 406251881Speter { 407251881Speter if (n->content_state == svn_wc_notify_state_merged) 408251881Speter statchar_buf[0] = 'G'; 409251881Speter else if (n->content_state == svn_wc_notify_state_changed) 410251881Speter statchar_buf[0] = 'U'; 411251881Speter } 412251881Speter 413251881Speter if (n->prop_state == svn_wc_notify_state_conflicted) 414251881Speter { 415251881Speter store_path(nb, nb->conflict_stats->prop_conflicts, path_local); 416251881Speter statchar_buf[1] = 'C'; 417251881Speter } 418251881Speter else if (n->prop_state == svn_wc_notify_state_changed) 419251881Speter statchar_buf[1] = 'U'; 420251881Speter 421251881Speter if (statchar_buf[0] != ' ' || statchar_buf[1] != ' ') 422251881Speter { 423299742Sdim SVN_ERR(svn_cmdline_printf(pool, "%s %s\n", 424299742Sdim statchar_buf, path_local)); 425251881Speter } 426251881Speter } 427251881Speter break; 428251881Speter 429251881Speter case svn_wc_notify_patch_applied_hunk: 430251881Speter nb->received_some_change = TRUE; 431251881Speter if (n->hunk_original_start != n->hunk_matched_line) 432251881Speter { 433251881Speter apr_uint64_t off; 434251881Speter const char *s; 435251881Speter const char *minus; 436251881Speter 437251881Speter if (n->hunk_matched_line > n->hunk_original_start) 438251881Speter { 439251881Speter /* If we are patching from the start of an empty file, 440251881Speter it is nicer to show offset 0 */ 441251881Speter if (n->hunk_original_start == 0 && n->hunk_matched_line == 1) 442251881Speter off = 0; /* No offset, just adding */ 443251881Speter else 444251881Speter off = n->hunk_matched_line - n->hunk_original_start; 445251881Speter 446251881Speter minus = ""; 447251881Speter } 448251881Speter else 449251881Speter { 450251881Speter off = n->hunk_original_start - n->hunk_matched_line; 451251881Speter minus = "-"; 452251881Speter } 453251881Speter 454251881Speter /* ### We're creating the localized strings without 455251881Speter * ### APR_INT64_T_FMT since it isn't translator-friendly */ 456251881Speter if (n->hunk_fuzz) 457251881Speter { 458251881Speter 459251881Speter if (n->prop_name) 460251881Speter { 461251881Speter s = _("> applied hunk ## -%lu,%lu +%lu,%lu ## " 462251881Speter "with offset %s"); 463251881Speter 464299742Sdim SVN_ERR(svn_cmdline_printf(pool, 465299742Sdim apr_pstrcat(pool, s, 466299742Sdim "%"APR_UINT64_T_FMT 467299742Sdim " and fuzz %lu (%s)\n", 468299742Sdim SVN_VA_NULL), 469299742Sdim n->hunk_original_start, 470299742Sdim n->hunk_original_length, 471299742Sdim n->hunk_modified_start, 472299742Sdim n->hunk_modified_length, 473299742Sdim minus, off, n->hunk_fuzz, 474299742Sdim n->prop_name)); 475251881Speter } 476251881Speter else 477251881Speter { 478251881Speter s = _("> applied hunk @@ -%lu,%lu +%lu,%lu @@ " 479251881Speter "with offset %s"); 480251881Speter 481299742Sdim SVN_ERR(svn_cmdline_printf(pool, 482299742Sdim apr_pstrcat(pool, s, 483299742Sdim "%"APR_UINT64_T_FMT 484299742Sdim " and fuzz %lu\n", 485299742Sdim SVN_VA_NULL), 486299742Sdim n->hunk_original_start, 487299742Sdim n->hunk_original_length, 488299742Sdim n->hunk_modified_start, 489299742Sdim n->hunk_modified_length, 490299742Sdim minus, off, n->hunk_fuzz)); 491251881Speter } 492251881Speter } 493251881Speter else 494251881Speter { 495251881Speter 496251881Speter if (n->prop_name) 497251881Speter { 498251881Speter s = _("> applied hunk ## -%lu,%lu +%lu,%lu ## " 499251881Speter "with offset %s"); 500299742Sdim SVN_ERR(svn_cmdline_printf(pool, 501299742Sdim apr_pstrcat(pool, s, 502299742Sdim "%"APR_UINT64_T_FMT" (%s)\n", 503299742Sdim SVN_VA_NULL), 504299742Sdim n->hunk_original_start, 505299742Sdim n->hunk_original_length, 506299742Sdim n->hunk_modified_start, 507299742Sdim n->hunk_modified_length, 508299742Sdim minus, off, n->prop_name)); 509251881Speter } 510251881Speter else 511251881Speter { 512251881Speter s = _("> applied hunk @@ -%lu,%lu +%lu,%lu @@ " 513251881Speter "with offset %s"); 514299742Sdim SVN_ERR(svn_cmdline_printf(pool, 515299742Sdim apr_pstrcat(pool, s, 516299742Sdim "%"APR_UINT64_T_FMT"\n", 517299742Sdim SVN_VA_NULL), 518299742Sdim n->hunk_original_start, 519299742Sdim n->hunk_original_length, 520299742Sdim n->hunk_modified_start, 521299742Sdim n->hunk_modified_length, 522299742Sdim minus, off)); 523251881Speter } 524251881Speter } 525251881Speter } 526251881Speter else if (n->hunk_fuzz) 527251881Speter { 528251881Speter if (n->prop_name) 529299742Sdim SVN_ERR(svn_cmdline_printf(pool, 530251881Speter _("> applied hunk ## -%lu,%lu +%lu,%lu ## " 531251881Speter "with fuzz %lu (%s)\n"), 532251881Speter n->hunk_original_start, 533251881Speter n->hunk_original_length, 534251881Speter n->hunk_modified_start, 535251881Speter n->hunk_modified_length, 536251881Speter n->hunk_fuzz, 537299742Sdim n->prop_name)); 538251881Speter else 539299742Sdim SVN_ERR(svn_cmdline_printf(pool, 540251881Speter _("> applied hunk @@ -%lu,%lu +%lu,%lu @@ " 541251881Speter "with fuzz %lu\n"), 542251881Speter n->hunk_original_start, 543251881Speter n->hunk_original_length, 544251881Speter n->hunk_modified_start, 545251881Speter n->hunk_modified_length, 546299742Sdim n->hunk_fuzz)); 547251881Speter 548251881Speter } 549251881Speter break; 550251881Speter 551251881Speter case svn_wc_notify_patch_rejected_hunk: 552251881Speter nb->received_some_change = TRUE; 553251881Speter 554251881Speter if (n->prop_name) 555299742Sdim SVN_ERR(svn_cmdline_printf(pool, 556299742Sdim _("> rejected hunk " 557299742Sdim "## -%lu,%lu +%lu,%lu ## (%s)\n"), 558299742Sdim n->hunk_original_start, 559299742Sdim n->hunk_original_length, 560299742Sdim n->hunk_modified_start, 561299742Sdim n->hunk_modified_length, 562299742Sdim n->prop_name)); 563251881Speter else 564299742Sdim SVN_ERR(svn_cmdline_printf(pool, 565299742Sdim _("> rejected hunk " 566299742Sdim "@@ -%lu,%lu +%lu,%lu @@\n"), 567299742Sdim n->hunk_original_start, 568299742Sdim n->hunk_original_length, 569299742Sdim n->hunk_modified_start, 570299742Sdim n->hunk_modified_length)); 571251881Speter break; 572251881Speter 573251881Speter case svn_wc_notify_patch_hunk_already_applied: 574251881Speter nb->received_some_change = TRUE; 575251881Speter if (n->prop_name) 576299742Sdim SVN_ERR(svn_cmdline_printf(pool, 577299742Sdim _("> hunk " 578299742Sdim "## -%lu,%lu +%lu,%lu ## " 579299742Sdim "already applied (%s)\n"), 580299742Sdim n->hunk_original_start, 581299742Sdim n->hunk_original_length, 582299742Sdim n->hunk_modified_start, 583299742Sdim n->hunk_modified_length, 584299742Sdim n->prop_name)); 585251881Speter else 586299742Sdim SVN_ERR(svn_cmdline_printf(pool, 587299742Sdim _("> hunk " 588299742Sdim "@@ -%lu,%lu +%lu,%lu @@ " 589299742Sdim "already applied\n"), 590299742Sdim n->hunk_original_start, 591299742Sdim n->hunk_original_length, 592299742Sdim n->hunk_modified_start, 593299742Sdim n->hunk_modified_length)); 594251881Speter break; 595251881Speter 596251881Speter case svn_wc_notify_update_update: 597251881Speter case svn_wc_notify_merge_record_info: 598251881Speter { 599251881Speter if (n->content_state == svn_wc_notify_state_conflicted) 600251881Speter { 601251881Speter store_path(nb, nb->conflict_stats->text_conflicts, path_local); 602251881Speter statchar_buf[0] = 'C'; 603251881Speter } 604251881Speter else if (n->kind == svn_node_file) 605251881Speter { 606251881Speter if (n->content_state == svn_wc_notify_state_merged) 607251881Speter statchar_buf[0] = 'G'; 608251881Speter else if (n->content_state == svn_wc_notify_state_changed) 609251881Speter statchar_buf[0] = 'U'; 610251881Speter } 611251881Speter 612251881Speter if (n->prop_state == svn_wc_notify_state_conflicted) 613251881Speter { 614251881Speter store_path(nb, nb->conflict_stats->prop_conflicts, path_local); 615251881Speter statchar_buf[1] = 'C'; 616251881Speter } 617251881Speter else if (n->prop_state == svn_wc_notify_state_merged) 618251881Speter statchar_buf[1] = 'G'; 619251881Speter else if (n->prop_state == svn_wc_notify_state_changed) 620251881Speter statchar_buf[1] = 'U'; 621251881Speter 622251881Speter if (n->lock_state == svn_wc_notify_lock_state_unlocked) 623251881Speter statchar_buf[2] = 'B'; 624251881Speter 625251881Speter if (statchar_buf[0] != ' ' || statchar_buf[1] != ' ') 626251881Speter nb->received_some_change = TRUE; 627251881Speter 628251881Speter if (statchar_buf[0] != ' ' || statchar_buf[1] != ' ' 629251881Speter || statchar_buf[2] != ' ') 630251881Speter { 631299742Sdim SVN_ERR(svn_cmdline_printf(pool, "%s %s\n", 632299742Sdim statchar_buf, path_local)); 633251881Speter } 634251881Speter } 635251881Speter break; 636251881Speter 637251881Speter case svn_wc_notify_update_external: 638251881Speter /* Remember that we're now "inside" an externals definition. */ 639299742Sdim ++nb->in_external; 640251881Speter 641251881Speter /* Currently this is used for checkouts and switches too. If we 642251881Speter want different output, we'll have to add new actions. */ 643299742Sdim SVN_ERR(svn_cmdline_printf(pool, 644299742Sdim _("\nFetching external item into '%s':\n"), 645299742Sdim path_local)); 646251881Speter break; 647251881Speter 648251881Speter case svn_wc_notify_failed_external: 649251881Speter /* If we are currently inside the handling of an externals 650251881Speter definition, then we can simply present n->err as a warning 651251881Speter and feel confident that after this, we aren't handling that 652251881Speter externals definition any longer. */ 653251881Speter if (nb->in_external) 654251881Speter { 655251881Speter svn_handle_warning2(stderr, n->err, "svn: "); 656299742Sdim --nb->in_external; 657299742Sdim SVN_ERR(svn_cmdline_printf(pool, "\n")); 658251881Speter } 659251881Speter /* Otherwise, we'll just print two warnings. Why? Because 660251881Speter svn_handle_warning2() only shows the single "best message", 661251881Speter but we have two pretty important ones: that the external at 662251881Speter '/some/path' didn't pan out, and then the more specific 663251881Speter reason why (from n->err). */ 664251881Speter else 665251881Speter { 666251881Speter svn_error_t *warn_err = 667299742Sdim svn_error_createf(SVN_ERR_CL_ERROR_PROCESSING_EXTERNALS, NULL, 668251881Speter _("Error handling externals definition for '%s':"), 669251881Speter path_local); 670251881Speter svn_handle_warning2(stderr, warn_err, "svn: "); 671251881Speter svn_error_clear(warn_err); 672251881Speter svn_handle_warning2(stderr, n->err, "svn: "); 673251881Speter } 674251881Speter break; 675251881Speter 676251881Speter case svn_wc_notify_update_started: 677251881Speter if (! (nb->in_external || 678251881Speter nb->is_checkout || 679251881Speter nb->is_export)) 680251881Speter { 681299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("Updating '%s':\n"), 682299742Sdim path_local)); 683251881Speter } 684251881Speter break; 685251881Speter 686251881Speter case svn_wc_notify_update_completed: 687251881Speter { 688251881Speter if (SVN_IS_VALID_REVNUM(n->revision)) 689251881Speter { 690251881Speter if (nb->is_export) 691251881Speter { 692299742Sdim SVN_ERR(svn_cmdline_printf( 693299742Sdim pool, nb->in_external 694299742Sdim ? _("Exported external at revision %ld.\n") 695299742Sdim : _("Exported revision %ld.\n"), 696299742Sdim n->revision)); 697251881Speter } 698251881Speter else if (nb->is_checkout) 699251881Speter { 700299742Sdim SVN_ERR(svn_cmdline_printf( 701299742Sdim pool, nb->in_external 702299742Sdim ? _("Checked out external at revision %ld.\n") 703299742Sdim : _("Checked out revision %ld.\n"), 704299742Sdim n->revision)); 705251881Speter } 706251881Speter else 707251881Speter { 708251881Speter if (nb->received_some_change) 709251881Speter { 710251881Speter nb->received_some_change = FALSE; 711299742Sdim SVN_ERR(svn_cmdline_printf( 712299742Sdim pool, nb->in_external 713299742Sdim ? _("Updated external to revision %ld.\n") 714299742Sdim : _("Updated to revision %ld.\n"), 715299742Sdim n->revision)); 716251881Speter } 717251881Speter else 718251881Speter { 719299742Sdim SVN_ERR(svn_cmdline_printf( 720299742Sdim pool, nb->in_external 721299742Sdim ? _("External at revision %ld.\n") 722299742Sdim : _("At revision %ld.\n"), 723299742Sdim n->revision)); 724251881Speter } 725251881Speter } 726251881Speter } 727251881Speter else /* no revision */ 728251881Speter { 729251881Speter if (nb->is_export) 730251881Speter { 731299742Sdim SVN_ERR(svn_cmdline_printf( 732299742Sdim pool, nb->in_external 733299742Sdim ? _("External export complete.\n") 734299742Sdim : _("Export complete.\n"))); 735251881Speter } 736251881Speter else if (nb->is_checkout) 737251881Speter { 738299742Sdim SVN_ERR(svn_cmdline_printf( 739299742Sdim pool, nb->in_external 740299742Sdim ? _("External checkout complete.\n") 741299742Sdim : _("Checkout complete.\n"))); 742251881Speter } 743251881Speter else 744251881Speter { 745299742Sdim SVN_ERR(svn_cmdline_printf( 746299742Sdim pool, nb->in_external 747299742Sdim ? _("External update complete.\n") 748299742Sdim : _("Update complete.\n"))); 749251881Speter } 750251881Speter } 751251881Speter } 752251881Speter 753251881Speter if (nb->in_external) 754251881Speter { 755299742Sdim --nb->in_external; 756299742Sdim SVN_ERR(svn_cmdline_printf(pool, "\n")); 757251881Speter } 758251881Speter break; 759251881Speter 760251881Speter case svn_wc_notify_status_external: 761299742Sdim SVN_ERR(svn_cmdline_printf( 762299742Sdim pool, _("\nPerforming status on external item at '%s':\n"), 763299742Sdim path_local)); 764251881Speter break; 765251881Speter 766299742Sdim case svn_wc_notify_info_external: 767299742Sdim SVN_ERR(svn_cmdline_printf( 768299742Sdim pool, _("\nPerforming info on external item at '%s':\n"), 769299742Sdim path_local)); 770299742Sdim break; 771299742Sdim 772251881Speter case svn_wc_notify_status_completed: 773251881Speter if (SVN_IS_VALID_REVNUM(n->revision)) 774299742Sdim SVN_ERR(svn_cmdline_printf(pool, 775299742Sdim _("Status against revision: %6ld\n"), 776299742Sdim n->revision)); 777251881Speter break; 778251881Speter 779251881Speter case svn_wc_notify_commit_modified: 780251881Speter /* xgettext: Align the %s's on this and the following 4 messages */ 781299742Sdim SVN_ERR(svn_cmdline_printf(pool, 782299742Sdim nb->is_wc_to_repos_copy 783299742Sdim ? _("Sending copy of %s\n") 784299742Sdim : _("Sending %s\n"), 785299742Sdim path_local)); 786251881Speter break; 787251881Speter 788251881Speter case svn_wc_notify_commit_added: 789251881Speter case svn_wc_notify_commit_copied: 790251881Speter if (n->mime_type && svn_mime_type_is_binary(n->mime_type)) 791251881Speter { 792299742Sdim SVN_ERR(svn_cmdline_printf(pool, 793299742Sdim nb->is_wc_to_repos_copy 794299742Sdim ? _("Adding copy of (bin) %s\n") 795299742Sdim : _("Adding (bin) %s\n"), 796299742Sdim path_local)); 797251881Speter } 798251881Speter else 799251881Speter { 800299742Sdim SVN_ERR(svn_cmdline_printf(pool, 801299742Sdim nb->is_wc_to_repos_copy 802299742Sdim ? _("Adding copy of %s\n") 803299742Sdim : _("Adding %s\n"), 804299742Sdim path_local)); 805251881Speter } 806251881Speter break; 807251881Speter 808251881Speter case svn_wc_notify_commit_deleted: 809299742Sdim SVN_ERR(svn_cmdline_printf(pool, 810299742Sdim nb->is_wc_to_repos_copy 811299742Sdim ? _("Deleting copy of %s\n") 812299742Sdim : _("Deleting %s\n"), 813299742Sdim path_local)); 814251881Speter break; 815251881Speter 816251881Speter case svn_wc_notify_commit_replaced: 817251881Speter case svn_wc_notify_commit_copied_replaced: 818299742Sdim SVN_ERR(svn_cmdline_printf(pool, 819299742Sdim nb->is_wc_to_repos_copy 820299742Sdim ? _("Replacing copy of %s\n") 821299742Sdim : _("Replacing %s\n"), 822299742Sdim path_local)); 823251881Speter break; 824251881Speter 825251881Speter case svn_wc_notify_commit_postfix_txdelta: 826251881Speter if (! nb->sent_first_txdelta) 827251881Speter { 828251881Speter nb->sent_first_txdelta = TRUE; 829299742Sdim SVN_ERR(svn_cmdline_printf(pool, 830299742Sdim _("Transmitting file data "))); 831251881Speter } 832251881Speter 833299742Sdim SVN_ERR(svn_cmdline_printf(pool, ".")); 834251881Speter break; 835251881Speter 836251881Speter case svn_wc_notify_locked: 837299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("'%s' locked by user '%s'.\n"), 838299742Sdim path_local, n->lock->owner)); 839251881Speter break; 840251881Speter 841251881Speter case svn_wc_notify_unlocked: 842299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("'%s' unlocked.\n"), 843299742Sdim path_local)); 844251881Speter break; 845251881Speter 846251881Speter case svn_wc_notify_failed_lock: 847251881Speter case svn_wc_notify_failed_unlock: 848251881Speter svn_handle_warning2(stderr, n->err, "svn: "); 849251881Speter break; 850251881Speter 851251881Speter case svn_wc_notify_changelist_set: 852299742Sdim SVN_ERR(svn_cmdline_printf(pool, "A [%s] %s\n", 853299742Sdim n->changelist_name, path_local)); 854251881Speter break; 855251881Speter 856251881Speter case svn_wc_notify_changelist_clear: 857251881Speter case svn_wc_notify_changelist_moved: 858299742Sdim SVN_ERR(svn_cmdline_printf(pool, 859299742Sdim "D [%s] %s\n", 860299742Sdim n->changelist_name, path_local)); 861251881Speter break; 862251881Speter 863251881Speter case svn_wc_notify_merge_begin: 864251881Speter if (n->merge_range == NULL) 865299742Sdim SVN_ERR(svn_cmdline_printf(pool, 866299742Sdim _("--- Merging differences between " 867299742Sdim "repository URLs into '%s':\n"), 868299742Sdim path_local)); 869251881Speter else if (n->merge_range->start == n->merge_range->end - 1 870251881Speter || n->merge_range->start == n->merge_range->end) 871299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("--- Merging r%ld into '%s':\n"), 872299742Sdim n->merge_range->end, path_local)); 873251881Speter else if (n->merge_range->start - 1 == n->merge_range->end) 874299742Sdim SVN_ERR(svn_cmdline_printf(pool, 875299742Sdim _("--- Reverse-merging r%ld into '%s':\n"), 876299742Sdim n->merge_range->start, path_local)); 877251881Speter else if (n->merge_range->start < n->merge_range->end) 878299742Sdim SVN_ERR(svn_cmdline_printf(pool, 879299742Sdim _("--- Merging r%ld through r%ld into " 880299742Sdim "'%s':\n"), 881299742Sdim n->merge_range->start + 1, 882299742Sdim n->merge_range->end, path_local)); 883251881Speter else /* n->merge_range->start > n->merge_range->end - 1 */ 884299742Sdim SVN_ERR(svn_cmdline_printf(pool, 885299742Sdim _("--- Reverse-merging r%ld through r%ld " 886299742Sdim "into '%s':\n"), 887299742Sdim n->merge_range->start, 888299742Sdim n->merge_range->end + 1, path_local)); 889251881Speter break; 890251881Speter 891251881Speter case svn_wc_notify_merge_record_info_begin: 892251881Speter if (!n->merge_range) 893251881Speter { 894299742Sdim SVN_ERR(svn_cmdline_printf(pool, 895299742Sdim _("--- Recording mergeinfo for merge " 896299742Sdim "between repository URLs into '%s':\n"), 897299742Sdim path_local)); 898251881Speter } 899251881Speter else 900251881Speter { 901251881Speter if (n->merge_range->start == n->merge_range->end - 1 902251881Speter || n->merge_range->start == n->merge_range->end) 903299742Sdim SVN_ERR(svn_cmdline_printf( 904251881Speter pool, 905251881Speter _("--- Recording mergeinfo for merge of r%ld into '%s':\n"), 906299742Sdim n->merge_range->end, path_local)); 907251881Speter else if (n->merge_range->start - 1 == n->merge_range->end) 908299742Sdim SVN_ERR(svn_cmdline_printf( 909251881Speter pool, 910251881Speter _("--- Recording mergeinfo for reverse merge of r%ld into '%s':\n"), 911299742Sdim n->merge_range->start, path_local)); 912251881Speter else if (n->merge_range->start < n->merge_range->end) 913299742Sdim SVN_ERR(svn_cmdline_printf( 914251881Speter pool, 915251881Speter _("--- Recording mergeinfo for merge of r%ld through r%ld into '%s':\n"), 916299742Sdim n->merge_range->start + 1, n->merge_range->end, path_local)); 917251881Speter else /* n->merge_range->start > n->merge_range->end - 1 */ 918299742Sdim SVN_ERR(svn_cmdline_printf( 919251881Speter pool, 920251881Speter _("--- Recording mergeinfo for reverse merge of r%ld through r%ld into '%s':\n"), 921299742Sdim n->merge_range->start, n->merge_range->end + 1, path_local)); 922251881Speter } 923251881Speter break; 924251881Speter 925251881Speter case svn_wc_notify_merge_elide_info: 926299742Sdim SVN_ERR(svn_cmdline_printf(pool, 927299742Sdim _("--- Eliding mergeinfo from '%s':\n"), 928299742Sdim path_local)); 929251881Speter break; 930251881Speter 931251881Speter case svn_wc_notify_foreign_merge_begin: 932251881Speter if (n->merge_range == NULL) 933299742Sdim SVN_ERR(svn_cmdline_printf(pool, 934299742Sdim _("--- Merging differences between " 935299742Sdim "foreign repository URLs into '%s':\n"), 936299742Sdim path_local)); 937251881Speter else if (n->merge_range->start == n->merge_range->end - 1 938251881Speter || n->merge_range->start == n->merge_range->end) 939299742Sdim SVN_ERR(svn_cmdline_printf(pool, 940299742Sdim _("--- Merging (from foreign repository) " 941299742Sdim "r%ld into '%s':\n"), 942299742Sdim n->merge_range->end, path_local)); 943251881Speter else if (n->merge_range->start - 1 == n->merge_range->end) 944299742Sdim SVN_ERR(svn_cmdline_printf(pool, 945299742Sdim _("--- Reverse-merging (from foreign " 946299742Sdim "repository) r%ld into '%s':\n"), 947299742Sdim n->merge_range->start, path_local)); 948251881Speter else if (n->merge_range->start < n->merge_range->end) 949299742Sdim SVN_ERR(svn_cmdline_printf(pool, 950299742Sdim _("--- Merging (from foreign repository) " 951299742Sdim "r%ld through r%ld into '%s':\n"), 952299742Sdim n->merge_range->start + 1, 953299742Sdim n->merge_range->end, path_local)); 954251881Speter else /* n->merge_range->start > n->merge_range->end - 1 */ 955299742Sdim SVN_ERR(svn_cmdline_printf(pool, 956299742Sdim _("--- Reverse-merging (from foreign " 957299742Sdim "repository) r%ld through r%ld into " 958299742Sdim "'%s':\n"), 959299742Sdim n->merge_range->start, 960299742Sdim n->merge_range->end + 1, path_local)); 961251881Speter break; 962251881Speter 963251881Speter case svn_wc_notify_tree_conflict: 964251881Speter store_path(nb, nb->conflict_stats->tree_conflicts, path_local); 965299742Sdim SVN_ERR(svn_cmdline_printf(pool, " C %s\n", path_local)); 966251881Speter break; 967251881Speter 968251881Speter case svn_wc_notify_update_shadowed_add: 969251881Speter nb->received_some_change = TRUE; 970299742Sdim SVN_ERR(svn_cmdline_printf(pool, " A %s\n", path_local)); 971251881Speter break; 972251881Speter 973251881Speter case svn_wc_notify_update_shadowed_update: 974251881Speter nb->received_some_change = TRUE; 975299742Sdim SVN_ERR(svn_cmdline_printf(pool, " U %s\n", path_local)); 976251881Speter break; 977251881Speter 978251881Speter case svn_wc_notify_update_shadowed_delete: 979251881Speter nb->received_some_change = TRUE; 980299742Sdim SVN_ERR(svn_cmdline_printf(pool, " D %s\n", path_local)); 981251881Speter break; 982251881Speter 983251881Speter case svn_wc_notify_property_modified: 984251881Speter case svn_wc_notify_property_added: 985299742Sdim SVN_ERR(svn_cmdline_printf(pool, 986299742Sdim _("property '%s' set on '%s'\n"), 987299742Sdim n->prop_name, path_local)); 988251881Speter break; 989251881Speter 990251881Speter case svn_wc_notify_property_deleted: 991299742Sdim SVN_ERR(svn_cmdline_printf(pool, 992299742Sdim _("property '%s' deleted from '%s'.\n"), 993299742Sdim n->prop_name, path_local)); 994251881Speter break; 995251881Speter 996251881Speter case svn_wc_notify_property_deleted_nonexistent: 997299742Sdim SVN_ERR(svn_cmdline_printf(pool, 998299742Sdim _("Attempting to delete nonexistent " 999299742Sdim "property '%s' on '%s'\n"), n->prop_name, 1000299742Sdim path_local)); 1001251881Speter break; 1002251881Speter 1003251881Speter case svn_wc_notify_revprop_set: 1004299742Sdim SVN_ERR(svn_cmdline_printf(pool, 1005251881Speter _("property '%s' set on repository revision %ld\n"), 1006299742Sdim n->prop_name, n->revision)); 1007251881Speter break; 1008251881Speter 1009251881Speter case svn_wc_notify_revprop_deleted: 1010299742Sdim SVN_ERR(svn_cmdline_printf(pool, 1011251881Speter _("property '%s' deleted from repository revision %ld\n"), 1012299742Sdim n->prop_name, n->revision)); 1013251881Speter break; 1014251881Speter 1015251881Speter case svn_wc_notify_upgraded_path: 1016299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("Upgraded '%s'\n"), path_local)); 1017251881Speter break; 1018251881Speter 1019251881Speter case svn_wc_notify_url_redirect: 1020299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("Redirecting to URL '%s':\n"), 1021299742Sdim n->url)); 1022251881Speter break; 1023251881Speter 1024251881Speter case svn_wc_notify_path_nonexistent: 1025299742Sdim SVN_ERR(svn_cmdline_printf(pool, "%s\n", 1026299742Sdim apr_psprintf(pool, _("'%s' is not under version control"), 1027299742Sdim path_local))); 1028251881Speter break; 1029251881Speter 1030251881Speter case svn_wc_notify_conflict_resolver_starting: 1031251881Speter /* Once all operations invoke the interactive conflict resolution after 1032251881Speter * they've completed, we can run svn_cl__notifier_print_conflict_stats() 1033251881Speter * here. */ 1034251881Speter break; 1035251881Speter 1036251881Speter case svn_wc_notify_conflict_resolver_done: 1037251881Speter break; 1038251881Speter 1039251881Speter case svn_wc_notify_foreign_copy_begin: 1040251881Speter if (n->merge_range == NULL) 1041251881Speter { 1042299742Sdim SVN_ERR(svn_cmdline_printf( 1043251881Speter pool, 1044251881Speter _("--- Copying from foreign repository URL '%s':\n"), 1045299742Sdim n->url)); 1046251881Speter } 1047251881Speter break; 1048251881Speter 1049251881Speter case svn_wc_notify_move_broken: 1050299742Sdim SVN_ERR(svn_cmdline_printf(pool, 1051299742Sdim _("Breaking move with source path '%s'\n"), 1052299742Sdim path_local)); 1053251881Speter break; 1054251881Speter 1055299742Sdim case svn_wc_notify_cleanup_external: 1056299742Sdim SVN_ERR(svn_cmdline_printf 1057299742Sdim (pool, _("Performing cleanup on external item at '%s'.\n"), 1058299742Sdim path_local)); 1059299742Sdim break; 1060299742Sdim 1061299742Sdim case svn_wc_notify_commit_finalizing: 1062299742Sdim if (nb->sent_first_txdelta) 1063299742Sdim { 1064299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("done\n"))); 1065299742Sdim } 1066299742Sdim SVN_ERR(svn_cmdline_printf(pool, _("Committing transaction...\n"))); 1067299742Sdim break; 1068299742Sdim 1069251881Speter default: 1070251881Speter break; 1071251881Speter } 1072251881Speter 1073299742Sdim SVN_ERR(svn_cmdline_fflush(stdout)); 1074251881Speter 1075299742Sdim return SVN_NO_ERROR; 1076299742Sdim} 1077251881Speter 1078299742Sdim/* This implements `svn_wc_notify_func2_t'. 1079299742Sdim * NOTE: This function can't fail, so we just ignore any print errors. */ 1080299742Sdimstatic void 1081299742Sdimnotify(void *baton, const svn_wc_notify_t *n, apr_pool_t *pool) 1082299742Sdim{ 1083299742Sdim struct notify_baton *nb = baton; 1084299742Sdim svn_error_t *err; 1085299742Sdim 1086299742Sdim err = notify_body(nb, n, pool); 1087299742Sdim 1088251881Speter /* If we had no errors before, print this error to stderr. Else, don't print 1089251881Speter anything. The user already knows there were some output errors, 1090251881Speter so there is no point in flooding her with an error per notification. */ 1091299742Sdim if (err && !nb->had_print_error) 1092251881Speter { 1093251881Speter nb->had_print_error = TRUE; 1094251881Speter /* Issue #3014: 1095251881Speter * Don't print anything on broken pipes. The pipe was likely 1096251881Speter * closed by the process at the other end. We expect that 1097251881Speter * process to perform error reporting as necessary. 1098251881Speter * 1099251881Speter * ### This assumes that there is only one error in a chain for 1100251881Speter * ### SVN_ERR_IO_PIPE_WRITE_ERROR. See svn_cmdline_fputs(). */ 1101251881Speter if (err->apr_err != SVN_ERR_IO_PIPE_WRITE_ERROR) 1102251881Speter svn_handle_error2(err, stderr, FALSE, "svn: "); 1103251881Speter } 1104251881Speter svn_error_clear(err); 1105251881Speter} 1106251881Speter 1107251881Spetersvn_error_t * 1108251881Spetersvn_cl__get_notifier(svn_wc_notify_func2_t *notify_func_p, 1109251881Speter void **notify_baton_p, 1110251881Speter svn_cl__conflict_stats_t *conflict_stats, 1111251881Speter apr_pool_t *pool) 1112251881Speter{ 1113251881Speter struct notify_baton *nb = apr_pcalloc(pool, sizeof(*nb)); 1114251881Speter 1115251881Speter nb->received_some_change = FALSE; 1116251881Speter nb->sent_first_txdelta = FALSE; 1117251881Speter nb->is_checkout = FALSE; 1118251881Speter nb->is_export = FALSE; 1119251881Speter nb->is_wc_to_repos_copy = FALSE; 1120299742Sdim nb->in_external = 0; 1121251881Speter nb->had_print_error = FALSE; 1122251881Speter nb->conflict_stats = conflict_stats; 1123251881Speter SVN_ERR(svn_dirent_get_absolute(&nb->path_prefix, "", pool)); 1124251881Speter 1125251881Speter *notify_func_p = notify; 1126251881Speter *notify_baton_p = nb; 1127251881Speter return SVN_NO_ERROR; 1128251881Speter} 1129251881Speter 1130251881Spetersvn_error_t * 1131251881Spetersvn_cl__notifier_mark_checkout(void *baton) 1132251881Speter{ 1133251881Speter struct notify_baton *nb = baton; 1134251881Speter 1135251881Speter nb->is_checkout = TRUE; 1136251881Speter return SVN_NO_ERROR; 1137251881Speter} 1138251881Speter 1139251881Spetersvn_error_t * 1140251881Spetersvn_cl__notifier_mark_export(void *baton) 1141251881Speter{ 1142251881Speter struct notify_baton *nb = baton; 1143251881Speter 1144251881Speter nb->is_export = TRUE; 1145251881Speter return SVN_NO_ERROR; 1146251881Speter} 1147251881Speter 1148251881Spetersvn_error_t * 1149251881Spetersvn_cl__notifier_mark_wc_to_repos_copy(void *baton) 1150251881Speter{ 1151251881Speter struct notify_baton *nb = baton; 1152251881Speter 1153251881Speter nb->is_wc_to_repos_copy = TRUE; 1154251881Speter return SVN_NO_ERROR; 1155251881Speter} 1156251881Speter 1157251881Spetervoid 1158251881Spetersvn_cl__check_externals_failed_notify_wrapper(void *baton, 1159251881Speter const svn_wc_notify_t *n, 1160251881Speter apr_pool_t *pool) 1161251881Speter{ 1162251881Speter struct svn_cl__check_externals_failed_notify_baton *nwb = baton; 1163251881Speter 1164251881Speter if (n->action == svn_wc_notify_failed_external) 1165251881Speter nwb->had_externals_error = TRUE; 1166251881Speter 1167251881Speter if (nwb->wrapped_func) 1168251881Speter nwb->wrapped_func(nwb->wrapped_baton, n, pool); 1169251881Speter} 1170