log.c revision 299742
1/* 2 * log.c : Functions for logging Subversion operations 3 * 4 * ==================================================================== 5 * Licensed to the Apache Software Foundation (ASF) under one 6 * or more contributor license agreements. See the NOTICE file 7 * distributed with this work for additional information 8 * regarding copyright ownership. The ASF licenses this file 9 * to you under the Apache License, Version 2.0 (the 10 * "License"); you may not use this file except in compliance 11 * with the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, 16 * software distributed under the License is distributed on an 17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18 * KIND, either express or implied. See the License for the 19 * specific language governing permissions and limitations 20 * under the License. 21 * ==================================================================== 22 */ 23 24 25 26 27#include <stdarg.h> 28 29#define APR_WANT_STRFUNC 30#include <apr_want.h> 31#include <apr_strings.h> 32 33#include "svn_types.h" 34#include "svn_error.h" 35#include "svn_mergeinfo.h" 36#include "svn_path.h" 37#include "svn_pools.h" 38#include "svn_string.h" 39#include "svn_hash.h" 40 41#include "private/svn_log.h" 42 43 44static const char * 45log_depth(svn_depth_t depth, apr_pool_t *pool) 46{ 47 if (depth == svn_depth_unknown) 48 return ""; 49 return apr_pstrcat(pool, " depth=", svn_depth_to_word(depth), SVN_VA_NULL); 50} 51 52static const char * 53log_include_merged_revisions(svn_boolean_t include_merged_revisions) 54{ 55 if (include_merged_revisions) 56 return " include-merged-revisions"; 57 return ""; 58} 59 60 61const char * 62svn_log__reparent(const char *path, apr_pool_t *pool) 63{ 64 return apr_psprintf(pool, "reparent %s", svn_path_uri_encode(path, pool)); 65 66} 67 68const char * 69svn_log__change_rev_prop(svn_revnum_t rev, const char *name, apr_pool_t *pool) 70{ 71 return apr_psprintf(pool, "change-rev-prop r%ld %s", rev, 72 svn_path_uri_encode(name, pool)); 73} 74 75const char * 76svn_log__rev_proplist(svn_revnum_t rev, apr_pool_t *pool) 77{ 78 return apr_psprintf(pool, "rev-proplist r%ld", rev); 79} 80 81const char * 82svn_log__rev_prop(svn_revnum_t rev, const char *name, apr_pool_t *pool) 83{ 84 return apr_psprintf(pool, "rev-prop r%ld %s", rev, 85 svn_path_uri_encode(name, pool)); 86} 87 88const char * 89svn_log__commit(svn_revnum_t rev, apr_pool_t *pool) 90{ 91 return apr_psprintf(pool, "commit r%ld", rev); 92} 93 94const char * 95svn_log__get_file(const char *path, svn_revnum_t rev, 96 svn_boolean_t want_contents, svn_boolean_t want_props, 97 apr_pool_t *pool) 98{ 99 return apr_psprintf(pool, "get-file %s r%ld%s%s", 100 svn_path_uri_encode(path, pool), rev, 101 want_contents ? " text" : "", 102 want_props ? " props" : ""); 103} 104 105const char * 106svn_log__get_dir(const char *path, svn_revnum_t rev, 107 svn_boolean_t want_contents, svn_boolean_t want_props, 108 apr_uint64_t dirent_fields, 109 apr_pool_t *pool) 110{ 111 return apr_psprintf(pool, "get-dir %s r%ld%s%s", 112 svn_path_uri_encode(path, pool), rev, 113 want_contents ? " text" : "", 114 want_props ? " props" : ""); 115} 116 117const char * 118svn_log__get_mergeinfo(const apr_array_header_t *paths, 119 svn_mergeinfo_inheritance_t inherit, 120 svn_boolean_t include_descendants, 121 apr_pool_t *pool) 122{ 123 int i; 124 apr_pool_t *iterpool = svn_pool_create(pool); 125 svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool); 126 127 for (i = 0; i < paths->nelts; i++) 128 { 129 const char *path = APR_ARRAY_IDX(paths, i, const char *); 130 svn_pool_clear(iterpool); 131 if (i != 0) 132 svn_stringbuf_appendcstr(space_separated_paths, " "); 133 svn_stringbuf_appendcstr(space_separated_paths, 134 svn_path_uri_encode(path, iterpool)); 135 } 136 svn_pool_destroy(iterpool); 137 138 return apr_psprintf(pool, "get-mergeinfo (%s) %s%s", 139 space_separated_paths->data, 140 svn_inheritance_to_word(inherit), 141 include_descendants ? " include-descendants" : ""); 142} 143 144const char * 145svn_log__checkout(const char *path, svn_revnum_t rev, svn_depth_t depth, 146 apr_pool_t *pool) 147{ 148 return apr_psprintf(pool, "checkout-or-export %s r%ld%s", 149 svn_path_uri_encode(path, pool), rev, 150 log_depth(depth, pool)); 151} 152 153const char * 154svn_log__update(const char *path, svn_revnum_t rev, svn_depth_t depth, 155 svn_boolean_t send_copyfrom_args, 156 apr_pool_t *pool) 157{ 158 return apr_psprintf(pool, "update %s r%ld%s%s", 159 svn_path_uri_encode(path, pool), rev, 160 log_depth(depth, pool), 161 (send_copyfrom_args 162 ? " send-copyfrom-args" 163 : "")); 164} 165 166const char * 167svn_log__switch(const char *path, const char *dst_path, svn_revnum_t revnum, 168 svn_depth_t depth, apr_pool_t *pool) 169{ 170 return apr_psprintf(pool, "switch %s %s@%ld%s", 171 svn_path_uri_encode(path, pool), 172 svn_path_uri_encode(dst_path, pool), revnum, 173 log_depth(depth, pool)); 174} 175 176const char * 177svn_log__status(const char *path, svn_revnum_t rev, svn_depth_t depth, 178 apr_pool_t *pool) 179{ 180 return apr_psprintf(pool, "status %s r%ld%s", 181 svn_path_uri_encode(path, pool), rev, 182 log_depth(depth, pool)); 183} 184 185const char * 186svn_log__diff(const char *path, svn_revnum_t from_revnum, 187 const char *dst_path, svn_revnum_t revnum, 188 svn_depth_t depth, svn_boolean_t ignore_ancestry, 189 apr_pool_t *pool) 190{ 191 const char *log_ignore_ancestry = (ignore_ancestry 192 ? " ignore-ancestry" 193 : ""); 194 if (strcmp(path, dst_path) == 0) 195 return apr_psprintf(pool, "diff %s r%ld:%ld%s%s", 196 svn_path_uri_encode(path, pool), from_revnum, revnum, 197 log_depth(depth, pool), log_ignore_ancestry); 198 return apr_psprintf(pool, "diff %s@%ld %s@%ld%s%s", 199 svn_path_uri_encode(path, pool), from_revnum, 200 svn_path_uri_encode(dst_path, pool), revnum, 201 log_depth(depth, pool), log_ignore_ancestry); 202} 203 204const char * 205svn_log__log(const apr_array_header_t *paths, 206 svn_revnum_t start, svn_revnum_t end, 207 int limit, svn_boolean_t discover_changed_paths, 208 svn_boolean_t strict_node_history, 209 svn_boolean_t include_merged_revisions, 210 const apr_array_header_t *revprops, apr_pool_t *pool) 211{ 212 int i; 213 apr_pool_t *iterpool = svn_pool_create(pool); 214 svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool); 215 svn_stringbuf_t *options = svn_stringbuf_create_empty(pool); 216 217 for (i = 0; i < paths->nelts; i++) 218 { 219 const char *path = APR_ARRAY_IDX(paths, i, const char *); 220 svn_pool_clear(iterpool); 221 if (i != 0) 222 svn_stringbuf_appendcstr(space_separated_paths, " "); 223 svn_stringbuf_appendcstr(space_separated_paths, 224 svn_path_uri_encode(path, iterpool)); 225 } 226 227 if (limit) 228 { 229 const char *tmp = apr_psprintf(pool, " limit=%d", limit); 230 svn_stringbuf_appendcstr(options, tmp); 231 } 232 if (discover_changed_paths) 233 svn_stringbuf_appendcstr(options, " discover-changed-paths"); 234 if (strict_node_history) 235 svn_stringbuf_appendcstr(options, " strict"); 236 if (include_merged_revisions) 237 svn_stringbuf_appendcstr(options, 238 log_include_merged_revisions(include_merged_revisions)); 239 if (revprops == NULL) 240 svn_stringbuf_appendcstr(options, " revprops=all"); 241 else if (revprops->nelts > 0) 242 { 243 svn_stringbuf_appendcstr(options, " revprops=("); 244 for (i = 0; i < revprops->nelts; i++) 245 { 246 const char *name = APR_ARRAY_IDX(revprops, i, const char *); 247 svn_pool_clear(iterpool); 248 if (i != 0) 249 svn_stringbuf_appendcstr(options, " "); 250 svn_stringbuf_appendcstr(options, svn_path_uri_encode(name, 251 iterpool)); 252 } 253 svn_stringbuf_appendcstr(options, ")"); 254 } 255 svn_pool_destroy(iterpool); 256 return apr_psprintf(pool, "log (%s) r%ld:%ld%s", 257 space_separated_paths->data, start, end, 258 options->data); 259} 260 261const char * 262svn_log__get_locations(const char *path, svn_revnum_t peg_revision, 263 const apr_array_header_t *location_revisions, 264 apr_pool_t *pool) 265{ 266 const svn_revnum_t *revision_ptr, *revision_ptr_start, *revision_ptr_end; 267 apr_pool_t *iterpool = svn_pool_create(pool); 268 svn_stringbuf_t *space_separated_revnums = svn_stringbuf_create_empty(pool); 269 270 revision_ptr_start = (const svn_revnum_t *)location_revisions->elts; 271 revision_ptr = revision_ptr_start; 272 revision_ptr_end = revision_ptr + location_revisions->nelts; 273 while (revision_ptr < revision_ptr_end) 274 { 275 svn_pool_clear(iterpool); 276 if (revision_ptr != revision_ptr_start) 277 svn_stringbuf_appendcstr(space_separated_revnums, " "); 278 svn_stringbuf_appendcstr(space_separated_revnums, 279 apr_psprintf(iterpool, "%ld", *revision_ptr)); 280 ++revision_ptr; 281 } 282 svn_pool_destroy(iterpool); 283 284 return apr_psprintf(pool, "get-locations %s@%ld (%s)", 285 svn_path_uri_encode(path, pool), 286 peg_revision, space_separated_revnums->data); 287} 288 289const char * 290svn_log__get_location_segments(const char *path, svn_revnum_t peg_revision, 291 svn_revnum_t start, svn_revnum_t end, 292 apr_pool_t *pool) 293{ 294 return apr_psprintf(pool, "get-location-segments %s@%ld r%ld:%ld", 295 svn_path_uri_encode(path, pool), 296 peg_revision, start, end); 297} 298 299const char * 300svn_log__get_file_revs(const char *path, svn_revnum_t start, svn_revnum_t end, 301 svn_boolean_t include_merged_revisions, 302 apr_pool_t *pool) 303{ 304 return apr_psprintf(pool, "get-file-revs %s r%ld:%ld%s", 305 svn_path_uri_encode(path, pool), start, end, 306 log_include_merged_revisions(include_merged_revisions)); 307} 308 309const char * 310svn_log__lock(apr_hash_t *targets, 311 svn_boolean_t steal, apr_pool_t *pool) 312{ 313 apr_hash_index_t *hi; 314 apr_pool_t *iterpool = svn_pool_create(pool); 315 svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool); 316 317 for (hi = apr_hash_first(pool, targets); hi; hi = apr_hash_next(hi)) 318 { 319 const char *path = apr_hash_this_key(hi); 320 svn_pool_clear(iterpool); 321 if (space_separated_paths->len) 322 svn_stringbuf_appendcstr(space_separated_paths, " "); 323 svn_stringbuf_appendcstr(space_separated_paths, 324 svn_path_uri_encode(path, iterpool)); 325 } 326 svn_pool_destroy(iterpool); 327 328 return apr_psprintf(pool, "lock (%s)%s", space_separated_paths->data, 329 steal ? " steal" : ""); 330} 331 332const char * 333svn_log__unlock(apr_hash_t *targets, 334 svn_boolean_t break_lock, apr_pool_t *pool) 335{ 336 apr_hash_index_t *hi; 337 apr_pool_t *iterpool = svn_pool_create(pool); 338 svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool); 339 340 for (hi = apr_hash_first(pool, targets); hi; hi = apr_hash_next(hi)) 341 { 342 const char *path = apr_hash_this_key(hi); 343 svn_pool_clear(iterpool); 344 if (space_separated_paths->len) 345 svn_stringbuf_appendcstr(space_separated_paths, " "); 346 svn_stringbuf_appendcstr(space_separated_paths, 347 svn_path_uri_encode(path, iterpool)); 348 } 349 svn_pool_destroy(iterpool); 350 351 return apr_psprintf(pool, "unlock (%s)%s", space_separated_paths->data, 352 break_lock ? " break" : ""); 353} 354 355const char * 356svn_log__lock_one_path(const char *path, svn_boolean_t steal, 357 apr_pool_t *pool) 358{ 359 apr_hash_t *paths = apr_hash_make(pool); 360 svn_hash_sets(paths, path, path); 361 return svn_log__lock(paths, steal, pool); 362} 363 364const char * 365svn_log__unlock_one_path(const char *path, svn_boolean_t break_lock, 366 apr_pool_t *pool) 367{ 368 apr_hash_t *paths = apr_hash_make(pool); 369 svn_hash_sets(paths, path, path); 370 return svn_log__unlock(paths, break_lock, pool); 371} 372 373const char * 374svn_log__replay(const char *path, svn_revnum_t rev, apr_pool_t *pool) 375{ 376 const char *log_path; 377 378 if (path && path[0] != '\0') 379 log_path = svn_path_uri_encode(path, pool); 380 else 381 log_path = "/"; 382 return apr_psprintf(pool, "replay %s r%ld", log_path, rev); 383} 384 385const char * 386svn_log__get_inherited_props(const char *path, 387 svn_revnum_t rev, 388 apr_pool_t *pool) 389{ 390 const char *log_path; 391 392 if (path && path[0] != '\0') 393 log_path = svn_path_uri_encode(path, pool); 394 else 395 log_path = "/"; 396 return apr_psprintf(pool, "get-inherited-props %s r%ld", log_path, rev); 397} 398