am: make direct call to mailinfo
And finally the endgame. Instead of spawning "git mailinfo" via the run_command() API the same number of times as there are incoming patches, make direct internal call to the libified mailinfo() from "git am" to reduce the spawning overhead, which would matter on some platforms. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano committed
Oct 14, 2015 at 17:45 UTC
4b98bae2cbc6bf49a5fd7bab330191d002e6e2fc
1 file changed
+23
-19
builtin/am.c
+23
-19
@@ -27,6 +27,7 @@
27
#include "notes-utils.h"
28
#include "rerere.h"
29
#include "prompt.h"
30
+#include "mailinfo.h"
31
32
/**
33
* Returns 1 if the file is empty or does not exist, 0 otherwise.
@@ -1258,58 +1259,61 @@ static void am_append_signoff(struct am_state *state)
1259
static int parse_mail(struct am_state *state, const char *mail)
1260
{
1261
FILE *fp;
1261
- struct child_process cp = CHILD_PROCESS_INIT;
1262
struct strbuf sb = STRBUF_INIT;
1263
struct strbuf msg = STRBUF_INIT;
1264
struct strbuf author_name = STRBUF_INIT;
1265
struct strbuf author_date = STRBUF_INIT;
1266
struct strbuf author_email = STRBUF_INIT;
1267
int ret = 0;
1268
+ struct mailinfo mi;
1269
1269
- cp.git_cmd = 1;
1270
- cp.in = xopen(mail, O_RDONLY, 0);
1271
- cp.out = xopen(am_path(state, "info"), O_WRONLY | O_CREAT, 0777);
1270
+ setup_mailinfo(&mi);
1271
1273
- argv_array_push(&cp.args, "mailinfo");
1274
- argv_array_push(&cp.args, state->utf8 ? "-u" : "-n");
1272
+ if (state->utf8)
1273
+ mi.metainfo_charset = get_commit_output_encoding();
1274
+ else
1275
+ mi.metainfo_charset = NULL;
1276
1277
switch (state->keep) {
1278
case KEEP_FALSE:
1279
break;
1280
case KEEP_TRUE:
1280
- argv_array_push(&cp.args, "-k");
1281
+ mi.keep_subject = 1;
1282
break;
1283
case KEEP_NON_PATCH:
1283
- argv_array_push(&cp.args, "-b");
1284
+ mi.keep_non_patch_brackets_in_subject = 1;
1285
break;
1286
default:
1287
die("BUG: invalid value for state->keep");
1288
}
1289
1290
if (state->message_id)
1290
- argv_array_push(&cp.args, "-m");
1291
+ mi.add_message_id = 1;
1292
1293
switch (state->scissors) {
1294
case SCISSORS_UNSET:
1295
break;
1296
case SCISSORS_FALSE:
1296
- argv_array_push(&cp.args, "--no-scissors");
1297
+ mi.use_scissors = 0;
1298
break;
1299
case SCISSORS_TRUE:
1299
- argv_array_push(&cp.args, "--scissors");
1300
+ mi.use_scissors = 1;
1301
break;
1302
default:
1303
die("BUG: invalid value for state->scissors");
1304
}
1305
1305
- argv_array_push(&cp.args, am_path(state, "msg"));
1306
- argv_array_push(&cp.args, am_path(state, "patch"));
1307
-
1308
- if (run_command(&cp) < 0)
1306
+ mi.input = fopen(mail, "r");
1307
+ if (!mi.input)
1308
+ die("could not open input");
1309
+ mi.output = fopen(am_path(state, "info"), "w");
1310
+ if (!mi.output)
1311
+ die("could not open output 'info'");
1312
+ if (mailinfo(&mi, am_path(state, "msg"), am_path(state, "patch")))
1313
die("could not parse patch");
1314
1311
- close(cp.in);
1312
- close(cp.out);
1315
+ fclose(mi.input);
1316
+ fclose(mi.output);
1317
1318
/* Extract message and author information */
1319
fp = xfopen(am_path(state, "info"), "r");
@@ -1341,8 +1345,7 @@ static int parse_mail(struct am_state *state, const char *mail)
1345
}
1346
1347
strbuf_addstr(&msg, "\n\n");
1344
- if (strbuf_read_file(&msg, am_path(state, "msg"), 0) < 0)
1345
- die_errno(_("could not read '%s'"), am_path(state, "msg"));
1348
+ strbuf_addbuf(&msg, &mi.log_message);
1349
stripspace(&msg, 0);
1350
1351
if (state->signoff)
@@ -1366,6 +1369,7 @@ finish:
1369
strbuf_release(&author_email);
1370
strbuf_release(&author_name);
1371
strbuf_release(&sb);
1372
+ clear_mailinfo(&mi);
1373
return ret;
1374
}
1375