Git fork
at reftables-rust 963 lines 25 kB view raw
1#define USE_THE_REPOSITORY_VARIABLE 2#define DISABLE_SIGN_COMPARE_WARNINGS 3 4#include "builtin.h" 5#include "config.h" 6#include "commit.h" 7#include "diff.h" 8#include "environment.h" 9#include "gettext.h" 10#include "hex.h" 11#include "revision.h" 12#include "list-objects.h" 13#include "list-objects-filter-options.h" 14#include "object.h" 15#include "object-name.h" 16#include "object-file.h" 17#include "odb.h" 18#include "pack-bitmap.h" 19#include "parse-options.h" 20#include "log-tree.h" 21#include "graph.h" 22#include "bisect.h" 23#include "progress.h" 24#include "reflog-walk.h" 25#include "oidset.h" 26#include "oidmap.h" 27#include "packfile.h" 28#include "quote.h" 29#include "strbuf.h" 30 31struct rev_list_info { 32 struct rev_info *revs; 33 int flags; 34 int show_timestamp; 35 int hdr_termination; 36 const char *header_prefix; 37}; 38 39static const char rev_list_usage[] = 40"git rev-list [<options>] <commit>... [--] [<path>...]\n" 41"\n" 42" limiting output:\n" 43" --max-count=<n>\n" 44" --max-age=<epoch>\n" 45" --min-age=<epoch>\n" 46" --sparse\n" 47" --no-merges\n" 48" --min-parents=<n>\n" 49" --no-min-parents\n" 50" --max-parents=<n>\n" 51" --no-max-parents\n" 52" --remove-empty\n" 53" --all\n" 54" --branches\n" 55" --tags\n" 56" --remotes\n" 57" --stdin\n" 58" --exclude-hidden=[fetch|receive|uploadpack]\n" 59" --quiet\n" 60" ordering output:\n" 61" --topo-order\n" 62" --date-order\n" 63" --reverse\n" 64" formatting output:\n" 65" --parents\n" 66" --children\n" 67" --objects | --objects-edge\n" 68" --disk-usage[=human]\n" 69" --unpacked\n" 70" --header | --pretty\n" 71" --[no-]object-names\n" 72" --abbrev=<n> | --no-abbrev\n" 73" --abbrev-commit\n" 74" --left-right\n" 75" --count\n" 76" -z\n" 77" special purpose:\n" 78" --bisect\n" 79" --bisect-vars\n" 80" --bisect-all" 81; 82 83static struct progress *progress; 84static unsigned progress_counter; 85 86static struct oidset omitted_objects; 87static int arg_print_omitted; /* print objects omitted by filter */ 88 89struct missing_objects_map_entry { 90 struct oidmap_entry entry; 91 const char *path; 92 unsigned type; 93}; 94static struct oidmap missing_objects; 95enum missing_action { 96 MA_ERROR = 0, /* fail if any missing objects are encountered */ 97 MA_ALLOW_ANY, /* silently allow ALL missing objects */ 98 MA_PRINT, /* print ALL missing objects in special section */ 99 MA_PRINT_INFO, /* same as MA_PRINT but also prints missing object info */ 100 MA_ALLOW_PROMISOR, /* silently allow all missing PROMISOR objects */ 101}; 102static enum missing_action arg_missing_action; 103 104/* display only the oid of each object encountered */ 105static int arg_show_object_names = 1; 106 107#define DEFAULT_OIDSET_SIZE (16*1024) 108 109static char line_term = '\n'; 110static char info_term = ' '; 111 112static int show_disk_usage; 113static off_t total_disk_usage; 114static int human_readable; 115 116static off_t get_object_disk_usage(struct object *obj) 117{ 118 off_t size; 119 struct object_info oi = OBJECT_INFO_INIT; 120 oi.disk_sizep = &size; 121 if (odb_read_object_info_extended(the_repository->objects, 122 &obj->oid, &oi, 0) < 0) 123 die(_("unable to get disk usage of %s"), oid_to_hex(&obj->oid)); 124 return size; 125} 126 127static void add_missing_object_entry(struct object_id *oid, const char *path, 128 unsigned type) 129{ 130 struct missing_objects_map_entry *entry; 131 132 if (oidmap_get(&missing_objects, oid)) 133 return; 134 135 CALLOC_ARRAY(entry, 1); 136 entry->entry.oid = *oid; 137 entry->type = type; 138 if (path) 139 entry->path = xstrdup(path); 140 oidmap_put(&missing_objects, entry); 141} 142 143static void print_missing_object(struct missing_objects_map_entry *entry, 144 int print_missing_info) 145{ 146 struct strbuf sb = STRBUF_INIT; 147 148 if (line_term) 149 printf("?%s", oid_to_hex(&entry->entry.oid)); 150 else 151 printf("%s%cmissing=yes", oid_to_hex(&entry->entry.oid), 152 info_term); 153 154 if (!print_missing_info) { 155 putchar(line_term); 156 return; 157 } 158 159 if (entry->path && *entry->path) { 160 strbuf_addf(&sb, "%cpath=", info_term); 161 162 if (line_term) { 163 struct strbuf path = STRBUF_INIT; 164 165 quote_path(entry->path, NULL, &path, QUOTE_PATH_QUOTE_SP); 166 strbuf_addbuf(&sb, &path); 167 168 strbuf_release(&path); 169 } else { 170 strbuf_addstr(&sb, entry->path); 171 } 172 } 173 if (entry->type) 174 strbuf_addf(&sb, "%ctype=%s", info_term, type_name(entry->type)); 175 176 fwrite(sb.buf, sizeof(char), sb.len, stdout); 177 putchar(line_term); 178 179 strbuf_release(&sb); 180} 181 182static inline void finish_object__ma(struct object *obj, const char *name) 183{ 184 /* 185 * Whether or not we try to dynamically fetch missing objects 186 * from the server, we currently DO NOT have the object. We 187 * can either print, allow (ignore), or conditionally allow 188 * (ignore) them. 189 */ 190 switch (arg_missing_action) { 191 case MA_ERROR: 192 die("missing %s object '%s'", 193 type_name(obj->type), oid_to_hex(&obj->oid)); 194 return; 195 196 case MA_ALLOW_ANY: 197 return; 198 199 case MA_PRINT: 200 case MA_PRINT_INFO: 201 add_missing_object_entry(&obj->oid, name, obj->type); 202 return; 203 204 case MA_ALLOW_PROMISOR: 205 if (is_promisor_object(the_repository, &obj->oid)) 206 return; 207 die("unexpected missing %s object '%s'", 208 type_name(obj->type), oid_to_hex(&obj->oid)); 209 return; 210 211 default: 212 BUG("unhandled missing_action"); 213 return; 214 } 215} 216 217static void finish_commit(struct commit *commit) 218{ 219 free_commit_list(commit->parents); 220 commit->parents = NULL; 221 free_commit_buffer(the_repository->parsed_objects, 222 commit); 223} 224 225static void show_commit(struct commit *commit, void *data) 226{ 227 struct rev_list_info *info = data; 228 struct rev_info *revs = info->revs; 229 230 display_progress(progress, ++progress_counter); 231 232 if (revs->do_not_die_on_missing_objects && 233 oidset_contains(&revs->missing_commits, &commit->object.oid)) { 234 finish_object__ma(&commit->object, NULL); 235 return; 236 } 237 238 if (show_disk_usage) 239 total_disk_usage += get_object_disk_usage(&commit->object); 240 241 if (info->flags & REV_LIST_QUIET) { 242 finish_commit(commit); 243 return; 244 } 245 246 graph_show_commit(revs->graph); 247 248 if (revs->count) { 249 if (commit->object.flags & PATCHSAME) 250 revs->count_same++; 251 else if (commit->object.flags & SYMMETRIC_LEFT) 252 revs->count_left++; 253 else 254 revs->count_right++; 255 finish_commit(commit); 256 return; 257 } 258 259 if (info->show_timestamp) 260 printf("%"PRItime" ", commit->date); 261 if (info->header_prefix) 262 fputs(info->header_prefix, stdout); 263 264 if (revs->include_header) { 265 if (!revs->graph && line_term) 266 fputs(get_revision_mark(revs, commit), stdout); 267 if (revs->abbrev_commit && revs->abbrev) 268 fputs(repo_find_unique_abbrev(the_repository, &commit->object.oid, revs->abbrev), 269 stdout); 270 else 271 fputs(oid_to_hex(&commit->object.oid), stdout); 272 273 if (!line_term) { 274 if (commit->object.flags & BOUNDARY) 275 printf("%cboundary=yes", info_term); 276 } 277 } 278 if (revs->print_parents) { 279 struct commit_list *parents = commit->parents; 280 while (parents) { 281 printf(" %s", oid_to_hex(&parents->item->object.oid)); 282 parents = parents->next; 283 } 284 } 285 if (revs->children.name) { 286 struct commit_list *children; 287 288 children = lookup_decoration(&revs->children, &commit->object); 289 while (children) { 290 printf(" %s", oid_to_hex(&children->item->object.oid)); 291 children = children->next; 292 } 293 } 294 show_decorations(revs, commit); 295 if (revs->commit_format == CMIT_FMT_ONELINE) 296 putchar(' '); 297 else if (revs->include_header) 298 putchar(line_term); 299 300 if (revs->verbose_header) { 301 struct strbuf buf = STRBUF_INIT; 302 struct pretty_print_context ctx = {0}; 303 ctx.abbrev = revs->abbrev; 304 ctx.date_mode = revs->date_mode; 305 ctx.date_mode_explicit = revs->date_mode_explicit; 306 ctx.fmt = revs->commit_format; 307 ctx.output_encoding = get_log_output_encoding(); 308 ctx.color = revs->diffopt.use_color; 309 ctx.rev = revs; 310 pretty_print_commit(&ctx, commit, &buf); 311 if (buf.len) { 312 if (revs->commit_format != CMIT_FMT_ONELINE) 313 graph_show_oneline(revs->graph); 314 315 graph_show_commit_msg(revs->graph, stdout, &buf); 316 317 /* 318 * Add a newline after the commit message. 319 * 320 * Usually, this newline produces a blank 321 * padding line between entries, in which case 322 * we need to add graph padding on this line. 323 * 324 * However, the commit message may not end in a 325 * newline. In this case the newline simply 326 * ends the last line of the commit message, 327 * and we don't need any graph output. (This 328 * always happens with CMIT_FMT_ONELINE, and it 329 * happens with CMIT_FMT_USERFORMAT when the 330 * format doesn't explicitly end in a newline.) 331 */ 332 if (buf.len && buf.buf[buf.len - 1] == '\n') 333 graph_show_padding(revs->graph); 334 putchar(info->hdr_termination); 335 } else { 336 /* 337 * If the message buffer is empty, just show 338 * the rest of the graph output for this 339 * commit. 340 */ 341 if (graph_show_remainder(revs->graph)) 342 putchar('\n'); 343 if (revs->commit_format == CMIT_FMT_ONELINE) 344 putchar('\n'); 345 } 346 strbuf_release(&buf); 347 } else { 348 if (graph_show_remainder(revs->graph)) 349 putchar('\n'); 350 } 351 maybe_flush_or_die(stdout, "stdout"); 352 finish_commit(commit); 353} 354 355static int finish_object(struct object *obj, const char *name, void *cb_data) 356{ 357 struct rev_list_info *info = cb_data; 358 if (odb_read_object_info_extended(the_repository->objects, 359 &obj->oid, NULL, 0) < 0) { 360 finish_object__ma(obj, name); 361 return 1; 362 } 363 if (info->revs->verify_objects && !obj->parsed && obj->type != OBJ_COMMIT) 364 parse_object(the_repository, &obj->oid); 365 return 0; 366} 367 368static void show_object(struct object *obj, const char *name, void *cb_data) 369{ 370 struct rev_list_info *info = cb_data; 371 struct rev_info *revs = info->revs; 372 373 if (finish_object(obj, name, cb_data)) 374 return; 375 display_progress(progress, ++progress_counter); 376 if (show_disk_usage) 377 total_disk_usage += get_object_disk_usage(obj); 378 if (info->flags & REV_LIST_QUIET) 379 return; 380 381 if (revs->count) { 382 /* 383 * The object count is always accumulated in the .count_right 384 * field for traversal that is not a left-right traversal, 385 * and cmd_rev_list() made sure that a .count request that 386 * wants to count non-commit objects, which is handled by 387 * the show_object() callback, does not ask for .left_right. 388 */ 389 revs->count_right++; 390 return; 391 } 392 393 printf("%s", oid_to_hex(&obj->oid)); 394 395 if (arg_show_object_names) { 396 if (line_term) { 397 putchar(info_term); 398 for (const char *p = name; *p && *p != '\n'; p++) 399 putchar(*p); 400 } else if (*name) { 401 printf("%cpath=%s", info_term, name); 402 } 403 } 404 405 putchar(line_term); 406} 407 408static void show_edge(struct commit *commit) 409{ 410 printf("-%s\n", oid_to_hex(&commit->object.oid)); 411} 412 413static void print_var_str(const char *var, const char *val) 414{ 415 printf("%s='%s'\n", var, val); 416} 417 418static void print_var_int(const char *var, int val) 419{ 420 printf("%s=%d\n", var, val); 421} 422 423static int show_bisect_vars(struct rev_list_info *info, int reaches, int all) 424{ 425 int cnt, flags = info->flags; 426 char hex[GIT_MAX_HEXSZ + 1] = ""; 427 struct commit_list *tried; 428 struct rev_info *revs = info->revs; 429 430 if (!revs->commits) 431 return 1; 432 433 revs->commits = filter_skipped(revs->commits, &tried, 434 flags & BISECT_SHOW_ALL, 435 NULL, NULL); 436 437 /* 438 * revs->commits can reach "reaches" commits among 439 * "all" commits. If it is good, then there are 440 * (all-reaches) commits left to be bisected. 441 * On the other hand, if it is bad, then the set 442 * to bisect is "reaches". 443 * A bisect set of size N has (N-1) commits further 444 * to test, as we already know one bad one. 445 */ 446 cnt = all - reaches; 447 if (cnt < reaches) 448 cnt = reaches; 449 450 if (revs->commits) 451 oid_to_hex_r(hex, &revs->commits->item->object.oid); 452 453 if (flags & BISECT_SHOW_ALL) { 454 traverse_commit_list(revs, show_commit, show_object, info); 455 printf("------\n"); 456 } 457 458 print_var_str("bisect_rev", hex); 459 print_var_int("bisect_nr", cnt - 1); 460 print_var_int("bisect_good", all - reaches - 1); 461 print_var_int("bisect_bad", reaches - 1); 462 print_var_int("bisect_all", all); 463 print_var_int("bisect_steps", estimate_bisect_steps(all)); 464 465 return 0; 466} 467 468static int show_object_fast( 469 const struct object_id *oid, 470 enum object_type type UNUSED, 471 int exclude UNUSED, 472 uint32_t name_hash UNUSED, 473 struct packed_git *found_pack UNUSED, 474 off_t found_offset UNUSED, 475 void *payload UNUSED) 476{ 477 fprintf(stdout, "%s\n", oid_to_hex(oid)); 478 return 1; 479} 480 481static void print_disk_usage(off_t size) 482{ 483 struct strbuf sb = STRBUF_INIT; 484 if (human_readable) 485 strbuf_humanise_bytes(&sb, size); 486 else 487 strbuf_addf(&sb, "%"PRIuMAX, (uintmax_t)size); 488 puts(sb.buf); 489 strbuf_release(&sb); 490} 491 492static inline int parse_missing_action_value(const char *value) 493{ 494 if (!strcmp(value, "error")) { 495 arg_missing_action = MA_ERROR; 496 return 1; 497 } 498 499 if (!strcmp(value, "allow-any")) { 500 arg_missing_action = MA_ALLOW_ANY; 501 fetch_if_missing = 0; 502 return 1; 503 } 504 505 if (!strcmp(value, "print")) { 506 arg_missing_action = MA_PRINT; 507 fetch_if_missing = 0; 508 return 1; 509 } 510 511 if (!strcmp(value, "print-info")) { 512 arg_missing_action = MA_PRINT_INFO; 513 fetch_if_missing = 0; 514 return 1; 515 } 516 517 if (!strcmp(value, "allow-promisor")) { 518 arg_missing_action = MA_ALLOW_PROMISOR; 519 fetch_if_missing = 0; 520 return 1; 521 } 522 523 return 0; 524} 525 526static int try_bitmap_count(struct rev_info *revs, 527 int filter_provided_objects) 528{ 529 uint32_t commit_count = 0, 530 tag_count = 0, 531 tree_count = 0, 532 blob_count = 0; 533 int max_count; 534 struct bitmap_index *bitmap_git; 535 536 /* This function only handles counting, not general traversal. */ 537 if (!revs->count) 538 return -1; 539 540 /* 541 * A bitmap result can't know left/right, etc, because we don't 542 * actually traverse. 543 */ 544 if (revs->left_right || revs->cherry_mark) 545 return -1; 546 547 /* 548 * If we're counting reachable objects, we can't handle a max count of 549 * commits to traverse, since we don't know which objects go with which 550 * commit. 551 */ 552 if (revs->max_count >= 0 && 553 (revs->tag_objects || revs->tree_objects || revs->blob_objects)) 554 return -1; 555 556 /* 557 * This must be saved before doing any walking, since the revision 558 * machinery will count it down to zero while traversing. 559 */ 560 max_count = revs->max_count; 561 562 bitmap_git = prepare_bitmap_walk(revs, filter_provided_objects); 563 if (!bitmap_git) 564 return -1; 565 566 count_bitmap_commit_list(bitmap_git, &commit_count, 567 revs->tree_objects ? &tree_count : NULL, 568 revs->blob_objects ? &blob_count : NULL, 569 revs->tag_objects ? &tag_count : NULL); 570 if (max_count >= 0 && max_count < commit_count) 571 commit_count = max_count; 572 573 printf("%d\n", commit_count + tree_count + blob_count + tag_count); 574 free_bitmap_index(bitmap_git); 575 return 0; 576} 577 578static int try_bitmap_traversal(struct rev_info *revs, 579 int filter_provided_objects) 580{ 581 struct bitmap_index *bitmap_git; 582 583 /* 584 * We can't use a bitmap result with a traversal limit, since the set 585 * of commits we'd get would be essentially random. 586 */ 587 if (revs->max_count >= 0) 588 return -1; 589 590 /* 591 * We can't know which commits were left/right in a single traversal, 592 * and we don't yet know how to traverse them separately. 593 */ 594 if (revs->left_right) 595 return -1; 596 597 bitmap_git = prepare_bitmap_walk(revs, filter_provided_objects); 598 if (!bitmap_git) 599 return -1; 600 601 traverse_bitmap_commit_list(bitmap_git, revs, &show_object_fast); 602 free_bitmap_index(bitmap_git); 603 return 0; 604} 605 606static int try_bitmap_disk_usage(struct rev_info *revs, 607 int filter_provided_objects) 608{ 609 struct bitmap_index *bitmap_git; 610 off_t size_from_bitmap; 611 612 if (!show_disk_usage) 613 return -1; 614 615 bitmap_git = prepare_bitmap_walk(revs, filter_provided_objects); 616 if (!bitmap_git) 617 return -1; 618 619 size_from_bitmap = get_disk_usage_from_bitmap(bitmap_git, revs); 620 print_disk_usage(size_from_bitmap); 621 622 free_bitmap_index(bitmap_git); 623 return 0; 624} 625 626int cmd_rev_list(int argc, 627 const char **argv, 628 const char *prefix, 629 struct repository *repo UNUSED) 630{ 631 struct rev_info revs; 632 struct rev_list_info info; 633 struct setup_revision_opt s_r_opt = { 634 .allow_exclude_promisor_objects = 1, 635 }; 636 int i; 637 int bisect_list = 0; 638 int bisect_show_vars = 0; 639 int bisect_find_all = 0; 640 int use_bitmap_index = 0; 641 int filter_provided_objects = 0; 642 const char *show_progress = NULL; 643 int ret = 0; 644 645 show_usage_if_asked(argc, argv, rev_list_usage); 646 647 repo_config(the_repository, git_default_config, NULL); 648 repo_init_revisions(the_repository, &revs, prefix); 649 revs.abbrev = DEFAULT_ABBREV; 650 revs.commit_format = CMIT_FMT_UNSPECIFIED; 651 revs.include_header = 1; 652 653 /* 654 * Scan the argument list before invoking setup_revisions(), so that we 655 * know if fetch_if_missing needs to be set to 0. 656 * 657 * "--exclude-promisor-objects" acts as a pre-filter on missing objects 658 * by not crossing the boundary from realized objects to promisor 659 * objects. 660 * 661 * Let "--missing" to conditionally set fetch_if_missing. 662 */ 663 664 /* 665 * NEEDSWORK: The next loop is utterly broken. It tries to 666 * notice an option is used, but without understanding if each 667 * option takes an argument, which fundamentally would not 668 * work. It would not know "--grep 669 * --exclude-promisor-objects" is not triggering 670 * "--exclude-promisor-objects" option, for example. 671 * 672 * We really need setup_revisions() to have a mechanism to 673 * allow and disallow some sets of options for different 674 * commands (like rev-list, replay, etc). Such a mechanism 675 * should do an early parsing of options and be able to manage 676 * the `--missing=...` and `--exclude-promisor-objects` 677 * options below. 678 */ 679 for (i = 1; i < argc; i++) { 680 const char *arg = argv[i]; 681 if (!strcmp(arg, "--exclude-promisor-objects")) { 682 fetch_if_missing = 0; 683 revs.exclude_promisor_objects = 1; 684 } else if (skip_prefix(arg, "--missing=", &arg)) { 685 parse_missing_action_value(arg); 686 } else if (!strcmp(arg, "-z")) { 687 line_term = '\0'; 688 info_term = '\0'; 689 } 690 } 691 692 die_for_incompatible_opt2(revs.exclude_promisor_objects, 693 "--exclude_promisor_objects", 694 arg_missing_action, "--missing"); 695 696 if (arg_missing_action) 697 revs.do_not_die_on_missing_objects = 1; 698 699 argc = setup_revisions(argc, argv, &revs, &s_r_opt); 700 701 memset(&info, 0, sizeof(info)); 702 info.revs = &revs; 703 if (revs.bisect) 704 bisect_list = 1; 705 706 if (revs.diffopt.flags.quick) 707 info.flags |= REV_LIST_QUIET; 708 for (i = 1 ; i < argc; i++) { 709 const char *arg = argv[i]; 710 711 if (!strcmp(arg, "--header")) { 712 revs.verbose_header = 1; 713 continue; 714 } 715 if (!strcmp(arg, "--timestamp")) { 716 info.show_timestamp = 1; 717 continue; 718 } 719 if (!strcmp(arg, "--bisect")) { 720 bisect_list = 1; 721 continue; 722 } 723 if (!strcmp(arg, "--bisect-all")) { 724 bisect_list = 1; 725 bisect_find_all = 1; 726 info.flags |= BISECT_SHOW_ALL; 727 revs.show_decorations = 1; 728 continue; 729 } 730 if (!strcmp(arg, "--bisect-vars")) { 731 bisect_list = 1; 732 bisect_show_vars = 1; 733 continue; 734 } 735 if (!strcmp(arg, "--use-bitmap-index")) { 736 use_bitmap_index = 1; 737 continue; 738 } 739 if (!strcmp(arg, "--test-bitmap")) { 740 test_bitmap_walk(&revs); 741 goto cleanup; 742 } 743 if (skip_prefix(arg, "--progress=", &arg)) { 744 show_progress = arg; 745 continue; 746 } 747 if (!strcmp(arg, "--filter-provided-objects")) { 748 filter_provided_objects = 1; 749 continue; 750 } 751 if (!strcmp(arg, "--filter-print-omitted")) { 752 arg_print_omitted = 1; 753 continue; 754 } 755 756 if (!strcmp(arg, "--exclude-promisor-objects")) 757 continue; /* already handled above */ 758 if (skip_prefix(arg, "--missing=", &arg)) 759 continue; /* already handled above */ 760 761 if (!strcmp(arg, ("--no-object-names"))) { 762 arg_show_object_names = 0; 763 continue; 764 } 765 766 if (!strcmp(arg, ("--object-names"))) { 767 arg_show_object_names = 1; 768 continue; 769 } 770 771 if (!strcmp(arg, ("--commit-header"))) { 772 revs.include_header = 1; 773 continue; 774 } 775 776 if (!strcmp(arg, ("--no-commit-header"))) { 777 revs.include_header = 0; 778 continue; 779 } 780 781 if (skip_prefix(arg, "--disk-usage", &arg)) { 782 if (*arg == '=') { 783 if (!strcmp(++arg, "human")) { 784 human_readable = 1; 785 } else 786 die(_("invalid value for '%s': '%s', the only allowed format is '%s'"), 787 "--disk-usage=<format>", arg, "human"); 788 } else if (*arg) { 789 /* 790 * Arguably should goto a label to continue chain of ifs? 791 * Doesn't matter unless we try to add --disk-usage-foo 792 * afterwards. 793 */ 794 usage(rev_list_usage); 795 } 796 show_disk_usage = 1; 797 info.flags |= REV_LIST_QUIET; 798 continue; 799 } 800 801 usage(rev_list_usage); 802 803 } 804 805 /* 806 * Reject options currently incompatible with -z. For some options, this 807 * is not an inherent limitation and support may be implemented in the 808 * future. 809 */ 810 if (!line_term) { 811 if (revs.graph || revs.verbose_header || show_disk_usage || 812 info.show_timestamp || info.header_prefix || bisect_list || 813 use_bitmap_index || revs.edge_hint || revs.left_right || 814 revs.cherry_mark) 815 die(_("-z option used with unsupported option")); 816 } 817 818 if (revs.commit_format != CMIT_FMT_USERFORMAT) 819 revs.include_header = 1; 820 if (revs.commit_format != CMIT_FMT_UNSPECIFIED) { 821 /* The command line has a --pretty */ 822 info.hdr_termination = '\n'; 823 if (revs.commit_format == CMIT_FMT_ONELINE || !revs.include_header) 824 info.header_prefix = ""; 825 else 826 info.header_prefix = "commit "; 827 } 828 else if (revs.verbose_header) 829 /* Only --header was specified */ 830 revs.commit_format = CMIT_FMT_RAW; 831 832 if ((!revs.commits && reflog_walk_empty(revs.reflog_info) && 833 (!(revs.tag_objects || revs.tree_objects || revs.blob_objects) && 834 !revs.pending.nr) && 835 !revs.rev_input_given && !revs.read_from_stdin) || 836 revs.diff) 837 usage(rev_list_usage); 838 839 if (revs.show_notes) 840 die(_("rev-list does not support display of notes")); 841 842 if (revs.count && 843 (revs.tag_objects || revs.tree_objects || revs.blob_objects) && 844 (revs.left_right || revs.cherry_mark)) 845 die(_("marked counting and '%s' cannot be used together"), "--objects"); 846 847 save_commit_buffer = (revs.verbose_header || 848 revs.grep_filter.pattern_list || 849 revs.grep_filter.header_list); 850 if (bisect_list) 851 revs.limited = 1; 852 853 if (show_progress) 854 progress = start_delayed_progress(the_repository, 855 show_progress, 0); 856 857 if (use_bitmap_index) { 858 if (!try_bitmap_count(&revs, filter_provided_objects)) 859 goto cleanup; 860 if (!try_bitmap_disk_usage(&revs, filter_provided_objects)) 861 goto cleanup; 862 if (!try_bitmap_traversal(&revs, filter_provided_objects)) 863 goto cleanup; 864 } 865 866 if (prepare_revision_walk(&revs)) 867 die("revision walk setup failed"); 868 if (revs.tree_objects) 869 mark_edges_uninteresting(&revs, show_edge, 0); 870 871 if (bisect_list) { 872 int reaches, all; 873 unsigned bisect_flags = 0; 874 875 if (bisect_find_all) 876 bisect_flags |= FIND_BISECTION_ALL; 877 878 if (revs.first_parent_only) 879 bisect_flags |= FIND_BISECTION_FIRST_PARENT_ONLY; 880 881 find_bisection(&revs.commits, &reaches, &all, bisect_flags); 882 883 if (bisect_show_vars) { 884 ret = show_bisect_vars(&info, reaches, all); 885 goto cleanup; 886 } 887 } 888 889 if (filter_provided_objects) { 890 struct commit_list *c; 891 for (i = 0; i < revs.pending.nr; i++) { 892 struct object_array_entry *pending = revs.pending.objects + i; 893 pending->item->flags |= NOT_USER_GIVEN; 894 } 895 for (c = revs.commits; c; c = c->next) 896 c->item->object.flags |= NOT_USER_GIVEN; 897 } 898 899 if (arg_print_omitted) 900 oidset_init(&omitted_objects, DEFAULT_OIDSET_SIZE); 901 if (arg_missing_action == MA_PRINT || 902 arg_missing_action == MA_PRINT_INFO) { 903 struct oidset_iter iter; 904 struct object_id *oid; 905 906 oidmap_init(&missing_objects, DEFAULT_OIDSET_SIZE); 907 oidset_iter_init(&revs.missing_commits, &iter); 908 909 /* Add missing tips */ 910 while ((oid = oidset_iter_next(&iter))) 911 add_missing_object_entry(oid, NULL, 0); 912 913 oidset_clear(&revs.missing_commits); 914 } 915 916 traverse_commit_list_filtered( 917 &revs, show_commit, show_object, &info, 918 (arg_print_omitted ? &omitted_objects : NULL)); 919 920 if (arg_print_omitted) { 921 struct oidset_iter iter; 922 struct object_id *oid; 923 oidset_iter_init(&omitted_objects, &iter); 924 while ((oid = oidset_iter_next(&iter))) 925 printf("~%s\n", oid_to_hex(oid)); 926 oidset_clear(&omitted_objects); 927 } 928 if (arg_missing_action == MA_PRINT || 929 arg_missing_action == MA_PRINT_INFO) { 930 struct missing_objects_map_entry *entry; 931 struct oidmap_iter iter; 932 933 oidmap_iter_init(&missing_objects, &iter); 934 935 while ((entry = oidmap_iter_next(&iter))) { 936 print_missing_object(entry, arg_missing_action == 937 MA_PRINT_INFO); 938 free((void *)entry->path); 939 } 940 941 oidmap_clear(&missing_objects, true); 942 } 943 944 stop_progress(&progress); 945 946 if (revs.count) { 947 if (revs.left_right && revs.cherry_mark) 948 printf("%d\t%d\t%d\n", revs.count_left, revs.count_right, revs.count_same); 949 else if (revs.left_right) 950 printf("%d\t%d\n", revs.count_left, revs.count_right); 951 else if (revs.cherry_mark) 952 printf("%d\t%d\n", revs.count_left + revs.count_right, revs.count_same); 953 else 954 printf("%d\n", revs.count_left + revs.count_right); 955 } 956 957 if (show_disk_usage) 958 print_disk_usage(total_disk_usage); 959 960cleanup: 961 release_revisions(&revs); 962 return ret; 963}