diff --git a/Documentation/git-cat-file.adoc b/Documentation/git-cat-file.adoc index c139f55a16..86b9181599 100644 --- a/Documentation/git-cat-file.adoc +++ b/Documentation/git-cat-file.adoc @@ -174,6 +174,11 @@ flush:: since the beginning or since the last flush was issued. When `--buffer` is used, no output will come until a `flush` is issued. When `--buffer` is not used, commands are flushed each time without issuing `flush`. + +`mailmap ()`:: + Enable or disable mailmap for subsequent commands. The `` + argument accepts the same boolean values as linkgit:git-config[1]. + The mailmap data is read upon the first use and only once. -- + diff --git a/builtin/cat-file.c b/builtin/cat-file.c index d9fbad5358..fa45f774d7 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -57,6 +57,20 @@ static int use_mailmap; static char *replace_idents_using_mailmap(char *, size_t *); +/* + * The mailmap is initialized with .strdup_strings set to 0, + * but read_mailmap() sets the bit to 1 (this is true even when + * not a single mailmap entry is read), so it can be used for + * lazy loading. + */ +static void load_mailmap(void) +{ + if (mailmap.strdup_strings) + return; + + read_mailmap(the_repository, &mailmap); +} + static char *replace_idents_using_mailmap(char *object_buf, size_t *size) { struct strbuf sb = STRBUF_INIT; @@ -692,6 +706,20 @@ static void parse_cmd_info(struct batch_options *opt, batch_one_object(line, output, opt, data); } +static void parse_cmd_mailmap(struct batch_options *opt UNUSED, + const char *line, + struct strbuf *output UNUSED, + struct expand_data *data UNUSED) +{ + use_mailmap = git_parse_maybe_bool(line); + + if (use_mailmap < 0) + die(_("mailmap: invalid boolean '%s'"), line); + + if (use_mailmap) + load_mailmap(); +} + static void dispatch_calls(struct batch_options *opt, struct strbuf *output, struct expand_data *data, @@ -725,9 +753,10 @@ static const struct parse_cmd { parse_cmd_fn_t fn; unsigned takes_args; } commands[] = { - { "contents", parse_cmd_contents, 1}, - { "info", parse_cmd_info, 1}, - { "flush", NULL, 0}, + { "contents", parse_cmd_contents, 1 }, + { "info", parse_cmd_info, 1 }, + { "flush", NULL, 0 }, + { "mailmap", parse_cmd_mailmap, 1 }, }; static void batch_objects_command(struct batch_options *opt, @@ -1131,7 +1160,7 @@ int cmd_cat_file(int argc, opt_epts = (opt == 'e' || opt == 'p' || opt == 't' || opt == 's'); if (use_mailmap) - read_mailmap(the_repository, &mailmap); + load_mailmap(); switch (batch.objects_filter.choice) { case LOFC_DISABLED: diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh index 74b7ddccb2..249548eb9b 100755 --- a/t/t4203-mailmap.sh +++ b/t/t4203-mailmap.sh @@ -1133,6 +1133,111 @@ test_expect_success 'git cat-file --batch-command returns correct size with --us test_cmp expect actual ' +test_expect_success 'git cat-file --batch-command mailmap yes enables mailmap mid-stream' ' + test_when_finished "rm .mailmap" && + cat >.mailmap <<-\EOF && + C O Mitter Orig + EOF + commit_sha=$(git rev-parse HEAD) && + git cat-file commit HEAD >commit_no_mailmap.out && + git cat-file --use-mailmap commit HEAD >commit_mailmap.out && + size_no_mailmap=$(wc -c actual && + echo $commit_sha commit $size_no_mailmap >expect && + echo $commit_sha commit $size_mailmap >>expect && + test_cmp expect actual +' + +test_expect_success 'git cat-file --batch-command mailmap no disables mailmap mid-stream' ' + test_when_finished "rm .mailmap" && + cat >.mailmap <<-\EOF && + C O Mitter Orig + EOF + commit_sha=$(git rev-parse HEAD) && + git cat-file commit HEAD >commit_no_mailmap.out && + git cat-file --use-mailmap commit HEAD >commit_mailmap.out && + size_no_mailmap=$(wc -c actual && + echo $commit_sha commit $size_mailmap >expect && + echo $commit_sha commit $size_no_mailmap >>expect && + test_cmp expect actual +' + +test_expect_success 'git cat-file --batch-command mailmap works in --buffer mode' ' + test_when_finished "rm .mailmap" && + cat >.mailmap <<-\EOF && + C O Mitter Orig + EOF + commit_sha=$(git rev-parse HEAD) && + git cat-file commit HEAD >commit_no_mailmap.out && + git cat-file --use-mailmap commit HEAD >commit_mailmap.out && + size_no_mailmap=$(wc -c actual && + echo $commit_sha commit $size_mailmap >expect && + echo $commit_sha commit $size_no_mailmap >>expect && + test_cmp expect actual +' + +test_expect_success 'git cat-file --batch-command mailmap no overrides startup --mailmap' ' + test_when_finished "rm .mailmap" && + cat >.mailmap <<-\EOF && + C O Mitter Orig + EOF + commit_sha=$(git rev-parse HEAD) && + git cat-file --use-mailmap commit HEAD >commit_mailmap.out && + size_mailmap=$(wc -c commit_no_mailmap.out && + size_no_mailmap=$(wc -c actual && + echo $commit_sha commit $size_mailmap >expect && + echo $commit_sha commit $size_no_mailmap >>expect && + test_cmp expect actual +' + +test_expect_success 'git cat-file --batch-command mailmap yes overrides startup --no-mailmap' ' + test_when_finished "rm .mailmap" && + cat >.mailmap <<-\EOF && + C O Mitter Orig + EOF + commit_sha=$(git rev-parse HEAD) && + git cat-file commit HEAD >commit_no_mailmap.out && + size_no_mailmap=$(wc -c commit_mailmap.out && + size_mailmap=$(wc -c actual && + echo $commit_sha commit $size_no_mailmap >expect && + echo $commit_sha commit $size_mailmap >>expect && + test_cmp expect actual +' + +test_expect_success 'git cat-file --batch-command mailmap accepts true/false' ' + test_when_finished "rm .mailmap" && + cat >.mailmap <<-\EOF && + C O Mitter Orig + EOF + commit_sha=$(git rev-parse HEAD) && + git cat-file commit HEAD >commit_no_mailmap.out && + size_no_mailmap=$(wc -c commit_mailmap.out && + size_mailmap=$(wc -c actual && + echo $commit_sha commit $size_mailmap >expect && + echo $commit_sha commit $size_no_mailmap >>expect && + test_cmp expect actual +' + +test_expect_success 'git cat-file --batch-command mailmap rejects invalid boolean' ' + echo "mailmap maybe" >in && + test_must_fail git cat-file --batch-command err && + test_grep "mailmap: invalid boolean .*maybe" err +' + test_expect_success 'git cat-file --mailmap works with different author and committer' ' test_when_finished "rm .mailmap" && cat >.mailmap <<-\EOF &&