]> git.ipfire.org Git - thirdparty/git.git/commitdiff
format-patch: return an allocated string from log_write_email_headers()
authorJeff King <peff@peff.net>
Wed, 20 Mar 2024 00:35:33 +0000 (20:35 -0400)
committerJunio C Hamano <gitster@pobox.com>
Wed, 20 Mar 2024 00:54:16 +0000 (17:54 -0700)
When pretty-printing a commit in the email format, we have to fill in
the "after subject" field of the pretty_print_context with any extra
headers the user provided (e.g., from "--to" or "--cc" options) plus any
special MIME headers.

We return an out-pointer that sometimes points to a newly heap-allocated
string and sometimes not. To avoid leaking, we store the allocated
version in a buffer with static lifetime, which is ugly. Worse, as we
extend the header feature, we'll end up having to repeat this ugly
pattern.

Instead, let's have our out-pointer pass ownership back to the caller,
and duplicate the string when necessary. This does mean one extra
allocation per commit when you use extra headers, but in the context of
format-patch which is showing diffs, I don't think that's even
measurable.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/log.c
log-tree.c
log-tree.h
pretty.h

index de1c1cbec1a666a5ed3fac58464136d4d0d53e92..ebd3f642dae3fac1407f4a8dbe91b18176bfbf42 100644 (file)
@@ -1370,6 +1370,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
                           encoding, need_8bit_cte);
        fprintf(rev->diffopt.file, "%s\n", sb.buf);
 
+       free(pp.after_subject);
        strbuf_release(&sb);
 
        shortlog_init(&log);
index 78e678e0e7926934e8d27005540e59e1cf3c9a39..c3e77064e42fcecac60f569b2dd27f5e22f83586 100644 (file)
@@ -470,11 +470,11 @@ void fmt_output_email_subject(struct strbuf *sb, struct rev_info *opt)
 }
 
 void log_write_email_headers(struct rev_info *opt, struct commit *commit,
-                            const char **extra_headers_p,
+                            char **extra_headers_p,
                             int *need_8bit_cte_p,
                             int maybe_multipart)
 {
-       const char *extra_headers = opt->extra_headers;
+       char *extra_headers = xstrdup_or_null(opt->extra_headers);
        const char *name = oid_to_hex(opt->zero_commit ?
                                      null_oid() : &commit->object.oid);
 
@@ -496,12 +496,11 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
                graph_show_oneline(opt->graph);
        }
        if (opt->mime_boundary && maybe_multipart) {
-               static struct strbuf subject_buffer = STRBUF_INIT;
+               struct strbuf subject_buffer = STRBUF_INIT;
                static struct strbuf buffer = STRBUF_INIT;
                struct strbuf filename =  STRBUF_INIT;
                *need_8bit_cte_p = -1; /* NEVER */
 
-               strbuf_reset(&subject_buffer);
                strbuf_reset(&buffer);
 
                strbuf_addf(&subject_buffer,
@@ -519,7 +518,8 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
                         extra_headers ? extra_headers : "",
                         mime_boundary_leader, opt->mime_boundary,
                         mime_boundary_leader, opt->mime_boundary);
-               extra_headers = subject_buffer.buf;
+               free(extra_headers);
+               extra_headers = strbuf_detach(&subject_buffer, NULL);
 
                if (opt->numbered_files)
                        strbuf_addf(&filename, "%d", opt->nr);
@@ -854,6 +854,7 @@ void show_log(struct rev_info *opt)
 
        strbuf_release(&msgbuf);
        free(ctx.notes_message);
+       free(ctx.after_subject);
 
        if (cmit_fmt_is_mail(ctx.fmt) && opt->idiff_oid1) {
                struct diff_queue_struct dq;
index 41c776fea52e6867800caf2eb919379fc6e54218..94978e2c838ce98bdd442006b942cce38e2ef6c8 100644 (file)
@@ -29,7 +29,7 @@ void format_decorations(struct strbuf *sb, const struct commit *commit,
                        int use_color, const struct decoration_options *opts);
 void show_decorations(struct rev_info *opt, struct commit *commit);
 void log_write_email_headers(struct rev_info *opt, struct commit *commit,
-                            const char **extra_headers_p,
+                            char **extra_headers_p,
                             int *need_8bit_cte_p,
                             int maybe_multipart);
 void load_ref_decorations(struct decoration_filter *filter, int flags);
index 021bc1d6582414ea89543c36098eb76c0312a8ee..9cc9e5d42b8525a40698420d8a3a6ad09742498a 100644 (file)
--- a/pretty.h
+++ b/pretty.h
@@ -35,7 +35,7 @@ struct pretty_print_context {
         */
        enum cmit_fmt fmt;
        int abbrev;
-       const char *after_subject;
+       char *after_subject;
        int preserve_subject;
        struct date_mode date_mode;
        unsigned date_mode_explicit:1;