@matheusbsbs / matheus-bagliano / commits / 0b9a969e0f
Fork 0

git-fmt-merge-msg: make it usable from other builtins

Move all functionality (except config and option parsing) from cmd_fmt_merge_msg() to fmt_merge_msg(), so that other builtins can use it without a child process. All functions have been changed to use strbufs, and now only cmd_fmt_merge_msg() reads directly from a file / writes anything to stdout. Signed-off-by: Miklos Vajna <vmiklos@frugalware.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Miklos Vajna committed Jun 27, 2008 at 18:21 UTC 0b9a969e0fbb0a09e9de931cfe27005cbfd6cb7d
2 files changed +92 -66
builtin-fmt-merge-msg.c
+89 -66
@@ -159,23 +159,24 @@ static int handle_line(char *line)
159 }
160
161 static void print_joined(const char *singular, const char *plural,
162 - struct list *list)
162 + struct list *list, struct strbuf *out)
163 {
164 if (list->nr == 0)
165 return;
166 if (list->nr == 1) {
167 - printf("%s%s", singular, list->list[0]);
167 + strbuf_addf(out, "%s%s", singular, list->list[0]);
168 } else {
169 int i;
170 - printf("%s", plural);
170 + strbuf_addstr(out, plural);
171 for (i = 0; i < list->nr - 1; i++)
172 - printf("%s%s", i > 0 ? ", " : "", list->list[i]);
173 - printf(" and %s", list->list[list->nr - 1]);
172 + strbuf_addf(out, "%s%s", i > 0 ? ", " : "", list->list[i]);
173 + strbuf_addf(out, " and %s", list->list[list->nr - 1]);
174 }
175 }
176
177 static void shortlog(const char *name, unsigned char *sha1,
178 - struct commit *head, struct rev_info *rev, int limit)
178 + struct commit *head, struct rev_info *rev, int limit,
179 + struct strbuf *out)
180 {
181 int i, count = 0;
182 struct commit *commit;
@@ -232,15 +233,15 @@ static void shortlog(const char *name, unsigned char *sha1,
233 }
234
235 if (count > limit)
235 - printf("\n* %s: (%d commits)\n", name, count);
236 + strbuf_addf(out, "\n* %s: (%d commits)\n", name, count);
237 else
237 - printf("\n* %s:\n", name);
238 + strbuf_addf(out, "\n* %s:\n", name);
239
240 for (i = 0; i < subjects.nr; i++)
241 if (i >= limit)
241 - printf(" ...\n");
242 + strbuf_addf(out, " ...\n");
243 else
243 - printf(" %s\n", subjects.list[i]);
244 + strbuf_addf(out, " %s\n", subjects.list[i]);
245
246 clear_commit_marks((struct commit *)branch, flags);
247 clear_commit_marks(head, flags);
@@ -251,43 +252,13 @@ static void shortlog(const char *name, unsigned char *sha1,
252 free_list(&subjects);
253 }
254
254 -int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
255 -{
256 - int limit = 20, i = 0;
255 +int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
256 + int limit = 20, i = 0, pos = 0;
257 char line[1024];
258 - FILE *in = stdin;
259 - const char *sep = "";
258 + char *p = line, *sep = "";
259 unsigned char head_sha1[20];
260 const char *current_branch;
261
263 - git_config(fmt_merge_msg_config, NULL);
264 -
265 - while (argc > 1) {
266 - if (!strcmp(argv[1], "--log") || !strcmp(argv[1], "--summary"))
267 - merge_summary = 1;
268 - else if (!strcmp(argv[1], "--no-log")
269 - || !strcmp(argv[1], "--no-summary"))
270 - merge_summary = 0;
271 - else if (!strcmp(argv[1], "-F") || !strcmp(argv[1], "--file")) {
272 - if (argc < 3)
273 - die ("Which file?");
274 - if (!strcmp(argv[2], "-"))
275 - in = stdin;
276 - else {
277 - fclose(in);
278 - in = fopen(argv[2], "r");
279 - if (!in)
280 - die("cannot open %s", argv[2]);
281 - }
282 - argc--; argv++;
283 - } else
284 - break;
285 - argc--; argv++;
286 - }
287 -
288 - if (argc > 1)
289 - usage(fmt_merge_msg_usage);
290 -
262 /* get current branch */
263 current_branch = resolve_ref("HEAD", head_sha1, 1, NULL);
264 if (!current_branch)
@@ -295,75 +266,127 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
266 if (!prefixcmp(current_branch, "refs/heads/"))
267 current_branch += 11;
268
298 - while (fgets(line, sizeof(line), in)) {
269 + /* get a line */
270 + while (pos < in->len) {
271 + int len;
272 + char *newline;
273 +
274 + p = in->buf + pos;
275 + newline = strchr(p, '\n');
276 + len = newline ? newline - p : strlen(p);
277 + pos += len + !!newline;
278 i++;
300 - if (line[0] == 0)
301 - continue;
302 - if (handle_line(line))
303 - die ("Error in line %d: %s", i, line);
279 + p[len] = 0;
280 + if (handle_line(p))
281 + die ("Error in line %d: %.*s", i, len, p);
282 }
283
306 - printf("Merge ");
284 + strbuf_addstr(out, "Merge ");
285 for (i = 0; i < srcs.nr; i++) {
286 struct src_data *src_data = srcs.payload[i];
287 const char *subsep = "";
288
311 - printf(sep);
289 + strbuf_addstr(out, sep);
290 sep = "; ";
291
292 if (src_data->head_status == 1) {
315 - printf(srcs.list[i]);
293 + strbuf_addstr(out, srcs.list[i]);
294 continue;
295 }
296 if (src_data->head_status == 3) {
297 subsep = ", ";
320 - printf("HEAD");
298 + strbuf_addstr(out, "HEAD");
299 }
300 if (src_data->branch.nr) {
323 - printf(subsep);
301 + strbuf_addstr(out, subsep);
302 subsep = ", ";
325 - print_joined("branch ", "branches ", &src_data->branch);
303 + print_joined("branch ", "branches ", &src_data->branch,
304 + out);
305 }
306 if (src_data->r_branch.nr) {
328 - printf(subsep);
307 + strbuf_addstr(out, subsep);
308 subsep = ", ";
309 print_joined("remote branch ", "remote branches ",
331 - &src_data->r_branch);
310 + &src_data->r_branch, out);
311 }
312 if (src_data->tag.nr) {
334 - printf(subsep);
313 + strbuf_addstr(out, subsep);
314 subsep = ", ";
336 - print_joined("tag ", "tags ", &src_data->tag);
315 + print_joined("tag ", "tags ", &src_data->tag, out);
316 }
317 if (src_data->generic.nr) {
339 - printf(subsep);
340 - print_joined("commit ", "commits ", &src_data->generic);
318 + strbuf_addstr(out, subsep);
319 + print_joined("commit ", "commits ", &src_data->generic,
320 + out);
321 }
322 if (strcmp(".", srcs.list[i]))
343 - printf(" of %s", srcs.list[i]);
323 + strbuf_addf(out, " of %s", srcs.list[i]);
324 }
325
326 if (!strcmp("master", current_branch))
347 - putchar('\n');
327 + strbuf_addch(out, '\n');
328 else
349 - printf(" into %s\n", current_branch);
329 + strbuf_addf(out, " into %s\n", current_branch);
330
331 if (merge_summary) {
332 struct commit *head;
333 struct rev_info rev;
334
335 head = lookup_commit(head_sha1);
356 - init_revisions(&rev, prefix);
336 + init_revisions(&rev, NULL);
337 rev.commit_format = CMIT_FMT_ONELINE;
338 rev.ignore_merges = 1;
339 rev.limited = 1;
340
341 for (i = 0; i < origins.nr; i++)
342 shortlog(origins.list[i], origins.payload[i],
363 - head, &rev, limit);
343 + head, &rev, limit, out);
344 }
345 + return 0;
346 +}
347 +
348 +int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
349 +{
350 + FILE *in = stdin;
351 + struct strbuf input, output;
352 + int ret;
353 +
354 + git_config(fmt_merge_msg_config, NULL);
355 +
356 + while (argc > 1) {
357 + if (!strcmp(argv[1], "--log") || !strcmp(argv[1], "--summary"))
358 + merge_summary = 1;
359 + else if (!strcmp(argv[1], "--no-log")
360 + || !strcmp(argv[1], "--no-summary"))
361 + merge_summary = 0;
362 + else if (!strcmp(argv[1], "-F") || !strcmp(argv[1], "--file")) {
363 + if (argc < 3)
364 + die ("Which file?");
365 + if (!strcmp(argv[2], "-"))
366 + in = stdin;
367 + else {
368 + fclose(in);
369 + in = fopen(argv[2], "r");
370 + if (!in)
371 + die("cannot open %s", argv[2]);
372 + }
373 + argc--; argv++;
374 + } else
375 + break;
376 + argc--; argv++;
377 + }
378 +
379 + if (argc > 1)
380 + usage(fmt_merge_msg_usage);
381
366 - /* No cleanup yet; is standalone anyway */
382 + strbuf_init(&input, 0);
383 + if (strbuf_read(&input, fileno(in), 0) < 0)
384 + die("could not read input file %s", strerror(errno));
385 + strbuf_init(&output, 0);
386
387 + ret = fmt_merge_msg(merge_summary, &input, &output);
388 + if (ret)
389 + return ret;
390 + printf("%s", output.buf);
391 return 0;
392 }
builtin.h
+3
@@ -2,6 +2,7 @@
2 #define BUILTIN_H
3
4 #include "git-compat-util.h"
5 +#include "strbuf.h"
6
7 extern const char git_version_string[];
8 extern const char git_usage_string[];
@@ -11,6 +12,8 @@ extern void list_common_cmds_help(void);
12 extern void help_unknown_cmd(const char *cmd);
13 extern void prune_packed_objects(int);
14 extern int read_line_with_nul(char *buf, int size, FILE *file);
15 +extern int fmt_merge_msg(int merge_summary, struct strbuf *in,
16 + struct strbuf *out);
17
18 extern int cmd_add(int argc, const char **argv, const char *prefix);
19 extern int cmd_annotate(int argc, const char **argv, const char *prefix);