From 6b9c58f4669b3832ed2830f0cb1a307ea6bc6063 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 15 Apr 2006 23:46:36 -0700 Subject: [PATCH 1/4] Split init_revisions() out of setup_revisions() Merging all three option parsers related to whatchanged is unarguably the right thing, but the fallout was too big to scare me away. Let's try it once again, but once step at time. This splits out init_revisions() call from setup_revisions(), so that the callers can set different defaults to match the traditional benaviour. The rev-list command is still broken in a big way, which is the topic of next step. Signed-off-by: Junio C Hamano --- commit.h | 2 ++ diff-tree.c | 1 + git.c | 1 + http-push.c | 1 + revision.c | 6 +----- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/commit.h b/commit.h index 918c9ab5e4..de142afe73 100644 --- a/commit.h +++ b/commit.h @@ -45,6 +45,8 @@ enum cmit_fmt { CMIT_FMT_FULL, CMIT_FMT_FULLER, CMIT_FMT_ONELINE, + + CMIT_FMT_UNSPECIFIED, }; extern enum cmit_fmt get_commit_format(const char *arg); diff --git a/diff-tree.c b/diff-tree.c index 979f792b67..e578798537 100644 --- a/diff-tree.c +++ b/diff-tree.c @@ -69,6 +69,7 @@ int main(int argc, const char **argv) git_config(git_diff_config); nr_sha1 = 0; + init_revisions(opt); opt->abbrev = 0; argc = setup_revisions(argc, argv, opt, NULL); diff --git a/git.c b/git.c index 9d885569d8..d172626230 100644 --- a/git.c +++ b/git.c @@ -286,6 +286,7 @@ static int cmd_log(int argc, const char **argv, char **envp) const char *commit_prefix = "commit "; int shown = 0; + init_revisions(&rev); rev.abbrev = DEFAULT_ABBREV; argc = setup_revisions(argc, argv, &rev, "HEAD"); if (argc > 1) diff --git a/http-push.c b/http-push.c index 19a0f772e7..4a9dcf2bf6 100644 --- a/http-push.c +++ b/http-push.c @@ -2498,6 +2498,7 @@ int main(int argc, char **argv) commit_argv[3] = old_sha1_hex; commit_argc++; } + init_revisions(&revs); setup_revisions(commit_argc, commit_argv, &revs, NULL); free(new_sha1_hex); if (old_sha1_hex) { diff --git a/revision.c b/revision.c index bdf8005aec..9693b6e4c7 100644 --- a/revision.c +++ b/revision.c @@ -475,11 +475,9 @@ static void handle_all(struct rev_info *revs, unsigned flags) void init_revisions(struct rev_info *revs) { - unsigned abbrev = revs->abbrev; - memset(revs, 0, sizeof(*revs)); - revs->abbrev = abbrev; + revs->abbrev = DEFAULT_ABBREV; revs->ignore_merges = 1; revs->pruning.recursive = 1; revs->pruning.add_remove = file_add_remove; @@ -516,8 +514,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch const char **unrecognized = argv + 1; int left = 1; - init_revisions(revs); - /* First, search for "--" */ seen_dashdash = 0; for (i = 1; i < argc; i++) { From 7594c4b2d7cc81f806453402aefe1bf71ae6dd53 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 15 Apr 2006 23:48:27 -0700 Subject: [PATCH 2/4] rev-list option parser fix. The big option parser unification broke rev-list the big way; this makes it use options from the parsed revs structure. Signed-off-by: Junio C Hamano --- rev-list.c | 82 +++++++++++++++--------------------------------------- 1 file changed, 23 insertions(+), 59 deletions(-) diff --git a/rev-list.c b/rev-list.c index 0de21810c9..000f27a8fe 100644 --- a/rev-list.c +++ b/rev-list.c @@ -39,24 +39,20 @@ static const char rev_list_usage[] = struct rev_info revs; static int bisect_list = 0; -static int verbose_header = 0; -static int abbrev = DEFAULT_ABBREV; -static int abbrev_commit = 0; static int show_timestamp = 0; static int hdr_termination = 0; -static const char *commit_prefix = ""; -static enum cmit_fmt commit_format = CMIT_FMT_RAW; static void show_commit(struct commit *commit) { if (show_timestamp) printf("%lu ", commit->date); - if (commit_prefix[0]) - fputs(commit_prefix, stdout); + if (*revs.header_prefix) + fputs(revs.header_prefix, stdout); if (commit->object.flags & BOUNDARY) putchar('-'); - if (abbrev_commit && abbrev) - fputs(find_unique_abbrev(commit->object.sha1, abbrev), stdout); + if (revs.abbrev_commit && revs.abbrev) + fputs(find_unique_abbrev(commit->object.sha1, revs.abbrev), + stdout); else fputs(sha1_to_hex(commit->object.sha1), stdout); if (revs.parents) { @@ -78,14 +74,16 @@ static void show_commit(struct commit *commit) parents = parents->next) parents->item->object.flags &= ~TMP_MARK; } - if (commit_format == CMIT_FMT_ONELINE) + if (revs.commit_format == CMIT_FMT_ONELINE) putchar(' '); else putchar('\n'); - if (verbose_header) { + if (revs.verbose_header) { static char pretty_header[16384]; - pretty_print_commit(commit_format, commit, ~0, pretty_header, sizeof(pretty_header), abbrev); + pretty_print_commit(revs.commit_format, commit, ~0, + pretty_header, sizeof(pretty_header), + revs.abbrev); printf("%s%c", pretty_header, hdr_termination); } fflush(stdout); @@ -297,58 +295,16 @@ int main(int argc, const char **argv) struct commit_list *list; int i; + init_revisions(&revs); + revs.abbrev = 0; + revs.commit_format = CMIT_FMT_UNSPECIFIED; argc = setup_revisions(argc, argv, &revs, NULL); for (i = 1 ; i < argc; i++) { const char *arg = argv[i]; - /* accept -, like traditilnal "head" */ - if ((*arg == '-') && isdigit(arg[1])) { - revs.max_count = atoi(arg + 1); - continue; - } - if (!strcmp(arg, "-n")) { - if (++i >= argc) - die("-n requires an argument"); - revs.max_count = atoi(argv[i]); - continue; - } - if (!strncmp(arg,"-n",2)) { - revs.max_count = atoi(arg + 2); - continue; - } if (!strcmp(arg, "--header")) { - verbose_header = 1; - continue; - } - if (!strcmp(arg, "--no-abbrev")) { - abbrev = 0; - continue; - } - if (!strcmp(arg, "--abbrev")) { - abbrev = DEFAULT_ABBREV; - continue; - } - if (!strcmp(arg, "--abbrev-commit")) { - abbrev_commit = 1; - continue; - } - 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; - continue; - } - if (!strncmp(arg, "--pretty", 8)) { - commit_format = get_commit_format(arg+8); - verbose_header = 1; - hdr_termination = '\n'; - if (commit_format == CMIT_FMT_ONELINE) - commit_prefix = ""; - else - commit_prefix = "commit "; + revs.verbose_header = 1; continue; } if (!strcmp(arg, "--timestamp")) { @@ -362,6 +318,14 @@ int main(int argc, const char **argv) usage(rev_list_usage); } + if (revs.commit_format != CMIT_FMT_UNSPECIFIED) { + /* The command line has a --pretty */ + hdr_termination = '\n'; + if (revs.commit_format == CMIT_FMT_ONELINE) + revs.header_prefix = ""; + else + revs.header_prefix = "commit "; + } list = revs.commits; @@ -371,7 +335,7 @@ int main(int argc, const char **argv) revs.diff) usage(rev_list_usage); - save_commit_buffer = verbose_header; + save_commit_buffer = revs.verbose_header; track_object_refs = 0; prepare_revision_walk(&revs); From 5b84f4d87a1bd58c7540e9ea82ee3673ecddbad5 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 16 Apr 2006 00:07:41 -0700 Subject: [PATCH 3/4] Built-in git-whatchanged. Split internal "git log" into reusable piece and add "git whatchanged". This is based on the option parsing unification work Linus did. Signed-off-by: Junio C Hamano --- git.c | 62 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/git.c b/git.c index d172626230..9a89b0afbd 100644 --- a/git.c +++ b/git.c @@ -278,36 +278,33 @@ static int cmd_help(int argc, const char **argv, char **envp) #define LOGSIZE (65536) -static int cmd_log(int argc, const char **argv, char **envp) +static int cmd_log_wc(int argc, const char **argv, char **envp, + struct rev_info *rev) { - struct rev_info rev; struct commit *commit; char *buf = xmalloc(LOGSIZE); const char *commit_prefix = "commit "; int shown = 0; - init_revisions(&rev); - rev.abbrev = DEFAULT_ABBREV; - argc = setup_revisions(argc, argv, &rev, "HEAD"); if (argc > 1) die("unrecognized argument: %s", argv[1]); - - rev.no_commit_id = 1; - if (rev.commit_format == CMIT_FMT_ONELINE) + if (rev->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 && rev.diff && rev.commit_format != CMIT_FMT_ONELINE) + while ((commit = get_revision(rev)) != NULL) { + if (shown && rev->diff && + rev->commit_format != CMIT_FMT_ONELINE) putchar('\n'); fputs(commit_prefix, stdout); - if (rev.abbrev_commit && rev.abbrev) - fputs(find_unique_abbrev(commit->object.sha1, rev.abbrev), + if (rev->abbrev_commit && rev->abbrev) + fputs(find_unique_abbrev(commit->object.sha1, + rev->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); @@ -326,15 +323,15 @@ static int cmd_log(int argc, const char **argv, char **envp) parents = parents->next) parents->item->object.flags &= ~TMP_MARK; } - if (rev.commit_format == CMIT_FMT_ONELINE) + if (rev->commit_format == CMIT_FMT_ONELINE) putchar(' '); else putchar('\n'); - pretty_print_commit(rev.commit_format, commit, ~0, buf, - LOGSIZE, rev.abbrev); + pretty_print_commit(rev->commit_format, commit, ~0, buf, + LOGSIZE, rev->abbrev); printf("%s\n", buf); - if (rev.diff) - log_tree_commit(&rev, commit); + if (rev->diff) + log_tree_commit(rev, commit); shown = 1; free(commit->buffer); commit->buffer = NULL; @@ -343,6 +340,32 @@ static int cmd_log(int argc, const char **argv, char **envp) return 0; } +static int cmd_wc(int argc, const char **argv, char **envp) +{ + struct rev_info rev; + + init_revisions(&rev); + rev.abbrev = DEFAULT_ABBREV; + rev.no_commit_id = 1; + rev.commit_format = CMIT_FMT_DEFAULT; + rev.diff = 1; + rev.diffopt.recursive = 1; + argc = setup_revisions(argc, argv, &rev, "HEAD"); + return cmd_log_wc(argc, argv, envp, &rev); +} + +static int cmd_log(int argc, const char **argv, char **envp) +{ + struct rev_info rev; + + init_revisions(&rev); + rev.abbrev = DEFAULT_ABBREV; + rev.no_commit_id = 1; + rev.commit_format = CMIT_FMT_DEFAULT; + argc = setup_revisions(argc, argv, &rev, "HEAD"); + return cmd_log_wc(argc, argv, envp, &rev); +} + static void handle_internal_command(int argc, const char **argv, char **envp) { const char *cmd = argv[0]; @@ -353,6 +376,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "version", cmd_version }, { "help", cmd_help }, { "log", cmd_log }, + { "whatchanged", cmd_wc }, }; int i; From ba1d45051e050cbcf68ccccacea86a4b6ecde731 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 15 Apr 2006 12:09:56 -0700 Subject: [PATCH 4/4] Tentative built-in "git show" This uses the "--no-walk" flag that I never actually implemented (but I'm sure I mentioned it) to make "git show" be essentially the same thing as "git whatchanged --no-walk". It just refuses to add more interesting parents to the revision walking history, so you don't actually get any history, you just get the commit you asked for. I was going to add "--no-walk" as a real argument flag to git-rev-list too, but I'm not sure anybody actually needs it. Although it might be useful for porcelain, so I left the door open. [jc: ported to the unified option structure by Linus] Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- git.c | 18 ++++++++++++++++++ revision.c | 5 +++++ revision.h | 1 + 3 files changed, 24 insertions(+) diff --git a/git.c b/git.c index 9a89b0afbd..9e29ade2b4 100644 --- a/git.c +++ b/git.c @@ -354,6 +354,23 @@ static int cmd_wc(int argc, const char **argv, char **envp) return cmd_log_wc(argc, argv, envp, &rev); } +static int cmd_show(int argc, const char **argv, char **envp) +{ + struct rev_info rev; + + init_revisions(&rev); + rev.diff = 1; + rev.ignore_merges = 0; + rev.combine_merges = 1; + rev.dense_combined_merges = 1; + rev.abbrev = DEFAULT_ABBREV; + rev.commit_format = CMIT_FMT_DEFAULT; + rev.diffopt.recursive = 1; + rev.no_walk = 1; + argc = setup_revisions(argc, argv, &rev, "HEAD"); + return cmd_log_wc(argc, argv, envp, &rev); +} + static int cmd_log(int argc, const char **argv, char **envp) { struct rev_info rev; @@ -377,6 +394,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "help", cmd_help }, { "log", cmd_log }, { "whatchanged", cmd_wc }, + { "show", cmd_show }, }; int i; diff --git a/revision.c b/revision.c index 9693b6e4c7..f8fb028855 100644 --- a/revision.c +++ b/revision.c @@ -380,6 +380,9 @@ static void add_parents_to_list(struct rev_info *revs, struct commit *commit, st if (revs->prune_fn) revs->prune_fn(revs, commit); + if (revs->no_walk) + return; + parent = commit->parents; while (parent) { struct commit *p = parent->item; @@ -816,6 +819,8 @@ void prepare_revision_walk(struct rev_info *revs) list = list->next; } + if (revs->no_walk) + return; if (revs->limited) limit_list(revs); if (revs->topo_order) diff --git a/revision.h b/revision.h index 6eaa9048a9..7b854866b2 100644 --- a/revision.h +++ b/revision.h @@ -26,6 +26,7 @@ struct rev_info { /* Traversal flags */ unsigned int dense:1, no_merges:1, + no_walk:1, remove_empty_trees:1, lifo:1, topo_order:1,