builtin-am: implement committing applied patch

Implement do_commit(), which commits the index which contains the results of applying the patch, along with the extracted commit message and authorship information. Since 29b6754 (am: remove rebase-apply directory before gc, 2010-02-22), git gc --auto is also invoked to pack the loose objects that are created from making the commits. Signed-off-by: Paul Tan <pyokagan@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Paul Tan committed Aug 4, 2015 at 21:51 UTC c9e8d960b612d5962cd1e952916c2ab6f483e620
1 file changed +51 -4
builtin/am.c
+51 -4
@@ -11,6 +11,9 @@
11 #include "run-command.h"
12 #include "quote.h"
13 #include "lockfile.h"
14 +#include "cache-tree.h"
15 +#include "refs.h"
16 +#include "commit.h"
17
18 /**
19 * Returns 1 if the file is empty or does not exist, 0 otherwise.
@@ -673,11 +676,57 @@ static int run_apply(const struct am_state *state)
676 return 0;
677 }
678
679 +/**
680 + * Commits the current index with state->msg as the commit message and
681 + * state->author_name, state->author_email and state->author_date as the author
682 + * information.
683 + */
684 +static void do_commit(const struct am_state *state)
685 +{
686 + unsigned char tree[GIT_SHA1_RAWSZ], parent[GIT_SHA1_RAWSZ],
687 + commit[GIT_SHA1_RAWSZ];
688 + unsigned char *ptr;
689 + struct commit_list *parents = NULL;
690 + const char *reflog_msg, *author;
691 + struct strbuf sb = STRBUF_INIT;
692 +
693 + if (write_cache_as_tree(tree, 0, NULL))
694 + die(_("git write-tree failed to write a tree"));
695 +
696 + if (!get_sha1_commit("HEAD", parent)) {
697 + ptr = parent;
698 + commit_list_insert(lookup_commit(parent), &parents);
699 + } else {
700 + ptr = NULL;
701 + fprintf_ln(stderr, _("applying to an empty history"));
702 + }
703 +
704 + author = fmt_ident(state->author_name, state->author_email,
705 + state->author_date, IDENT_STRICT);
706 +
707 + if (commit_tree(state->msg, state->msg_len, tree, parents, commit,
708 + author, NULL))
709 + die(_("failed to write commit object"));
710 +
711 + reflog_msg = getenv("GIT_REFLOG_ACTION");
712 + if (!reflog_msg)
713 + reflog_msg = "am";
714 +
715 + strbuf_addf(&sb, "%s: %.*s", reflog_msg, linelen(state->msg),
716 + state->msg);
717 +
718 + update_ref(sb.buf, "HEAD", commit, ptr, 0, UPDATE_REFS_DIE_ON_ERR);
719 +
720 + strbuf_release(&sb);
721 +}
722 +
723 /**
724 * Applies all queued mail.
725 */
726 static void am_run(struct am_state *state)
727 {
728 + const char *argv_gc_auto[] = {"gc", "--auto", NULL};
729 +
730 refresh_and_write_cache();
731
732 while (state->cur <= state->last) {
@@ -709,16 +758,14 @@ static void am_run(struct am_state *state)
758 exit(128);
759 }
760
712 - /*
713 - * NEEDSWORK: After the patch has been applied to the index
714 - * with git-apply, we need to make commit as well.
715 - */
761 + do_commit(state);
762
763 next:
764 am_next(state);
765 }
766
767 am_destroy(state);
768 + run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
769 }
770
771 /**