Skip to content

Commit a797c0e

Browse files
edith007gitster
authored andcommitted
cat-file: add mailmap support to --batch-check option
Even though the cat-file command with `--batch-check` option does not complain when `--use-mailmap` option is given, the latter option is ignored. Compute the size of the object after replacing the idents and report it instead. In order to make `--batch-check` option honour the mailmap mechanism we have to read the contents of the commit/tag object. There were two ways to do it: 1. Make two calls to `oid_object_info_extended()`. If `--use-mailmap` option is given, the first call will get us the type of the object and second call will only be made if the object type is either a commit or tag to get the contents of the object. 2. Make one call to `oid_object_info_extended()` to get the type of the object. Then, if the object type is either of commit or tag, make a call to `repo_read_object_file()` to read the contents of the object. I benchmarked the following command with both the above approaches and compared against the current implementation where `--use-mailmap` option is ignored: `git cat-file --use-mailmap --batch-all-objects --batch-check --buffer --unordered` The results can be summarized as follows: Time (mean ± σ) default 827.7 ms ± 104.8 ms first approach 6.197 s ± 0.093 s second approach 1.975 s ± 0.217 s Since, the second approach is faster than the first one, I implemented it in this patch. The command git cat-file can now use the mailmap mechanism to replace idents with canonical versions for commit and tag objects. There are several options like `--batch`, `--batch-check` and `--batch-command` that can be combined with `--use-mailmap`. But the documentation for `--batch`, `--batch-check` and `--batch-command` doesn't say so. This patch fixes that documentation. Mentored-by: Christian Couder <[email protected]> Mentored-by: John Cai <[email protected]> Helped-by: Taylor Blau <[email protected]> Helped-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Siddharth Asthana <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 49050a0 commit a797c0e

File tree

3 files changed

+87
-13
lines changed

3 files changed

+87
-13
lines changed

Documentation/git-cat-file.txt

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,26 +91,49 @@ OPTIONS
9191
--batch::
9292
--batch=<format>::
9393
Print object information and contents for each object provided
94-
on stdin. May not be combined with any other options or arguments
95-
except `--textconv` or `--filters`, in which case the input lines
96-
also need to specify the path, separated by whitespace. See the
97-
section `BATCH OUTPUT` below for details.
94+
on stdin. May not be combined with any other options or arguments
95+
except `--textconv`, `--filters`, or `--use-mailmap`.
96+
+
97+
* When used with `--textconv` or `--filters`, the input lines
98+
must specify the path, separated by whitespace. See the section
99+
`BATCH OUTPUT` below for details.
100+
+
101+
* When used with `--use-mailmap`, for commit and tag objects, the
102+
contents part of the output shows the identities replaced using the
103+
mailmap mechanism, while the information part of the output shows
104+
the size of the object as if it actually recorded the replacement
105+
identities.
98106

99107
--batch-check::
100108
--batch-check=<format>::
101-
Print object information for each object provided on stdin. May
102-
not be combined with any other options or arguments except
103-
`--textconv` or `--filters`, in which case the input lines also
104-
need to specify the path, separated by whitespace. See the
105-
section `BATCH OUTPUT` below for details.
109+
Print object information for each object provided on stdin. May not be
110+
combined with any other options or arguments except `--textconv`, `--filters`
111+
or `--use-mailmap`.
112+
+
113+
* When used with `--textconv` or `--filters`, the input lines must
114+
specify the path, separated by whitespace. See the section
115+
`BATCH OUTPUT` below for details.
116+
+
117+
* When used with `--use-mailmap`, for commit and tag objects, the
118+
printed object information shows the size of the object as if the
119+
identities recorded in it were replaced by the mailmap mechanism.
106120

