path: root/builtin/log.c
diff options
authorJeff King <>2013-07-03 07:08:22 (GMT)
committerJunio C Hamano <>2013-07-03 19:11:04 (GMT)
commita90804752f6ab2b911882d47fafb6c2b78f447c3 (patch)
treeecf64fa9f0317643baf5fb9ec791729edee98ea5 /builtin/log.c
parent10f2fbff6859a22327d04f9eb0c1a38995ff48b1 (diff)
teach format-patch to place other authors into in-body "From"
Format-patch generates emails with the "From" address set to the author of each patch. If you are going to send the emails, however, you would want to replace the author identity with yours (if they are not the same), and bump the author identity to an in-body header. Normally this is handled by git-send-email, which does the transformation before sending out the emails. However, some workflows may not use send-email (e.g., imap-send, or a custom script which feeds the mbox to a non-git MUA). They could each implement this feature themselves, but getting it right is non-trivial (one must canonicalize the identities by reversing any RFC2047 encoding or RFC822 quoting of the headers, which has caused many bugs in send-email over the years). This patch takes a different approach: it teaches format-patch a "--from" option which handles the ident check and in-body header while it is writing out the email. It's much simpler to do at this level (because we haven't done any quoting yet), and any workflow based on format-patch can easily turn it on. Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'builtin/log.c')
1 files changed, 24 insertions, 0 deletions
diff --git a/builtin/log.c b/builtin/log.c
index e3222ed..2625f98 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -1112,6 +1112,21 @@ static int cc_callback(const struct option *opt, const char *arg, int unset)
return 0;
+static int from_callback(const struct option *opt, const char *arg, int unset)
+ char **from = opt->value;
+ free(*from);
+ if (unset)
+ *from = NULL;
+ else if (arg)
+ *from = xstrdup(arg);
+ else
+ *from = xstrdup(git_committer_info(IDENT_NO_DATE));
+ return 0;
int cmd_format_patch(int argc, const char **argv, const char *prefix)
struct commit *commit;
@@ -1134,6 +1149,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
int quiet = 0;
int reroll_count = -1;
char *branch_name = NULL;
+ char *from = NULL;
const struct option builtin_format_patch_options[] = {
{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
N_("use [PATCH n/m] even with a single patch"),
@@ -1177,6 +1193,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
0, to_callback },
{ OPTION_CALLBACK, 0, "cc", NULL, N_("email"), N_("add Cc: header"),
0, cc_callback },
+ { OPTION_CALLBACK, 0, "from", &from, N_("ident"),
+ N_("set From address to <ident> (or committer ident if absent)"),
+ PARSE_OPT_OPTARG, from_callback },
OPT_STRING(0, "in-reply-to", &in_reply_to, N_("message-id"),
N_("make first mail a reply to <message-id>")),
{ OPTION_CALLBACK, 0, "attach", &rev, N_("boundary"),
@@ -1264,6 +1283,11 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
rev.extra_headers = strbuf_detach(&buf, NULL);
+ if (from) {
+ if (split_ident_line(&rev.from_ident, from, strlen(from)))
+ die(_("invalid ident line: %s"), from);
+ }
if (start_number < 0)
start_number = 1;