show: suppress extra newline when showing annotated tag
[gitweb.git] / log-tree.c
index 84a74e544b7bcc20c887f321e389ecf3cfb560d6..6f73c17d74bee326a40505b29bba762bade2451e 100644 (file)
@@ -6,6 +6,7 @@
 #include "log-tree.h"
 #include "reflog-walk.h"
 #include "refs.h"
+#include "string-list.h"
 
 struct decoration name_decoration = { "object names" };
 
@@ -24,6 +25,7 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in
        struct object *obj = parse_object(sha1);
        if (!obj)
                return 0;
+       refname = prettify_refname(refname);
        add_name_decoration("", refname, obj);
        while (obj->type == OBJ_TAG) {
                obj = ((struct tag *)obj)->tagged;
@@ -79,18 +81,18 @@ void show_decorations(struct rev_info *opt, struct commit *commit)
  */
 static int detect_any_signoff(char *letter, int size)
 {
-       char ch, *cp;
+       char *cp;
        int seen_colon = 0;
        int seen_at = 0;
        int seen_name = 0;
        int seen_head = 0;
 
        cp = letter + size;
-       while (letter <= --cp && (ch = *cp) == '\n')
+       while (letter <= --cp && *cp == '\n')
                continue;
 
        while (letter <= cp) {
-               ch = *cp--;
+               char ch = *cp--;
                if (ch == '\n')
                        break;
 
@@ -178,13 +180,31 @@ static int has_non_ascii(const char *s)
        return 0;
 }
 
-void log_write_email_headers(struct rev_info *opt, const char *name,
+void get_patch_filename(struct commit *commit, int nr, const char *suffix,
+                       struct strbuf *buf)
+{
+       int suffix_len = strlen(suffix) + 1;
+       int start_len = buf->len;
+
+       strbuf_addf(buf, commit ? "%04d-" : "%d", nr);
+       if (commit) {
+               int max_len = start_len + FORMAT_PATCH_NAME_MAX - suffix_len;
+
+               format_commit_message(commit, "%f", buf, DATE_NORMAL);
+               if (max_len < buf->len)
+                       strbuf_setlen(buf, max_len);
+               strbuf_addstr(buf, suffix);
+       }
+}
+
+void log_write_email_headers(struct rev_info *opt, struct commit *commit,
                             const char **subject_p,
                             const char **extra_headers_p,
                             int *need_8bit_cte_p)
 {
        const char *subject = NULL;
        const char *extra_headers = opt->extra_headers;
+       const char *name = sha1_to_hex(commit->object.sha1);
 
        *need_8bit_cte_p = 0; /* unknown */
        if (opt->total > 0) {
@@ -211,14 +231,19 @@ void log_write_email_headers(struct rev_info *opt, const char *name,
                printf("Message-Id: <%s>\n", opt->message_id);
                graph_show_oneline(opt->graph);
        }
-       if (opt->ref_message_id) {
-               printf("In-Reply-To: <%s>\nReferences: <%s>\n",
-                      opt->ref_message_id, opt->ref_message_id);
+       if (opt->ref_message_ids && opt->ref_message_ids->nr > 0) {
+               int i, n;
+               n = opt->ref_message_ids->nr;
+               printf("In-Reply-To: <%s>\n", opt->ref_message_ids->items[n-1].string);
+               for (i = 0; i < n; i++)
+                       printf("%s<%s>\n", (i > 0 ? "\t" : "References: "),
+                              opt->ref_message_ids->items[i].string);
                graph_show_oneline(opt->graph);
        }
        if (opt->mime_boundary) {
                static char subject_buffer[1024];
                static char buffer[1024];
+               struct strbuf filename =  STRBUF_INIT;
                *need_8bit_cte_p = -1; /* NEVER */
                snprintf(subject_buffer, sizeof(subject_buffer) - 1,
                         "%s"
@@ -237,18 +262,21 @@ void log_write_email_headers(struct rev_info *opt, const char *name,
                         mime_boundary_leader, opt->mime_boundary);
                extra_headers = subject_buffer;
 
+               get_patch_filename(opt->numbered_files ? NULL : commit, opt->nr,
+                                   opt->patch_suffix, &filename);
                snprintf(buffer, sizeof(buffer) - 1,
                         "\n--%s%s\n"
                         "Content-Type: text/x-patch;"
-                        " name=\"%s.diff\"\n"
+                        " name=\"%s\"\n"
                         "Content-Transfer-Encoding: 8bit\n"
                         "Content-Disposition: %s;"
-                        " filename=\"%s.diff\"\n\n",
+                        " filename=\"%s\"\n\n",
                         mime_boundary_leader, opt->mime_boundary,
-                        name,
+                        filename.buf,
                         opt->no_inline ? "attachment" : "inline",
-                        name);
+                        filename.buf);
                opt->diffopt.stat_sep = buffer;
+               strbuf_release(&filename);
        }
        *subject_p = subject;
        *extra_headers_p = extra_headers;
@@ -293,7 +321,8 @@ void show_log(struct rev_info *opt)
        }
 
        /*
-        * If use_terminator is set, add a newline at the end of the entry.
+        * If use_terminator is set, we already handled any record termination
+        * at the end of the last record.
         * Otherwise, add a diffopt.line_termination character before all
         * entries but the first.  (IOW, as a separator between entries)
         */
@@ -328,8 +357,7 @@ void show_log(struct rev_info *opt)
         */
 
        if (opt->commit_format == CMIT_FMT_EMAIL) {
-               log_write_email_headers(opt, sha1_to_hex(commit->object.sha1),
-                                       &subject, &extra_headers,
+               log_write_email_headers(opt, commit, &subject, &extra_headers,
                                        &need_8bit_cte);
        } else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
                fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);