Merge branch 'nd/git-common-dir-fix' into maint
[gitweb.git] / builtin / am.c
index 4e396c832139aa3c4ae4e68e9d265b0107817aa9..95decc6a594a2cf379501a478fd2cdf207cecdc5 100644 (file)
@@ -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.
@@ -1258,58 +1259,61 @@ 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");
@@ -1341,8 +1345,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 +1369,7 @@ static int parse_mail(struct am_state *state, const char *mail)
        strbuf_release(&author_email);
        strbuf_release(&author_name);
        strbuf_release(&sb);
+       clear_mailinfo(&mi);
        return ret;
 }
 
@@ -1437,7 +1441,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 +1657,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);
@@ -1935,6 +1939,7 @@ static void am_run(struct am_state *state, int resume)
         */
        if (!state->rebasing) {
                am_destroy(state);
+               close_all_packs();
                run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
        }
 }