Skip to content

Commit e9c1b0e

Browse files
edith007gitster
authored andcommitted
revision: improve commit_rewrite_person()
The function, commit_rewrite_person(), is designed to find and replace an ident string in the header part, and the way it avoids a random occurrence of "author A U Thor <[email protected]" in the text is by insisting "author" to appear at the beginning of line by passing "\nauthor " as "what". The implementation also doesn't make any effort to limit itself to the commit header by locating the blank line that appears after the header part and stopping the search there. Also, the interface forces the caller to make multiple calls if it wants to rewrite idents on multiple headers. It shouldn't be the case. To support the existing caller better, update commit_rewrite_person() to: - Make a single pass in the input buffer to locate headers named "author" and "committer" and replace idents on them. - Stop at the end of the header, ensuring that nothing in the body of the commit object is modified. The return type of the function commit_rewrite_person() has also been changed from int to void. This has been done because the caller of the function doesn't do anything with the return value of the function. By simplifying the interface of the commit_rewrite_person(), we also intend to expose it as a public function. We will also be renaming the function in a future commit to a different name which clearly tells that the function replaces idents in the header of the commit buffer. Mentored-by: Christian Couder <[email protected]> Mentored-by: John Cai <[email protected]> Helped-by: Đoàn Trần Công Danh <[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 30cc8d0 commit e9c1b0e

File tree

1 file changed

+47
-17
lines changed

1 file changed

+47
-17
lines changed

revision.c

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3755,25 +3755,18 @@ int rewrite_parents(struct rev_info *revs, struct commit *commit,
37553755
return 0;
37563756
}
37573757

3758-
static int commit_rewrite_person(struct strbuf *buf, const char *what, struct string_list *mailmap)
3758+
/*
3759+
* Returns the difference between the new and old length of the ident line.
3760+
*/
3761+
static ssize_t rewrite_ident_line(const char *person, size_t len,
3762+
struct strbuf *buf,
3763+
struct string_list *mailmap)
37593764
{
3760-
char *person, *endp;
3761-
size_t len, namelen, maillen;
3765+
size_t namelen, maillen;
37623766
const char *name;
37633767
const char *mail;
37643768
struct ident_split ident;
37653769

3766-
person = strstr(buf->buf, what);
3767-
if (!person)
3768-
return 0;
3769-
3770-
person += strlen(what);
3771-
endp = strchr(person, '\n');
3772-
if (!endp)
3773-
return 0;
3774-
3775-
len = endp - person;
3776-
37773770
if (split_ident_line(&ident, person, len))
37783771
return 0;
37793772

@@ -3784,22 +3777,58 @@ static int commit_rewrite_person(struct strbuf *buf, const char *what, struct st
37843777

37853778
if (map_user(mailmap, &mail, &maillen, &name, &namelen)) {
37863779
struct strbuf namemail = STRBUF_INIT;
3780+
size_t newlen;
37873781

37883782
strbuf_addf(&namemail, "%.*s <%.*s>",
37893783
(int)namelen, name, (int)maillen, mail);
37903784

37913785
strbuf_splice(buf, ident.name_begin - buf->buf,
37923786
ident.mail_end - ident.name_begin + 1,
37933787
namemail.buf, namemail.len);
3788+
newlen = namemail.len;
37943789

37953790
strbuf_release(&namemail);
37963791

3797-
return 1;
3792+
return newlen - (ident.mail_end - ident.name_begin);
37983793
}
37993794

38003795
return 0;
38013796
}
38023797

3798+
static void commit_rewrite_person(struct strbuf *buf, const char **header,
3799+
struct string_list *mailmap)
3800+
{
3801+
size_t buf_offset = 0;
3802+
3803+
if (!mailmap)
3804+
return;
3805+
3806+
for (;;) {
3807+
const char *person, *line;
3808+
size_t i;
3809+
int found_header = 0;
3810+
3811+
line = buf->buf + buf_offset;
3812+
if (!*line || *line == '\n')
3813+
return; /* End of headers */
3814+
3815+
for (i = 0; header[i]; i++)
3816+
if (skip_prefix(line, header[i], &person)) {
3817+
const char *endp = strchrnul(person, '\n');
3818+
found_header = 1;
3819+
buf_offset += endp - line;
3820+
buf_offset += rewrite_ident_line(person, endp - person, buf, mailmap);
3821+
break;
3822+
}
3823+
3824+
if (!found_header) {
3825+
buf_offset = strchrnul(line, '\n') - buf->buf;
3826+
if (buf->buf[buf_offset] == '\n')
3827+
buf_offset++;
3828+
}
3829+
}
3830+
}
3831+
38033832
static int commit_match(struct commit *commit, struct rev_info *opt)
38043833
{
38053834
int retval;
@@ -3832,11 +3861,12 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
38323861
strbuf_addstr(&buf, message);
38333862

38343863
if (opt->grep_filter.header_list && opt->mailmap) {
3864+
const char *commit_headers[] = { "author ", "committer ", NULL };
3865+
38353866
if (!buf.len)
38363867
strbuf_addstr(&buf, message);
38373868

3838-
commit_rewrite_person(&buf, "\nauthor ", opt->mailmap);
3839-
commit_rewrite_person(&buf, "\ncommitter ", opt->mailmap);
3869+
commit_rewrite_person(&buf, commit_headers, opt->mailmap);
38403870
}
38413871

38423872
/* Append "fake" message parts as needed */

0 commit comments

Comments
 (0)