diff options
Diffstat (limited to 'builtin/am.c')
-rw-r--r-- | builtin/am.c | 86 |
1 files changed, 38 insertions, 48 deletions
diff --git a/builtin/am.c b/builtin/am.c index 4e396c8321..d003939bc5 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -27,6 +27,7 @@ #include "notes-utils.h" #include "rerere.h" #include "prompt.h" +#include "mailinfo.h" /** * Returns 1 if the file is empty or does not exist, 0 otherwise. @@ -45,21 +46,6 @@ static int is_empty_file(const char *filename) } /** - * Like strbuf_getline(), but treats both '\n' and "\r\n" as line terminators. - */ -static int strbuf_getline_crlf(struct strbuf *sb, FILE *fp) -{ - if (strbuf_getwholeline(sb, fp, '\n')) - return EOF; - if (sb->buf[sb->len - 1] == '\n') { - strbuf_setlen(sb, sb->len - 1); - if (sb->len > 0 && sb->buf[sb->len - 1] == '\r') - strbuf_setlen(sb, sb->len - 1); - } - return 0; -} - -/** * Returns the length of the first line of msg. */ static int linelen(const char *msg) @@ -283,7 +269,7 @@ static char *read_shell_var(FILE *fp, const char *key) struct strbuf sb = STRBUF_INIT; const char *str; - if (strbuf_getline(&sb, fp, '\n')) + if (strbuf_getline_lf(&sb, fp)) goto fail; if (!skip_prefix(sb.buf, key, &str)) @@ -572,7 +558,7 @@ static int copy_notes_for_rebase(const struct am_state *state) fp = xfopen(am_path(state, "rewritten"), "r"); - while (!strbuf_getline(&sb, fp, '\n')) { + while (!strbuf_getline_lf(&sb, fp)) { unsigned char from_obj[GIT_SHA1_RAWSZ], to_obj[GIT_SHA1_RAWSZ]; if (sb.len != GIT_SHA1_HEXSZ * 2 + 1) { @@ -627,7 +613,7 @@ static int is_mail(FILE *fp) if (regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) die("invalid pattern: %s", header_regex); - while (!strbuf_getline_crlf(&sb, fp)) { + while (!strbuf_getline(&sb, fp)) { if (!sb.len) break; /* End of header */ @@ -674,7 +660,7 @@ static int detect_patch_format(const char **paths) fp = xfopen(*paths, "r"); - while (!strbuf_getline_crlf(&l1, fp)) { + while (!strbuf_getline(&l1, fp)) { if (l1.len) break; } @@ -695,9 +681,9 @@ static int detect_patch_format(const char **paths) } strbuf_reset(&l2); - strbuf_getline_crlf(&l2, fp); + strbuf_getline(&l2, fp); strbuf_reset(&l3); - strbuf_getline_crlf(&l3, fp); + strbuf_getline(&l3, fp); /* * If the second line is empty and the third is a From, Author or Date @@ -816,7 +802,7 @@ static int stgit_patch_to_mail(FILE *out, FILE *in, int keep_cr) struct strbuf sb = STRBUF_INIT; int subject_printed = 0; - while (!strbuf_getline(&sb, in, '\n')) { + while (!strbuf_getline_lf(&sb, in)) { const char *str; if (str_isspace(sb.buf)) @@ -874,7 +860,7 @@ static int split_mail_stgit_series(struct am_state *state, const char **paths, return error(_("could not open '%s' for reading: %s"), *paths, strerror(errno)); - while (!strbuf_getline(&sb, fp, '\n')) { + while (!strbuf_getline_lf(&sb, fp)) { if (*sb.buf == '#') continue; /* skip comment lines */ @@ -899,7 +885,7 @@ static int hg_patch_to_mail(FILE *out, FILE *in, int keep_cr) { struct strbuf sb = STRBUF_INIT; - while (!strbuf_getline(&sb, in, '\n')) { + while (!strbuf_getline_lf(&sb, in)) { const char *str; if (skip_prefix(sb.buf, "# User ", &str)) @@ -1258,62 +1244,65 @@ static void am_append_signoff(struct am_state *state) static int parse_mail(struct am_state *state, const char *mail) { FILE *fp; - struct child_process cp = CHILD_PROCESS_INIT; struct strbuf sb = STRBUF_INIT; struct strbuf msg = STRBUF_INIT; struct strbuf author_name = STRBUF_INIT; struct strbuf author_date = STRBUF_INIT; struct strbuf author_email = STRBUF_INIT; int ret = 0; + struct mailinfo mi; - cp.git_cmd = 1; - cp.in = xopen(mail, O_RDONLY, 0); - cp.out = xopen(am_path(state, "info"), O_WRONLY | O_CREAT, 0777); + setup_mailinfo(&mi); - argv_array_push(&cp.args, "mailinfo"); - argv_array_push(&cp.args, state->utf8 ? "-u" : "-n"); + if (state->utf8) + mi.metainfo_charset = get_commit_output_encoding(); + else + mi.metainfo_charset = NULL; switch (state->keep) { case KEEP_FALSE: break; case KEEP_TRUE: - argv_array_push(&cp.args, "-k"); + mi.keep_subject = 1; break; case KEEP_NON_PATCH: - argv_array_push(&cp.args, "-b"); + mi.keep_non_patch_brackets_in_subject = 1; break; default: die("BUG: invalid value for state->keep"); } if (state->message_id) - argv_array_push(&cp.args, "-m"); + mi.add_message_id = 1; switch (state->scissors) { case SCISSORS_UNSET: break; case SCISSORS_FALSE: - argv_array_push(&cp.args, "--no-scissors"); + mi.use_scissors = 0; break; case SCISSORS_TRUE: - argv_array_push(&cp.args, "--scissors"); + mi.use_scissors = 1; break; default: die("BUG: invalid value for state->scissors"); } - argv_array_push(&cp.args, am_path(state, "msg")); - argv_array_push(&cp.args, am_path(state, "patch")); - - if (run_command(&cp) < 0) + mi.input = fopen(mail, "r"); + if (!mi.input) + die("could not open input"); + mi.output = fopen(am_path(state, "info"), "w"); + if (!mi.output) + die("could not open output 'info'"); + if (mailinfo(&mi, am_path(state, "msg"), am_path(state, "patch"))) die("could not parse patch"); - close(cp.in); - close(cp.out); + fclose(mi.input); + fclose(mi.output); /* Extract message and author information */ fp = xfopen(am_path(state, "info"), "r"); - while (!strbuf_getline(&sb, fp, '\n')) { + while (!strbuf_getline_lf(&sb, fp)) { const char *x; if (skip_prefix(sb.buf, "Subject: ", &x)) { @@ -1341,8 +1330,7 @@ static int parse_mail(struct am_state *state, const char *mail) } strbuf_addstr(&msg, "\n\n"); - if (strbuf_read_file(&msg, am_path(state, "msg"), 0) < 0) - die_errno(_("could not read '%s'"), am_path(state, "msg")); + strbuf_addbuf(&msg, &mi.log_message); strbuf_stripspace(&msg, 0); if (state->signoff) @@ -1366,6 +1354,7 @@ finish: strbuf_release(&author_email); strbuf_release(&author_name); strbuf_release(&sb); + clear_mailinfo(&mi); return ret; } @@ -1379,7 +1368,7 @@ static int get_mail_commit_sha1(unsigned char *commit_id, const char *mail) FILE *fp = xfopen(mail, "r"); const char *x; - if (strbuf_getline(&sb, fp, '\n')) + if (strbuf_getline_lf(&sb, fp)) return -1; if (!skip_prefix(sb.buf, "From ", &x)) @@ -1437,7 +1426,7 @@ static void get_commit_info(struct am_state *state, struct commit *commit) assert(!state->msg); msg = strstr(buffer, "\n\n"); if (!msg) - die(_("unable to parse commit %s"), sha1_to_hex(commit->object.sha1)); + die(_("unable to parse commit %s"), oid_to_hex(&commit->object.oid)); state->msg = xstrdup(msg + 2); state->msg_len = strlen(state->msg); } @@ -1653,7 +1642,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa init_revisions(&rev_info, NULL); rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS; - diff_opt_parse(&rev_info.diffopt, &diff_filter_str, 1); + diff_opt_parse(&rev_info.diffopt, &diff_filter_str, 1, rev_info.prefix); add_pending_sha1(&rev_info, "HEAD", our_tree, 0); diff_setup_done(&rev_info.diffopt); run_diff_index(&rev_info, 1); @@ -1817,7 +1806,7 @@ static int do_interactive(struct am_state *state) if (!pager) pager = "cat"; - argv_array_push(&cp.args, pager); + prepare_pager_args(&cp, pager); argv_array_push(&cp.args, am_path(state, "patch")); run_command(&cp); } @@ -1935,6 +1924,7 @@ next: */ if (!state->rebasing) { am_destroy(state); + close_all_packs(); run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); } } |