notify.c revision 289180
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; 55289180Speter 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{ 132289180Speter 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 * 148289180Spetersvn_cl__print_conflict_stats(svn_cl__conflict_stats_t *conflict_stats, 149289180Speter apr_pool_t *scratch_pool) 150251881Speter{ 151289180Speter int n_text = apr_hash_count(conflict_stats->text_conflicts); 152289180Speter int n_prop = apr_hash_count(conflict_stats->prop_conflicts); 153289180Speter int n_tree = apr_hash_count(conflict_stats->tree_conflicts); 154289180Speter int n_text_r = conflict_stats->text_conflicts_resolved; 155289180Speter int n_prop_r = conflict_stats->prop_conflicts_resolved; 156289180Speter 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 161289180Speter || 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 } 198289180Speter if (conflict_stats->skipped_paths > 0) 199251881Speter SVN_ERR(svn_cmdline_printf(scratch_pool, 200251881Speter _(" Skipped paths: %d\n"), 201289180Speter conflict_stats->skipped_paths)); 202251881Speter 203251881Speter return SVN_NO_ERROR; 204251881Speter} 205251881Speter 206289180Spetersvn_error_t * 207289180Spetersvn_cl__notifier_print_conflict_stats(void *baton, apr_pool_t *scratch_pool) 208251881Speter{ 209251881Speter struct notify_baton *nb = baton; 210289180Speter 211289180Speter SVN_ERR(svn_cl__print_conflict_stats(nb->conflict_stats, scratch_pool)); 212289180Speter return SVN_NO_ERROR; 213289180Speter} 214289180Speter 215289180Speter/* The body for notify() function with standard error handling semantic. 216289180Speter * Handling of errors implemented at caller side. */ 217289180Speterstatic svn_error_t * 218289180Speternotify_body(struct notify_baton *nb, 219289180Speter const svn_wc_notify_t *n, 220289180Speter apr_pool_t *pool) 221289180Speter{ 222251881Speter char statchar_buf[5] = " "; 223251881Speter const char *path_local; 224251881Speter 225251881Speter if (n->url) 226251881Speter path_local = n->url; 227251881Speter else 228251881Speter { 229289180Speter /* Skip the path prefix in N, if supplied, or else the path prefix 230289180Speter 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); 234289180Speter 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 { 245289180Speter SVN_ERR(svn_cmdline_printf(pool, 246289180Speter _("Skipped missing target: '%s'\n"), 247289180Speter path_local)); 248251881Speter } 249251881Speter else if (n->content_state == svn_wc_notify_state_source_missing) 250251881Speter { 251289180Speter SVN_ERR(svn_cmdline_printf( 252289180Speter pool, 253289180Speter _("Skipped target: '%s' -- copy-source is missing\n"), 254289180Speter path_local)); 255251881Speter } 256251881Speter else 257251881Speter { 258289180Speter 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++; 263289180Speter SVN_ERR(svn_cmdline_printf( 264289180Speter pool, 265289180Speter _("Skipped '%s' -- An obstructing working copy was found\n"), 266289180Speter path_local)); 267251881Speter break; 268251881Speter case svn_wc_notify_update_skip_working_only: 269251881Speter nb->conflict_stats->skipped_paths++; 270289180Speter SVN_ERR(svn_cmdline_printf( 271289180Speter pool, _("Skipped '%s' -- Has no versioned parent\n"), 272289180Speter path_local)); 273251881Speter break; 274251881Speter case svn_wc_notify_update_skip_access_denied: 275251881Speter nb->conflict_stats->skipped_paths++; 276289180Speter SVN_ERR(svn_cmdline_printf( 277289180Speter pool, _("Skipped '%s' -- Access denied\n"), 278289180Speter path_local)); 279251881Speter break; 280251881Speter case svn_wc_notify_skip_conflicted: 281251881Speter nb->conflict_stats->skipped_paths++; 282289180Speter SVN_ERR(svn_cmdline_printf( 283289180Speter pool, _("Skipped '%s' -- Node remains in conflict\n"), 284289180Speter path_local)); 285251881Speter break; 286251881Speter case svn_wc_notify_update_delete: 287251881Speter case svn_wc_notify_exclude: 288251881Speter nb->received_some_change = TRUE; 289289180Speter SVN_ERR(svn_cmdline_printf(pool, "D %s\n", path_local)); 290251881Speter break; 291251881Speter case svn_wc_notify_update_broken_lock: 292289180Speter 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 { 299289180Speter SVN_ERR(svn_cmdline_printf(pool, _("Removed external '%s': %s\n"), 300289180Speter path_local, n->err->message)); 301251881Speter } 302251881Speter else 303251881Speter { 304289180Speter SVN_ERR(svn_cmdline_printf(pool, _("Removed external '%s'\n"), 305289180Speter path_local)); 306251881Speter } 307251881Speter break; 308251881Speter 309251881Speter case svn_wc_notify_left_local_modifications: 310289180Speter SVN_ERR(svn_cmdline_printf(pool, _("Left local modifications as '%s'\n"), 311289180Speter path_local)); 312251881Speter break; 313251881Speter 314251881Speter case svn_wc_notify_update_replace: 315251881Speter nb->received_some_change = TRUE; 316289180Speter 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); 324289180Speter SVN_ERR(svn_cmdline_printf(pool, "C %s\n", path_local)); 325251881Speter } 326251881Speter else 327251881Speter { 328289180Speter 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 350289180Speter SVN_ERR(svn_cmdline_printf(pool, "%s %s\n", statchar_buf, path_local)); 351251881Speter break; 352251881Speter 353251881Speter case svn_wc_notify_restore: 354289180Speter SVN_ERR(svn_cmdline_printf(pool, _("Restored '%s'\n"), 355289180Speter path_local)); 356251881Speter break; 357251881Speter 358251881Speter case svn_wc_notify_revert: 359289180Speter SVN_ERR(svn_cmdline_printf(pool, _("Reverted '%s'\n"), 360289180Speter path_local)); 361251881Speter break; 362251881Speter 363251881Speter case svn_wc_notify_failed_revert: 364289180Speter SVN_ERR(svn_cmdline_printf(pool, _("Failed to revert '%s' -- " 365289180Speter "try updating instead.\n"), 366289180Speter path_local)); 367251881Speter break; 368251881Speter 369251881Speter case svn_wc_notify_resolved: 370289180Speter SVN_ERR(svn_cmdline_printf(pool, 371289180Speter _("Resolved conflicted state of '%s'\n"), 372289180Speter 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 { 381289180Speter SVN_ERR(svn_cmdline_printf(pool, "A (bin) %s\n", 382289180Speter path_local)); 383251881Speter } 384251881Speter else 385251881Speter { 386289180Speter SVN_ERR(svn_cmdline_printf(pool, "A %s\n", 387289180Speter path_local)); 388251881Speter } 389251881Speter break; 390251881Speter 391251881Speter case svn_wc_notify_delete: 392251881Speter nb->received_some_change = TRUE; 393289180Speter SVN_ERR(svn_cmdline_printf(pool, "D %s\n", 394289180Speter 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 { 423289180Speter SVN_ERR(svn_cmdline_printf(pool, "%s %s\n", 424289180Speter 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 464289180Speter SVN_ERR(svn_cmdline_printf(pool, 465289180Speter apr_pstrcat(pool, s, 466289180Speter "%"APR_UINT64_T_FMT 467289180Speter " and fuzz %lu (%s)\n", 468289180Speter SVN_VA_NULL), 469289180Speter n->hunk_original_start, 470289180Speter n->hunk_original_length, 471289180Speter n->hunk_modified_start, 472289180Speter n->hunk_modified_length, 473289180Speter minus, off, n->hunk_fuzz, 474289180Speter n->prop_name)); 475251881Speter } 476251881Speter else 477251881Speter { 478251881Speter s = _("> applied hunk @@ -%lu,%lu +%lu,%lu @@ " 479251881Speter "with offset %s"); 480251881Speter 481289180Speter SVN_ERR(svn_cmdline_printf(pool, 482289180Speter apr_pstrcat(pool, s, 483289180Speter "%"APR_UINT64_T_FMT 484289180Speter " and fuzz %lu\n", 485289180Speter SVN_VA_NULL), 486289180Speter n->hunk_original_start, 487289180Speter n->hunk_original_length, 488289180Speter n->hunk_modified_start, 489289180Speter n->hunk_modified_length, 490289180Speter 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"); 500289180Speter SVN_ERR(svn_cmdline_printf(pool, 501289180Speter apr_pstrcat(pool, s, 502289180Speter "%"APR_UINT64_T_FMT" (%s)\n", 503289180Speter SVN_VA_NULL), 504289180Speter n->hunk_original_start, 505289180Speter n->hunk_original_length, 506289180Speter n->hunk_modified_start, 507289180Speter n->hunk_modified_length, 508289180Speter minus, off, n->prop_name)); 509251881Speter } 510251881Speter else 511251881Speter { 512251881Speter s = _("> applied hunk @@ -%lu,%lu +%lu,%lu @@ " 513251881Speter "with offset %s"); 514289180Speter SVN_ERR(svn_cmdline_printf(pool, 515289180Speter apr_pstrcat(pool, s, 516289180Speter "%"APR_UINT64_T_FMT"\n", 517289180Speter SVN_VA_NULL), 518289180Speter n->hunk_original_start, 519289180Speter n->hunk_original_length, 520289180Speter n->hunk_modified_start, 521289180Speter n->hunk_modified_length, 522289180Speter minus, off)); 523251881Speter } 524251881Speter } 525251881Speter } 526251881Speter else if (n->hunk_fuzz) 527251881Speter { 528251881Speter if (n->prop_name) 529289180Speter 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, 537289180Speter n->prop_name)); 538251881Speter else 539289180Speter 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, 546289180Speter 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) 555289180Speter SVN_ERR(svn_cmdline_printf(pool, 556289180Speter _("> rejected hunk " 557289180Speter "## -%lu,%lu +%lu,%lu ## (%s)\n"), 558289180Speter n->hunk_original_start, 559289180Speter n->hunk_original_length, 560289180Speter n->hunk_modified_start, 561289180Speter n->hunk_modified_length, 562289180Speter n->prop_name)); 563251881Speter else 564289180Speter SVN_ERR(svn_cmdline_printf(pool, 565289180Speter _("> rejected hunk " 566289180Speter "@@ -%lu,%lu +%lu,%lu @@\n"), 567289180Speter n->hunk_original_start, 568289180Speter n->hunk_original_length, 569289180Speter n->hunk_modified_start, 570289180Speter 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) 576289180Speter SVN_ERR(svn_cmdline_printf(pool, 577289180Speter _("> hunk " 578289180Speter "## -%lu,%lu +%lu,%lu ## " 579289180Speter "already applied (%s)\n"), 580289180Speter n->hunk_original_start, 581289180Speter n->hunk_original_length, 582289180Speter n->hunk_modified_start, 583289180Speter n->hunk_modified_length, 584289180Speter n->prop_name)); 585251881Speter else 586289180Speter SVN_ERR(svn_cmdline_printf(pool, 587289180Speter _("> hunk " 588289180Speter "@@ -%lu,%lu +%lu,%lu @@ " 589289180Speter "already applied\n"), 590289180Speter n->hunk_original_start, 591289180Speter n->hunk_original_length, 592289180Speter n->hunk_modified_start, 593289180Speter 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 { 631289180Speter SVN_ERR(svn_cmdline_printf(pool, "%s %s\n", 632289180Speter 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. */ 639289180Speter ++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. */ 643289180Speter SVN_ERR(svn_cmdline_printf(pool, 644289180Speter _("\nFetching external item into '%s':\n"), 645289180Speter 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: "); 656289180Speter --nb->in_external; 657289180Speter 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 = 667289180Speter 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 { 681289180Speter SVN_ERR(svn_cmdline_printf(pool, _("Updating '%s':\n"), 682289180Speter 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 { 692289180Speter SVN_ERR(svn_cmdline_printf( 693289180Speter pool, nb->in_external 694289180Speter ? _("Exported external at revision %ld.\n") 695289180Speter : _("Exported revision %ld.\n"), 696289180Speter n->revision)); 697251881Speter } 698251881Speter else if (nb->is_checkout) 699251881Speter { 700289180Speter SVN_ERR(svn_cmdline_printf( 701289180Speter pool, nb->in_external 702289180Speter ? _("Checked out external at revision %ld.\n") 703289180Speter : _("Checked out revision %ld.\n"), 704289180Speter n->revision)); 705251881Speter } 706251881Speter else 707251881Speter { 708251881Speter if (nb->received_some_change) 709251881Speter { 710251881Speter nb->received_some_change = FALSE; 711289180Speter SVN_ERR(svn_cmdline_printf( 712289180Speter pool, nb->in_external 713289180Speter ? _("Updated external to revision %ld.\n") 714289180Speter : _("Updated to revision %ld.\n"), 715289180Speter n->revision)); 716251881Speter } 717251881Speter else 718251881Speter { 719289180Speter SVN_ERR(svn_cmdline_printf( 720289180Speter pool, nb->in_external 721289180Speter ? _("External at revision %ld.\n") 722289180Speter : _("At revision %ld.\n"), 723289180Speter n->revision)); 724251881Speter } 725251881Speter } 726251881Speter } 727251881Speter else /* no revision */ 728251881Speter { 729251881Speter if (nb->is_export) 730251881Speter { 731289180Speter SVN_ERR(svn_cmdline_printf( 732289180Speter pool, nb->in_external 733289180Speter ? _("External export complete.\n") 734289180Speter : _("Export complete.\n"))); 735251881Speter } 736251881Speter else if (nb->is_checkout) 737251881Speter { 738289180Speter SVN_ERR(svn_cmdline_printf( 739289180Speter pool, nb->in_external 740289180Speter ? _("External checkout complete.\n") 741289180Speter : _("Checkout complete.\n"))); 742251881Speter } 743251881Speter else 744251881Speter { 745289180Speter SVN_ERR(svn_cmdline_printf( 746289180Speter pool, nb->in_external 747289180Speter ? _("External update complete.\n") 748289180Speter : _("Update complete.\n"))); 749251881Speter } 750251881Speter } 751251881Speter } 752251881Speter 753251881Speter if (nb->in_external) 754251881Speter { 755289180Speter --nb->in_external; 756289180Speter SVN_ERR(svn_cmdline_printf(pool, "\n")); 757251881Speter } 758251881Speter break; 759251881Speter 760251881Speter case svn_wc_notify_status_external: 761289180Speter SVN_ERR(svn_cmdline_printf( 762289180Speter pool, _("\nPerforming status on external item at '%s':\n"), 763289180Speter path_local)); 764251881Speter break; 765251881Speter 766289180Speter case svn_wc_notify_info_external: 767289180Speter SVN_ERR(svn_cmdline_printf( 768289180Speter pool, _("\nPerforming info on external item at '%s':\n"), 769289180Speter path_local)); 770289180Speter break; 771289180Speter 772251881Speter case svn_wc_notify_status_completed: 773251881Speter if (SVN_IS_VALID_REVNUM(n->revision)) 774289180Speter SVN_ERR(svn_cmdline_printf(pool, 775289180Speter _("Status against revision: %6ld\n"), 776289180Speter 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 */ 781289180Speter SVN_ERR(svn_cmdline_printf(pool, 782289180Speter nb->is_wc_to_repos_copy 783289180Speter ? _("Sending copy of %s\n") 784289180Speter : _("Sending %s\n"), 785289180Speter 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 { 792289180Speter SVN_ERR(svn_cmdline_printf(pool, 793289180Speter nb->is_wc_to_repos_copy 794289180Speter ? _("Adding copy of (bin) %s\n") 795289180Speter : _("Adding (bin) %s\n"), 796289180Speter path_local)); 797251881Speter } 798251881Speter else 799251881Speter { 800289180Speter SVN_ERR(svn_cmdline_printf(pool, 801289180Speter nb->is_wc_to_repos_copy 802289180Speter ? _("Adding copy of %s\n") 803289180Speter : _("Adding %s\n"), 804289180Speter path_local)); 805251881Speter } 806251881Speter break; 807251881Speter 808251881Speter case svn_wc_notify_commit_deleted: 809289180Speter SVN_ERR(svn_cmdline_printf(pool, 810289180Speter nb->is_wc_to_repos_copy 811289180Speter ? _("Deleting copy of %s\n") 812289180Speter : _("Deleting %s\n"), 813289180Speter path_local)); 814251881Speter break; 815251881Speter 816251881Speter case svn_wc_notify_commit_replaced: 817251881Speter case svn_wc_notify_commit_copied_replaced: 818289180Speter SVN_ERR(svn_cmdline_printf(pool, 819289180Speter nb->is_wc_to_repos_copy 820289180Speter ? _("Replacing copy of %s\n") 821289180Speter : _("Replacing %s\n"), 822289180Speter 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; 829289180Speter SVN_ERR(svn_cmdline_printf(pool, 830289180Speter _("Transmitting file data "))); 831251881Speter } 832251881Speter 833289180Speter SVN_ERR(svn_cmdline_printf(pool, ".")); 834251881Speter break; 835251881Speter 836251881Speter case svn_wc_notify_locked: 837289180Speter SVN_ERR(svn_cmdline_printf(pool, _("'%s' locked by user '%s'.\n"), 838289180Speter path_local, n->lock->owner)); 839251881Speter break; 840251881Speter 841251881Speter case svn_wc_notify_unlocked: 842289180Speter SVN_ERR(svn_cmdline_printf(pool, _("'%s' unlocked.\n"), 843289180Speter 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: 852289180Speter SVN_ERR(svn_cmdline_printf(pool, "A [%s] %s\n", 853289180Speter n->changelist_name, path_local)); 854251881Speter break; 855251881Speter 856251881Speter case svn_wc_notify_changelist_clear: 857251881Speter case svn_wc_notify_changelist_moved: 858289180Speter SVN_ERR(svn_cmdline_printf(pool, 859289180Speter "D [%s] %s\n", 860289180Speter n->changelist_name, path_local)); 861251881Speter break; 862251881Speter 863251881Speter case svn_wc_notify_merge_begin: 864251881Speter if (n->merge_range == NULL) 865289180Speter SVN_ERR(svn_cmdline_printf(pool, 866289180Speter _("--- Merging differences between " 867289180Speter "repository URLs into '%s':\n"), 868289180Speter path_local)); 869251881Speter else if (n->merge_range->start == n->merge_range->end - 1 870251881Speter || n->merge_range->start == n->merge_range->end) 871289180Speter SVN_ERR(svn_cmdline_printf(pool, _("--- Merging r%ld into '%s':\n"), 872289180Speter n->merge_range->end, path_local)); 873251881Speter else if (n->merge_range->start - 1 == n->merge_range->end) 874289180Speter SVN_ERR(svn_cmdline_printf(pool, 875289180Speter _("--- Reverse-merging r%ld into '%s':\n"), 876289180Speter n->merge_range->start, path_local)); 877251881Speter else if (n->merge_range->start < n->merge_range->end) 878289180Speter SVN_ERR(svn_cmdline_printf(pool, 879289180Speter _("--- Merging r%ld through r%ld into " 880289180Speter "'%s':\n"), 881289180Speter n->merge_range->start + 1, 882289180Speter n->merge_range->end, path_local)); 883251881Speter else /* n->merge_range->start > n->merge_range->end - 1 */ 884289180Speter SVN_ERR(svn_cmdline_printf(pool, 885289180Speter _("--- Reverse-merging r%ld through r%ld " 886289180Speter "into '%s':\n"), 887289180Speter n->merge_range->start, 888289180Speter 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 { 894289180Speter SVN_ERR(svn_cmdline_printf(pool, 895289180Speter _("--- Recording mergeinfo for merge " 896289180Speter "between repository URLs into '%s':\n"), 897289180Speter 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) 903289180Speter SVN_ERR(svn_cmdline_printf( 904251881Speter pool, 905251881Speter _("--- Recording mergeinfo for merge of r%ld into '%s':\n"), 906289180Speter n->merge_range->end, path_local)); 907251881Speter else if (n->merge_range->start - 1 == n->merge_range->end) 908289180Speter SVN_ERR(svn_cmdline_printf( 909251881Speter pool, 910251881Speter _("--- Recording mergeinfo for reverse merge of r%ld into '%s':\n"), 911289180Speter n->merge_range->start, path_local)); 912251881Speter else if (n->merge_range->start < n->merge_range->end) 913289180Speter SVN_ERR(svn_cmdline_printf( 914251881Speter pool, 915251881Speter _("--- Recording mergeinfo for merge of r%ld through r%ld into '%s':\n"), 916289180Speter n->merge_range->start + 1, n->merge_range->end, path_local)); 917251881Speter else /* n->merge_range->start > n->merge_range->end - 1 */ 918289180Speter SVN_ERR(svn_cmdline_printf( 919251881Speter pool, 920251881Speter _("--- Recording mergeinfo for reverse merge of r%ld through r%ld into '%s':\n"), 921289180Speter n->merge_range->start, n->merge_range->end + 1, path_local)); 922251881Speter } 923251881Speter break; 924251881Speter 925251881Speter case svn_wc_notify_merge_elide_info: 926289180Speter SVN_ERR(svn_cmdline_printf(pool, 927289180Speter _("--- Eliding mergeinfo from '%s':\n"), 928289180Speter path_local)); 929251881Speter break; 930251881Speter 931251881Speter case svn_wc_notify_foreign_merge_begin: 932251881Speter if (n->merge_range == NULL) 933289180Speter SVN_ERR(svn_cmdline_printf(pool, 934289180Speter _("--- Merging differences between " 935289180Speter "foreign repository URLs into '%s':\n"), 936289180Speter path_local)); 937251881Speter else if (n->merge_range->start == n->merge_range->end - 1 938251881Speter || n->merge_range->start == n->merge_range->end) 939289180Speter SVN_ERR(svn_cmdline_printf(pool, 940289180Speter _("--- Merging (from foreign repository) " 941289180Speter "r%ld into '%s':\n"), 942289180Speter n->merge_range->end, path_local)); 943251881Speter else if (n->merge_range->start - 1 == n->merge_range->end) 944289180Speter SVN_ERR(svn_cmdline_printf(pool, 945289180Speter _("--- Reverse-merging (from foreign " 946289180Speter "repository) r%ld into '%s':\n"), 947289180Speter n->merge_range->start, path_local)); 948251881Speter else if (n->merge_range->start < n->merge_range->end) 949289180Speter SVN_ERR(svn_cmdline_printf(pool, 950289180Speter _("--- Merging (from foreign repository) " 951289180Speter "r%ld through r%ld into '%s':\n"), 952289180Speter n->merge_range->start + 1, 953289180Speter n->merge_range->end, path_local)); 954251881Speter else /* n->merge_range->start > n->merge_range->end - 1 */ 955289180Speter SVN_ERR(svn_cmdline_printf(pool, 956289180Speter _("--- Reverse-merging (from foreign " 957289180Speter "repository) r%ld through r%ld into " 958289180Speter "'%s':\n"), 959289180Speter n->merge_range->start, 960289180Speter 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); 965289180Speter 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; 970289180Speter 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; 975289180Speter 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; 980289180Speter 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: 985289180Speter SVN_ERR(svn_cmdline_printf(pool, 986289180Speter _("property '%s' set on '%s'\n"), 987289180Speter n->prop_name, path_local)); 988251881Speter break; 989251881Speter 990251881Speter case svn_wc_notify_property_deleted: 991289180Speter SVN_ERR(svn_cmdline_printf(pool, 992289180Speter _("property '%s' deleted from '%s'.\n"), 993289180Speter n->prop_name, path_local)); 994251881Speter break; 995251881Speter 996251881Speter case svn_wc_notify_property_deleted_nonexistent: 997289180Speter SVN_ERR(svn_cmdline_printf(pool, 998289180Speter _("Attempting to delete nonexistent " 999289180Speter "property '%s' on '%s'\n"), n->prop_name, 1000289180Speter path_local)); 1001251881Speter break; 1002251881Speter 1003251881Speter case svn_wc_notify_revprop_set: 1004289180Speter SVN_ERR(svn_cmdline_printf(pool, 1005251881Speter _("property '%s' set on repository revision %ld\n"), 1006289180Speter n->prop_name, n->revision)); 1007251881Speter break; 1008251881Speter 1009251881Speter case svn_wc_notify_revprop_deleted: 1010289180Speter SVN_ERR(svn_cmdline_printf(pool, 1011251881Speter _("property '%s' deleted from repository revision %ld\n"), 1012289180Speter n->prop_name, n->revision)); 1013251881Speter break; 1014251881Speter 1015251881Speter case svn_wc_notify_upgraded_path: 1016289180Speter SVN_ERR(svn_cmdline_printf(pool, _("Upgraded '%s'\n"), path_local)); 1017251881Speter break; 1018251881Speter 1019251881Speter case svn_wc_notify_url_redirect: 1020289180Speter SVN_ERR(svn_cmdline_printf(pool, _("Redirecting to URL '%s':\n"), 1021289180Speter n->url)); 1022251881Speter break; 1023251881Speter 1024251881Speter case svn_wc_notify_path_nonexistent: 1025289180Speter SVN_ERR(svn_cmdline_printf(pool, "%s\n", 1026289180Speter apr_psprintf(pool, _("'%s' is not under version control"), 1027289180Speter 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 { 1042289180Speter SVN_ERR(svn_cmdline_printf( 1043251881Speter pool, 1044251881Speter _("--- Copying from foreign repository URL '%s':\n"), 1045289180Speter n->url)); 1046251881Speter } 1047251881Speter break; 1048251881Speter 1049251881Speter case svn_wc_notify_move_broken: 1050289180Speter SVN_ERR(svn_cmdline_printf(pool, 1051289180Speter _("Breaking move with source path '%s'\n"), 1052289180Speter path_local)); 1053251881Speter break; 1054251881Speter 1055289180Speter case svn_wc_notify_cleanup_external: 1056289180Speter SVN_ERR(svn_cmdline_printf 1057289180Speter (pool, _("Performing cleanup on external item at '%s'.\n"), 1058289180Speter path_local)); 1059289180Speter break; 1060289180Speter 1061289180Speter case svn_wc_notify_commit_finalizing: 1062289180Speter if (nb->sent_first_txdelta) 1063289180Speter { 1064289180Speter SVN_ERR(svn_cmdline_printf(pool, _("done\n"))); 1065289180Speter } 1066289180Speter SVN_ERR(svn_cmdline_printf(pool, _("Committing transaction...\n"))); 1067289180Speter break; 1068289180Speter 1069251881Speter default: 1070251881Speter break; 1071251881Speter } 1072251881Speter 1073289180Speter SVN_ERR(svn_cmdline_fflush(stdout)); 1074251881Speter 1075289180Speter return SVN_NO_ERROR; 1076289180Speter} 1077251881Speter 1078289180Speter/* This implements `svn_wc_notify_func2_t'. 1079289180Speter * NOTE: This function can't fail, so we just ignore any print errors. */ 1080289180Speterstatic void 1081289180Speternotify(void *baton, const svn_wc_notify_t *n, apr_pool_t *pool) 1082289180Speter{ 1083289180Speter struct notify_baton *nb = baton; 1084289180Speter svn_error_t *err; 1085289180Speter 1086289180Speter err = notify_body(nb, n, pool); 1087289180Speter 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. */ 1091289180Speter 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; 1120289180Speter 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