From f4235f8b2ef875b85ead74ffa199d827f9ee9d8d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 15 Apr 2006 03:16:46 -0700 Subject: [PATCH] Extract "log [diff options]" parser out. Merging of the log-tree-opt structure with rev-info structure did not work out very well and it broke things that did not want diff options and/or rev options. This is an alternative approach to define a combined interface that can be used by commands that wants both. The use of it is opt-in to reduce the risk of breaking existing programs. We might want to slurp "setup_revisions() places things in pending objects list" part from Linus's earlier attempt. Signed-off-by: Junio C Hamano --- git.c | 96 ++++++++++++++------------------------------------------------ log-tree.c | 65 ++++++++++++++++++++++++++++++++++++++++++ log-tree.h | 14 +++++++++ 3 files changed, 100 insertions(+), 75 deletions(-) diff --git a/git.c b/git.c index 78ed403ed..0741c5a36 100644 --- a/git.c +++ b/git.c @@ -280,89 +280,35 @@ static int cmd_help(int argc, const char **argv, char **envp) static int cmd_log(int argc, const char **argv, char **envp) { - struct rev_info rev; + struct whatchanged_opt wcopt; struct commit *commit; char *buf = xmalloc(LOGSIZE); - static enum cmit_fmt commit_format = CMIT_FMT_DEFAULT; - int abbrev = DEFAULT_ABBREV; - int abbrev_commit = 0; const char *commit_prefix = "commit "; - struct log_tree_opt opt; int shown = 0; - int do_diff = 0; - int full_diff = 0; - - init_log_tree_opt(&opt); - argc = setup_revisions(argc, argv, &rev, "HEAD"); - while (1 < argc) { - const char *arg = argv[1]; - if (!strncmp(arg, "--pretty", 8)) { - commit_format = get_commit_format(arg + 8); - if (commit_format == CMIT_FMT_ONELINE) - commit_prefix = ""; - } - else if (!strcmp(arg, "--no-abbrev")) { - abbrev = 0; - } - else if (!strcmp(arg, "--abbrev")) { - abbrev = DEFAULT_ABBREV; - } - else if (!strcmp(arg, "--abbrev-commit")) { - abbrev_commit = 1; - } - else if (!strncmp(arg, "--abbrev=", 9)) { - abbrev = strtoul(arg + 9, NULL, 10); - if (abbrev && abbrev < MINIMUM_ABBREV) - abbrev = MINIMUM_ABBREV; - else if (40 < abbrev) - abbrev = 40; - } - else if (!strcmp(arg, "--full-diff")) { - do_diff = 1; - full_diff = 1; - } - else { - int cnt = log_tree_opt_parse(&opt, argv+1, argc-1); - if (0 < cnt) { - do_diff = 1; - argv += cnt; - argc -= cnt; - continue; - } - die("unrecognized argument: %s", arg); - } + struct rev_info *rev = &wcopt.revopt; + struct log_tree_opt *opt = &wcopt.logopt; - argc--; argv++; - } + init_log_tree_opt(&wcopt.logopt); + wcopt.commit_format = CMIT_FMT_DEFAULT; + wcopt.abbrev = DEFAULT_ABBREV; + argc = parse_whatchanged_opt(argc, argv, &wcopt); - if (do_diff) { - opt.diffopt.abbrev = abbrev; - opt.verbose_header = 0; - opt.always_show_header = 0; - opt.no_commit_id = 1; - if (opt.combine_merges) - opt.ignore_merges = 0; - if (opt.dense_combined_merges) - opt.diffopt.output_format = DIFF_FORMAT_PATCH; - if (opt.diffopt.output_format == DIFF_FORMAT_PATCH) - opt.diffopt.recursive = 1; - if (!full_diff && rev.prune_data) - diff_tree_setup_paths(rev.prune_data, &opt.diffopt); - diff_setup_done(&opt.diffopt); - } + if (wcopt.logopt.commit_format == CMIT_FMT_ONELINE) + commit_prefix = ""; - prepare_revision_walk(&rev); + prepare_revision_walk(rev); setup_pager(); - while ((commit = get_revision(&rev)) != NULL) { - if (shown && do_diff && commit_format != CMIT_FMT_ONELINE) + while ((commit = get_revision(rev)) != NULL) { + if (shown && wcopt.do_diff && + wcopt.commit_format != CMIT_FMT_ONELINE) putchar('\n'); fputs(commit_prefix, stdout); - if (abbrev_commit && abbrev) - fputs(find_unique_abbrev(commit->object.sha1, abbrev), + if (wcopt.abbrev_commit && wcopt.abbrev) + fputs(find_unique_abbrev(commit->object.sha1, wcopt.abbrev), stdout); else fputs(sha1_to_hex(commit->object.sha1), stdout); - if (rev.parents) { + if (rev->parents) { struct commit_list *parents = commit->parents; while (parents) { struct object *o = &(parents->item->object); @@ -381,15 +327,15 @@ static int cmd_log(int argc, const char **argv, char **envp) parents = parents->next) parents->item->object.flags &= ~TMP_MARK; } - if (commit_format == CMIT_FMT_ONELINE) + if (wcopt.commit_format == CMIT_FMT_ONELINE) putchar(' '); else putchar('\n'); - pretty_print_commit(commit_format, commit, ~0, buf, - LOGSIZE, abbrev); + pretty_print_commit(wcopt.commit_format, commit, ~0, buf, + LOGSIZE, wcopt.abbrev); printf("%s\n", buf); - if (do_diff) - log_tree_commit(&opt, commit); + if (wcopt.do_diff) + log_tree_commit(opt, commit); shown = 1; free(commit->buffer); commit->buffer = NULL; diff --git a/log-tree.c b/log-tree.c index 3d404824a..cb0d0b15e 100644 --- a/log-tree.c +++ b/log-tree.c @@ -173,3 +173,68 @@ int log_tree_commit(struct log_tree_opt *opt, struct commit *commit) } return 0; } + +int parse_whatchanged_opt(int ac, const char **av, struct whatchanged_opt *wcopt) +{ + struct rev_info *rev = &wcopt->revopt; + struct log_tree_opt *opt = &wcopt->logopt; + const char **unrecognized = av+1; + int left = 1; + + ac = setup_revisions(ac, av, rev, "HEAD"); + while (1 < ac) { + const char *arg = av[1]; + if (!strncmp(arg, "--pretty", 8)) { + opt->commit_format = get_commit_format(arg + 8); + } + else if (!strcmp(arg, "--no-abbrev")) { + wcopt->abbrev = 0; + } + else if (!strcmp(arg, "--abbrev")) { + wcopt->abbrev = DEFAULT_ABBREV; + } + else if (!strcmp(arg, "--abbrev-commit")) { + wcopt->abbrev_commit = 1; + } + else if (!strncmp(arg, "--abbrev=", 9)) { + wcopt->abbrev = strtoul(arg + 9, NULL, 10); + if (wcopt->abbrev && wcopt->abbrev < MINIMUM_ABBREV) + wcopt->abbrev = MINIMUM_ABBREV; + else if (40 < wcopt->abbrev) + wcopt->abbrev = 40; + } + else if (!strcmp(arg, "--full-diff")) { + wcopt->do_diff = 1; + wcopt->full_diff = 1; + } + else { + int cnt = log_tree_opt_parse(opt, av+1, ac-1); + if (0 < cnt) { + wcopt->do_diff = 1; + av += cnt; + ac -= cnt; + continue; + } + *unrecognized++ = arg; + left++; + } + ac--; av++; + } + + if (wcopt->do_diff) { + opt->diffopt.abbrev = wcopt->abbrev; + opt->verbose_header = 0; + opt->always_show_header = 0; + opt->no_commit_id = 1; + if (opt->combine_merges) + opt->ignore_merges = 0; + if (opt->dense_combined_merges) + opt->diffopt.output_format = DIFF_FORMAT_PATCH; + if (opt->diffopt.output_format == DIFF_FORMAT_PATCH) + opt->diffopt.recursive = 1; + if (!wcopt->full_diff && rev->prune_data) + diff_tree_setup_paths(rev->prune_data, &opt->diffopt); + diff_setup_done(&opt->diffopt); + } + return left; +} diff --git a/log-tree.h b/log-tree.h index da166c6f2..50cbfb301 100644 --- a/log-tree.h +++ b/log-tree.h @@ -1,6 +1,8 @@ #ifndef LOG_TREE_H #define LOG_TREE_H +#include "revision.h" + struct log_tree_opt { struct diff_options diffopt; int show_root_diff; @@ -20,4 +22,16 @@ int log_tree_diff_flush(struct log_tree_opt *); int log_tree_commit(struct log_tree_opt *, struct commit *); int log_tree_opt_parse(struct log_tree_opt *, const char **, int); +struct whatchanged_opt { + struct rev_info revopt; + struct log_tree_opt logopt; + enum cmit_fmt commit_format; + int abbrev; + int abbrev_commit; + int do_diff; + int full_diff; +}; + +int parse_whatchanged_opt(int, const char **, struct whatchanged_opt *); + #endif -- 2.11.0