X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=builtin-log.c;h=f4d974a7b8bfa0472a110273edf62b34b90902fe;hb=e968751573a4ded76201a0e4414ec36649a92dda;hp=53a47c9aa4b9de6a1a3457847175db766360c6f9;hpb=2448482b3d5e265dd29fa38c3827565f6f2f31ec;p=git.git diff --git a/builtin-log.c b/builtin-log.c index 53a47c9a..f4d974a7 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -11,6 +11,9 @@ #include "log-tree.h" #include "builtin.h" +/* this is in builtin-diff.c */ +void add_head(struct rev_info *revs); + static int cmd_log_wc(int argc, const char **argv, char **envp, struct rev_info *rev) { @@ -20,6 +23,13 @@ static int cmd_log_wc(int argc, const char **argv, char **envp, rev->commit_format = CMIT_FMT_DEFAULT; rev->verbose_header = 1; argc = setup_revisions(argc, argv, rev, "HEAD"); + if (rev->always_show_header) { + if (rev->diffopt.pickaxe || rev->diffopt.filter) { + rev->always_show_header = 0; + if (rev->diffopt.output_format == DIFF_FORMAT_RAW) + rev->diffopt.output_format = DIFF_FORMAT_NO_OUTPUT; + } + } if (argc > 1) die("unrecognized argument: %s", argv[1]); @@ -41,6 +51,7 @@ int cmd_whatchanged(int argc, const char **argv, char **envp) init_revisions(&rev); rev.diff = 1; rev.diffopt.recursive = 1; + rev.simplify_history = 0; return cmd_log_wc(argc, argv, envp, &rev); } @@ -75,17 +86,34 @@ static int istitlechar(char c) (c >= '0' && c <= '9') || c == '.' || c == '_'; } +static char *extra_headers = NULL; +static int extra_headers_size = 0; + +static int git_format_config(const char *var, const char *value) +{ + if (!strcmp(var, "format.headers")) { + int len = strlen(value); + extra_headers_size += len + 1; + extra_headers = realloc(extra_headers, extra_headers_size); + extra_headers[extra_headers_size - len - 1] = 0; + strcat(extra_headers, value); + return 0; + } + return git_default_config(var, value); +} + + static FILE *realstdout = NULL; -static char *output_directory = NULL; +static const char *output_directory = NULL; -static void reopen_stdout(struct commit *commit, int nr) +static void reopen_stdout(struct commit *commit, int nr, int keep_subject) { char filename[1024]; char *sol; int len = 0; if (output_directory) { - strncpy(filename, output_directory, 1010); + safe_strncpy(filename, output_directory, 1010); len = strlen(filename); if (filename[len - 1] != '/') filename[len++] = '/'; @@ -100,7 +128,7 @@ static void reopen_stdout(struct commit *commit, int nr) sol += 2; /* strip [PATCH] or [PATCH blabla] */ - if (!strncmp(sol, "[PATCH", 6)) { + if (!keep_subject && !strncmp(sol, "[PATCH", 6)) { char *eos = strchr(sol + 6, ']'); if (eos) { while (isspace(*eos)) @@ -137,6 +165,10 @@ int cmd_format_patch(int argc, const char **argv, char **envp) 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; + char *add_signoff = NULL; init_revisions(&rev); rev.commit_format = CMIT_FMT_EMAIL; @@ -148,6 +180,9 @@ int cmd_format_patch(int argc, const char **argv, char **envp) rev.ignore_merges = 1; rev.diffopt.output_format = DIFF_FORMAT_PATCH; + git_config(git_format_config); + rev.extra_headers = extra_headers; + /* * Parse the arguments before setup_revisions(), or something * like "git fmt-patch -o a123 HEAD^.." may fail; a123 is @@ -156,23 +191,72 @@ int cmd_format_patch(int argc, const char **argv, char **envp) for (i = 1, j = 1; i < argc; i++) { if (!strcmp(argv[i], "--stdout")) use_stdout = 1; - else if (!strcmp(argv[i], "-o")) { - if (argc < 3) - die ("Which directory?"); - if (mkdir(argv[i + 1], 0777) < 0 && errno != EEXIST) - die("Could not create directory %s", - argv[i + 1]); - output_directory = strdup(argv[i + 1]); + else if (!strcmp(argv[i], "-n") || + !strcmp(argv[i], "--numbered")) + numbered = 1; + else if (!strncmp(argv[i], "--start-number=", 15)) + start_number = strtol(argv[i] + 15, NULL, 10); + else if (!strcmp(argv[i], "--start-number")) { + i++; + if (i == argc) + die("Need a number for --start-number"); + start_number = strtol(argv[i], NULL, 10); + } + else if (!strcmp(argv[i], "-k") || + !strcmp(argv[i], "--keep-subject")) { + keep_subject = 1; + rev.total = -1; + } + else if (!strcmp(argv[i], "--output-directory") || + !strcmp(argv[i], "-o")) { i++; - } else + if (argc <= i) + die("Which directory?"); + if (output_directory) + die("Two output directories?"); + output_directory = argv[i]; + } + else if (!strcmp(argv[i], "--signoff") || + !strcmp(argv[i], "-s")) { + const char *committer = git_committer_info(1); + const char *endpos = strchr(committer, '>'); + if (!endpos) + die("bogos committer info %s\n", committer); + add_signoff = xmalloc(endpos - committer + 2); + memcpy(add_signoff, committer, endpos - committer + 1); + add_signoff[endpos - committer + 1] = 0; + } + else if (!strcmp(argv[i], "--attach")) + rev.mime_boundary = git_version_string; + else if (!strncmp(argv[i], "--attach=", 9)) + rev.mime_boundary = argv[i] + 9; + else argv[j++] = argv[i]; } argc = j; + if (start_number < 0) + start_number = 1; + if (numbered && keep_subject) + die ("-n and -k are mutually exclusive."); + argc = setup_revisions(argc, argv, &rev, "HEAD"); if (argc > 1) die ("unrecognized argument: %s", argv[1]); + if (output_directory) { + if (use_stdout) + die("standard output, or directory, which one?"); + if (mkdir(output_directory, 0777) < 0 && errno != EEXIST) + die("Could not create directory %s", + output_directory); + } + + if (rev.pending_objects && rev.pending_objects->next == NULL) { + rev.pending_objects->item->flags |= UNINTERESTING; + add_head(&rev); + } + if (!use_stdout) realstdout = fdopen(dup(1), "w"); @@ -186,21 +270,38 @@ int cmd_format_patch(int argc, const char **argv, char **envp) list[nr - 1] = commit; } total = nr; + if (numbered) + rev.total = total + start_number - 1; + rev.add_signoff = add_signoff; while (0 <= --nr) { int shown; commit = list[nr]; + rev.nr = total - nr + (start_number - 1); if (!use_stdout) - reopen_stdout(commit, total - nr); + reopen_stdout(commit, rev.nr, keep_subject); shown = log_tree_commit(&rev, commit); free(commit->buffer); commit->buffer = NULL; - if (shown) - printf("-- \n%s\n\n", git_version_string); + + /* We put one extra blank line between formatted + * patches and this flag is used by log-tree code + * to see if it needs to emit a LF before showing + * the log; when using one file per patch, we do + * not want the extra blank line. + */ + if (!use_stdout) + rev.shown_one = 0; + if (shown) { + if (rev.mime_boundary) + printf("\n--%s%s--\n\n\n", + mime_boundary_leader, + rev.mime_boundary); + else + printf("-- \n%s\n\n", git_version_string); + } if (!use_stdout) fclose(stdout); } - if (output_directory) - free(output_directory); free(list); return 0; }