format-patch: improve head calculation for cover-letter
[gitweb.git] / log-tree.c
index 5dc45c4812bdfd0d7a6b71d529eaa37df8178186..7cc7d598e712fab531f7c6f938be17c317161f3e 100644 (file)
@@ -9,6 +9,7 @@
 #include "string-list.h"
 #include "color.h"
 #include "gpg-interface.h"
+#include "sequencer.h"
 
 struct decoration name_decoration = { "object names" };
 
@@ -206,89 +207,6 @@ void show_decorations(struct rev_info *opt, struct commit *commit)
        putchar(')');
 }
 
-/*
- * Search for "^[-A-Za-z]+: [^@]+@" pattern. It usually matches
- * Signed-off-by: and Acked-by: lines.
- */
-static int detect_any_signoff(char *letter, int size)
-{
-       char *cp;
-       int seen_colon = 0;
-       int seen_at = 0;
-       int seen_name = 0;
-       int seen_head = 0;
-
-       cp = letter + size;
-       while (letter <= --cp && *cp == '\n')
-               continue;
-
-       while (letter <= cp) {
-               char ch = *cp--;
-               if (ch == '\n')
-                       break;
-
-               if (!seen_at) {
-                       if (ch == '@')
-                               seen_at = 1;
-                       continue;
-               }
-               if (!seen_colon) {
-                       if (ch == '@')
-                               return 0;
-                       else if (ch == ':')
-                               seen_colon = 1;
-                       else
-                               seen_name = 1;
-                       continue;
-               }
-               if (('A' <= ch && ch <= 'Z') ||
-                   ('a' <= ch && ch <= 'z') ||
-                   ch == '-') {
-                       seen_head = 1;
-                       continue;
-               }
-               /* no empty last line doesn't match */
-               return 0;
-       }
-       return seen_head && seen_name;
-}
-
-static void append_signoff(struct strbuf *sb, const char *signoff)
-{
-       static const char signed_off_by[] = "Signed-off-by: ";
-       size_t signoff_len = strlen(signoff);
-       int has_signoff = 0;
-       char *cp;
-
-       cp = sb->buf;
-
-       /* First see if we already have the sign-off by the signer */
-       while ((cp = strstr(cp, signed_off_by))) {
-
-               has_signoff = 1;
-
-               cp += strlen(signed_off_by);
-               if (cp + signoff_len >= sb->buf + sb->len)
-                       break;
-               if (strncmp(cp, signoff, signoff_len))
-                       continue;
-               if (!isspace(cp[signoff_len]))
-                       continue;
-               /* we already have him */
-               return;
-       }
-
-       if (!has_signoff)
-               has_signoff = detect_any_signoff(sb->buf, sb->len);
-
-       if (!has_signoff)
-               strbuf_addch(sb, '\n');
-
-       strbuf_addstr(sb, signed_off_by);
-       strbuf_add(sb, signoff, signoff_len);
-       strbuf_addch(sb, '\n');
-}
-
 static unsigned int digits_in_number(unsigned int number)
 {
        unsigned int i = 10, result = 1;
@@ -444,7 +362,7 @@ static void show_signature(struct rev_info *opt, struct commit *commit)
 
        status = verify_signed_buffer(payload.buf, payload.len,
                                      signature.buf, signature.len,
-                                     &gpg_output);
+                                     &gpg_output, NULL);
        if (status && !gpg_output.len)
                strbuf_addstr(&gpg_output, "No signature\n");
 
@@ -508,20 +426,17 @@ static void show_one_mergetag(struct rev_info *opt,
        gpg_message_offset = verify_message.len;
 
        payload_size = parse_signature(extra->value, extra->len);
-       if ((extra->len <= payload_size) ||
-           (verify_signed_buffer(extra->value, payload_size,
-                                 extra->value + payload_size,
-                                 extra->len - payload_size,
-                                 &verify_message) &&
-            verify_message.len <= gpg_message_offset)) {
-               strbuf_addstr(&verify_message, "No signature\n");
-               status = -1;
-       }
-       else if (strstr(verify_message.buf + gpg_message_offset,
-                       ": Good signature from "))
-               status = 0;
-       else
-               status = -1;
+       status = -1;
+       if (extra->len > payload_size)
+               if (verify_signed_buffer(extra->value, payload_size,
+                                        extra->value + payload_size,
+                                        extra->len - payload_size,
+                                        &verify_message, NULL)) {
+                       if (verify_message.len <= gpg_message_offset)
+                               strbuf_addstr(&verify_message, "No signature\n");
+                       else
+                               status = 0;
+               }
 
        show_sig_lines(opt, status, verify_message.buf);
        strbuf_release(&verify_message);
@@ -672,8 +587,10 @@ void show_log(struct rev_info *opt)
        /*
         * And then the pretty-printed message itself
         */
-       if (ctx.need_8bit_cte >= 0)
-               ctx.need_8bit_cte = has_non_ascii(opt->add_signoff);
+       if (ctx.need_8bit_cte >= 0 && opt->add_signoff)
+               ctx.need_8bit_cte =
+                       has_non_ascii(fmt_name(getenv("GIT_COMMITTER_NAME"),
+                                              getenv("GIT_COMMITTER_EMAIL")));
        ctx.date_mode = opt->date_mode;
        ctx.date_mode_explicit = opt->date_mode_explicit;
        ctx.abbrev = opt->diffopt.abbrev;
@@ -686,7 +603,7 @@ void show_log(struct rev_info *opt)
        pretty_print_commit(&ctx, commit, &msgbuf);
 
        if (opt->add_signoff)
-               append_signoff(&msgbuf, opt->add_signoff);
+               append_signoff(&msgbuf, 0, APPEND_SIGNOFF_DEDUP);
 
        if ((ctx.fmt != CMIT_FMT_USERFORMAT) &&
            ctx.notes_message && *ctx.notes_message) {
@@ -792,11 +709,14 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
 {
        int showed_log;
        struct commit_list *parents;
-       unsigned const char *sha1 = commit->object.sha1;
+       unsigned const char *sha1;
 
        if (!opt->diff && !DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS))
                return 0;
 
+       parse_commit(commit);
+       sha1 = commit->tree->object.sha1;
+
        /* Root commit? */
        parents = commit->parents;
        if (!parents) {
@@ -819,7 +739,9 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
                         * parent, showing summary diff of the others
                         * we merged _in_.
                         */
-                       diff_tree_sha1(parents->item->object.sha1, sha1, "", &opt->diffopt);
+                       parse_commit(parents->item);
+                       diff_tree_sha1(parents->item->tree->object.sha1,
+                                      sha1, "", &opt->diffopt);
                        log_tree_diff_flush(opt);
                        return !opt->loginfo;
                }
@@ -832,7 +754,9 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
        for (;;) {
                struct commit *parent = parents->item;
 
-               diff_tree_sha1(parent->object.sha1, sha1, "", &opt->diffopt);
+               parse_commit(parent);
+               diff_tree_sha1(parent->tree->object.sha1,
+                              sha1, "", &opt->diffopt);
                log_tree_diff_flush(opt);
 
                showed_log |= !opt->loginfo;