From cf2251b60460e651a5e00afe9ef7c427ad296711 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 31 May 2006 15:11:49 -0700 Subject: [PATCH 1/3] format-patch --signoff This resurrects --signoff option to format-patch. Signed-off-by: Junio C Hamano --- builtin-log.c | 18 ++++++++++++++++-- log-tree.c | 35 +++++++++++++++++++++++++++++++++++ revision.h | 1 + 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/builtin-log.c b/builtin-log.c index db1912a05be..ac4822deaf2 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -150,6 +150,7 @@ int cmd_format_patch(int argc, const char **argv, char **envp) int numbered = 0; int start_number = -1; int keep_subject = 0; + char *add_signoff = NULL; init_revisions(&rev); rev.commit_format = CMIT_FMT_EMAIL; @@ -179,11 +180,13 @@ int cmd_format_patch(int argc, const char **argv, char **envp) if (i == argc) die("Need a number for --start-number"); start_number = strtol(argv[i], NULL, 10); - } else if (!strcmp(argv[i], "-k") || + } + else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--keep-subject")) { keep_subject = 1; rev.total = -1; - } else if (!strcmp(argv[i], "-o")) { + } + else if (!strcmp(argv[i], "-o")) { if (argc < 3) die ("Which directory?"); if (mkdir(argv[i + 1], 0777) < 0 && errno != EEXIST) @@ -192,6 +195,16 @@ int cmd_format_patch(int argc, const char **argv, char **envp) output_directory = strdup(argv[i + 1]); 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)) @@ -230,6 +243,7 @@ int cmd_format_patch(int argc, const char **argv, char **envp) total = nr; if (numbered) rev.total = total + start_number - 1; + rev.add_signoff = add_signoff; while (0 <= --nr) { int shown; commit = list[nr]; diff --git a/log-tree.c b/log-tree.c index 58b016378c1..e86e16bcad9 100644 --- a/log-tree.c +++ b/log-tree.c @@ -12,6 +12,37 @@ static void show_parents(struct commit *commit, int abbrev) } } +static int append_signoff(char *buf, int buf_sz, int at, const char *signoff) +{ + int signoff_len = strlen(signoff); + static const char signed_off_by[] = "Signed-off-by: "; + char *cp = buf; + + /* Do we have enough space to add it? */ + if (buf_sz - at <= strlen(signed_off_by) + signoff_len + 2) + return at; + + /* First see if we already have the sign-off by the signer */ + while (1) { + cp = strstr(cp, signed_off_by); + if (!cp) + break; + cp += strlen(signed_off_by); + if ((cp + signoff_len < buf + at) && + !strncmp(cp, signoff, signoff_len) && + isspace(cp[signoff_len])) + return at; /* we already have him */ + } + + strcpy(buf + at, signed_off_by); + at += strlen(signed_off_by); + strcpy(buf + at, signoff); + at += signoff_len; + buf[at++] = '\n'; + buf[at] = 0; + return at; +} + void show_log(struct rev_info *opt, struct log_info *log, const char *sep) { static char this_header[16384]; @@ -111,6 +142,10 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep) * And then the pretty-printed message itself */ len = pretty_print_commit(opt->commit_format, commit, ~0u, this_header, sizeof(this_header), abbrev, subject, after_subject); + + if (opt->add_signoff) + len = append_signoff(this_header, sizeof(this_header), len, + opt->add_signoff); printf("%s%s%s", this_header, extra, sep); } diff --git a/revision.h b/revision.h index bdbdd235d82..75796bc1388 100644 --- a/revision.h +++ b/revision.h @@ -60,6 +60,7 @@ struct rev_info { struct log_info *loginfo; int nr, total; const char *mime_boundary; + const char *add_signoff; /* special limits */ int max_count; From 20ff06805c66826404b154b9309a8581449af2b0 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 2 Jun 2006 15:21:17 +0200 Subject: [PATCH 2/3] format-patch: resurrect extra headers from config Once again, if you have [format] headers = "Origamization: EvilEmpire\n" format-patch will add these headers just after the "Subject:" line. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-log.c | 20 ++++++++++++++++++++ log-tree.c | 8 +++++--- revision.h | 1 + 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/builtin-log.c b/builtin-log.c index ac4822deaf2..6612f4c2a80 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -85,6 +85,23 @@ 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; @@ -162,6 +179,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 diff --git a/log-tree.c b/log-tree.c index e86e16bcad9..ebb49f29701 100644 --- a/log-tree.c +++ b/log-tree.c @@ -51,7 +51,7 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep) int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40; const char *extra; int len; - char *subject = NULL, *after_subject = NULL; + const char *subject = NULL, *extra_headers = opt->extra_headers; opt->loginfo = NULL; if (!opt->verbose_header) { @@ -100,6 +100,7 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep) static char subject_buffer[1024]; static char buffer[1024]; snprintf(subject_buffer, sizeof(subject_buffer) - 1, + "%s" "MIME-Version: 1.0\n" "Content-Type: multipart/mixed;\n" " boundary=\"%s%s\"\n" @@ -110,9 +111,10 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep) "Content-Type: text/plain; " "charset=UTF-8; format=fixed\n" "Content-Transfer-Encoding: 8bit\n\n", + extra_headers ? extra_headers : "", mime_boundary_leader, opt->mime_boundary, mime_boundary_leader, opt->mime_boundary); - after_subject = subject_buffer; + extra_headers = subject_buffer; snprintf(buffer, sizeof(buffer) - 1, "--%s%s\n" @@ -141,7 +143,7 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep) /* * And then the pretty-printed message itself */ - len = pretty_print_commit(opt->commit_format, commit, ~0u, this_header, sizeof(this_header), abbrev, subject, after_subject); + len = pretty_print_commit(opt->commit_format, commit, ~0u, this_header, sizeof(this_header), abbrev, subject, extra_headers); if (opt->add_signoff) len = append_signoff(this_header, sizeof(this_header), len, diff --git a/revision.h b/revision.h index 75796bc1388..7d85b0f2e97 100644 --- a/revision.h +++ b/revision.h @@ -61,6 +61,7 @@ struct rev_info { int nr, total; const char *mime_boundary; const char *add_signoff; + const char *extra_headers; /* special limits */ int max_count; From 2052d146f60eaeeef50cb4d437e4a25051f8d8c3 Mon Sep 17 00:00:00 2001 From: Dennis Stosberg Date: Wed, 31 May 2006 16:14:08 +0200 Subject: [PATCH 3/3] Update documentation for git-format-patch [jc: adjusted for recently resurrected features] Signed-off-by: Dennis Stosberg Signed-off-by: Junio C Hamano --- Documentation/git-format-patch.txt | 69 +++++++++++++++--------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 7cc7fafc1d7..493cac22dbe 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -9,37 +9,46 @@ git-format-patch - Prepare patches for e-mail submission SYNOPSIS -------- [verse] -'git-format-patch' [-n | -k] [-o | --stdout] [--attach] [-s] [-c] - [--diff-options] [] +'git-format-patch' [-n | -k] [-o | --stdout] [--attach] + [-s | --signoff] [--diff-options] [--start-number ] + [..] DESCRIPTION ----------- -Prepare each commit with its patch since head forked from - head, one file per patch formatted to resemble UNIX mailbox -format, for e-mail submission or use with gitlink:git-am[1]. + +Prepare each commit between and with its patch in +one file per commit, formatted to resemble UNIX mailbox format. +If .. is not specified, the head of the current working +tree is implied. + +The output of this command is convenient for e-mail submission or +for use with gitlink:git-am[1]. Each output file is numbered sequentially from 1, and uses the -first line of the commit message (massaged for pathname safety) -as the filename. +first line of the commit message (massaged for pathname safety) as +the filename. The names of the output files are printed to standard +output, unless the --stdout option is specified. -When -o is specified, output files are created in ; otherwise -they are created in the current working directory. This option -is ignored if --stdout is specified. +If -o is specified, output files are created in . Otherwise +they are created in the current working directory. -When -n is specified, instead of "[PATCH] Subject", the first -line is formatted as "[PATCH N/M] Subject", unless you have only -one patch. +If -n is specified, instead of "[PATCH] Subject", the first line +is formatted as "[PATCH n/m] Subject". OPTIONS ------- -o|--output-directory :: Use to store the resulting files, instead of the - current working directory. + current working directory. This option is ignored if + --stdout is specified. -n|--numbered:: Name output in '[PATCH n/m]' format. +--start-number :: + Start numbering the patches at instead of 1. + -k|--keep-subject:: Do not strip/add '[PATCH]' from the first line of the commit log message. @@ -48,17 +57,9 @@ OPTIONS Add `Signed-off-by:` line to the commit message, using the committer identity of yourself. --c|--check:: - Display suspicious lines in the patch. The definition - of 'suspicious lines' is currently the lines that has - trailing whitespaces, and the lines whose indentation - has a SP character immediately followed by a TAB - character. - --stdout:: - This flag generates the mbox formatted output to the - standard output, instead of saving them into a file per - patch and implies --mbox. + Print all commits to the standard output in mbox format, + instead of creating a file for each one. --attach:: Create attachments instead of inlining patches. @@ -82,18 +83,18 @@ git-format-patch -k --stdout R1..R2 | git-am -3 -k:: cherry-pick them. git-format-patch origin:: - Extract commits the current branch accumulated since it - pulled from origin the last time in a patch form for - e-mail submission. + Extract all commits which are in the current branch but + not in the origin branch. For each commit a separate file + is created in the current directory. git-format-patch -M -B origin:: - The same as the previous one, except detect and handle - renames and complete rewrites intelligently to produce - renaming patch. A renaming patch reduces the amount of - text output, and generally makes it easier to review - it. Note that the "patch" program does not understand - renaming patch well, so use it only when you know the - recipient uses git to apply your patch. + The same as the previous one. Additionally, it detects + and handles renames and complete rewrites intelligently to + produce a renaming patch. A renaming patch reduces the + amount of text output, and generally makes it easier to + review it. Note that the "patch" program does not + understand renaming patches, so use it only when you know + the recipient uses git to apply your patch. See Also