From: Junio C Hamano Date: Fri, 21 Apr 2006 20:19:58 +0000 (-0700) Subject: Merge branch 'master' into jc/fmt-patch X-Git-Tag: v1.4.0-rc1~76^2~13 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=91efcf60653b2538b05625807293b97c07cb04f4;hp=70827b15bfb11f7aea52c6995956be9d149233e1;p=git.git Merge branch 'master' into jc/fmt-patch * master: Split up builtin commands into separate files from git.c git-log produces no output fix pack-object buffer size mailinfo: decode underscore used in "Q" encoding properly. Reintroduce svn pools to solve the memory leak. pack-objects: do not stop at object that is "too small" git-commit --amend: two fixes. get_tree_entry(): make it available from tree-walk sha1_name.c: no need to include diff.h; tree-walk.h will do. sha1_name.c: prepare to make get_tree_entry() reusable from others. get_sha1() shorthands for blob/tree objects pre-commit hook: complain about conflict markers. git-merge: a bit more readable user guidance. diff: move diff.c to diff-lib.c to make room. git log: don't do merge diffs by default Allow "git repack" users to specify repacking window/depth Document git-clone --reference Fix filename scaling for binary files Fix uninteresting tags in new revision parsing Conflicts: Adjusted the addition of fmt-patch to match the recent split from git.c to builtin.log.c. --- diff --git a/builtin-log.c b/builtin-log.c index 69f2911c..a39aed6d 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -9,6 +9,7 @@ #include "diff.h" #include "revision.h" #include "log-tree.h" +#include "builtin.h" static int cmd_log_wc(int argc, const char **argv, char **envp, struct rev_info *rev) @@ -67,3 +68,41 @@ int cmd_log(int argc, const char **argv, char **envp) rev.diffopt.recursive = 1; return cmd_log_wc(argc, argv, envp, &rev); } + +int cmd_format_patch(int argc, const char **argv, char **envp) +{ + struct commit *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"); + + prepare_revision_walk(&rev); + while ((commit = get_revision(&rev)) != NULL) { + 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_string); + } + free(list); + return 0; +} + diff --git a/builtin.h b/builtin.h index 47408a05..94dc0732 100644 --- a/builtin.h +++ b/builtin.h @@ -19,5 +19,6 @@ extern int cmd_version(int argc, const char **argv, char **envp); extern int cmd_whatchanged(int argc, const char **argv, char **envp); extern int cmd_show(int argc, const char **argv, char **envp); extern int cmd_log(int argc, const char **argv, char **envp); +extern int cmd_format_patch(int argc, const char **argv, char **envp); #endif diff --git a/commit.c b/commit.c index 2717dd81..06e00987 100644 --- a/commit.c +++ b/commit.c @@ -36,6 +36,8 @@ enum cmit_fmt get_commit_format(const char *arg) return CMIT_FMT_FULL; if (!strcmp(arg, "=fuller")) return CMIT_FMT_FULLER; + if (!strcmp(arg, "=email")) + return CMIT_FMT_EMAIL; if (!strcmp(arg, "=oneline")) return CMIT_FMT_ONELINE; die("invalid --pretty format"); @@ -428,6 +430,10 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, const c time = strtoul(date, &date, 10); tz = strtol(date, NULL, 10); + if (fmt == CMIT_FMT_EMAIL) { + what = "From"; + filler = ""; + } ret = sprintf(buf, "%s: %.*s%.*s\n", what, (fmt == CMIT_FMT_FULLER) ? 4 : 0, filler, namelen, line); @@ -435,6 +441,9 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, const c case CMIT_FMT_MEDIUM: ret += sprintf(buf + ret, "Date: %s\n", show_date(time, tz)); break; + case CMIT_FMT_EMAIL: + ret += sprintf(buf + ret, "Date: %s\n", show_date(time, tz)); + break; case CMIT_FMT_FULLER: ret += sprintf(buf + ret, "%sDate: %s\n", what, show_date(time, tz)); break; @@ -445,10 +454,12 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, const c return ret; } -static int is_empty_line(const char *line, int len) +static int is_empty_line(const char *line, int *len_p) { + int len = *len_p; while (len && isspace(line[len-1])) len--; + *len_p = len; return !len; } @@ -457,7 +468,8 @@ static int add_merge_info(enum cmit_fmt fmt, char *buf, const struct commit *com struct commit_list *parent = commit->parents; int offset; - if ((fmt == CMIT_FMT_ONELINE) || !parent || !parent->next) + if ((fmt == CMIT_FMT_ONELINE) || (fmt == CMIT_FMT_EMAIL) || + !parent || !parent->next) return 0; offset = sprintf(buf, "Merge:"); @@ -480,9 +492,15 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit { int hdr = 1, body = 0; unsigned long offset = 0; - int indent = (fmt == CMIT_FMT_ONELINE) ? 0 : 4; + int indent = 4; int parents_shown = 0; const char *msg = commit->buffer; + const char *subject = NULL; + + if (fmt == CMIT_FMT_EMAIL) + subject = "Subject: [PATCH] "; + if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL) + indent = 0; for (;;) { const char *line = msg; @@ -506,7 +524,7 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit if (hdr) { if (linelen == 1) { hdr = 0; - if (fmt != CMIT_FMT_ONELINE) + if ((fmt != CMIT_FMT_ONELINE) && !subject) buf[offset++] = '\n'; continue; } @@ -544,20 +562,28 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit continue; } - if (is_empty_line(line, linelen)) { + if (is_empty_line(line, &linelen)) { if (!body) continue; + if (subject) + continue; if (fmt == CMIT_FMT_SHORT) break; } else { body = 1; } + if (subject) { + memcpy(buf + offset, subject, 9); + offset += 9; + } memset(buf + offset, ' ', indent); memcpy(buf + offset + indent, line, linelen); offset += linelen + indent; + buf[offset++] = '\n'; if (fmt == CMIT_FMT_ONELINE) break; + subject = NULL; } while (offset && isspace(buf[offset-1])) offset--; diff --git a/commit.h b/commit.h index de142afe..01eec60a 100644 --- a/commit.h +++ b/commit.h @@ -45,6 +45,7 @@ enum cmit_fmt { CMIT_FMT_FULL, CMIT_FMT_FULLER, CMIT_FMT_ONELINE, + CMIT_FMT_EMAIL, CMIT_FMT_UNSPECIFIED, }; diff --git a/git.c b/git.c index aa2b814d..619c6654 100644 --- a/git.c +++ b/git.c @@ -47,6 +47,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "log", cmd_log }, { "whatchanged", cmd_whatchanged }, { "show", cmd_show }, + { "fmt-patch", cmd_format_patch }, }; int i; diff --git a/log-tree.c b/log-tree.c index 9634c467..aaf2b942 100644 --- a/log-tree.c +++ b/log-tree.c @@ -37,12 +37,20 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep) /* * Print header line of header.. */ - printf("%s%s", - opt->commit_format == CMIT_FMT_ONELINE ? "" : "commit ", - diff_unique_abbrev(commit->object.sha1, abbrev_commit)); - if (parent) - printf(" (from %s)", diff_unique_abbrev(parent->object.sha1, abbrev_commit)); - putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n'); + + if (opt->commit_format == CMIT_FMT_EMAIL) + printf("From %s Thu Apr 7 15:13:13 2005\n", + sha1_to_hex(commit->object.sha1)); + else { + printf("%s%s", + opt->commit_format == CMIT_FMT_ONELINE ? "" : "commit ", + diff_unique_abbrev(commit->object.sha1, abbrev_commit)); + if (parent) + printf(" (from %s)", + diff_unique_abbrev(parent->object.sha1, + abbrev_commit)); + putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n'); + } /* * And then the pretty-printed message itself @@ -152,15 +160,18 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log int log_tree_commit(struct rev_info *opt, struct commit *commit) { struct log_info log; + int shown; log.commit = commit; log.parent = NULL; opt->loginfo = &log; - if (!log_tree_diff(opt, commit, &log) && opt->loginfo && opt->always_show_header) { + shown = log_tree_diff(opt, commit, &log); + if (!shown && opt->loginfo && opt->always_show_header) { log.parent = NULL; show_log(opt, opt->loginfo, ""); + shown = 1; } opt->loginfo = NULL; - return 0; + return shown; }