From 70b006b9712b57741ec1320b15aef2f8b1d6a905 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 28 Feb 2006 11:30:19 -0800 Subject: Tie it all together: "git log" This is what the previous diffs all built up to. We can do "git log" as a trivial small helper function inside git.c, because the infrastructure is all there for us to use as a library. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- git.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'git.c') diff --git a/git.c b/git.c index 993cd0d490..b0da6b1945 100644 --- a/git.c +++ b/git.c @@ -12,6 +12,10 @@ #include "git-compat-util.h" #include "exec_cmd.h" +#include "cache.h" +#include "commit.h" +#include "revision.h" + #ifndef PATH_MAX # define PATH_MAX 4096 #endif @@ -245,6 +249,25 @@ static int cmd_help(int argc, char **argv, char **envp) return 0; } +#define LOGSIZE (65536) + +static int cmd_log(int argc, char **argv, char **envp) +{ + struct rev_info rev; + struct commit *commit; + char *buf = xmalloc(LOGSIZE); + + argc = setup_revisions(argc, argv, &rev, "HEAD"); + prepare_revision_walk(&rev); + setup_pager(); + while ((commit = get_revision(&rev)) != NULL) { + pretty_print_commit(CMIT_FMT_DEFAULT, commit, ~0, buf, LOGSIZE, 18); + printf("%s\n", buf); + } + free(buf); + return 0; +} + #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) static void handle_internal_command(int argc, char **argv, char **envp) @@ -256,6 +279,7 @@ static void handle_internal_command(int argc, char **argv, char **envp) } commands[] = { { "version", cmd_version }, { "help", cmd_help }, + { "log", cmd_log }, }; int i; -- cgit v1.3 From 7ae0b0cb65f069b657155abcb6aa6780b93ce881 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 1 Mar 2006 00:58:56 -0800 Subject: git-log (internal): more options. This ports the following options from rev-list based git-log implementation: * -, -n, and -n . I am still wondering if we want this natively supported by setup_revisions(), which already takes --max-count. We may want to move them in the next round. Also I am not sure if we can get away with not setting revs->limited when we set max-count. The latest rev-list.c and revision.c in this series do not, so I left them as they are. * --pretty and --pretty=. * --abbrev= and --no-abbrev. The previous commit already handles time-based limiters (--since, --until and friends). The remaining things that rev-list based git-log happens to do are not useful in a pure log-viewing purposes, and not ported: * --bisect (obviously). * --header. I am actually in favor of doing the NUL terminated record format, but rev-list based one always passed --pretty, which defeated this option. Maybe next round. * --parents. I do not think of a reason a log viewer wants this. The flag is primarily for feeding squashed history via pipe to downstream tools. Signed-off-by: Junio C Hamano --- git.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- rev-list.c | 5 ++--- revision.h | 1 + 3 files changed, 72 insertions(+), 4 deletions(-) (limited to 'git.c') diff --git a/git.c b/git.c index b0da6b1945..bf68daca20 100644 --- a/git.c +++ b/git.c @@ -256,12 +256,80 @@ static int cmd_log(int argc, char **argv, char **envp) struct rev_info rev; struct commit *commit; char *buf = xmalloc(LOGSIZE); + static enum cmit_fmt commit_format = CMIT_FMT_DEFAULT; + int abbrev = DEFAULT_ABBREV; + int show_parents = 0; + const char *commit_prefix = "commit "; argc = setup_revisions(argc, argv, &rev, "HEAD"); + while (1 < argc) { + char *arg = argv[1]; + /* accept -, like traditilnal "head" */ + if ((*arg == '-') && isdigit(arg[1])) { + rev.max_count = atoi(arg + 1); + } + else if (!strcmp(arg, "-n")) { + if (argc < 2) + die("-n requires an argument"); + rev.max_count = atoi(argv[2]); + argc--; argv++; + } + else if (!strncmp(arg,"-n",2)) { + rev.max_count = atoi(arg + 2); + } + else if (!strncmp(arg, "--pretty", 8)) { + commit_format = get_commit_format(arg + 8); + if (commit_format == CMIT_FMT_ONELINE) + commit_prefix = ""; + } + else if (!strcmp(arg, "--parents")) { + show_parents = 1; + } + else if (!strcmp(arg, "--no-abbrev")) { + abbrev = 0; + } + 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 + die("unrecognized argument: %s", arg); + argc--; argv++; + } + prepare_revision_walk(&rev); setup_pager(); while ((commit = get_revision(&rev)) != NULL) { - pretty_print_commit(CMIT_FMT_DEFAULT, commit, ~0, buf, LOGSIZE, 18); + printf("%s%s", commit_prefix, + sha1_to_hex(commit->object.sha1)); + if (show_parents) { + struct commit_list *parents = commit->parents; + while (parents) { + struct object *o = &(parents->item->object); + parents = parents->next; + if (o->flags & TMP_MARK) + continue; + printf(" %s", sha1_to_hex(o->sha1)); + o->flags |= TMP_MARK; + } + /* TMP_MARK is a general purpose flag that can + * be used locally, but the user should clean + * things up after it is done with them. + */ + for (parents = commit->parents; + parents; + parents = parents->next) + parents->item->object.flags &= ~TMP_MARK; + } + if (commit_format == CMIT_FMT_ONELINE) + putchar(' '); + else + putchar('\n'); + pretty_print_commit(commit_format, commit, ~0, buf, + LOGSIZE, abbrev); printf("%s\n", buf); } free(buf); diff --git a/rev-list.c b/rev-list.c index 6af8d869ee..8e4d83efba 100644 --- a/rev-list.c +++ b/rev-list.c @@ -7,10 +7,9 @@ #include "diff.h" #include "revision.h" -/* bits #0-3 in revision.h */ +/* bits #0-4 in revision.h */ -#define COUNTED (1u << 4) -#define TMP_MARK (1u << 5) /* for isolated cases; clean after use */ +#define COUNTED (1u<<5) static const char rev_list_usage[] = "git-rev-list [OPTION] ... [ -- paths... ]\n" diff --git a/revision.h b/revision.h index 0043c1694c..31e8f61567 100644 --- a/revision.h +++ b/revision.h @@ -5,6 +5,7 @@ #define UNINTERESTING (1u<<1) #define TREECHANGE (1u<<2) #define SHOWN (1u<<3) +#define TMP_MARK (1u<<4) /* for isolated cases; clean after use */ struct rev_info { /* Starting list */ -- cgit v1.3 From 64bc6e3db54ef9e2accfdb8e6c8168f789946fcb Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 2 Mar 2006 15:24:01 -0800 Subject: setup_revisions(): handle -n and - internally. This moves the handling of max-count shorthand from the internal implementation of "git log" to setup_revisions() so other users of setup_revisions() can use it. Signed-off-by: Junio C Hamano --- git.c | 15 +-------------- revision.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'git.c') diff --git a/git.c b/git.c index bf68daca20..a547dbd913 100644 --- a/git.c +++ b/git.c @@ -264,20 +264,7 @@ static int cmd_log(int argc, char **argv, char **envp) argc = setup_revisions(argc, argv, &rev, "HEAD"); while (1 < argc) { char *arg = argv[1]; - /* accept -, like traditilnal "head" */ - if ((*arg == '-') && isdigit(arg[1])) { - rev.max_count = atoi(arg + 1); - } - else if (!strcmp(arg, "-n")) { - if (argc < 2) - die("-n requires an argument"); - rev.max_count = atoi(argv[2]); - argc--; argv++; - } - else if (!strncmp(arg,"-n",2)) { - rev.max_count = atoi(arg + 2); - } - else if (!strncmp(arg, "--pretty", 8)) { + if (!strncmp(arg, "--pretty", 8)) { commit_format = get_commit_format(arg + 8); if (commit_format == CMIT_FMT_ONELINE) commit_prefix = ""; diff --git a/revision.c b/revision.c index 4885871425..a3df810076 100644 --- a/revision.c +++ b/revision.c @@ -482,6 +482,21 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch revs->max_count = atoi(arg + 12); continue; } + /* accept -, like traditilnal "head" */ + if ((*arg == '-') && isdigit(arg[1])) { + revs->max_count = atoi(arg + 1); + continue; + } + if (!strcmp(arg, "-n")) { + if (argc <= i + 1) + 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 (!strncmp(arg, "--max-age=", 10)) { revs->max_age = atoi(arg + 10); revs->limited = 1; -- cgit v1.3