shortlog: optimize "--summary" mode
[gitweb.git] / builtin / shortlog.c
index 35ebd17f80d7784f17023a4f76ac71e1317a94d0..973b50d417753618da50b9d74d290280bc914ff7 100644 (file)
@@ -91,63 +91,59 @@ static void insert_one_record(struct shortlog *log,
 
 static void read_from_stdin(struct shortlog *log)
 {
-       char author[1024], oneline[1024];
+       struct strbuf author = STRBUF_INIT;
+       struct strbuf oneline = STRBUF_INIT;
 
-       while (fgets(author, sizeof(author), stdin) != NULL) {
-               if (!(author[0] == 'A' || author[0] == 'a') ||
-                   !starts_with(author + 1, "uthor: "))
+       while (strbuf_getline(&author, stdin, '\n') != EOF) {
+               const char *v;
+               if (!skip_prefix(author.buf, "Author: ", &v) &&
+                   !skip_prefix(author.buf, "author ", &v))
                        continue;
-               while (fgets(oneline, sizeof(oneline), stdin) &&
-                      oneline[0] != '\n')
+               while (strbuf_getline(&oneline, stdin, '\n') != EOF &&
+                      oneline.len)
                        ; /* discard headers */
-               while (fgets(oneline, sizeof(oneline), stdin) &&
-                      oneline[0] == '\n')
+               while (strbuf_getline(&oneline, stdin, '\n') != EOF &&
+                      !oneline.len)
                        ; /* discard blanks */
-               insert_one_record(log, author + 8, oneline);
+               insert_one_record(log, v, oneline.buf);
        }
+       strbuf_release(&author);
+       strbuf_release(&oneline);
 }
 
 void shortlog_add_commit(struct shortlog *log, struct commit *commit)
 {
-       const char *author = NULL, *buffer;
-       struct strbuf buf = STRBUF_INIT;
-       struct strbuf ufbuf = STRBUF_INIT;
-
-       pp_commit_easy(CMIT_FMT_RAW, commit, &buf);
-       buffer = buf.buf;
-       while (*buffer && *buffer != '\n') {
-               const char *eol = strchr(buffer, '\n');
-
-               if (eol == NULL)
-                       eol = buffer + strlen(buffer);
-               else
-                       eol++;
-
-               if (starts_with(buffer, "author "))
-                       author = buffer + 7;
-               buffer = eol;
-       }
-       if (!author) {
+       struct strbuf author = STRBUF_INIT;
+       struct strbuf oneline = STRBUF_INIT;
+       struct pretty_print_context ctx = {0};
+
+       ctx.fmt = CMIT_FMT_USERFORMAT;
+       ctx.abbrev = log->abbrev;
+       ctx.subject = "";
+       ctx.after_subject = "";
+       ctx.date_mode.type = DATE_NORMAL;
+       ctx.output_encoding = get_log_output_encoding();
+
+       format_commit_message(commit, "%an <%ae>", &author, &ctx);
+       /* we can detect a total failure only by seeing " <>" in the output */
+       if (author.len <= 3) {
                warning(_("Missing author: %s"),
                    oid_to_hex(&commit->object.oid));
-               return;
+               goto out;
        }
-       if (log->user_format) {
-               struct pretty_print_context ctx = {0};
-               ctx.fmt = CMIT_FMT_USERFORMAT;
-               ctx.abbrev = log->abbrev;
-               ctx.subject = "";
-               ctx.after_subject = "";
-               ctx.date_mode.type = DATE_NORMAL;
-               ctx.output_encoding = get_log_output_encoding();
-               pretty_print_commit(&ctx, commit, &ufbuf);
-               buffer = ufbuf.buf;
-       } else if (*buffer) {
-               buffer++;
+
+       if (!log->summary) {
+               if (log->user_format)
+                       pretty_print_commit(&ctx, commit, &oneline);
+               else
+                       format_commit_message(commit, "%s", &oneline, &ctx);
        }
-       insert_one_record(log, author, !*buffer ? "<none>" : buffer);
-       strbuf_release(&ufbuf);
-       strbuf_release(&buf);
+
+       insert_one_record(log, author.buf, oneline.len ? oneline.buf : "<none>");
+
+out:
+       strbuf_release(&author);
+       strbuf_release(&oneline);
 }
 
 static void get_from_rev(struct rev_info *rev, struct shortlog *log)