Merge branch 'tr/log-tree-optim'
authorJunio C Hamano <gitster@pobox.com>
Tue, 2 Apr 2013 22:10:46 +0000 (15:10 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 2 Apr 2013 22:10:46 +0000 (15:10 -0700)
Optimize "log" that shows the difference between the parent and the
child.

* tr/log-tree-optim:
Avoid loading commits twice in log with diffs

1  2 
log-tree.c
diff --combined log-tree.c
index 92bb2bf48e641ee6161a0e10dd87d9ce06632f7c,8a34332e6df0d7a95406bf4f1c7772ce7fe14339..7cc7d598e712fab531f7c6f938be17c317161f3e
@@@ -9,7 -9,6 +9,7 @@@
  #include "string-list.h"
  #include "color.h"
  #include "gpg-interface.h"
 +#include "sequencer.h"
  
  struct decoration name_decoration = { "object names" };
  
@@@ -207,6 -206,89 +207,6 @@@ void show_decorations(struct rev_info *
        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;
@@@ -362,7 -444,7 +362,7 @@@ static void show_signature(struct rev_i
  
        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");
  
@@@ -426,17 -508,20 +426,17 @@@ static void show_one_mergetag(struct re
        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);
@@@ -587,10 -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;
        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) {
@@@ -709,11 -792,14 +709,14 @@@ static int log_tree_diff(struct rev_inf
  {
        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) {
                         * 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;
                }
        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;