From: Siddharth Asthana <siddharthasthana31@xxxxxxxxx> The git cat-file command with --mailmap option fails to apply mailmap transformations to the committer field when the author and committer identities are different. This occurs due to a missing newline handling in apply_mailmap_to_header() after processing each identity line. When rewrite_ident_line() processes an identity, it stops at the end of the identity data (e.g., "Author Name <email> timestamp"), but doesn't account for the trailing newline. The current code adds the identity length to buf_offset but fails to advance past the newline character. This causes the next iteration to start parsing from the newline instead of the beginning of the next header line, making it impossible to match subsequent headers like "committer". Additionally, rewrite_ident_line() may reallocate the buffer during its operation. Any code using pointers into the old buffer would be using invalid memory after such a reallocation. Let's fix this by addressing both issues: 1. After processing an identity line, we now check if we're at a newline and advance past it, ensuring the next header line is parsed correctly. 2. We recompute the buffer position after rewrite_ident_line() to handle potential buffer reallocation. This ensures that all identity headers in commit and tag objects are consistently processed regardless of whether the author and committer are the same person. Reported-by: Vasilii Iakliushin <viakliushin@xxxxxxxxxx> Reviewed-by: Christian Couder <christian.couder@xxxxxxxxx> Signed-off-by: Siddharth Asthana <siddharthasthana31@xxxxxxxxx> --- ident.c | 4 ++++ t/t4203-mailmap.sh | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/ident.c b/ident.c index 967895d885..281e830573 100644 --- a/ident.c +++ b/ident.c @@ -412,6 +412,10 @@ void apply_mailmap_to_header(struct strbuf *buf, const char **header, found_header = 1; buf_offset += endp - line; buf_offset += rewrite_ident_line(person, endp - person, buf, mailmap); + /* Recompute endp after potential buffer reallocation */ + endp = buf->buf + buf_offset; + if (*endp == '\n') + buf_offset++; break; } diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh index 4a6242ff99..98dd0ae12f 100755 --- a/t/t4203-mailmap.sh +++ b/t/t4203-mailmap.sh @@ -1133,4 +1133,37 @@ test_expect_success 'git cat-file --batch-command returns correct size with --us test_cmp expect actual ' +test_expect_success 'git cat-file --mailmap works with different author and committer' ' + test_when_finished "rm .mailmap" && + cat >.mailmap <<-\EOF && + Mailmapped User <mailmapped-user@xxxxxxxxxx> C O Mitter <committer@xxxxxxxxxxx> + EOF + git commit --allow-empty -m "different author/committer" \ + --author="Different Author <different@xxxxxxxxxxx>" && + cat >expect <<-\EOF && + author Different Author <different@xxxxxxxxxxx> + committer Mailmapped User <mailmapped-user@xxxxxxxxxx> + EOF + git cat-file --mailmap commit HEAD >log && + sed -n "/^author /s/\([^>]*>\).*/\1/p; /^committer /s/\([^>]*>\).*/\1/p" log >actual && + test_cmp expect actual +' + +test_expect_success 'git cat-file --mailmap maps both author and committer when both need mapping' ' + test_when_finished "rm .mailmap" && + cat >.mailmap <<-\EOF && + Mapped Author <mapped-author@xxxxxxxxxxx> <different@xxxxxxxxxxx> + Mapped Committer <mapped-committer@xxxxxxxxxxx> C O Mitter <committer@xxxxxxxxxxx> + EOF + git commit --allow-empty -m "both author and committer mapped" \ + --author="Different Author <different@xxxxxxxxxxx>" && + cat >expect <<-\EOF && + author Mapped Author <mapped-author@xxxxxxxxxxx> + committer Mapped Committer <mapped-committer@xxxxxxxxxxx> + EOF + git cat-file --mailmap commit HEAD >log && + sed -n "/^author /s/\([^>]*>\).*/\1/p; /^committer /s/\([^>]*>\).*/\1/p" log >actual && + test_cmp expect actual +' + test_done -- 2.49.0