X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=git.c;h=0c40773a87b81b123b7ef3053dfd59f836b96a04;hb=4c4b158b8f31a19f724a84b11fa538bfbf465d32;hp=0b40e3060d8d95a6da7c8603317c6e2cb6c5ec46;hpb=b4a081b428c607f98c5d0a0eec8d543dc1f2abcd;p=git.git diff --git a/git.c b/git.c index 0b40e306..0c40773a 100644 --- a/git.c +++ b/git.c @@ -15,7 +15,9 @@ #include "cache.h" #include "commit.h" +#include "diff.h" #include "revision.h" +#include "log-tree.h" #ifndef PATH_MAX # define PATH_MAX 4096 @@ -172,7 +174,7 @@ static void list_commands(const char *exec_path, const char *pattern) putchar('\n'); } -static void list_common_cmds_help() +static void list_common_cmds_help(void) { int i, longest = 0; @@ -274,80 +276,103 @@ static int cmd_help(int argc, const char **argv, char **envp) return 0; } -#define LOGSIZE (65536) - -static int cmd_log(int argc, const char **argv, char **envp) +static int cmd_format_patch(int argc, const 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 "; - + struct commit **list = NULL; + struct rev_info rev; + int nr = 0; + + init_revisions(&rev); + rev.commit_format = CMIT_FMT_EMAIL; + rev.verbose_header = 1; + rev.diff = 1; + rev.diffopt.with_raw = 0; + rev.diffopt.with_stat = 1; + rev.combine_merges = 0; + rev.ignore_merges = 1; + rev.diffopt.output_format = DIFF_FORMAT_PATCH; 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, "--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) { - 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); + nr++; + list = realloc(list, nr * sizeof(list[0])); + list[nr - 1] = commit; + } + while (0 <= --nr) { + int shown; + commit = list[nr]; + shown = log_tree_commit(&rev, commit); + free(commit->buffer); + commit->buffer = NULL; + if (shown) + printf("-- \n%s\n\n", GIT_VERSION); + } + free(list); + return 0; +} + +static int cmd_log_wc(int argc, const char **argv, char **envp, + struct rev_info *rev) +{ + struct commit *commit; + + rev->abbrev = DEFAULT_ABBREV; + rev->commit_format = CMIT_FMT_DEFAULT; + rev->verbose_header = 1; + argc = setup_revisions(argc, argv, rev, "HEAD"); + + if (argc > 1) + die("unrecognized argument: %s", argv[1]); + + prepare_revision_walk(rev); + setup_pager(); + while ((commit = get_revision(rev)) != NULL) { + log_tree_commit(rev, commit); + free(commit->buffer); + commit->buffer = NULL; } - free(buf); return 0; } +static int cmd_wc(int argc, const char **argv, char **envp) +{ + struct rev_info rev; + + init_revisions(&rev); + rev.diff = 1; + rev.diffopt.recursive = 1; + 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.diffopt.recursive = 1; + rev.combine_merges = 1; + rev.dense_combined_merges = 1; + rev.always_show_header = 1; + rev.ignore_merges = 0; + rev.no_walk = 1; + 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.always_show_header = 1; + rev.diffopt.recursive = 1; + rev.combine_merges = 1; + rev.ignore_merges = 0; + 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]; @@ -358,9 +383,18 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "version", cmd_version }, { "help", cmd_help }, { "log", cmd_log }, + { "whatchanged", cmd_wc }, + { "show", cmd_show }, + { "format-patch", cmd_format_patch }, }; int i; + /* Turn "git cmd --help" into "git help cmd" */ + if (argc > 1 && !strcmp(argv[1], "--help")) { + argv[1] = argv[0]; + argv[0] = cmd = "help"; + } + for (i = 0; i < ARRAY_SIZE(commands); i++) { struct cmd_struct *p = commands+i; if (strcmp(p->cmd, cmd))