From: Jacob Keller <jacob.keller@xxxxxxxxx> Git has support for a mailmap file which translates author and committer names and email addresses to canonical values. Git log has log.mailmap, and the associated --mailmap and --use-mailmap options. Teach git format-patch the format.mailmap and --mailmap options so that formatting a patch can also reflect the canonical values from the mailmap file. Reported-by: Anthony Nguyen <anthony.l.nguyen@xxxxxxxxx> Signed-off-by: Jacob Keller <jacob.keller@xxxxxxxxx> --- builtin/log.c | 13 ++++++++++ Documentation/git-format-patch.txt | 7 ++++++ t/t4014-format-patch.sh | 49 +++++++++++++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/builtin/log.c b/builtin/log.c index 4d4b60caa76a..94560add6fbc 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -975,6 +975,7 @@ struct format_config { struct log_config log; enum thread_level thread; int do_signoff; + int use_mailmap; enum auto_base_setting auto_base; char *base_commit; char *from; @@ -1131,6 +1132,10 @@ static int git_format_config(const char *var, const char *value, cfg->do_signoff = git_config_bool(var, value); return 0; } + if (!strcmp(var, "format.mailmap")) { + cfg->use_mailmap = git_config_bool(var, value); + return 0; + } if (!strcmp(var, "format.signature")) { FREE_AND_NULL(cfg->signature); return git_config_string(&cfg->signature, var, value); @@ -2042,6 +2047,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) N_("generate a cover letter")), OPT_BOOL(0, "numbered-files", &just_numbers, N_("use simple number sequence for output file names")), + OPT_BOOL(0, "use-mailmap", &cfg.use_mailmap, N_("use mail map file")), + OPT_ALIAS(0, "mailmap", "use-mailmap"), OPT_STRING(0, "suffix", &fmt_patch_suffix, N_("sfx"), N_("use <sfx> instead of '.patch'")), OPT_INTEGER(0, "start-number", &start_number, @@ -2160,6 +2167,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.force_in_body_from = force_in_body_from; + if (cfg.use_mailmap) { + rev.mailmap = xmalloc(sizeof(struct string_list)); + string_list_init_nodup(rev.mailmap); + read_mailmap(rev.mailmap); + } + if (!fmt_patch_suffix) fmt_patch_suffix = cfg.fmt_patch_suffix; diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 8708b3159309..f3de349990bf 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -30,6 +30,7 @@ SYNOPSIS [--range-diff=<previous> [--creation-factor=<percent>]] [--filename-max-length=<n>] [--progress] + [(--mailmap|--no-mailmap|--use-mailmap|--no-use-mailmap)] [<common-diff-options>] [ <since> | <revision-range> ] @@ -145,6 +146,12 @@ include::diff-options.txt[] Print all commits to the standard output in mbox format, instead of creating a file for each one. +--[no-]mailmap:: +--[no-]use-mailmap:: + Use mailmap file to map author and committer names and email + addresses to canonical real names and email addresses. See + linkgit:git-shortlog[1]. + --attach[=<boundary>]:: Create multipart/mixed attachment, the first part of which is the commit message and the patch itself in the diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 884f83fb8a45..3a3ebddfe5c4 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -1215,7 +1215,7 @@ check_author() { echo content >>file && git add file && GIT_AUTHOR_NAME=$1 git commit -m author-check && - git format-patch --stdout -1 >patch && + git format-patch $2 --stdout -1 >patch && sed -n "/^From: /p; /^ /p; /^$/q" patch >actual && test_cmp expect actual } @@ -1285,6 +1285,53 @@ test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' ' check_author "Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar" ' +cat >mail.map <<'EOF' +Foo B. Baz <author@xxxxxxxxxxx> +EOF + +cat >expect <<'EOF' +From: "Foo B. Baz" <author@xxxxxxxxxxx> +EOF +test_expect_success 'format-patch format.mailmap maps properly' ' + test_config format.mailmap true && + test_config mailmap.file mail.map && + check_author "Foo B. Bar" +' + +cat >expect <<'EOF' +From: "Foo B. Bar" <author@xxxxxxxxxxx> +EOF +test_expect_success 'format-patch --no-mailmap overrides format.mailmap' ' + test_config format.mailmap true && + test_config mailmap.file mail.map && + check_author "Foo B. Bar" "--no-mailmap" +' + +cat >expect <<'EOF' +From: "Foo B. Bar" <author@xxxxxxxxxxx> +EOF +test_expect_success 'format-patch --no-use-mailmap overrides format.mailmap' ' + test_config format.mailmap true && + test_config mailmap.file mail.map && + check_author "Foo B. Bar" "--no-use-mailmap" +' + +cat >expect <<'EOF' +From: "Foo B. Baz" <author@xxxxxxxxxxx> +EOF +test_expect_success 'format-patch --mailmap' ' + test_config mailmap.file mail.map && + check_author "Foo B. Bar" "--mailmap" +' + +cat >expect <<'EOF' +From: "Foo B. Baz" <author@xxxxxxxxxxx> +EOF +test_expect_success 'format-patch --use-mailmap' ' + test_config mailmap.file mail.map && + check_author "Foo B. Bar" "--use-mailmap" +' + cat >expect <<'EOF' From: Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo --- base-commit: 406f326d271e0bacecdb00425422c5fa3f314930 change-id: 20240813-jk-support-mailmap-git-format-patch-439073f25010 Best regards, -- Jacob Keller <jacob.keller@xxxxxxxxx>