@matheusbsbs / matheus-bagliano / commits / 552bcac3f9
Fork 0

Add API access to shortlog

Shortlog is gives a pretty simple API for cases where you're already identifying all of the individual commits. Make this available to other code instead of requiring them to use the revision API and command line. Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>

Daniel Barkalow committed Feb 25, 2008 at 18:24 UTC 552bcac3f9f34833cf546f8c197da4c1985a0b84
2 files changed +106 -68
builtin-shortlog.c
+80 -68
@@ -6,13 +6,11 @@
6 #include "revision.h"
7 #include "utf8.h"
8 #include "mailmap.h"
9 +#include "shortlog.h"
10
11 static const char shortlog_usage[] =
12 "git-shortlog [-n] [-s] [-e] [<commit-id>... ]";
13
13 -static char *common_repo_prefix;
14 -static int email;
15 -
14 static int compare_by_number(const void *a1, const void *a2)
15 {
16 const struct path_list_item *i1 = a1, *i2 = a2;
@@ -26,13 +24,11 @@ static int compare_by_number(const void *a1, const void *a2)
24 return -1;
25 }
26
29 -static struct path_list mailmap = {NULL, 0, 0, 0};
30 -
31 -static void insert_one_record(struct path_list *list,
27 +static void insert_one_record(struct shortlog *log,
28 const char *author,
29 const char *oneline)
30 {
35 - const char *dot3 = common_repo_prefix;
31 + const char *dot3 = log->common_repo_prefix;
32 char *buffer, *p;
33 struct path_list_item *item;
34 struct path_list *onelines;
@@ -47,7 +43,7 @@ static void insert_one_record(struct path_list *list,
43 eoemail = strchr(boemail, '>');
44 if (!eoemail)
45 return;
50 - if (!map_email(&mailmap, boemail+1, namebuf, sizeof(namebuf))) {
46 + if (!map_email(&log->mailmap, boemail+1, namebuf, sizeof(namebuf))) {
47 while (author < boemail && isspace(*author))
48 author++;
49 for (len = 0;
@@ -61,14 +57,14 @@ static void insert_one_record(struct path_list *list,
57 else
58 len = strlen(namebuf);
59
64 - if (email) {
60 + if (log->email) {
61 size_t room = sizeof(namebuf) - len - 1;
62 int maillen = eoemail - boemail + 1;
63 snprintf(namebuf + len, room, " %.*s", maillen, boemail);
64 }
65
66 buffer = xstrdup(namebuf);
71 - item = path_list_insert(buffer, list);
67 + item = path_list_insert(buffer, &log->list);
68 if (item->util == NULL)
69 item->util = xcalloc(1, sizeof(struct path_list));
70 else
@@ -114,7 +110,7 @@ static void insert_one_record(struct path_list *list,
110 onelines->items[onelines->nr++].path = buffer;
111 }
112
117 -static void read_from_stdin(struct path_list *list)
113 +static void read_from_stdin(struct shortlog *log)
114 {
115 char author[1024], oneline[1024];
116
@@ -128,38 +124,43 @@ static void read_from_stdin(struct path_list *list)
124 while (fgets(oneline, sizeof(oneline), stdin) &&
125 oneline[0] == '\n')
126 ; /* discard blanks */
131 - insert_one_record(list, author + 8, oneline);
127 + insert_one_record(log, author + 8, oneline);
128 }
129 }
130
135 -static void get_from_rev(struct rev_info *rev, struct path_list *list)
131 +void shortlog_add_commit(struct shortlog *log, struct commit *commit)
132 {
137 - struct commit *commit;
138 -
139 - prepare_revision_walk(rev);
140 - while ((commit = get_revision(rev)) != NULL) {
141 - const char *author = NULL, *buffer;
133 + const char *author = NULL, *buffer;
134
143 - buffer = commit->buffer;
144 - while (*buffer && *buffer != '\n') {
145 - const char *eol = strchr(buffer, '\n');
135 + buffer = commit->buffer;
136 + while (*buffer && *buffer != '\n') {
137 + const char *eol = strchr(buffer, '\n');
138
147 - if (eol == NULL)
148 - eol = buffer + strlen(buffer);
149 - else
150 - eol++;
139 + if (eol == NULL)
140 + eol = buffer + strlen(buffer);
141 + else
142 + eol++;
143
152 - if (!prefixcmp(buffer, "author "))
153 - author = buffer + 7;
154 - buffer = eol;
155 - }
156 - if (!author)
157 - die("Missing author: %s",
158 - sha1_to_hex(commit->object.sha1));
159 - if (*buffer)
160 - buffer++;
161 - insert_one_record(list, author, !*buffer ? "<none>" : buffer);
144 + if (!prefixcmp(buffer, "author "))
145 + author = buffer + 7;
146 + buffer = eol;
147 }
148 + if (!author)
149 + die("Missing author: %s",
150 + sha1_to_hex(commit->object.sha1));
151 + if (*buffer)
152 + buffer++;
153 + insert_one_record(log, author, !*buffer ? "<none>" : buffer);
154 +}
155 +
156 +static void get_from_rev(struct rev_info *rev, struct shortlog *log)
157 +{
158 + struct commit *commit;
159 +
160 + if (prepare_revision_walk(rev))
161 + die("revision walk setup failed");
162 + while ((commit = get_revision(rev)) != NULL)
163 + shortlog_add_commit(log, commit);
164 }
165
166 static int parse_uint(char const **arg, int comma)
@@ -211,29 +212,38 @@ static void parse_wrap_args(const char *arg, int *in1, int *in2, int *wrap)
212 die(wrap_arg_usage);
213 }
214
215 +void shortlog_init(struct shortlog *log)
216 +{
217 + memset(log, 0, sizeof(*log));
218 +
219 + read_mailmap(&log->mailmap, ".mailmap", &log->common_repo_prefix);
220 +
221 + log->list.strdup_paths = 1;
222 + log->wrap = DEFAULT_WRAPLEN;
223 + log->in1 = DEFAULT_INDENT1;
224 + log->in2 = DEFAULT_INDENT2;
225 +}
226 +
227 int cmd_shortlog(int argc, const char **argv, const char *prefix)
228 {
229 + struct shortlog log;
230 struct rev_info rev;
217 - struct path_list list = { NULL, 0, 0, 1 };
218 - int i, j, sort_by_number = 0, summary = 0;
219 - int wrap_lines = 0;
220 - int wrap = DEFAULT_WRAPLEN;
221 - int in1 = DEFAULT_INDENT1;
222 - int in2 = DEFAULT_INDENT2;
231 +
232 + shortlog_init(&log);
233
234 /* since -n is a shadowed rev argument, parse our args first */
235 while (argc > 1) {
236 if (!strcmp(argv[1], "-n") || !strcmp(argv[1], "--numbered"))
227 - sort_by_number = 1;
237 + log.sort_by_number = 1;
238 else if (!strcmp(argv[1], "-s") ||
239 !strcmp(argv[1], "--summary"))
230 - summary = 1;
240 + log.summary = 1;
241 else if (!strcmp(argv[1], "-e") ||
242 !strcmp(argv[1], "--email"))
233 - email = 1;
243 + log.email = 1;
244 else if (!prefixcmp(argv[1], "-w")) {
235 - wrap_lines = 1;
236 - parse_wrap_args(argv[1], &in1, &in2, &wrap);
245 + log.wrap_lines = 1;
246 + parse_wrap_args(argv[1], &log.in1, &log.in2, &log.wrap);
247 }
248 else if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
249 usage(shortlog_usage);
@@ -247,34 +257,38 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
257 if (argc > 1)
258 die ("unrecognized argument: %s", argv[1]);
259
250 - read_mailmap(&mailmap, ".mailmap", &common_repo_prefix);
251 -
260 /* assume HEAD if from a tty */
261 if (!rev.pending.nr && isatty(0))
262 add_head_to_pending(&rev);
263 if (rev.pending.nr == 0) {
256 - read_from_stdin(&list);
264 + read_from_stdin(&log);
265 }
266 else
259 - get_from_rev(&rev, &list);
267 + get_from_rev(&rev, &log);
268
261 - if (sort_by_number)
262 - qsort(list.items, list.nr, sizeof(struct path_list_item),
263 - compare_by_number);
269 + shortlog_output(&log);
270 + return 0;
271 +}
272
265 - for (i = 0; i < list.nr; i++) {
266 - struct path_list *onelines = list.items[i].util;
273 +void shortlog_output(struct shortlog *log)
274 +{
275 + int i, j;
276 + if (log->sort_by_number)
277 + qsort(log->list.items, log->list.nr, sizeof(struct path_list_item),
278 + compare_by_number);
279 + for (i = 0; i < log->list.nr; i++) {
280 + struct path_list *onelines = log->list.items[i].util;
281
268 - if (summary) {
269 - printf("%6d\t%s\n", onelines->nr, list.items[i].path);
282 + if (log->summary) {
283 + printf("%6d\t%s\n", onelines->nr, log->list.items[i].path);
284 } else {
271 - printf("%s (%d):\n", list.items[i].path, onelines->nr);
285 + printf("%s (%d):\n", log->list.items[i].path, onelines->nr);
286 for (j = onelines->nr - 1; j >= 0; j--) {
287 const char *msg = onelines->items[j].path;
288
275 - if (wrap_lines) {
276 - int col = print_wrapped_text(msg, in1, in2, wrap);
277 - if (col != wrap)
289 + if (log->wrap_lines) {
290 + int col = print_wrapped_text(msg, log->in1, log->in2, log->wrap);
291 + if (col != log->wrap)
292 putchar('\n');
293 }
294 else
@@ -286,13 +300,11 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
300 onelines->strdup_paths = 1;
301 path_list_clear(onelines, 1);
302 free(onelines);
289 - list.items[i].util = NULL;
303 + log->list.items[i].util = NULL;
304 }
305
292 - list.strdup_paths = 1;
293 - path_list_clear(&list, 1);
294 - mailmap.strdup_paths = 1;
295 - path_list_clear(&mailmap, 1);
296 -
297 - return 0;
306 + log->list.strdup_paths = 1;
307 + path_list_clear(&log->list, 1);
308 + log->mailmap.strdup_paths = 1;
309 + path_list_clear(&log->mailmap, 1);
310 }
shortlog.h new
+26
@@ -0,0 +1,26 @@
1 +#ifndef SHORTLOG_H
2 +#define SHORTLOG_H
3 +
4 +#include "path-list.h"
5 +
6 +struct shortlog {
7 + struct path_list list;
8 + int summary;
9 + int wrap_lines;
10 + int sort_by_number;
11 + int wrap;
12 + int in1;
13 + int in2;
14 +
15 + char *common_repo_prefix;
16 + int email;
17 + struct path_list mailmap;
18 +};
19 +
20 +void shortlog_init(struct shortlog *log);
21 +
22 +void shortlog_add_commit(struct shortlog *log, struct commit *commit);
23 +
24 +void shortlog_output(struct shortlog *log);
25 +
26 +#endif