Skip to content

Commit 976f8a0

Browse files
edith007gitster
authored andcommitted
cat-file: add mailmap support
git-cat-file is used by tools like GitLab to get commit tag contents that are then displayed to users. This content which has author, committer or tagger information, could benefit from passing through the mailmap mechanism before being sent or displayed. This patch adds --[no-]use-mailmap command line option to the git cat-file command. It also adds --[no-]mailmap option as an alias to --[no-]use-mailmap. This patch also introduces new test cases to test the mailmap mechanism in git cat-file command. Mentored-by: Christian Couder <[email protected]> Mentored-by: John Cai <[email protected]> Helped-by: Phillip Wood <[email protected]> Helped-by: Johannes Schindelin <[email protected]> Signed-off-by: Siddharth Asthana <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent eacc1d4 commit 976f8a0

File tree

3 files changed

+107
-1
lines changed

3 files changed

+107
-1
lines changed

Documentation/git-cat-file.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ OPTIONS
6363
or to ask for a "blob" with `<object>` being a tag object that
6464
points at it.
6565

66+
--[no-]mailmap::
67+
--[no-]use-mailmap::
68+
Use mailmap file to map author, committer and tagger names
69+
and email addresses to canonical real names and email addresses.
70+
See linkgit:git-shortlog[1].
71+
6672
--textconv::
6773
Show the content as transformed by a textconv filter. In this case,
6874
`<object>` has to be of the form `<tree-ish>:<path>`, or `:<path>` in

builtin/cat-file.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "packfile.h"
1717
#include "object-store.h"
1818
#include "promisor-remote.h"
19+
#include "mailmap.h"
1920

2021
enum batch_mode {
2122
BATCH_MODE_CONTENTS,
@@ -36,6 +37,22 @@ struct batch_options {
3637

3738
static const char *force_path;
3839

40+
static struct string_list mailmap = STRING_LIST_INIT_NODUP;
41+
static int use_mailmap;
42+
43+
static char *replace_idents_using_mailmap(char *, size_t *);
44+
45+
static char *replace_idents_using_mailmap(char *object_buf, size_t *size)
46+
{
47+
struct strbuf sb = STRBUF_INIT;
48+
const char *headers[] = { "author ", "committer ", "tagger ", NULL };
49+
50+
strbuf_attach(&sb, object_buf, *size, *size + 1);
51+
apply_mailmap_to_header(&sb, headers, &mailmap);
52+
*size = sb.len;
53+
return strbuf_detach(&sb, NULL);
54+
}
55+
3956
static int filter_object(const char *path, unsigned mode,
4057
const struct object_id *oid,
4158
char **buf, unsigned long *size)
@@ -152,6 +169,12 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
152169
if (!buf)
153170
die("Cannot read object %s", obj_name);
154171

172+
if (use_mailmap) {
173+
size_t s = size;
174+
buf = replace_idents_using_mailmap(buf, &s);
175+
size = cast_size_t_to_ulong(s);
176+
}
177+
155178
/* otherwise just spit out the data */
156179
break;
157180

@@ -183,6 +206,12 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
183206
}
184207
buf = read_object_with_reference(the_repository, &oid,
185208
exp_type_id, &size, NULL);
209+
210+
if (use_mailmap) {
211+
size_t s = size;
212+
buf = replace_idents_using_mailmap(buf, &s);
213+
size = cast_size_t_to_ulong(s);
214+
}
186215
break;
187216
}
188217
default:
@@ -348,11 +377,18 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
348377
void *contents;
349378

350379
contents = read_object_file(oid, &type, &size);
380+
381+
if (use_mailmap) {
382+
size_t s = size;
383+
contents = replace_idents_using_mailmap(contents, &s);
384+
size = cast_size_t_to_ulong(s);
385+
}
386+
351387
if (!contents)
352388
die("object %s disappeared", oid_to_hex(oid));
353389
if (type != data->type)
354390
die("object %s changed type!?", oid_to_hex(oid));
355-
if (data->info.sizep && size != data->size)
391+
if (data->info.sizep && size != data->size && !use_mailmap)
356392
die("object %s changed size!?", oid_to_hex(oid));
357393

