X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=builtin-log.c;h=e1f1cf67143721933010065130adaba8723b272b;hb=faf8280850e9af4ef63decd8d4e65a7609544c21;hp=e8b982db7cf7c98bff9d64affcb573b3d9676cb1;hpb=2e13e5d89252ceef606a0a7be32dbf5bea7e5aca;p=git.git diff --git a/builtin-log.c b/builtin-log.c index e8b982db7..e1f1cf671 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -55,13 +55,13 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix, rev->abbrev = DEFAULT_ABBREV; rev->commit_format = CMIT_FMT_DEFAULT; rev->verbose_header = 1; - rev->diffopt.recursive = 1; + DIFF_OPT_SET(&rev->diffopt, RECURSIVE); rev->show_root_diff = default_show_root; rev->subject_prefix = fmt_patch_subject_prefix; argc = setup_revisions(argc, argv, rev, "HEAD"); if (rev->diffopt.pickaxe || rev->diffopt.filter) rev->always_show_header = 0; - if (rev->diffopt.follow_renames) { + if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) { rev->always_show_header = 0; if (rev->diffopt.nr_paths != 1) usage("git logs can only follow renames on one pathname at a time"); @@ -77,11 +77,134 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix, } } +/* + * This gives a rough estimate for how many commits we + * will print out in the list. + */ +static int estimate_commit_count(struct rev_info *rev, struct commit_list *list) +{ + int n = 0; + + while (list) { + struct commit *commit = list->item; + unsigned int flags = commit->object.flags; + list = list->next; + if (!(flags & (TREESAME | UNINTERESTING))) + n++; + } + return n; +} + +static void show_early_header(struct rev_info *rev, const char *stage, int nr) +{ + if (rev->shown_one) { + rev->shown_one = 0; + if (rev->commit_format != CMIT_FMT_ONELINE) + putchar(rev->diffopt.line_termination); + } + printf("Final output: %d %s\n", nr, stage); +} + +struct itimerval early_output_timer; + +static void log_show_early(struct rev_info *revs, struct commit_list *list) +{ + int i = revs->early_output; + int show_header = 1; + + sort_in_topological_order(&list, revs->lifo); + while (list && i) { + struct commit *commit = list->item; + switch (simplify_commit(revs, commit)) { + case commit_show: + if (show_header) { + int n = estimate_commit_count(revs, list); + show_early_header(revs, "incomplete", n); + show_header = 0; + } + log_tree_commit(revs, commit); + i--; + break; + case commit_ignore: + break; + case commit_error: + return; + } + list = list->next; + } + + /* Did we already get enough commits for the early output? */ + if (!i) + return; + + /* + * ..if no, then repeat it twice a second until we + * do. + * + * NOTE! We don't use "it_interval", because if the + * reader isn't listening, we want our output to be + * throttled by the writing, and not have the timer + * trigger every second even if we're blocked on a + * reader! + */ + early_output_timer.it_value.tv_sec = 0; + early_output_timer.it_value.tv_usec = 500000; + setitimer(ITIMER_REAL, &early_output_timer, NULL); +} + +static void early_output(int signal) +{ + show_early_output = log_show_early; +} + +static void setup_early_output(struct rev_info *rev) +{ + struct sigaction sa; + + /* + * Set up the signal handler, minimally intrusively: + * we only set a single volatile integer word (not + * using sigatomic_t - trying to avoid unnecessary + * system dependencies and headers), and using + * SA_RESTART. + */ + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = early_output; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sigaction(SIGALRM, &sa, NULL); + + /* + * If we can get the whole output in less than a + * tenth of a second, don't even bother doing the + * early-output thing.. + * + * This is a one-time-only trigger. + */ + early_output_timer.it_value.tv_sec = 0; + early_output_timer.it_value.tv_usec = 100000; + setitimer(ITIMER_REAL, &early_output_timer, NULL); +} + +static void finish_early_output(struct rev_info *rev) +{ + int n = estimate_commit_count(rev, rev->commits); + signal(SIGALRM, SIG_IGN); + show_early_header(rev, "done", n); +} + static int cmd_log_walk(struct rev_info *rev) { struct commit *commit; + if (rev->early_output) + setup_early_output(rev); + prepare_revision_walk(rev); + + if (rev->early_output) + finish_early_output(rev); + while ((commit = get_revision(rev)) != NULL) { log_tree_commit(rev, commit); if (!rev->reflog_info) { @@ -185,11 +308,9 @@ int cmd_show(int argc, const char **argv, const char *prefix) struct tag *t = (struct tag *)o; printf("%stag %s%s\n\n", - diff_get_color(rev.diffopt.color_diff, - DIFF_COMMIT), + diff_get_color_opt(&rev.diffopt, DIFF_COMMIT), t->tag, - diff_get_color(rev.diffopt.color_diff, - DIFF_RESET)); + diff_get_color_opt(&rev.diffopt, DIFF_RESET)); ret = show_object(o->sha1, 1); objects[i].item = (struct object *)t->tagged; i--; @@ -197,11 +318,9 @@ int cmd_show(int argc, const char **argv, const char *prefix) } case OBJ_TREE: printf("%stree %s%s\n\n", - diff_get_color(rev.diffopt.color_diff, - DIFF_COMMIT), + diff_get_color_opt(&rev.diffopt, DIFF_COMMIT), name, - diff_get_color(rev.diffopt.color_diff, - DIFF_RESET)); + diff_get_color_opt(&rev.diffopt, DIFF_RESET)); read_tree_recursive((struct tree *)o, "", 0, 0, NULL, show_tree_object); break; @@ -273,6 +392,8 @@ static int istitlechar(char c) static char *extra_headers = NULL; static int extra_headers_size = 0; static const char *fmt_patch_suffix = ".patch"; +static int numbered = 0; +static int auto_number = 0; static int git_format_config(const char *var, const char *value) { @@ -297,6 +418,15 @@ static int git_format_config(const char *var, const char *value) if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) { return 0; } + if (!strcmp(var, "format.numbered")) { + if (!strcasecmp(value, "auto")) { + auto_number = 1; + return 0; + } + + numbered = git_config_bool(var, value); + return 0; + } return git_log_config(var, value); } @@ -466,7 +596,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) struct rev_info rev; int nr = 0, total, i, j; int use_stdout = 0; - int numbered = 0; int start_number = -1; int keep_subject = 0; int numbered_files = 0; /* _just_ numbers */ @@ -487,7 +616,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.combine_merges = 0; rev.ignore_merges = 1; rev.diffopt.msg_sep = ""; - rev.diffopt.recursive = 1; + DIFF_OPT_SET(&rev.diffopt, RECURSIVE); rev.subject_prefix = fmt_patch_subject_prefix; rev.extra_headers = extra_headers; @@ -503,6 +632,11 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--numbered")) numbered = 1; + else if (!strcmp(argv[i], "-N") || + !strcmp(argv[i], "--no-numbered")) { + numbered = 0; + auto_number = 0; + } else if (!prefixcmp(argv[i], "--start-number=")) start_number = strtol(argv[i] + 15, NULL, 10); else if (!strcmp(argv[i], "--numbered-files")) @@ -590,8 +724,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH; - if (!rev.diffopt.text) - rev.diffopt.binary = 1; + if (!DIFF_OPT_TST(&rev.diffopt, TEXT)) + DIFF_OPT_SET(&rev.diffopt, BINARY); if (!output_directory && !use_stdout) output_directory = prefix; @@ -642,6 +776,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) list[nr - 1] = commit; } total = nr; + if (!keep_subject && auto_number && total > 1) + numbered = 1; if (numbered) rev.total = total + start_number - 1; rev.add_signoff = add_signoff; @@ -747,7 +883,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix) revs.diff = 1; revs.combine_merges = 0; revs.ignore_merges = 1; - revs.diffopt.recursive = 1; + DIFF_OPT_SET(&revs.diffopt, RECURSIVE); if (add_pending_commit(head, &revs, 0)) die("Unknown commit %s", head); @@ -787,7 +923,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix) struct strbuf buf; strbuf_init(&buf, 0); pretty_print_commit(CMIT_FMT_ONELINE, commit, - &buf, 0, NULL, NULL, 0); + &buf, 0, NULL, NULL, 0, 0); printf("%c %s %s\n", sign, sha1_to_hex(commit->object.sha1), buf.buf); strbuf_release(&buf);