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