358394
batch_write(opt, contents, size);
@@ -843,6 +879,8 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
843879
OPT_CMDMODE('s', NULL, &opt, N_("show object size"), 's'),
844880
OPT_BOOL(0, "allow-unknown-type", &unknown_type,
845881
N_("allow -s and -t to work with broken/corrupt objects")),
882+
OPT_BOOL(0, "use-mailmap", &use_mailmap, N_("use mail map file")),
883+
OPT_ALIAS(0, "mailmap", "use-mailmap"),
846884
/* Batch mode */
847885
OPT_GROUP(N_("Batch objects requested on stdin (or --batch-all-objects)")),
848886
OPT_CALLBACK_F(0, "batch", &batch, N_("format"),
@@ -885,6 +923,9 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
885923
opt_cw = (opt == 'c' || opt == 'w');
886924
opt_epts = (opt == 'e' || opt == 'p' || opt == 't' || opt == 's');
887925

926+
if (use_mailmap)
927+
read_mailmap(&mailmap);
928+
888929
/* --batch-all-objects? */
889930
if (opt == 'b')
890931
batch.all_objects = 1;

t/t4203-mailmap.sh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,4 +963,63 @@ test_expect_success SYMLINKS 'symlinks not respected in-tree' '
963963
test_cmp expect actual
964964
'
965965

966+
test_expect_success 'prepare for cat-file --mailmap' '
967+
rm -f .mailmap &&
968+
git commit --allow-empty -m foo --author="Orig <[email protected]>"
969+
'
970+
971+
test_expect_success '--no-use-mailmap disables mailmap in cat-file' '
972+
test_when_finished "rm .mailmap" &&
973+
cat >.mailmap <<-EOF &&
974+
975+
EOF
976+
cat >expect <<-EOF &&
977+
author Orig <[email protected]>
978+
EOF
979+
git cat-file --no-use-mailmap commit HEAD >log &&
980+
sed -n "/^author /s/\([^>]*>\).*/\1/p" log >actual &&
981+
test_cmp expect actual
982+
'
983+
984+
test_expect_success '--use-mailmap enables mailmap in cat-file' '
985+
test_when_finished "rm .mailmap" &&
986+
cat >.mailmap <<-EOF &&
987+
988+
EOF
989+
cat >expect <<-EOF &&
990+
author A U Thor <[email protected]>
991+
EOF
992+
git cat-file --use-mailmap commit HEAD >log &&
993+
sed -n "/^author /s/\([^>]*>\).*/\1/p" log >actual &&
994+
test_cmp expect actual
995+
'
996+
997+
test_expect_success '--no-mailmap disables mailmap in cat-file for annotated tag objects' '
998+
test_when_finished "rm .mailmap" &&
999+
cat >.mailmap <<-EOF &&
1000+
1001+
EOF
1002+
cat >expect <<-EOF &&
1003+
tagger C O Mitter <[email protected]>
1004+
EOF
1005+
git tag -a -m "annotated tag" v1 &&
1006+
git cat-file --no-mailmap -p v1 >log &&
1007+
sed -n "/^tagger /s/\([^>]*>\).*/\1/p" log >actual &&
1008+
test_cmp expect actual
1009+
'
1010+
1011+
test_expect_success '--mailmap enables mailmap in cat-file for annotated tag objects' '
1012+
test_when_finished "rm .mailmap" &&
1013+
cat >.mailmap <<-EOF &&
1014+
1015+
EOF
1016+
cat >expect <<-EOF &&
1017+
tagger Orig <[email protected]>
1018+
EOF
1019+
git tag -a -m "annotated tag" v2 &&
1020+
git cat-file --mailmap -p v2 >log &&
1021+
sed -n "/^tagger /s/\([^>]*>\).*/\1/p" log >actual &&
1022+
test_cmp expect actual
1023+
'
1024+
9661025
test_done

0 commit comments

Comments
 (0)