7 void shortlog_init(struct shortlog *log)
9 memset(log, 0, sizeof(*log));
11 read_mailmap(&log->mailmap, &log->common_repo_prefix);
13 log->list.strdup_strings = 1;
14 log->wrap = DEFAULT_WRAPLEN;
15 log->in1 = DEFAULT_INDENT1;
16 log->in2 = DEFAULT_INDENT2;
19 void shortlog_insert_one_record(struct shortlog *log,
23 const char *dot3 = log->common_repo_prefix;
25 struct string_list_item *item;
26 const char *mailbuf, *namebuf;
27 size_t namelen, maillen;
29 struct strbuf subject = STRBUF_INIT;
30 struct strbuf namemailbuf = STRBUF_INIT;
31 struct ident_split ident;
33 if (split_ident_line(&ident, author, strlen(author)))
36 namebuf = ident.name_begin;
37 mailbuf = ident.mail_begin;
38 namelen = ident.name_end - ident.name_begin;
39 maillen = ident.mail_end - ident.mail_begin;
41 map_user(&log->mailmap, &mailbuf, &maillen, &namebuf, &namelen);
42 strbuf_add(&namemailbuf, namebuf, namelen);
45 strbuf_addf(&namemailbuf, " <%.*s>", (int)maillen, mailbuf);
47 item = string_list_insert(&log->list, namemailbuf.buf);
48 if (item->util == NULL)
49 item->util = xcalloc(1, sizeof(struct string_list));
51 /* Skip any leading whitespace, including any blank lines. */
52 while (*oneline && isspace(*oneline))
54 eol = strchr(oneline, '\n');
56 eol = oneline + strlen(oneline);
57 if (!prefixcmp(oneline, "[PATCH")) {
58 char *eob = strchr(oneline, ']');
59 if (eob && (!eol || eob < eol))
62 while (*oneline && isspace(*oneline) && *oneline != '\n')
64 format_subject(&subject, oneline, " ");
65 buffer = strbuf_detach(&subject, NULL);
68 int dot3len = strlen(dot3);
70 while ((p = strstr(buffer, dot3)) != NULL) {
71 int taillen = strlen(p) - dot3len;
72 memcpy(p, "/.../", 5);
73 memmove(p + 5, p + dot3len, taillen + 1);
78 string_list_append(item->util, buffer);
81 void shortlog_add_commit(struct shortlog *log, struct commit *commit)
83 const char *author = NULL, *buffer;
84 struct strbuf buf = STRBUF_INIT;
85 struct strbuf ufbuf = STRBUF_INIT;
87 pp_commit_easy(CMIT_FMT_RAW, commit, &buf);
89 while (*buffer && *buffer != '\n') {
90 const char *eol = strchr(buffer, '\n');
93 eol = buffer + strlen(buffer);
97 if (!prefixcmp(buffer, "author "))
102 die(_("Missing author: %s"),
103 sha1_to_hex(commit->object.sha1));
104 if (log->user_format) {
105 struct pretty_print_context ctx = {0};
106 ctx.fmt = CMIT_FMT_USERFORMAT;
107 ctx.abbrev = log->abbrev;
109 ctx.after_subject = "";
110 ctx.date_mode = DATE_NORMAL;
111 ctx.output_encoding = get_log_output_encoding();
112 pretty_print_commit(&ctx, commit, &ufbuf);
114 } else if (*buffer) {
117 shortlog_insert_one_record(log, author, !*buffer ? "<none>" : buffer);
118 strbuf_release(&ufbuf);
119 strbuf_release(&buf);
122 static int compare_by_number(const void *a1, const void *a2)
124 const struct string_list_item *i1 = a1, *i2 = a2;
125 const struct string_list *l1 = i1->util, *l2 = i2->util;
129 else if (l1->nr == l2->nr)
135 static void add_wrapped_shortlog_msg(struct strbuf *sb, const char *s,
136 const struct shortlog *log)
138 strbuf_add_wrapped_text(sb, s, log->in1, log->in2, log->wrap);
139 strbuf_addch(sb, '\n');
142 void shortlog_output(struct shortlog *log)
145 struct strbuf sb = STRBUF_INIT;
147 if (log->sort_by_number)
148 qsort(log->list.items, log->list.nr, sizeof(struct string_list_item),
150 for (i = 0; i < log->list.nr; i++) {
151 struct string_list *onelines = log->list.items[i].util;
154 printf("%6d\t%s\n", onelines->nr, log->list.items[i].string);
156 printf("%s (%d):\n", log->list.items[i].string, onelines->nr);
157 for (j = onelines->nr - 1; j >= 0; j--) {
158 const char *msg = onelines->items[j].string;
160 if (log->wrap_lines) {
162 add_wrapped_shortlog_msg(&sb, msg, log);
163 fwrite(sb.buf, sb.len, 1, stdout);
166 printf(" %s\n", msg);
171 onelines->strdup_strings = 1;
172 string_list_clear(onelines, 0);
174 log->list.items[i].util = NULL;
178 log->list.strdup_strings = 1;
179 string_list_clear(&log->list, 1);
180 clear_mailmap(&log->mailmap);