107121
--batch-command::
108122
--batch-command=<format>::
109123
Enter a command mode that reads commands and arguments from stdin. May
110-
only be combined with `--buffer`, `--textconv` or `--filters`. In the
111-
case of `--textconv` or `--filters`, the input lines also need to specify
112-
the path, separated by whitespace. See the section `BATCH OUTPUT` below
113-
for details.
124+
only be combined with `--buffer`, `--textconv`, `--use-mailmap` or
125+
`--filters`.
126+
+
127+
* When used with `--textconv` or `--filters`, the input lines must
128+
specify the path, separated by whitespace. See the section
129+
`BATCH OUTPUT` below for details.
130+
+
131+
* When used with `--use-mailmap`, for commit and tag objects, the
132+
`contents` command shows the identities replaced using the
133+
mailmap mechanism, while the `info` command shows the size
134+
of the object as if it actually recorded the replacement
135+
identities.
136+
114137
+
115138
`--batch-command` recognizes the following commands:
116139
+

builtin/cat-file.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,9 @@ static void batch_object_write(const char *obj_name,
444444
if (!data->skip_object_info) {
445445
int ret;
446446

447+
if (use_mailmap)
448+
data->info.typep = &data->type;
449+
447450
if (pack)
448451
ret = packed_object_info(the_repository, pack, offset,
449452
&data->info);
@@ -457,6 +460,18 @@ static void batch_object_write(const char *obj_name,
457460
fflush(stdout);
458461
return;
459462
}
463+
464+
if (use_mailmap && (data->type == OBJ_COMMIT || data->type == OBJ_TAG)) {
465+
size_t s = data->size;
466+
char *buf = NULL;
467+
468+
buf = repo_read_object_file(the_repository, &data->oid, &data->type,
469+
&data->size);
470+
buf = replace_idents_using_mailmap(buf, &s);
471+
data->size = cast_size_t_to_ulong(s);
472+
473+
free(buf);
474+
}
460475
}
461476

462477
strbuf_reset(scratch);

t/t4203-mailmap.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,4 +1051,40 @@ test_expect_success 'git cat-file -s returns correct size with --use-mailmap for
10511051
test_cmp expect actual
10521052
'
10531053

1054+
test_expect_success 'git cat-file --batch-check returns correct size with --use-mailmap' '
1055+
test_when_finished "rm .mailmap" &&
1056+
cat >.mailmap <<-\EOF &&
1057+
1058+
EOF
1059+
git cat-file commit HEAD >commit.out &&
1060+
commit_size=$(wc -c <commit.out) &&
1061+
commit_sha=$(git rev-parse HEAD) &&
1062+
echo $commit_sha commit $commit_size >expect &&
1063+
git cat-file --use-mailmap commit HEAD >commit.out &&
1064+
commit_size=$(wc -c <commit.out) &&
1065+
echo $commit_sha commit $commit_size >>expect &&
1066+
echo "HEAD" >in &&
1067+
git cat-file --batch-check <in >actual &&
1068+
git cat-file --use-mailmap --batch-check <in >>actual &&
1069+
test_cmp expect actual
1070+
'
1071+
1072+
test_expect_success 'git cat-file --batch-command returns correct size with --use-mailmap' '
1073+
test_when_finished "rm .mailmap" &&
1074+
cat >.mailmap <<-\EOF &&
1075+
1076+
EOF
1077+
git cat-file commit HEAD >commit.out &&
1078+
commit_size=$(wc -c <commit.out) &&
1079+
commit_sha=$(git rev-parse HEAD) &&
1080+
echo $commit_sha commit $commit_size >expect &&
1081+
git cat-file --use-mailmap commit HEAD >commit.out &&
1082+
commit_size=$(wc -c <commit.out) &&
1083+
echo $commit_sha commit $commit_size >>expect &&
1084+
echo "info HEAD" >in &&
1085+
git cat-file --batch-command <in >actual &&
1086+
git cat-file --use-mailmap --batch-command <in >>actual &&
1087+
test_cmp expect actual
1088+
'
1089+
10541090
test_done

0 commit comments

Comments
 (0)